import { useState } from 'react' import { Link } from 'react-router-dom' import { api } from '../../api/client.js' import PlayerShell from './PlayerShell.jsx' // Public "forgot password" request page. Submitting emails a tokened reset link to // every active account on the address (see ResetPassword for the other half). The // server never reveals whether the email exists — it always answers the same way — // so this page shows an identical confirmation regardless, to avoid enumeration. export default function ForgotPassword() { const [email, setEmail] = useState('') const [error, setError] = useState('') const [busy, setBusy] = useState(false) const [sent, setSent] = useState(false) async function onSubmit(e) { e.preventDefault() setError('') if (!/.+@.+\..+/.test(email.trim())) return setError('Enter a valid email address.') setBusy(true) try { await api.forgotPassword(email.trim()) setSent(true) } catch (err) { // Only a rate-limit (429) or a real outage surfaces here — a non-match still // returns 200. Keep the message generic either way. if (err.status === 429) setError('Too many requests. Please try again in a little while.') else setError('Could not send the reset email right now. Please try again later.') setBusy(false) } } if (sent) { return (

If an account exists for {email.trim()}, we’ve sent a link to reset its password. Check your inbox (and spam) — the link expires in about an hour.

Back to sign in

) } return ( Remembered it?{' '} Sign in

} >

Enter the email on your account and we’ll send you a link to choose a new password.

{error &&

{error}

}
) }