diff --git a/src/pages/Login.jsx b/src/pages/Login.jsx index 2cbde64..14ecbf2 100644 --- a/src/pages/Login.jsx +++ b/src/pages/Login.jsx @@ -1,19 +1,43 @@ -import { useState } from 'react'; +import { useState, useEffect } from 'react'; import { Link, useNavigate } from 'react-router-dom'; import { useAuth } from '../contexts/AuthContext'; import { useLanguage } from '../contexts/LanguageContext'; -import { Mail, Lock, ArrowRight, Loader2 } from 'lucide-react'; +import { Mail, Lock, ArrowRight, Loader2, AlertTriangle, RefreshCw } from 'lucide-react'; import BrandLogo from '../components/BrandLogo'; +import api from '../services/api'; import toast from 'react-hot-toast'; export default function Login() { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [loading, setLoading] = useState(false); + const [needsVerification, setNeedsVerification] = useState(false); + const [resendCooldown, setResendCooldown] = useState(0); + const [resending, setResending] = useState(false); const { login } = useAuth(); const { t } = useLanguage(); const navigate = useNavigate(); + useEffect(() => { + if (resendCooldown <= 0) return; + const timer = setTimeout(() => setResendCooldown(c => c - 1), 1000); + return () => clearTimeout(timer); + }, [resendCooldown]); + + const handleResend = async () => { + if (resendCooldown > 0 || resending) return; + setResending(true); + try { + await api.post('/auth/resend-verification', { email }); + toast.success(t('auth.emailVerificationResendSuccess')); + setResendCooldown(60); + } catch { + toast.error(t('auth.emailVerificationResendFailed')); + } finally { + setResending(false); + } + }; + const handleSubmit = async (e) => { e.preventDefault(); setLoading(true); @@ -22,7 +46,11 @@ export default function Login() { toast.success(t('auth.loginSuccess')); navigate('/dashboard'); } catch (err) { - toast.error(err.response?.data?.error || t('auth.loginFailed')); + if (err.response?.data?.needsVerification) { + setNeedsVerification(true); + } else { + toast.error(err.response?.data?.error || t('auth.loginFailed')); + } } finally { setLoading(false); } @@ -101,6 +129,25 @@ export default function Login() { + {needsVerification && ( +
{t('auth.emailVerificationBanner')}
+{t('auth.noAccount')}{' '}