import React, { useState } from 'react'; import { login, getMicrosoftLoginUrl } from '../api/auth'; import { Link } from 'react-router-dom'; export default function Login() { const [username, setUsername] = useState(''); const [password, setPassword] = useState(''); const [error, setError] = useState(''); const [loading, setLoading] = useState(false); const [showPassword, setShowPassword] = useState(false); const [tenantChoices, setTenantChoices] = useState(null); const handleSubmit = async (e, tenantSlug) => { if (e) e.preventDefault(); setError(''); setLoading(true); try { const data = await login(username, password, tenantSlug || undefined); if (data.needs_tenant) { setTenantChoices(data.tenants || []); setLoading(false); return; } // SimpleJWT devuelve "access" y "refresh" (tokens estándar de EFC) const accessToken = data.access || data.access_token; const refreshToken = data.refresh || data.refresh_token; if (accessToken) localStorage.setItem('access', accessToken); if (refreshToken) localStorage.setItem('refresh', refreshToken); window.dispatchEvent(new CustomEvent('authStateChanged')); // Login único: la sesión local de EFC ya quedó establecida con los tokens // recibidos. En el primer ingreso el backend dispara la provisión/migración // en Hub en segundo plano — no forzamos al usuario a pasar por el Hub. // (El logout sí lo redirige al Hub para cerrar la sesión KC.) window.location.href = '/admin'; } catch (err) { setError(err.message || 'Usuario o contraseña incorrectos'); } finally { setLoading(false); } }; return (
{/* Background pattern */}
{/* Header */}

EFC

Bienvenido de vuelta

Inicia sesión para acceder a tu plataforma aduanal

{/* Selector multi-tenant */} {tenantChoices && (

Tu cuenta tiene acceso a varias organizaciones. Selecciona una:

{tenantChoices.map(t => ( ))}
)}
{/* Username */}
setUsername(e.target.value)} onFocus={e => { e.target.style.borderColor = 'transparent'; e.target.style.boxShadow = '0 0 0 2px #4DA6FF'; }} onBlur={e => { e.target.style.borderColor = '#d1d5db'; e.target.style.boxShadow = 'none'; }} />
{/* Password */}
setPassword(e.target.value)} onFocus={e => { e.target.style.borderColor = 'transparent'; e.target.style.boxShadow = '0 0 0 2px #4DA6FF'; }} onBlur={e => { e.target.style.borderColor = '#d1d5db'; e.target.style.boxShadow = 'none'; }} />
{/* Error */} {error && (

{error}

)} {/* Botón login */} {/* Divider */}
o continúa con
{/* Links */}
e.target.style.color = '#1976D2'} onMouseLeave={e => e.target.style.color = '#4DA6FF'} > ¿Olvidaste tu contraseña?
e.target.style.color = '#1976D2'} onMouseLeave={e => e.target.style.color = '#4DA6FF'} > Volver al inicio
{/* Footer */}

Desarrollado por @AduanaSoft

Solución especializada para Agentes Aduanales

{/* Floating decorations */}
); }