MotorSignal-App/website/components/recovery-form.tsx

39 lines
2.6 KiB
TypeScript

'use client';
import { FormEvent, useState } from 'react';
export function RecoveryForm({ initialToken = '' }: { initialToken?: string }) {
const [email, setEmail] = useState('');
const [token, setToken] = useState(initialToken);
const [password, setPassword] = useState('');
const [message, setMessage] = useState('');
const [busy, setBusy] = useState(false);
async function submitRequest(event: FormEvent) {
event.preventDefault();
setBusy(true); setMessage('');
try {
const response = await fetch('/api/auth/password-reset-request', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ email }) });
const body = await response.json().catch(() => ({}));
if (!response.ok) throw new Error(body.detail ?? 'Unable to request reset.');
setMessage('If the account exists, reset instructions have been sent.');
} catch (error) { setMessage(error instanceof Error ? error.message : 'Unable to request reset.'); }
finally { setBusy(false); }
}
async function submitReset(event: FormEvent) {
event.preventDefault();
setBusy(true); setMessage('');
try {
const response = await fetch('/api/auth/password-reset', { method: 'POST', headers: { 'content-type': 'application/json' }, body: JSON.stringify({ token, password }) });
const body = await response.json().catch(() => ({}));
if (!response.ok) throw new Error(body.detail ?? 'Unable to reset password.');
setMessage('Password reset complete. You can sign in now.');
setToken(''); setPassword('');
} catch (error) { setMessage(error instanceof Error ? error.message : 'Unable to reset password.'); }
finally { setBusy(false); }
}
return <div className="recovery-stack"><form className="auth-form" onSubmit={submitRequest}><label>Email<input required type="email" autoComplete="email" value={email} onChange={(event) => setEmail(event.target.value)} /></label><button className="button" disabled={busy} type="submit">{busy ? 'Working...' : 'Email reset link'}</button></form><div className="form-divider">Already have a reset link?</div><form className="auth-form" onSubmit={submitReset}><label>Reset token<input required value={token} onChange={(event) => setToken(event.target.value)} /></label><label>New password<input required minLength={12} type="password" autoComplete="new-password" value={password} onChange={(event) => setPassword(event.target.value)} /></label><button className="button button-secondary" disabled={busy} type="submit">Set new password</button></form>{message && <p className="form-message" role="status">{message}</p>}</div>;
}