NEXUS / src /app /login /page.tsx
dimensionalpulsar's picture
Upload 29 files
8457d97 verified
"use client";
import React, { useState, useEffect } from "react";
import { auth } from "@/lib/firebase";
import { signInWithEmailAndPassword, onAuthStateChanged } from "firebase/auth";
import { useRouter } from "next/navigation";
export default function LoginPage() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const router = useRouter();
useEffect(() => {
const unsub = onAuthStateChanged(auth, (user) => {
if (user) router.push("/");
});
return () => unsub();
}, [router]);
const handleLogin = async (e: React.FormEvent) => {
e.preventDefault();
setLoading(true);
setError("");
try {
await signInWithEmailAndPassword(auth, email, password);
router.push("/");
} catch (err: any) {
setError(err.message || "Error al iniciar sesión");
} finally {
setLoading(false);
}
};
return (
<div className="min-h-screen bg-[#0f172a] flex items-center justify-center p-6 relative overflow-hidden">
{/* Background Decor */}
<div className="absolute top-0 left-0 w-full h-full">
<div className="absolute top-[-10%] left-[-10%] w-[40%] h-[40%] bg-blue-600/20 blur-[120px] rounded-full"></div>
<div className="absolute bottom-[-10%] right-[-10%] w-[40%] h-[40%] bg-purple-600/20 blur-[120px] rounded-full"></div>
</div>
<div className="w-full max-w-md relative z-10 transition-all duration-700 animate-in fade-in slide-in-from-bottom-8">
<div className="bg-white/5 border border-white/10 p-10 rounded-[40px] backdrop-blur-3xl shadow-2xl">
<div className="text-center mb-10">
<h1 className="text-4xl font-black bg-gradient-to-r from-blue-400 to-indigo-500 bg-clip-text text-transparent mb-2">
ERP System
</h1>
<p className="text-gray-400 text-sm font-medium">Panel de control empresarial premium</p>
</div>
<form onSubmit={handleLogin} className="space-y-6">
<div>
<input
type="email"
placeholder="Email corporativo"
required
value={email}
onChange={(e) => setEmail(e.target.value)}
className="w-full bg-white/5 border border-white/10 rounded-2xl px-6 py-4 outline-none focus:border-blue-500/50 focus:bg-white/10 transition-all placeholder:text-gray-600"
/>
</div>
<div>
<input
type="password"
placeholder="Contraseña"
required
value={password}
onChange={(e) => setPassword(e.target.value)}
className="w-full bg-white/5 border border-white/10 rounded-2xl px-6 py-4 outline-none focus:border-blue-500/50 focus:bg-white/10 transition-all placeholder:text-gray-600"
/>
</div>
{error && (
<div className="bg-red-500/10 border border-red-500/20 text-red-400 text-xs p-4 rounded-xl animate-shake">
{error}
</div>
)}
<button
type="submit"
disabled={loading}
className="w-full bg-gradient-to-r from-blue-600 to-indigo-600 hover:from-blue-500 hover:to-indigo-500 text-white font-bold py-4 rounded-2xl shadow-lg shadow-blue-900/20 hover:shadow-blue-900/40 transition-all transform active:scale-95 disabled:opacity-50"
>
{loading ? (
<span className="flex items-center justify-center gap-2">
<svg className="animate-spin h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
Autenticando...
</span>
) : (
"Entrar"
)}
</button>
</form>
<p className="mt-8 text-center text-xs text-gray-500 font-medium">
Acceso restringido para administradores autorizados
</p>
</div>
</div>
</div>
);
}