'use client'; import { Button } from '@/components/actions/Button'; import { FormField } from '@/components/forms/FormField'; import { AuthShell } from '@/components/auth/AuthShell'; import { API_BASE } from '@/lib/api'; import { localizedModePath, modeFromPathname, type Locale } from '@/lib/localization/config'; import { usePathname, useSearchParams } from 'next/navigation'; import { Suspense, useState } from 'react'; import styles from './AuthForms.module.css'; interface Dict { title: string; subtitle: string; newPassword: string; confirmPassword: string; submit: string; submitting: string; backToLogin: string; successTitle: string; successBody: string; signIn: string; errorMismatch: string; errorShort: string; errorInvalidToken: string; errorGeneric: string; noToken: string; requestNew: string; } const dicts: Record = { en: { title: 'Set new password', subtitle: 'Choose a strong password for your account.', newPassword: 'New password', confirmPassword: 'Confirm password', submit: 'Reset password', submitting: 'Resetting…', backToLogin: 'Back to sign in', successTitle: 'Password updated', successBody: 'Your password has been reset. You can now sign in with your new password.', signIn: 'Sign in', errorMismatch: 'Passwords do not match.', errorShort: 'Password must be at least 8 characters.', errorInvalidToken: 'This reset link is invalid or has expired. Please request a new one.', errorGeneric: 'Something went wrong. Please try again.', noToken: 'No reset token found. Please request a new password reset.', requestNew: 'Request new reset link', }, fr: { title: 'Nouveau mot de passe', subtitle: 'Choisissez un mot de passe fort pour votre compte.', newPassword: 'Nouveau mot de passe', confirmPassword: 'Confirmer le mot de passe', submit: 'Réinitialiser', submitting: 'Traitement…', backToLogin: 'Retour à la connexion', successTitle: 'Mot de passe mis à jour', successBody: 'Votre mot de passe a été réinitialisé. Vous pouvez maintenant vous connecter.', signIn: 'Se connecter', errorMismatch: 'Les mots de passe ne correspondent pas.', errorShort: 'Le mot de passe doit contenir au moins 8 caractères.', errorInvalidToken: 'Ce lien est invalide ou a expiré. Veuillez en demander un nouveau.', errorGeneric: 'Une erreur est survenue. Veuillez réessayer.', noToken: 'Aucun jeton de réinitialisation trouvé. Veuillez demander un nouveau lien.', requestNew: 'Demander un nouveau lien', }, ar: { title: 'تعيين كلمة مرور جديدة', subtitle: 'اختر كلمة مرور قوية لحسابك.', newPassword: 'كلمة المرور الجديدة', confirmPassword: 'تأكيد كلمة المرور', submit: 'إعادة تعيين', submitting: 'جارٍ المعالجة…', backToLogin: 'العودة إلى تسجيل الدخول', successTitle: 'تم تحديث كلمة المرور', successBody: 'تم إعادة تعيين كلمة المرور. يمكنك الآن تسجيل الدخول.', signIn: 'تسجيل الدخول', errorMismatch: 'كلمتا المرور غير متطابقتين.', errorShort: 'يجب أن تتكون كلمة المرور من 8 أحرف على الأقل.', errorInvalidToken: 'رابط إعادة التعيين غير صالح أو منتهي الصلاحية.', errorGeneric: 'حدث خطأ ما. يرجى المحاولة مرة أخرى.', noToken: 'لم يتم العثور على رمز إعادة التعيين. يرجى طلب رابط جديد.', requestNew: 'طلب رابط جديد', }, }; function ResetPasswordContent({ locale }: { locale: Locale }) { const dict = (dicts[locale] ?? dicts.en) as Dict; const searchParams = useSearchParams(); const mode = modeFromPathname(usePathname()); const token = searchParams.get('token'); const [password, setPassword] = useState(''); const [showPassword, setShowPassword] = useState(false); const [confirm, setConfirm] = useState(''); const [showConfirm, setShowConfirm] = useState(false); const [loading, setLoading] = useState(false); const [done, setDone] = useState(false); const [error, setError] = useState(null); async function handleSubmit(e: React.FormEvent) { e.preventDefault(); if (password.length < 8) { setError(dict.errorShort); return; } if (password !== confirm) { setError(dict.errorMismatch); return; } setLoading(true); setError(null); try { // Try employee endpoint first, fall back to admin let res = await fetch(`${API_BASE}/auth/employee/reset-password`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ token, password }), }); if (!res.ok) { res = await fetch(`${API_BASE}/admin/auth/reset-password`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ token, password }), }); } const json = await res.json(); if (!res.ok) { if (json?.error === 'invalid_token') throw new Error(dict.errorInvalidToken); throw new Error(dict.errorGeneric); } setDone(true); } catch (error: unknown) { setError(error instanceof Error ? error.message : dict.errorGeneric); } finally { setLoading(false); } } const signInHref = localizedModePath('sign-in', locale, mode); const forgotHref = localizedModePath('forgot-password', locale, mode); if (!token) { return (

{dict.noToken}

); } if (done) { return (

{dict.successTitle}

{dict.successBody}

); } return (
{error ? (
{error}
) : null}
setPassword(e.target.value)} placeholder="••••••••" autoComplete="new-password" className={styles.passwordInput} />
setConfirm(e.target.value)} placeholder="••••••••" autoComplete="new-password" className={styles.passwordInput} />
{dict.backToLogin}
); } export function ResetPasswordForm({ locale }: { locale: Locale }) { return ( ); }