feat: add email verification resend functionality to login page and backend route
All checks were successful
Build and Push App / build (push) Successful in 5m35s
All checks were successful
Build and Push App / build (push) Successful in 5m35s
This commit is contained in:
@@ -13,7 +13,10 @@ const LoginPage = () => {
|
||||
const [email, setEmail] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [error, setError] = useState('');
|
||||
const [isUnverified, setIsUnverified] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [resendLoading, setResendLoading] = useState(false);
|
||||
const [resendMessage, setResendMessage] = useState('');
|
||||
const router = useRouter();
|
||||
const searchParams = useSearchParams();
|
||||
|
||||
@@ -24,6 +27,8 @@ const LoginPage = () => {
|
||||
e.preventDefault();
|
||||
setLoading(true);
|
||||
setError('');
|
||||
setIsUnverified(false);
|
||||
setResendMessage('');
|
||||
|
||||
try {
|
||||
const res = await fetch('/api/auth/login', {
|
||||
@@ -35,6 +40,9 @@ const LoginPage = () => {
|
||||
const data = await res.json();
|
||||
|
||||
if (!res.ok) {
|
||||
if (res.status === 403 && data.error?.includes('vérifier')) {
|
||||
setIsUnverified(true);
|
||||
}
|
||||
throw new Error(data.error || 'Erreur lors de la connexion');
|
||||
}
|
||||
|
||||
@@ -48,6 +56,33 @@ const LoginPage = () => {
|
||||
}
|
||||
};
|
||||
|
||||
const handleResendVerification = async () => {
|
||||
setResendLoading(true);
|
||||
setError('');
|
||||
setResendMessage('');
|
||||
|
||||
try {
|
||||
const res = await fetch('/api/auth/resend-verification', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email }),
|
||||
});
|
||||
|
||||
const data = await res.json();
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error(data.error || "Erreur lors de l'envoi");
|
||||
}
|
||||
|
||||
setResendMessage(data.message);
|
||||
setIsUnverified(false); // Hide the resend link after successful send
|
||||
} catch (err: any) {
|
||||
setError(err.message);
|
||||
} finally {
|
||||
setResendLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="min-h-[80vh] flex items-center justify-center bg-gray-50 py-12 px-4 sm:px-6 lg:px-8">
|
||||
<div className="max-w-md w-full space-y-8">
|
||||
@@ -69,10 +104,29 @@ const LoginPage = () => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{resendMessage && (
|
||||
<div className="bg-blue-50 border-l-4 border-blue-500 p-4 rounded flex items-center gap-3 text-blue-700 text-sm">
|
||||
<CheckCircle2 className="w-5 h-5 text-blue-500 flex-shrink-0" />
|
||||
<p>{resendMessage}</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{(error || queryError) && (
|
||||
<div className="bg-red-50 border-l-4 border-red-500 p-4 rounded flex items-center gap-3 text-red-700 text-sm">
|
||||
<AlertCircle className="w-5 h-5 text-red-500 flex-shrink-0" />
|
||||
<p>{error || queryError}</p>
|
||||
<div className="bg-red-50 border-l-4 border-red-500 p-4 rounded flex flex-col gap-2 text-red-700 text-sm">
|
||||
<div className="flex items-center gap-3">
|
||||
<AlertCircle className="w-5 h-5 text-red-500 flex-shrink-0" />
|
||||
<p>{error || queryError}</p>
|
||||
</div>
|
||||
{isUnverified && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleResendVerification}
|
||||
disabled={resendLoading}
|
||||
className="ml-8 text-left font-bold underline hover:text-red-800 disabled:opacity-50"
|
||||
>
|
||||
{resendLoading ? 'Envoi en cours...' : "Renvoyer l'email de vérification"}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user