import { useMemo, useState } from 'react'; import { X } from 'lucide-react'; import { useAuth } from '../contexts/AuthContext'; import { useLanguage } from '../contexts/LanguageContext'; interface AuthModalProps { onClose: () => void; mandatory?: boolean; } export default function AuthModal({ onClose, mandatory = false }: AuthModalProps) { const { signIn, signUp, beginGoogleOAuth, authPhase, authError } = useAuth(); const { t } = useLanguage(); const [mode, setMode] = useState<'signin' | 'signup'>('signin'); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const [localError, setLocalError] = useState(''); const [fieldErrors, setFieldErrors] = useState<{ email?: string; password?: string; confirmPassword?: string }>({}); const isBusy = useMemo( () => ['email_signing_in', 'email_signing_up', 'oauth_redirecting', 'oauth_exchanging'].includes(authPhase), [authPhase] ); const submitText = mode === 'signup' ? t.auth.signUp : t.auth.signIn; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setLocalError(''); const nextFieldErrors: { email?: string; password?: string; confirmPassword?: string } = {}; const normalizedEmail = email.trim(); if (!normalizedEmail) { nextFieldErrors.email = t.auth.emailRequired; } else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(normalizedEmail)) { nextFieldErrors.email = t.auth.emailInvalid; } if (!password) { nextFieldErrors.password = t.auth.passwordRequired; } if (mode === 'signup') { if (password && password.length < 6) { nextFieldErrors.password = t.auth.passwordHint; } if (!confirmPassword) { nextFieldErrors.confirmPassword = t.auth.passwordRequired; } else if (password !== confirmPassword) { nextFieldErrors.confirmPassword = t.auth.passwordMismatch; } } setFieldErrors(nextFieldErrors); if (Object.keys(nextFieldErrors).length > 0) { return; } const result = mode === 'signup' ? await signUp(normalizedEmail, password) : await signIn(normalizedEmail, password); if (!result.error) { onClose(); } }; const handleGoogleOAuth = async () => { await beginGoogleOAuth(); }; return (

{mode === 'signup' ? t.auth.signUpTitle : t.auth.signInTitle}

{!mandatory && ( )}
{ setEmail(e.target.value); if (fieldErrors.email) { setFieldErrors((prev) => ({ ...prev, email: undefined })); } }} className={`w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent ${ fieldErrors.email ? 'border-red-400' : 'border-gray-300' }`} placeholder="your@email.com" required disabled={isBusy} /> {fieldErrors.email &&

{fieldErrors.email}

} {mode === 'signup' && (

{t.auth.emailHint}

)}
{ setPassword(e.target.value); if (fieldErrors.password) { setFieldErrors((prev) => ({ ...prev, password: undefined })); } }} className={`w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent ${ fieldErrors.password ? 'border-red-400' : 'border-gray-300' }`} placeholder="••••••••" required minLength={6} disabled={isBusy} /> {fieldErrors.password &&

{fieldErrors.password}

} {mode === 'signup' && (

{t.auth.passwordHint}

)}
{mode === 'signup' && (
{ setConfirmPassword(e.target.value); if (fieldErrors.confirmPassword) { setFieldErrors((prev) => ({ ...prev, confirmPassword: undefined })); } }} className={`w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent ${ fieldErrors.confirmPassword ? 'border-red-400' : 'border-gray-300' }`} placeholder="••••••••" required minLength={6} disabled={isBusy} /> {fieldErrors.confirmPassword &&

{fieldErrors.confirmPassword}

}
)} {(localError || authError) && (
{t.auth.error}: {localError || authError}
)}
); }