import { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { supabase } from '@/lib/supabase'; import { useToast } from '@/hooks/use-toast'; import { Loader2, ArrowLeft } from 'lucide-react'; import { useTranslation } from 'react-i18next'; export default function PasswordReset() { const navigate = useNavigate(); const { toast } = useToast(); const { t } = useTranslation(); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const [loading, setLoading] = useState(false); // Recovery mode = user arrived via the password-reset email link (Supabase // establishes a temporary recovery session and emits PASSWORD_RECOVERY). const [recovery, setRecovery] = useState(false); useEffect(() => { if (window.location.hash.includes('type=recovery')) setRecovery(true); const { data } = supabase.auth.onAuthStateChange((event) => { if (event === 'PASSWORD_RECOVERY') setRecovery(true); }); return () => data.subscription.unsubscribe(); }, []); // Step 1: request a reset link (Supabase sends the email + handles the token). const handleRequestReset = async (e: React.FormEvent) => { e.preventDefault(); setLoading(true); try { const redirectTo = `${window.location.origin}/reset-password`; const { error } = await supabase.auth.resetPasswordForEmail(email.trim(), { redirectTo }); if (error) throw error; // Generic success message regardless of whether the email exists // (no account enumeration). toast({ title: t('passwordReset.resetEmailSent'), description: t('passwordReset.resetEmailSentDesc'), }); setEmail(''); } catch (error) { toast({ title: t('common.error'), description: error instanceof Error ? error.message : t('passwordReset.failedToSend'), variant: 'destructive', }); } finally { setLoading(false); } }; // Step 2: set the new password using the active recovery session. const handleResetPassword = async (e: React.FormEvent) => { e.preventDefault(); if (password !== confirmPassword) { toast({ title: t('common.error'), description: t('passwordReset.passwordMismatch'), variant: 'destructive' }); return; } if (password.length < 8) { toast({ title: t('common.error'), description: t('passwordReset.passwordTooShort'), variant: 'destructive' }); return; } setLoading(true); try { const { error } = await supabase.auth.updateUser({ password }); if (error) throw error; toast({ title: t('passwordReset.success'), description: t('passwordReset.successDesc') }); // Force a clean re-login with the new password. await supabase.auth.signOut(); navigate('/login'); } catch (error) { toast({ title: t('common.error'), description: error instanceof Error ? error.message : t('passwordReset.failedToReset'), variant: 'destructive', }); } finally { setLoading(false); } }; return (