diff --git a/frontend/src/pages/PasswordResetConfirm.tsx b/frontend/src/pages/PasswordResetConfirm.tsx new file mode 100644 index 0000000..46ac145 --- /dev/null +++ b/frontend/src/pages/PasswordResetConfirm.tsx @@ -0,0 +1,177 @@ +import React, { useState, useEffect } from 'react'; +import { useSearchParams, useNavigate, Link } from 'react-router-dom'; +import axios from 'axios'; +import { Logo } from '../components/Logo'; + +const API_URL = import.meta.env.VITE_API_URL || "/api"; + +export const PasswordResetConfirm: React.FC = () => { + const [searchParams] = useSearchParams(); + const navigate = useNavigate(); + const token = searchParams.get('token'); + + const [password, setPassword] = useState(''); + const [confirmPassword, setConfirmPassword] = useState(''); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(''); + const [success, setSuccess] = useState(false); + + useEffect(() => { + if (!token) { + setError('Invalid reset link. Please request a new password reset.'); + } + }, [token]); + + const handleSubmit = async (e: React.FormEvent) => { + e.preventDefault(); + setError(''); + + if (password !== confirmPassword) { + setError('Passwords do not match'); + return; + } + + if (password.length < 8) { + setError('Password must be at least 8 characters long'); + return; + } + + if (!token) { + setError('Invalid reset token'); + return; + } + + setLoading(true); + + try { + await axios.post(`${API_URL}/auth/password-reset-confirm`, { + token, + password, + }); + setSuccess(true); + setTimeout(() => { + navigate('/login'); + }, 3000); + } catch (err: unknown) { + let message = 'Failed to reset password'; + if (axios.isAxiosError(err)) { + if (err.response?.status === 404) { + message = 'Password reset feature is not enabled on this server'; + } else if (err.response?.data?.message) { + message = err.response.data.message; + } else if (err.response?.data?.error) { + message = err.response.data.error; + } else if (err.message) { + message = err.message; + } + } else if (err instanceof Error) { + message = err.message; + } + setError(message); + } finally { + setLoading(false); + } + }; + + if (success) { + return ( +
+ Your password has been reset. Redirecting to login... +
++ Enter your new password below. +
++ If an account with that email exists, a password reset link has been sent. +
++ Enter your email address and we'll send you a link to reset your password. +
+