'use client'; import { useState } from 'react'; import { useSearchParams, useRouter } from 'next/navigation'; import { useTranslations } from 'next-intl'; import Link from 'next/link'; export default function ResetPasswordPage() { const t = useTranslations('auth.resetPassword'); const params = useSearchParams(); const token = params.get('token') ?? ''; const router = useRouter(); const [password, setPassword] = useState(''); const [confirm, setConfirm] = useState(''); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); if (!token) { return (

{t('invalidLink')}

{t('requestNew')}
); } const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (password !== confirm) { setError(t('passwordMismatch')); return; } setLoading(true); setError(null); const res = await fetch('/api/auth/reset-password', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ token, password }), }); setLoading(false); if (res.ok) { router.push('/auth/login?reset=1'); } else { const d = (await res.json()) as { error?: string }; setError(d.error ?? t('error')); } }; return (

{t('title')}

setPassword(e.target.value)} required minLength={8} autoComplete="new-password" style={s.input} /> setConfirm(e.target.value)} required autoComplete="new-password" style={s.input} /> {error &&

{error}

}
); } const s = { page: { display: 'flex', flexDirection: 'column' as const, alignItems: 'center', minHeight: '100svh', padding: 'var(--space-8)', paddingTop: 'var(--space-16)', gap: 'var(--space-4)' }, heading: { fontFamily: 'var(--font-display)', fontSize: '1.5rem', fontWeight: 500, color: 'var(--color-ink)', marginBottom: 'var(--space-4)' }, form: { width: '100%', maxWidth: '26rem', display: 'flex', flexDirection: 'column' as const, gap: 'var(--space-2)' }, label: { fontFamily: 'var(--font-display)', fontSize: '0.875rem', fontWeight: 500, color: 'var(--color-ink)', marginTop: 'var(--space-3)' }, input: { padding: 'var(--space-3) var(--space-4)', background: 'var(--color-surface)', border: '1px solid var(--color-border)', borderRadius: '4px', fontFamily: 'var(--font-body)', fontSize: '1rem', color: 'var(--color-ink)', outline: 'none' }, error: { color: 'var(--color-misconception)', fontSize: '0.875rem', margin: 0 }, btn: { marginTop: 'var(--space-4)', padding: 'var(--space-3) var(--space-6)', background: 'var(--color-accent)', color: 'var(--color-on-accent)', border: 'none', borderRadius: '4px', fontFamily: 'var(--font-display)', fontSize: '0.9375rem', fontWeight: 500, cursor: 'pointer' }, link: { color: 'var(--color-accent)', fontFamily: 'var(--font-display)', fontSize: '0.875rem', textDecoration: 'none' }, } as const;