'use client'; import { useState } from 'react'; import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { z } from 'zod'; import { useAuth } from '@/lib/contexts/AuthContext'; import { mfaService } from '@/lib/services/auth'; import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Alert, AlertDescription } from '@/components/ui/alert'; import { AlertCircle, Loader2 } from 'lucide-react'; const loginSchema = z.object({ email: z.string().email('Invalid email address'), password: z.string().min(1, 'Password is required'), }); type LoginFormData = z.infer; interface LoginFormProps { onSuccess?: () => void; onSwitchToRegister?: () => void; onSwitchToReset?: () => void; } export function LoginForm({ onSuccess, onSwitchToRegister, onSwitchToReset }: LoginFormProps) { const { login } = useAuth(); const [error, setError] = useState(''); const [isLoading, setIsLoading] = useState(false); const [showMFAChallenge, setShowMFAChallenge] = useState(false); const [mfaCode, setMfaCode] = useState(''); const { register, handleSubmit, formState: { errors }, } = useForm({ resolver: zodResolver(loginSchema), }); const onSubmit = async (data: LoginFormData) => { setError(''); setIsLoading(true); try { await login(data); onSuccess?.(); } catch (err: any) { const errorMessage = err.response?.data?.detail || err.message || 'Login failed'; // Check if MFA is required if (errorMessage.toLowerCase().includes('mfa') || errorMessage.toLowerCase().includes('two-factor')) { setShowMFAChallenge(true); } else { setError(errorMessage); } } finally { setIsLoading(false); } }; const handleMFASubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(''); setIsLoading(true); try { await mfaService.challengeMFA({ code: mfaCode }); // Tokens are stored automatically by the service onSuccess?.(); } catch (err: any) { setError(err.response?.data?.detail || 'Invalid MFA code'); } finally { setIsLoading(false); } }; if (showMFAChallenge) { return (

Two-Factor Authentication

Enter the 6-digit code from your authenticator app

{error && ( {error} )}
setMfaCode(e.target.value.replace(/\D/g, ''))} disabled={isLoading} autoFocus />
); } return (
{error && ( {error} )}
{errors.email && (

{errors.email.message}

)}
{errors.password && (

{errors.password.message}

)}
{onSwitchToReset && ( )} {onSwitchToRegister && ( )}
); }