'use client'; import { useEffect, useState, useTransition } from 'react'; import { useRouter } from 'next/navigation'; import Link from 'next/link'; import type { AuthError } from '@supabase/supabase-js'; import { createSupabaseBrowserClient } from '@/lib/supabase/browser'; const RESEND_COOLDOWN = 45; function isEmailNotConfirmed(error: AuthError): boolean { return error.code === 'email_not_confirmed' || /not confirmed/i.test(error.message); } export default function LoginPage() { const router = useRouter(); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [error, setError] = useState(null); const [needsConfirm, setNeedsConfirm] = useState(false); const [resendInfo, setResendInfo] = useState(null); const [cooldown, setCooldown] = useState(0); const [isPending, startTransition] = useTransition(); const [isResending, startResend] = useTransition(); useEffect(() => { const params = new URLSearchParams(window.location.search); if (params.get('error') === 'verification_failed') { setError( 'Email verification failed or the link expired. Sign in below to resend a confirmation email.', ); } else if (params.get('mfa_reset') === '1') { setResendInfo( 'Your two-factor methods were reset. Sign in to set up a new one.', ); } }, []); useEffect(() => { if (cooldown <= 0) return; const t = setTimeout(() => setCooldown((c) => c - 1), 1000); return () => clearTimeout(t); }, [cooldown]); function onSubmit(e: React.FormEvent) { e.preventDefault(); setError(null); setResendInfo(null); const supabase = createSupabaseBrowserClient(); startTransition(async () => { const { error } = await supabase.auth.signInWithPassword({ email, password, }); if (error) { if (isEmailNotConfirmed(error)) { setNeedsConfirm(true); setError( 'Please confirm your email address before signing in. Check your inbox or resend the confirmation email below.', ); } else { setError(error.message); } return; } // Hand off to the MFA gate: the challenge page completes step-up (or // redirects to enrollment for users without a verified factor). router.push('/security/challenge'); router.refresh(); }); } function onResend() { setResendInfo(null); const supabase = createSupabaseBrowserClient(); startResend(async () => { const { error } = await supabase.auth.resend({ type: 'signup', email }); if (error) { setError(error.message); return; } setResendInfo('Confirmation email sent. Check your inbox.'); setCooldown(RESEND_COOLDOWN); }); } return (

Login

setEmail(e.target.value)} /> setPassword(e.target.value)} /> {error &&

{error}

} {resendInfo &&

{resendInfo}

} {needsConfirm && (
)}
Need an account?
); }