- Add reset-password page to handle password reset flow - Fix forgot-password to call real API - Update contest dates (validation: Dec 1-31, recovery: Dec 1 - Jan 31) - Update draw date to Feb 1, 2026 - Improve GamePeriod and GrandPrize components design - Remove "livré chez vous" text 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
163 lines
5.6 KiB
TypeScript
163 lines
5.6 KiB
TypeScript
"use client";
|
|
import { useState } from "react";
|
|
import Link from "next/link";
|
|
import { ROUTES, API_BASE_URL } from "@/utils/constants";
|
|
|
|
export default function ForgotPasswordPage() {
|
|
const [email, setEmail] = useState("");
|
|
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
const [isSuccess, setIsSuccess] = useState(false);
|
|
const [error, setError] = useState("");
|
|
|
|
const handleSubmit = async (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
setIsSubmitting(true);
|
|
setError("");
|
|
|
|
try {
|
|
const response = await fetch(`${API_BASE_URL}/auth/forgot-password`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
body: JSON.stringify({ email }),
|
|
});
|
|
|
|
const data = await response.json();
|
|
|
|
if (data.success) {
|
|
setIsSuccess(true);
|
|
} else {
|
|
setError(data.message || 'Une erreur est survenue');
|
|
}
|
|
} catch (err) {
|
|
setError('Erreur de connexion au serveur');
|
|
console.error('Forgot password error:', err);
|
|
} finally {
|
|
setIsSubmitting(false);
|
|
}
|
|
};
|
|
|
|
if (isSuccess) {
|
|
return (
|
|
<div className="min-h-screen bg-gray-50 flex items-center justify-center py-12 px-4">
|
|
<div className="w-full max-w-md">
|
|
|
|
{/* Title */}
|
|
<div className="text-center mb-8">
|
|
<h1 className="text-4xl font-bold text-gray-900 mb-2">Email envoyé !</h1>
|
|
<p className="text-gray-600">
|
|
Vérifiez votre boîte de réception
|
|
</p>
|
|
</div>
|
|
|
|
{/* Success Card */}
|
|
<div className="bg-white rounded-xl shadow-md p-8">
|
|
<div className="text-center">
|
|
<div className="mx-auto w-16 h-16 bg-green-100 rounded-full flex items-center justify-center mb-4">
|
|
<svg className="w-8 h-8 text-green-600" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M5 13l4 4L19 7" />
|
|
</svg>
|
|
</div>
|
|
|
|
<h2 className="text-xl font-bold text-gray-900 mb-2">
|
|
Lien de réinitialisation envoyé
|
|
</h2>
|
|
|
|
<p className="text-gray-600 mb-6">
|
|
Si cet email existe dans notre base, vous recevrez un lien de réinitialisation à <strong>{email}</strong>
|
|
</p>
|
|
|
|
<div className="bg-blue-50 border-l-4 border-blue-500 p-4 mb-6 text-left">
|
|
<p className="text-sm text-blue-800">
|
|
<strong>Conseil :</strong> Si vous ne recevez pas l'email dans quelques minutes, vérifiez votre dossier spam.
|
|
</p>
|
|
</div>
|
|
|
|
<Link
|
|
href={ROUTES.LOGIN}
|
|
className="inline-flex items-center justify-center w-full bg-[#1a4d2e] hover:bg-[#2d5a3d] text-white font-bold px-8 py-4 rounded-lg transition-all"
|
|
>
|
|
Retour à la connexion
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div className="min-h-screen bg-gray-50 flex items-center justify-center py-12 px-4">
|
|
<div className="w-full max-w-md">
|
|
|
|
{/* Title */}
|
|
<div className="text-center mb-8">
|
|
<h1 className="text-4xl font-bold text-gray-900 mb-2">Mot de passe oublié</h1>
|
|
<p className="text-gray-600">
|
|
Entrez votre email pour recevoir un lien de réinitialisation
|
|
</p>
|
|
</div>
|
|
|
|
{/* Main Card */}
|
|
<div className="bg-white rounded-xl shadow-md overflow-hidden">
|
|
|
|
{/* Form Container */}
|
|
<div className="p-8">
|
|
|
|
{/* Error Message */}
|
|
{error && (
|
|
<div className="mb-4 p-4 bg-red-50 border-l-4 border-red-500 text-red-700">
|
|
{error}
|
|
</div>
|
|
)}
|
|
|
|
{/* Form */}
|
|
<form onSubmit={handleSubmit} className="space-y-6">
|
|
|
|
{/* Email */}
|
|
<div>
|
|
<label htmlFor="email" className="block text-sm font-semibold text-gray-700 mb-2">
|
|
Email <span className="text-red-500">*</span>
|
|
</label>
|
|
<input
|
|
id="email"
|
|
type="email"
|
|
required
|
|
value={email}
|
|
onChange={(e) => setEmail(e.target.value)}
|
|
placeholder="votre.email@example.com"
|
|
className="w-full px-4 py-3 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-[#1a4d2e] focus:border-transparent"
|
|
/>
|
|
</div>
|
|
|
|
{/* Submit Button */}
|
|
<button
|
|
type="submit"
|
|
disabled={isSubmitting}
|
|
className="w-full bg-[#1a4d2e] hover:bg-[#2d5a3d] disabled:bg-gray-400 text-white font-bold px-8 py-4 rounded-lg transition-all"
|
|
>
|
|
{isSubmitting ? "Envoi en cours..." : "Envoyer le lien de r\u00e9initialisation"}
|
|
</button>
|
|
|
|
{/* Back to Login */}
|
|
<div className="text-center">
|
|
<p className="text-sm text-gray-600">
|
|
Vous vous souvenez de votre mot de passe ?{' '}
|
|
<Link
|
|
href={ROUTES.LOGIN}
|
|
className="text-[#1a4d2e] hover:text-[#f59e0b] hover:underline font-semibold transition-colors"
|
|
>
|
|
Se connecter
|
|
</Link>
|
|
</p>
|
|
</div>
|
|
</form>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|