'use client'; import { useState, useTransition } from 'react'; import { useTranslations } from 'next-intl'; import Link from 'next/link'; import { TesseraLogo } from '@/components/brand/tessera-logo'; const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3001'; /** * Password reset request page (D-03 self-service). * Simple form with email input. Always shows success message * regardless of whether email exists (T-02-12: prevent enumeration). * Part of (auth) route group -- no sidebar/header (D-04). */ export default function ResetPasswordPage() { const t = useTranslations('auth'); const [isPending, startTransition] = useTransition(); const [submitted, setSubmitted] = useState(false); const [error, setError] = useState(null); async function handleSubmit(e: React.FormEvent) { e.preventDefault(); setError(null); const formData = new FormData(e.currentTarget); const email = formData.get('email') as string; if (!email) return; startTransition(async () => { try { const response = await fetch(`${API_URL}/auth/request-reset`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email }), }); if (!response.ok) { setError('networkError'); return; } setSubmitted(true); } catch { setError('networkError'); } }); } return (
{/* Heading */}

{t('resetPassword.title')}

{submitted ? ( /* Success message -- always shown, prevents email enumeration */
{t('resetPassword.success')}
{t('resetPassword.backToLogin')}
) : ( /* Email form */ <> {/* Error message */} {error && (
{t(`error.${error}`)}
)}
{t('resetPassword.backToLogin')}
)}
); }