import { useState, useEffect } from 'react' import { Link, useSearchParams, useNavigate } from 'react-router-dom' import { authApi } from '@/api/auth' import { toast } from '@/lib/toast' import { BrandLogo } from '@/components/common/BrandLogo' import { PasswordInput } from '@/components/common/PasswordInput' import { PageMeta } from '@/components/common/PageMeta' import { cn } from '@/lib/utils' export function ResetPasswordPage() { const [searchParams] = useSearchParams() const navigate = useNavigate() const token = searchParams.get('token') || '' const [verifying, setVerifying] = useState(true) const [valid, setValid] = useState(false) const [email, setEmail] = useState(null) const [newPassword, setNewPassword] = useState('') const [confirmPassword, setConfirmPassword] = useState('') const [isLoading, setIsLoading] = useState(false) const [error, setError] = useState('') useEffect(() => { if (!token) { setVerifying(false) return } authApi.verifyResetToken(token).then((res) => { setValid(res.valid) setEmail(res.email || null) }).catch(() => { setValid(false) }).finally(() => { setVerifying(false) }) }, [token]) const handleSubmit = async (e: React.FormEvent) => { e.preventDefault() setError('') if (!newPassword || !confirmPassword) { setError('Please fill in all fields') return } if (newPassword !== confirmPassword) { setError('Passwords do not match') return } if (newPassword.length < 10) { setError('Password must be at least 10 characters') return } setIsLoading(true) try { await authApi.resetPassword(token, newPassword) toast.success('Password reset successfully. Please sign in.') navigate('/login', { replace: true }) } catch (err: unknown) { if (err && typeof err === 'object' && 'response' in err) { const axiosErr = err as { response?: { data?: { detail?: string } } } setError(axiosErr.response?.data?.detail || 'Failed to reset password') } else { setError('Failed to reset password') } } finally { setIsLoading(false) } } return ( <>

Reset Password

{verifying ? (

Verifying reset link...

) : !token || !valid ? (
This reset link is invalid or has expired. Please request a new one.
Request new reset link
) : (
{email && (

Resetting password for {email}

)} {error && (
{error}
)}
setNewPassword(e.target.value)} className={cn( 'block w-full rounded-xl border border-border bg-card px-3 py-2', 'text-foreground placeholder:text-muted-foreground', 'focus:border-primary focus:outline-hidden focus:ring-1 focus:ring-primary/20', 'transition-colors' )} placeholder="At least 10 characters" />

Must include uppercase, lowercase, and a digit.

setConfirmPassword(e.target.value)} className={cn( 'block w-full rounded-xl border border-border bg-card px-3 py-2', 'text-foreground placeholder:text-muted-foreground', 'focus:border-primary focus:outline-hidden focus:ring-1 focus:ring-primary/20', 'transition-colors' )} />
)}
) } export default ResetPasswordPage