import '@/index.css' import { useState, useEffect } from 'react' import { getCsrfToken } from '@rudderjs/middleware/client' // URL this view is served at — see Login.tsx for rationale. export const route = '/reset-password' export interface ResetPasswordProps { submitUrl?: string loginUrl?: string forgotPasswordUrl?: string } export default function ResetPassword(props: ResetPasswordProps) { const submitUrl = props.submitUrl ?? '/auth/reset-password' const loginUrl = props.loginUrl ?? '/login' const forgotPasswordUrl = props.forgotPasswordUrl ?? '/forgot-password' const [password, setPassword] = useState('') const [confirmPassword, setConfirm] = useState('') const [error, setError] = useState('') const [success, setSuccess] = useState('') const [loading, setLoading] = useState(false) const [token, setToken] = useState(null) const [email, setEmail] = useState(null) const [mounted, setMounted] = useState(false) useEffect(() => { const params = new URLSearchParams(window.location.search) setToken(params.get('token')) setEmail(params.get('email')) setMounted(true) }, []) async function handleSubmit(e: React.FormEvent) { e.preventDefault() setError('') setSuccess('') if (password !== confirmPassword) { setError('Passwords do not match.') return } setLoading(true) try { const res = await fetch(submitUrl, { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': getCsrfToken(), }, body: JSON.stringify({ token, email, newPassword: password }), }) if (res.ok) { setSuccess('Your password has been reset successfully.') } else { const body = await res.json().catch(() => ({})) as { message?: string } setError(body.message ?? 'Invalid or expired token.') } } catch { setError('Something went wrong. Please try again.') } setLoading(false) } if (!mounted) { return (
Loading...
) } if (!token) { return (

Missing reset token.

Request a new reset link

) } return (

Reset password

Enter your new password

{error &&

{error}

} {success && ( <>

{success}

Sign in

)} {!success && ( <>
setPassword(e.currentTarget.value)} required minLength={8} autoComplete="new-password" className="form-input" />
setConfirm(e.currentTarget.value)} required minLength={8} autoComplete="new-password" className="form-input" />
)}
) }