diff --git a/src/features/auth/pages/ConfirmEmailPage.client.js b/src/features/auth/pages/ConfirmEmailPage.client.js
index 46fbccf..3659b90 100644
--- a/src/features/auth/pages/ConfirmEmailPage.client.js
+++ b/src/features/auth/pages/ConfirmEmailPage.client.js
@@ -1,10 +1,7 @@
'use client';
-/**
- * Confirm Email Page Component
- */
-
import { useState, useEffect, useRef } from 'react';
+import { Card } from '@zen/core/shared/components';
export default function ConfirmEmailPage({ onSubmit, onNavigate, email, token }) {
const [error, setError] = useState('');
@@ -15,26 +12,20 @@ export default function ConfirmEmailPage({ onSubmit, onNavigate, email, token })
useEffect(() => {
console.log('ConfirmEmailPage useEffect triggered', { email, token, hasVerified });
-
- // Check for persisted success message on mount
+
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); // Mark as verified to prevent re-verification
- // Clear the persisted message after showing it
+ setHasVerified(true);
sessionStorage.removeItem('emailVerificationSuccess');
- // Redirect after showing the message
- setTimeout(() => {
- onNavigate('login');
- }, 3000);
+ setTimeout(() => onNavigate('login'), 3000);
return;
}
- // Auto-verify on mount, but only once
if (email && token && !hasVerified && !isVerifyingRef.current) {
console.log('Starting email verification');
verifyEmail();
@@ -46,22 +37,18 @@ export default function ConfirmEmailPage({ onSubmit, onNavigate, email, token })
}, [email, token, hasVerified, onNavigate]);
async function verifyEmail() {
- // Prevent multiple calls
if (hasVerified || isVerifyingRef.current) {
console.log('Email verification already attempted or in progress');
return;
}
-
- // Set flags IMMEDIATELY to prevent multiple calls
+
isVerifyingRef.current = true;
setHasVerified(true);
-
- // Clear any existing states at the start
setError('');
setSuccess('');
-
+
console.log('Starting email verification for:', email);
-
+
const formData = new FormData();
formData.set('email', email);
formData.set('token', token);
@@ -69,20 +56,14 @@ export default function ConfirmEmailPage({ onSubmit, onNavigate, email, 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.';
-
- // Persist success message in sessionStorage
sessionStorage.setItem('emailVerificationSuccess', successMessage);
-
setSuccess(successMessage);
setIsLoading(false);
- // Redirect to login after 3 seconds
- setTimeout(() => {
- onNavigate('login');
- }, 3000);
+ setTimeout(() => onNavigate('login'), 3000);
} else {
console.log('Verification failed:', result.error);
setError(result.error || 'Échec de la vérification de l\'e-mail');
@@ -98,65 +79,55 @@ export default function ConfirmEmailPage({ onSubmit, onNavigate, email, token })
console.log('ConfirmEmailPage render', { success, error, isLoading, hasVerified });
return (
-
- {/* Header */}
-
-
- Vérification de l'e-mail
-
-
- Nous vérifions votre adresse e-mail...
-
-
-
- {isLoading && (
-
-
-
Vérification de votre e-mail en cours...
-
- )}
-
- {/* Success Message - Only show if success and no error */}
- {success && !error && (
-
- )}
-
- {/* Error Message - Only show if error and no success */}
- {error && !success && (
-
- )}
-
- {/* Redirect message - Only show if success and no error */}
- {success && !error && (
-
Redirection vers la connexion...
- )}
+
+
+
+ Vérification de l'e-mail
+
+
+ Nous vérifions votre adresse e-mail...
+
+
+ {isLoading && (
+
+
+
Vérification de votre e-mail en cours...
+
+ )}
+
+ {success && !error && (
+
+ )}
+
+ {error && !success && (
+
+ )}
+
+ {success && !error && (
+ Redirection vers la connexion...
+ )}
+
);
}
-
-
-
diff --git a/src/features/auth/pages/ForgotPasswordPage.client.js b/src/features/auth/pages/ForgotPasswordPage.client.js
index a7c0e12..afe7126 100644
--- a/src/features/auth/pages/ForgotPasswordPage.client.js
+++ b/src/features/auth/pages/ForgotPasswordPage.client.js
@@ -1,18 +1,13 @@
'use client';
-/**
- * Forgot Password Page Component
- */
-
import { useState, useEffect } from 'react';
+import { Card, Input, Button } from '@zen/core/shared/components';
export default function ForgotPasswordPage({ onSubmit, onNavigate, currentUser = null }) {
const [error, setError] = useState('');
const [isLoading, setIsLoading] = useState(false);
const [success, setSuccess] = useState('');
- const [formData, setFormData] = useState({
- email: ''
- });
+ const [email, setEmail] = useState('');
const [honeypot, setHoneypot] = useState('');
const [formLoadedAt, setFormLoadedAt] = useState(0);
@@ -20,14 +15,6 @@ export default function ForgotPasswordPage({ onSubmit, onNavigate, currentUser =
setFormLoadedAt(Date.now());
}, []);
- const handleChange = (e) => {
- const { name, value } = e.target;
- setFormData(prev => ({
- ...prev,
- [name]: value
- }));
- };
-
async function handleSubmit(e) {
e.preventDefault();
setError('');
@@ -35,13 +22,13 @@ export default function ForgotPasswordPage({ onSubmit, onNavigate, currentUser =
setIsLoading(true);
const submitData = new FormData();
- submitData.append('email', formData.email);
+ submitData.append('email', email);
submitData.append('_hp', honeypot);
submitData.append('_t', String(formLoadedAt));
try {
const result = await onSubmit(submitData);
-
+
if (result.success) {
setSuccess(result.message);
setIsLoading(false);
@@ -56,119 +43,91 @@ export default function ForgotPasswordPage({ onSubmit, onNavigate, currentUser =
}
}
- const inputClasses = 'w-full px-3 py-2.5 rounded-lg text-sm focus:outline-none transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed bg-white border border-neutral-300 text-neutral-900 placeholder-neutral-400 focus:border-neutral-500 focus:ring-1 focus:ring-neutral-500/20 dark:bg-neutral-900 dark:border-neutral-700/50 dark:text-white dark:placeholder-neutral-500 dark:focus:border-neutral-600 dark:focus:ring-neutral-600/20';
-
return (
-
- {/* Header */}
-
-
- Mot de passe oublié
-
-
- Entrez votre adresse e-mail et nous vous enverrons un lien pour réinitialiser votre mot de passe.
-
-
-
- {/* Already Connected Message */}
- {currentUser && (
-
- )}
-
- {/* Error Message */}
- {error && (
-
- )}
-
- {/* Success Message */}
- {success && (
-
- )}
-
- {/* Forgot Password Form */}
-
-
- {/* Back to Login Link */}
-
+
+
+
+ Mot de passe oublié
+
+
+ Entrez votre adresse e-mail et nous vous enverrons un lien pour réinitialiser votre mot de passe.
+
+
+ {currentUser && (
+
+ )}
+
+ {error && (
+
+ )}
+
+ {success && (
+
+ )}
+
+
+
+
+
);
}
-
-
-
diff --git a/src/features/auth/pages/LoginPage.client.js b/src/features/auth/pages/LoginPage.client.js
index b419441..6e4fef3 100644
--- a/src/features/auth/pages/LoginPage.client.js
+++ b/src/features/auth/pages/LoginPage.client.js
@@ -1,20 +1,14 @@
'use client';
-/**
- * Login Page Component
- */
-
import { useState, useEffect } from 'react';
import { useRouter } from 'next/navigation';
+import { Card, Input, Button } from '@zen/core/shared/components';
export default function LoginPage({ onSubmit, onNavigate, onSetSessionCookie, redirectAfterLogin = '/', currentUser = null }) {
const [error, setError] = useState('');
const [success, setSuccess] = useState('');
const [isLoading, setIsLoading] = useState(false);
- const [formData, setFormData] = useState({
- email: '',
- password: ''
- });
+ const [formData, setFormData] = useState({ email: '', password: '' });
const [honeypot, setHoneypot] = useState('');
const [formLoadedAt, setFormLoadedAt] = useState(0);
const router = useRouter();
@@ -23,21 +17,12 @@ export default function LoginPage({ onSubmit, onNavigate, onSetSessionCookie, re
setFormLoadedAt(Date.now());
}, []);
- // If already logged in, redirect to redirectAfterLogin
useEffect(() => {
if (currentUser) {
router.replace(redirectAfterLogin);
}
}, [currentUser, redirectAfterLogin, router]);
- const handleChange = (e) => {
- const { name, value } = e.target;
- setFormData(prev => ({
- ...prev,
- [name]: value
- }));
- };
-
const handleKeyPress = (e) => {
if (e.key === 'Enter' && !isLoading && !success) {
handleSubmit();
@@ -57,21 +42,16 @@ export default function LoginPage({ onSubmit, onNavigate, onSetSessionCookie, re
try {
const result = await onSubmit(submitData);
-
+
if (result.success) {
const successMsg = result.message || 'Connexion réussie ! Redirection...';
-
- // Display success message immediately (no page refresh because we didn't set cookie yet)
setSuccess(successMsg);
setIsLoading(false);
-
- // Wait for user to see the success message
+
setTimeout(async () => {
- // Now set the session cookie (this might cause a refresh, but we're redirecting anyway)
if (result.sessionToken && onSetSessionCookie) {
await onSetSessionCookie(result.sessionToken);
}
- // Then navigate
router.push(redirectAfterLogin);
}, 1500);
} else {
@@ -85,144 +65,114 @@ export default function LoginPage({ onSubmit, onNavigate, onSetSessionCookie, re
}
};
- const inputClasses = 'w-full px-[10px] py-[7px] rounded text-[13px] focus:outline-none transition-all duration-[120ms] ease-out disabled:opacity-50 disabled:cursor-not-allowed bg-white border border-neutral-300 text-neutral-900 placeholder-neutral-400 focus:border-neutral-500 focus:ring-1 focus:ring-neutral-500/20 dark:bg-neutral-900 dark:border-neutral-700/50 dark:text-white dark:placeholder-neutral-500 dark:focus:border-neutral-600 dark:focus:ring-neutral-600/20';
-
return (
-
- {/* Header */}
-
-
- Connexion
-
-
- Veuillez vous connecter pour continuer.
-
-
-
- {/* Already logged in: redirecting (brief message while redirect runs) */}
- {currentUser && (
-
- )}
-
- {/* Success Message */}
- {success && (
-
- )}
-
- {/* Error Message */}
- {error && (
-
- )}
-
- {/* Login Form */}
-
- {/* Honeypot — invisible to humans, filled by bots */}
-
-
- setHoneypot(e.target.value)} />
-
-
-
-
-
-
-
-
-
-
-
- {/* Register Link */}
-
+
+
+
+ Connexion
+
+
+ Veuillez vous connecter pour continuer.
+
+
+ {currentUser && (
+
+ )}
+
+ {success && (
+
+ )}
+
+ {error && (
+
+ )}
+
+
+
+
+ setHoneypot(e.target.value)} />
+
+
+
setFormData(prev => ({ ...prev, email: value }))}
+ onKeyDown={handleKeyPress}
+ placeholder="your@email.com"
+ disabled={!!success || !!currentUser}
+ required
+ />
+
+
+
+
setFormData(prev => ({ ...prev, password: value }))}
+ onKeyDown={handleKeyPress}
+ placeholder="••••••••"
+ disabled={!!success || !!currentUser}
+ />
+
+
+
+
+
+
+
);
}
-
-
-
diff --git a/src/features/auth/pages/LogoutPage.client.js b/src/features/auth/pages/LogoutPage.client.js
index 6e383f5..59f7c56 100644
--- a/src/features/auth/pages/LogoutPage.client.js
+++ b/src/features/auth/pages/LogoutPage.client.js
@@ -1,11 +1,8 @@
'use client';
-/**
- * Logout Page Component
- */
-
import { useState } from 'react';
import { useRouter } from 'next/navigation';
+import { Card, Button } from '@zen/core/shared/components';
export default function LogoutPage({ onLogout, onSetSessionCookie }) {
const [error, setError] = useState('');
@@ -19,10 +16,8 @@ export default function LogoutPage({ onLogout, onSetSessionCookie }) {
setIsLoading(true);
try {
- // Call the logout action if provided
if (onLogout) {
const result = await onLogout();
-
if (result && !result.success) {
setError(result.error || 'Échec de la déconnexion');
setIsLoading(false);
@@ -30,20 +25,14 @@ export default function LogoutPage({ onLogout, onSetSessionCookie }) {
}
}
- // Clear session cookie if provided
if (onSetSessionCookie) {
await onSetSessionCookie('', { expires: new Date(0) });
}
- // Show success message
setSuccess('Vous avez été déconnecté. Redirection...');
setIsLoading(false);
-
- // Wait for user to see the success message, then redirect
- setTimeout(() => {
- router.push('/');
- }, 100);
-
+
+ setTimeout(() => router.push('/'), 100);
} catch (err) {
console.error('Logout error:', err);
setError('Une erreur inattendue s\'est produite lors de la déconnexion');
@@ -52,8 +41,7 @@ export default function LogoutPage({ onLogout, onSetSessionCookie }) {
};
return (
-
- {/* Header */}
+
Prêt à vous déconnecter ?
@@ -63,7 +51,6 @@ export default function LogoutPage({ onLogout, onSetSessionCookie }) {
- {/* Success Message */}
{success && (
@@ -73,7 +60,6 @@ export default function LogoutPage({ onLogout, onSetSessionCookie }) {
)}
- {/* Error Message */}
{error && (
@@ -83,35 +69,26 @@ export default function LogoutPage({ onLogout, onSetSessionCookie }) {
)}
- {/* Logout Button */}
-
-
-
+
- {/* Cancel Link */}
-
+
Vous avez changé d'avis ?
+
+ Retour
+
+
+
);
}
diff --git a/src/features/auth/pages/RegisterPage.client.js b/src/features/auth/pages/RegisterPage.client.js
index f0f3fb9..878301c 100644
--- a/src/features/auth/pages/RegisterPage.client.js
+++ b/src/features/auth/pages/RegisterPage.client.js
@@ -1,11 +1,7 @@
'use client';
-/**
- * Register Page Component
- */
-
import { useState, useEffect } from 'react';
-import { PasswordStrengthIndicator } from '@zen/core/shared/components';
+import { Card, Input, Button, PasswordStrengthIndicator } from '@zen/core/shared/components';
export default function RegisterPage({ onSubmit, onNavigate, currentUser = null }) {
const [error, setError] = useState('');
@@ -24,107 +20,50 @@ export default function RegisterPage({ onSubmit, onNavigate, currentUser = null
setFormLoadedAt(Date.now());
}, []);
- // Validation functions
const validateEmail = (email) => {
const errors = [];
-
- if (email.length > 254) {
- errors.push('L\'e-mail doit contenir 254 caractères ou moins');
- }
-
+ if (email.length > 254) errors.push('L\'e-mail doit contenir 254 caractères ou moins');
return errors;
};
const validatePassword = (password) => {
const errors = [];
-
- if (password.length < 8) {
- errors.push('Le mot de passe doit contenir au moins 8 caractères');
- }
-
- if (password.length > 128) {
- errors.push('Le mot de passe doit contenir 128 caractères ou moins');
- }
-
- if (!/[A-Z]/.test(password)) {
- errors.push('Le mot de passe doit contenir au moins une majuscule');
- }
-
- if (!/[a-z]/.test(password)) {
- errors.push('Le mot de passe doit contenir au moins une minuscule');
- }
-
- if (!/\d/.test(password)) {
- errors.push('Le mot de passe doit contenir au moins un chiffre');
- }
-
+ if (password.length < 8) errors.push('Le mot de passe doit contenir au moins 8 caractères');
+ if (password.length > 128) errors.push('Le mot de passe doit contenir 128 caractères ou moins');
+ if (!/[A-Z]/.test(password)) errors.push('Le mot de passe doit contenir au moins une majuscule');
+ if (!/[a-z]/.test(password)) errors.push('Le mot de passe doit contenir au moins une minuscule');
+ if (!/\d/.test(password)) errors.push('Le mot de passe doit contenir au moins un chiffre');
return errors;
};
const validateName = (name) => {
const errors = [];
-
- if (name.trim().length === 0) {
- errors.push('Le nom ne peut pas être vide');
- }
-
- if (name.length > 100) {
- errors.push('Le nom doit contenir 100 caractères ou moins');
- }
-
+ if (name.trim().length === 0) errors.push('Le nom ne peut pas être vide');
+ if (name.length > 100) errors.push('Le nom doit contenir 100 caractères ou moins');
return errors;
};
const isFormValid = () => {
- const emailErrors = validateEmail(formData.email);
- const passwordErrors = validatePassword(formData.password);
- const nameErrors = validateName(formData.name);
-
- return emailErrors.length === 0 &&
- passwordErrors.length === 0 &&
- nameErrors.length === 0 &&
+ return validateEmail(formData.email).length === 0 &&
+ validatePassword(formData.password).length === 0 &&
+ validateName(formData.name).length === 0 &&
formData.password === formData.confirmPassword &&
formData.email.trim().length > 0;
};
- const handleChange = (e) => {
- const { name, value } = e.target;
- setFormData(prev => ({
- ...prev,
- [name]: value
- }));
- };
-
async function handleSubmit(e) {
e.preventDefault();
setError('');
setSuccess('');
setIsLoading(true);
- // Frontend validation
const emailErrors = validateEmail(formData.email);
const passwordErrors = validatePassword(formData.password);
const nameErrors = validateName(formData.name);
-
- if (emailErrors.length > 0) {
- setError(emailErrors[0]); // Show first error
- setIsLoading(false);
- return;
- }
-
- if (passwordErrors.length > 0) {
- setError(passwordErrors[0]); // Show first error
- setIsLoading(false);
- return;
- }
-
- if (nameErrors.length > 0) {
- setError(nameErrors[0]); // Show first error
- setIsLoading(false);
- return;
- }
- // Validate password match
+ if (emailErrors.length > 0) { setError(emailErrors[0]); setIsLoading(false); return; }
+ if (passwordErrors.length > 0) { setError(passwordErrors[0]); setIsLoading(false); return; }
+ if (nameErrors.length > 0) { setError(nameErrors[0]); setIsLoading(false); return; }
if (formData.password !== formData.confirmPassword) {
setError('Les mots de passe ne correspondent pas');
setIsLoading(false);
@@ -141,7 +80,7 @@ export default function RegisterPage({ onSubmit, onNavigate, currentUser = null
try {
const result = await onSubmit(submitData);
-
+
if (result.success) {
setSuccess(result.message);
setIsLoading(false);
@@ -156,182 +95,140 @@ export default function RegisterPage({ onSubmit, onNavigate, currentUser = null
}
}
- const inputClasses = 'w-full px-3 py-2.5 rounded-lg text-sm focus:outline-none transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed bg-white border border-neutral-300 text-neutral-900 placeholder-neutral-400 focus:border-neutral-500 focus:ring-1 focus:ring-neutral-500/20 dark:bg-neutral-900 dark:border-neutral-700/50 dark:text-white dark:placeholder-neutral-500 dark:focus:border-neutral-600 dark:focus:ring-neutral-600/20';
-
return (
-
- {/* Header */}
-
-
- Créer un compte
-
-
- Inscrivez-vous pour commencer.
-
-
-
- {/* Already Connected Message */}
- {currentUser && (
-
- )}
-
- {/* Error Message */}
- {error && (
-
- )}
-
- {/* Success Message */}
- {success && (
-
- )}
-
- {/* Registration Form */}
-
-
- {/* Login Link */}
-
+
+
+
+ Créer un compte
+
+
+ Inscrivez-vous pour commencer.
+
+
+ {currentUser && (
+
+ )}
+
+ {error && (
+
+ )}
+
+ {success && (
+
+ )}
+
+
+
+
+
);
}
-
-
-
diff --git a/src/features/auth/pages/ResetPasswordPage.client.js b/src/features/auth/pages/ResetPasswordPage.client.js
index 9ece52b..fcc7545 100644
--- a/src/features/auth/pages/ResetPasswordPage.client.js
+++ b/src/features/auth/pages/ResetPasswordPage.client.js
@@ -1,80 +1,38 @@
'use client';
-/**
- * Reset Password Page Component
- */
-
import { useState } from 'react';
-import { PasswordStrengthIndicator } from '@zen/core/shared/components';
+import { Card, Input, Button, PasswordStrengthIndicator } from '@zen/core/shared/components';
export default function ResetPasswordPage({ onSubmit, onNavigate, email, token }) {
const [error, setError] = useState('');
const [isLoading, setIsLoading] = useState(false);
const [success, setSuccess] = useState('');
- const [formData, setFormData] = useState({
- newPassword: '',
- confirmPassword: ''
- });
+ const [formData, setFormData] = useState({ newPassword: '', confirmPassword: '' });
- // Validation functions
const validatePassword = (password) => {
const errors = [];
-
- if (password.length < 8) {
- errors.push('Le mot de passe doit contenir au moins 8 caractères');
- }
-
- if (password.length > 128) {
- errors.push('Le mot de passe doit contenir 128 caractères ou moins');
- }
-
- if (!/[A-Z]/.test(password)) {
- errors.push('Le mot de passe doit contenir au moins une majuscule');
- }
-
- if (!/[a-z]/.test(password)) {
- errors.push('Le mot de passe doit contenir au moins une minuscule');
- }
-
- if (!/\d/.test(password)) {
- errors.push('Le mot de passe doit contenir au moins un chiffre');
- }
-
+ if (password.length < 8) errors.push('Le mot de passe doit contenir au moins 8 caractères');
+ if (password.length > 128) errors.push('Le mot de passe doit contenir 128 caractères ou moins');
+ if (!/[A-Z]/.test(password)) errors.push('Le mot de passe doit contenir au moins une majuscule');
+ if (!/[a-z]/.test(password)) errors.push('Le mot de passe doit contenir au moins une minuscule');
+ if (!/\d/.test(password)) errors.push('Le mot de passe doit contenir au moins un chiffre');
return errors;
};
const isFormValid = () => {
- const passwordErrors = validatePassword(formData.newPassword);
-
- return passwordErrors.length === 0 &&
+ return validatePassword(formData.newPassword).length === 0 &&
formData.newPassword === formData.confirmPassword &&
formData.newPassword.length > 0;
};
- const handleChange = (e) => {
- const { name, value } = e.target;
- setFormData(prev => ({
- ...prev,
- [name]: value
- }));
- };
-
async function handleSubmit(e) {
e.preventDefault();
setError('');
setSuccess('');
setIsLoading(true);
- // Frontend validation
const passwordErrors = validatePassword(formData.newPassword);
-
- if (passwordErrors.length > 0) {
- setError(passwordErrors[0]); // Show first error
- setIsLoading(false);
- return;
- }
-
- // Validate password match
+ if (passwordErrors.length > 0) { setError(passwordErrors[0]); setIsLoading(false); return; }
if (formData.newPassword !== formData.confirmPassword) {
setError('Les mots de passe ne correspondent pas');
setIsLoading(false);
@@ -89,14 +47,11 @@ export default function ResetPasswordPage({ onSubmit, onNavigate, email, token }
try {
const result = await onSubmit(submitData);
-
+
if (result.success) {
setSuccess(result.message);
setIsLoading(false);
- // Redirect to login after 2 seconds
- setTimeout(() => {
- onNavigate('login');
- }, 2000);
+ setTimeout(() => onNavigate('login'), 2000);
} else {
setError(result.error || 'Échec de la réinitialisation du mot de passe');
setIsLoading(false);
@@ -108,115 +63,89 @@ export default function ResetPasswordPage({ onSubmit, onNavigate, email, token }
}
}
- const inputClasses = 'w-full px-3 py-2.5 rounded-lg text-sm focus:outline-none transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed bg-white border border-neutral-300 text-neutral-900 placeholder-neutral-400 focus:border-neutral-500 focus:ring-1 focus:ring-neutral-500/20 dark:bg-neutral-900 dark:border-neutral-700/50 dark:text-white dark:placeholder-neutral-500 dark:focus:border-neutral-600 dark:focus:ring-neutral-600/20';
-
return (
-
- {/* Header */}
-
-
- Réinitialiser le mot de passe
-
-
- Saisissez votre nouveau mot de passe ci-dessous.
-
-
-
- {/* Error Message */}
- {error && (
-
- )}
-
- {/* Success Message */}
- {success && (
-
- )}
-
- {/* Reset Password Form */}
-
-
- {/* Back to Login Link */}
-
+
+
+
+ Réinitialiser le mot de passe
+
+
+ Saisissez votre nouveau mot de passe ci-dessous.
+
+
+ {error && (
+
+ )}
+
+ {success && (
+
+ )}
+
+
+
+
+
);
}
-
-
-