1e529a6741
- use `min-h-dvh`, `flex-col`, and top-aligned justify on small screens in AuthPage - add `mx-auto` to all auth page cards for consistent centering
128 lines
4.9 KiB
JavaScript
128 lines
4.9 KiB
JavaScript
'use client';
|
|
|
|
import { useState, useEffect, useRef } from 'react';
|
|
import { Card } from '@zen/core/shared/components';
|
|
import AuthPageHeader from '../components/AuthPageHeader.js';
|
|
|
|
export default function ConfirmEmailPage({ onSubmit, onNavigate, email, token }) {
|
|
const [error, setError] = useState('');
|
|
const [isLoading, setIsLoading] = useState(true);
|
|
const [success, setSuccess] = useState('');
|
|
const [hasVerified, setHasVerified] = useState(false);
|
|
const isVerifyingRef = useRef(false);
|
|
|
|
useEffect(() => {
|
|
console.log('ConfirmEmailPage useEffect triggered', { email, token, hasVerified });
|
|
|
|
const persistedSuccess = sessionStorage.getItem('emailVerificationSuccess');
|
|
console.log('Persisted success message:', persistedSuccess);
|
|
|
|
if (persistedSuccess) {
|
|
console.log('Restoring persisted success message');
|
|
setSuccess(persistedSuccess);
|
|
setIsLoading(false);
|
|
setHasVerified(true);
|
|
sessionStorage.removeItem('emailVerificationSuccess');
|
|
setTimeout(() => onNavigate('login'), 3000);
|
|
return;
|
|
}
|
|
|
|
if (email && token && !hasVerified && !isVerifyingRef.current) {
|
|
console.log('Starting email verification');
|
|
verifyEmail();
|
|
} else if (!email || !token) {
|
|
console.log('Invalid email or token');
|
|
setError('Lien de vérification invalide');
|
|
setIsLoading(false);
|
|
}
|
|
}, [email, token, hasVerified, onNavigate]);
|
|
|
|
async function verifyEmail() {
|
|
if (hasVerified || isVerifyingRef.current) {
|
|
console.log('Email verification already attempted or in progress');
|
|
return;
|
|
}
|
|
|
|
isVerifyingRef.current = true;
|
|
setHasVerified(true);
|
|
setError('');
|
|
setSuccess('');
|
|
|
|
console.log('Starting email verification for:', email);
|
|
|
|
const formData = new FormData();
|
|
formData.set('email', email);
|
|
formData.set('token', token);
|
|
|
|
try {
|
|
const result = await onSubmit(formData);
|
|
console.log('Verification result:', result);
|
|
|
|
if (result.success) {
|
|
console.log('Verification successful');
|
|
const successMessage = result.message || 'E-mail vérifié avec succès. Vous pouvez maintenant vous connecter.';
|
|
sessionStorage.setItem('emailVerificationSuccess', successMessage);
|
|
setSuccess(successMessage);
|
|
setIsLoading(false);
|
|
setTimeout(() => onNavigate('login'), 3000);
|
|
} else {
|
|
console.log('Verification failed:', result.error);
|
|
setError(result.error || 'Échec de la vérification de l\'e-mail');
|
|
setIsLoading(false);
|
|
}
|
|
} catch (err) {
|
|
console.error('Email verification error:', err);
|
|
setError('Une erreur inattendue s\'est produite');
|
|
setIsLoading(false);
|
|
}
|
|
}
|
|
|
|
console.log('ConfirmEmailPage render', { success, error, isLoading, hasVerified });
|
|
|
|
return (
|
|
<Card variant="default" padding="md" spacing="none" className="w-full max-w-md mx-auto">
|
|
<AuthPageHeader title="Vérification de l'e-mail" description="Nous vérifions votre adresse e-mail..." />
|
|
|
|
{isLoading && (
|
|
<div className="flex flex-col items-center py-10">
|
|
<div className="w-12 h-12 border-4 border-neutral-300 border-t-neutral-900 rounded-full animate-spin dark:border-neutral-700/50 dark:border-t-white"></div>
|
|
<p className="mt-5 text-neutral-600 dark:text-neutral-400 text-sm">Vérification de votre e-mail en cours...</p>
|
|
</div>
|
|
)}
|
|
|
|
{success && !error && (
|
|
<div className="mb-4 p-3 bg-green-50 border border-green-200 rounded-lg dark:bg-green-500/10 dark:border-green-500/20">
|
|
<div className="flex items-center space-x-2">
|
|
<div className="w-1.5 h-1.5 bg-green-500 rounded-full flex-shrink-0"></div>
|
|
<span className="text-xs text-green-700 dark:text-green-400">{success}</span>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{error && !success && (
|
|
<div>
|
|
<div className="mb-4 p-3 bg-red-50 border border-red-200 rounded-lg dark:bg-red-500/10 dark:border-red-500/20">
|
|
<div className="flex items-center space-x-2">
|
|
<div className="w-1.5 h-1.5 bg-red-500 rounded-full flex-shrink-0"></div>
|
|
<span className="text-xs text-red-700 dark:text-red-400">{error}</span>
|
|
</div>
|
|
</div>
|
|
<div className="mt-6 pt-6 border-t border-neutral-200 dark:border-neutral-800/50 text-center">
|
|
<a
|
|
href="#"
|
|
onClick={(e) => { e.preventDefault(); onNavigate('login'); }}
|
|
className="text-sm text-neutral-900 hover:text-neutral-600 font-medium transition-colors duration-200 dark:text-white dark:hover:text-neutral-300"
|
|
>
|
|
← Retour à la connexion
|
|
</a>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
{success && !error && (
|
|
<p className="text-center text-neutral-600 dark:text-neutral-400 text-sm mt-3">Redirection vers la connexion...</p>
|
|
)}
|
|
</Card>
|
|
);
|
|
}
|