import type { FC, FormEvent } from 'react'; import { useEffect, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { Eye, EyeOff, LogIn } from 'lucide-react'; import { Button, Input } from '../components/ui'; import { odooApi } from '../services/odoo'; import { useAuth } from '../lib/auth'; import { useTheme } from '../lib/theme'; const Login: FC = () => { const { login, brand, setBrand } = useAuth(); const { theme } = useTheme(); const navigate = useNavigate(); const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const [showPassword, setShowPassword] = useState(false); const [submitting, setSubmitting] = useState(false); const [error, setError] = useState(null); const isHomeNest = theme === 'homenest'; // El logo sigue al tema (claro/oscuro) pero el asset lo define el brand. const logo = isHomeNest ? brand.logo_oscuro : brand.logo_claro; // Sin sesión aún: el login pide el brand directo (GET público) para pintar // nombre/logo de la clínica antes de autenticar. useEffect(() => { let vivo = true; odooApi.getBrand() .then((res) => { if (vivo && res.status === 'success' && res.brand) setBrand(res.brand); }) .catch(() => { /* queda el brand cacheado/default */ }); return () => { vivo = false; }; }, [setBrand]); const onSubmit = async (e: FormEvent) => { e.preventDefault(); setError(null); if (!username.trim() || !password) { setError('Escribe usuario y contraseña'); return; } try { setSubmitting(true); await login(username.trim(), password); navigate('/', { replace: true }); } catch (err) { // Mensajes amigables: nunca mostrar errores técnicos crudos. const msg = err instanceof Error ? err.message : ''; if (msg.includes('Credenciales inválidas') || msg.includes('401')) { setError('Usuario o contraseña incorrectos'); } else { setError('No se pudo iniciar sesión. Intenta de nuevo.'); } } finally { setSubmitting(false); } }; return (
{/* Círculos decorativos de la paleta */}
{brand.nombre}

Bienvenido

Inicia sesión para continuar

setUsername(e.target.value)} autoComplete="username" autoFocus inputClassName={isHomeNest ? 'bg-theme-bg border-theme-border-strong text-theme-heading placeholder:text-theme-muted/60 focus:border-theme-accent focus:ring-theme-accent/30' : 'bg-theme-surface/10 border-white/10 text-white placeholder:text-white/40 focus:border-theme-accent focus:ring-theme-accent/30' } labelClassName={isHomeNest ? 'text-theme-muted' : 'text-white/70'} />
setPassword(e.target.value)} autoComplete="current-password" inputClassName={`pr-10 ${isHomeNest ? 'bg-theme-bg border-theme-border-strong text-theme-heading placeholder:text-theme-muted/60 focus:border-theme-accent focus:ring-theme-accent/30' : 'bg-theme-surface/10 border-white/10 text-white placeholder:text-white/40 focus:border-theme-accent focus:ring-theme-accent/30' }`} labelClassName={isHomeNest ? 'text-theme-muted' : 'text-white/70'} />
{error &&

{error}

}

{brand.pie}

); }; export default Login;