'use client' import { useState, useEffect } from 'react' import { useRouter } from 'next/navigation' import { createClient } from '@/lib/supabase/client' export default function PasswordResetModal() { const router = useRouter() const [isOpen, setIsOpen] = useState(false) const [password, setPassword] = useState('') const [confirmPassword, setConfirmPassword] = useState('') const [error, setError] = useState(null) const [loading, setLoading] = useState(false) const [tokenError, setTokenError] = useState(null) useEffect(() => { const handleTokenFromUrl = async () => { const hash = window.location.hash if (!hash) return const params = new URLSearchParams(hash.substring(1)) const accessToken = params.get('access_token') const refreshToken = params.get('refresh_token') const type = params.get('type') if (accessToken && refreshToken && type === 'recovery') { const supabase = createClient() const { error } = await supabase.auth.setSession({ access_token: accessToken, refresh_token: refreshToken, }) if (error) { setTokenError('Invalid or expired reset link. Please request a new password reset.') return } // Clear hash from URL without reloading window.history.replaceState(null, '', window.location.pathname + window.location.search) setIsOpen(true) } } handleTokenFromUrl() }, []) async function handleSubmit(e: React.FormEvent) { e.preventDefault() setError(null) if (password !== confirmPassword) { setError('Passwords do not match') return } if (password.length < 6) { setError('Password must be at least 6 characters') return } setLoading(true) const supabase = createClient() const { error: updateError } = await supabase.auth.updateUser({ password, }) if (updateError) { setError(updateError.message) setLoading(false) return } await supabase.auth.signOut() setIsOpen(false) router.push('/login?message=password_reset_success') } if (tokenError) { return (

Reset link expired

{tokenError}

) } if (!isOpen) return null return (

Set new password

Enter your new password below.

{error && (

{error}

)}
setPassword(e.target.value)} className="mt-1 block w-full rounded-md border border-zinc-300 bg-white px-3 py-2 text-zinc-900 placeholder-zinc-400 shadow-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-50 dark:placeholder-zinc-500" placeholder="••••••••" />
setConfirmPassword(e.target.value)} className="mt-1 block w-full rounded-md border border-zinc-300 bg-white px-3 py-2 text-zinc-900 placeholder-zinc-400 shadow-sm focus:border-blue-500 focus:outline-none focus:ring-1 focus:ring-blue-500 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-50 dark:placeholder-zinc-500" placeholder="••••••••" />
) }