import React, { useEffect, useState, useRef } from 'react'; import { useNavigate, useSearchParams, Link } from 'react-router-dom'; import { useAuth } from '../contexts/AuthContext'; import { authAPI } from '../services/api'; import PasswordInput from '../components/PasswordInput'; import PasswordStrengthMeter from '../components/PasswordStrengthMeter'; const ResetPassword: React.FC = () => { const [searchParams] = useSearchParams(); const navigate = useNavigate(); const { openAuthModal } = useAuth(); const [error, setError] = useState(''); const [success, setSuccess] = useState(false); const [validating, setValidating] = useState(true); const [tokenValid, setTokenValid] = useState(false); const [submitting, setSubmitting] = useState(false); const [newPassword, setNewPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const hasValidated = useRef(false); useEffect(() => { const validateToken = async () => { // Prevent double execution in React StrictMode if (hasValidated.current) { return; } hasValidated.current = true; try { const token = searchParams.get('token'); if (!token) { setError('No reset token provided.'); setValidating(false); return; } // Verify the token is valid await authAPI.verifyResetToken(token); setTokenValid(true); setValidating(false); } catch (err: any) { console.error('Token validation error:', err); const errorData = err.response?.data; if (errorData?.code === 'TOKEN_EXPIRED') { setError('Your password reset link has expired. Please request a new one.'); } else if (errorData?.code === 'TOKEN_INVALID') { setError('Invalid password reset link. The link may have already been used or is incorrect.'); } else { setError(errorData?.error || 'Failed to validate reset link. Please try again.'); } setValidating(false); setTokenValid(false); } }; validateToken(); }, [searchParams]); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(''); // Validate passwords match if (newPassword !== confirmPassword) { setError('Passwords do not match.'); return; } setSubmitting(true); try { const token = searchParams.get('token'); if (!token) { setError('No reset token provided.'); setSubmitting(false); return; } await authAPI.resetPassword(token, newPassword); setSuccess(true); } catch (err: any) { console.error('Password reset error:', err); const errorData = err.response?.data; if (errorData?.code === 'TOKEN_EXPIRED') { setError('Your reset link has expired. Please request a new one.'); } else if (errorData?.code === 'TOKEN_INVALID') { setError('Invalid reset link. Please request a new one.'); } else if (errorData?.details) { // Validation errors const validationErrors = errorData.details.map((d: any) => d.message).join(', '); setError(validationErrors); } else { setError(errorData?.error || 'Failed to reset password. Please try again.'); } setSubmitting(false); } }; return (
{validating ? (
Loading...
Verifying Reset Link...

Please wait while we verify your password reset link.

) : success ? (
Password Reset Successfully!

Your password has been reset. You can now log in with your new password.

) : !tokenValid ? (
Invalid Reset Link

{error}

Return to Home
) : ( <>

Reset Your Password

Enter your new password below.

{error && (
{error}
)}
setNewPassword(e.target.value)} required />
setConfirmPassword(e.target.value)} required />
Return to Home
)}
); }; export default ResetPassword;