import { useEffect, useState } from 'react'; import { Link, useNavigate } from 'react-router'; import { Wordmark } from '../components/Logo'; import { Button } from '../components/ui/button'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../components/ui/card'; import { Input } from '../components/ui/input'; import { supabase } from '../lib/supabase'; export default function ResetPassword() { const navigate = useNavigate(); const [password, setPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const [error, setError] = useState(''); const [success, setSuccess] = useState(false); const [loading, setLoading] = useState(false); const [validToken, setValidToken] = useState(null); useEffect(() => { // Check if we have a valid recovery session // The Supabase client auto-detects the token from URL hash const checkSession = async () => { const { data: { session }, } = await supabase.auth.getSession(); // Check URL hash for recovery type const hash = window.location.hash; const isRecovery = hash.includes('type=recovery') || hash.includes('type=invite'); if (session || isRecovery) { setValidToken(true); } else { setValidToken(false); } }; checkSession(); // Listen for auth state changes (token validation) const { data: { subscription }, } = supabase.auth.onAuthStateChange((event, session) => { if (event === 'PASSWORD_RECOVERY') { setValidToken(true); } else if (event === 'SIGNED_IN' && session) { // Recovery token was validated setValidToken(true); } }); return () => subscription.unsubscribe(); }, []); 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'); return; } setLoading(true); try { const { error } = await supabase.auth.updateUser({ password, }); if (error) throw error; setSuccess(true); // Sign out and redirect to login after 2 seconds setTimeout(async () => { await supabase.auth.signOut(); navigate('/login?message=password_reset'); }, 2000); } catch (err) { setError(err instanceof Error ? err.message : 'Failed to reset password'); } finally { setLoading(false); } }; // Loading state while checking token if (validToken === null) { return (
Validating reset link...
); } // Invalid or expired token if (validToken === false) { return (
Invalid or expired link This password reset link is invalid or has expired.

Please request a new password reset link.

Request new link
); } return (
{/* Header */}
{/* Main content */}
{success ? 'Password updated' : 'Set new password'} {success ? 'Redirecting you to sign in...' : 'Enter your new password below'} {success ? (
Your password has been successfully updated. You'll be redirected to sign in shortly.
) : (
{error && (
{error}
)} setPassword(e.target.value)} required minLength={8} autoFocus /> setConfirmPassword(e.target.value)} required minLength={8} />
)}
); }