156 lines
6.2 KiB
TypeScript
156 lines
6.2 KiB
TypeScript
import React, { useState } from 'react';
|
|
import { useNavigate, Link } from 'react-router';
|
|
import { BrandLogo } from '../components/common/BrandLogo';
|
|
import { FiMail, FiLock, FiArrowRight } from 'react-icons/fi';
|
|
import { FaGoogle, FaGithub } from 'react-icons/fa';
|
|
|
|
interface LoginViewProps {
|
|
onShowToast: (msg: string) => void;
|
|
}
|
|
|
|
export const LoginView: React.FC<LoginViewProps> = ({ onShowToast }) => {
|
|
const navigate = useNavigate();
|
|
const [email, setEmail] = useState('');
|
|
const [password, setPassword] = useState('');
|
|
const [rememberMe, setRememberMe] = useState(true);
|
|
|
|
const handleSubmit = (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
if (email && password) {
|
|
onShowToast('¡Bienvenido de nuevo a RyCourses!');
|
|
navigate('/');
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="min-h-[85vh] flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8 relative bg-slate-950">
|
|
{/* Glow background accents */}
|
|
<div className="absolute top-1/4 left-1/4 w-72 h-72 bg-blue-600/10 rounded-full blur-3xl pointer-events-none" />
|
|
<div className="absolute bottom-1/4 right-1/4 w-72 h-72 bg-cyan-500/10 rounded-full blur-3xl pointer-events-none" />
|
|
|
|
<div className="max-w-md w-full space-y-8 bg-slate-900/90 border border-slate-800 p-8 sm:p-10 rounded-3xl shadow-2xl backdrop-blur-md relative z-10">
|
|
|
|
{/* Header */}
|
|
<div className="text-center space-y-3">
|
|
<div className="flex justify-center">
|
|
<BrandLogo size="lg" showSubtitle={false} />
|
|
</div>
|
|
<h1 className="text-2xl font-bold text-white tracking-tight">
|
|
Iniciar Sesión
|
|
</h1>
|
|
<p className="text-xs text-slate-400">
|
|
Ingresa tus credenciales para acceder a tu panel y cursos
|
|
</p>
|
|
</div>
|
|
|
|
{/* Social logins */}
|
|
<div className="grid grid-cols-2 gap-3 pt-2">
|
|
<button
|
|
type="button"
|
|
onClick={() => {
|
|
onShowToast('Iniciando sesión con Google...');
|
|
navigate('/');
|
|
}}
|
|
className="flex items-center justify-center gap-2 py-2.5 px-4 rounded-xl bg-slate-800 hover:bg-slate-700/80 border border-slate-700 text-xs font-semibold text-slate-200 transition"
|
|
>
|
|
<FaGoogle className="text-red-400" />
|
|
<span>Google</span>
|
|
</button>
|
|
|
|
<button
|
|
type="button"
|
|
onClick={() => {
|
|
onShowToast('Iniciando sesión con GitHub...');
|
|
navigate('/');
|
|
}}
|
|
className="flex items-center justify-center gap-2 py-2.5 px-4 rounded-xl bg-slate-800 hover:bg-slate-700/80 border border-slate-700 text-xs font-semibold text-slate-200 transition"
|
|
>
|
|
<FaGithub className="text-white" />
|
|
<span>GitHub</span>
|
|
</button>
|
|
</div>
|
|
|
|
<div className="relative my-4">
|
|
<div className="absolute inset-0 flex items-center">
|
|
<div className="w-full border-t border-slate-800" />
|
|
</div>
|
|
<div className="relative flex justify-center text-xs">
|
|
<span className="px-3 bg-slate-900 text-slate-500 font-medium">o continúa con correo</span>
|
|
</div>
|
|
</div>
|
|
|
|
{/* Form */}
|
|
<form onSubmit={handleSubmit} className="space-y-4">
|
|
<div>
|
|
<label className="block text-xs font-semibold text-slate-300 mb-1.5">
|
|
Correo Electrónico
|
|
</label>
|
|
<div className="relative">
|
|
<FiMail className="absolute left-3.5 top-3.5 text-slate-500" />
|
|
<input
|
|
type="email"
|
|
required
|
|
value={email}
|
|
onChange={(e) => setEmail(e.target.value)}
|
|
placeholder="[email protected]"
|
|
className="w-full pl-10 pr-4 py-3 bg-slate-950 border border-slate-700/80 rounded-xl text-xs text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-cyan-500"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div>
|
|
<div className="flex items-center justify-between mb-1.5">
|
|
<label className="block text-xs font-semibold text-slate-300">
|
|
Contraseña
|
|
</label>
|
|
<a href="#" className="text-[11px] text-cyan-400 hover:underline">
|
|
¿Olvidaste tu contraseña?
|
|
</a>
|
|
</div>
|
|
<div className="relative">
|
|
<FiLock className="absolute left-3.5 top-3.5 text-slate-500" />
|
|
<input
|
|
type="password"
|
|
required
|
|
value={password}
|
|
onChange={(e) => setPassword(e.target.value)}
|
|
placeholder="••••••••"
|
|
className="w-full pl-10 pr-4 py-3 bg-slate-950 border border-slate-700/80 rounded-xl text-xs text-white placeholder-slate-500 focus:outline-none focus:ring-2 focus:ring-cyan-500"
|
|
/>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="flex items-center justify-between pt-1">
|
|
<label className="flex items-center gap-2 cursor-pointer text-xs text-slate-400">
|
|
<input
|
|
type="checkbox"
|
|
checked={rememberMe}
|
|
onChange={(e) => setRememberMe(e.target.checked)}
|
|
className="rounded border-slate-700 bg-slate-950 text-cyan-500 focus:ring-cyan-500"
|
|
/>
|
|
<span>Recordar sesión</span>
|
|
</label>
|
|
</div>
|
|
|
|
<button
|
|
type="submit"
|
|
className="w-full py-3.5 px-4 bg-gradient-to-r from-blue-600 to-cyan-500 hover:from-blue-500 hover:to-cyan-400 text-white font-bold rounded-xl text-sm shadow-lg shadow-cyan-500/25 transition-all flex items-center justify-center gap-2"
|
|
>
|
|
<span>Iniciar Sesión</span>
|
|
<FiArrowRight />
|
|
</button>
|
|
</form>
|
|
|
|
{/* Footer link */}
|
|
<p className="text-center text-xs text-slate-400 pt-2">
|
|
¿No tienes una cuenta aún?{' '}
|
|
<Link to="/register" className="text-cyan-400 font-bold hover:underline">
|
|
Regístrate gratis
|
|
</Link>
|
|
</p>
|
|
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|