import React, { useState, useEffect, useRef } from 'react'; import { useAuth } from '../context/AuthContext'; interface AuthModalProps { isOpen: boolean; onClose: () => void; } export const AuthModal: React.FC = ({ isOpen, onClose }) => { const { signIn, signInEmail, signUpEmail, authError, clearAuthError } = useAuth(); const [authMode, setAuthMode] = useState<'signin' | 'signup' | 'verification_sent'>('signin'); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [displayName, setDisplayName] = useState(''); const [loadingGoogle, setLoadingGoogle] = useState(false); const [loadingEmail, setLoadingEmail] = useState(false); const [localError, setLocalError] = useState(null); const [successInfo, setSuccessInfo] = useState(null); const modalContentRef = useRef(null); // Close on Escape key press useEffect(() => { if (!isOpen) return; const handleKeyDown = (e: KeyboardEvent) => { if (e.key === 'Escape') { onClose(); } }; window.addEventListener('keydown', handleKeyDown); return () => window.removeEventListener('keydown', handleKeyDown); }, [isOpen, onClose]); if (!isOpen) return null; const handleGoogleAuth = async () => { setLoadingGoogle(true); setLocalError(null); setSuccessInfo(null); clearAuthError(); try { await signIn(); onClose(); } catch (err: any) { if (err?.code === 'auth/unauthorized-domain' || err?.message?.includes('authorized')) { setLocalError( 'Google Sign-in: This domain is not listed in your Firebase Authorized Domains. You can use Email Sign-in below or add your domain in Firebase Console.' ); } else { setLocalError(err?.message || 'Google sign-in popup was closed.'); } } finally { setLoadingGoogle(false); } }; const handleEmailAuth = async (e: React.FormEvent) => { e.preventDefault(); if (!email.trim() || !password.trim()) { setLocalError('Please enter both email and password.'); return; } setLoadingEmail(true); setLocalError(null); setSuccessInfo(null); clearAuthError(); try { if (authMode === 'signup') { await signUpEmail(email.trim(), password, displayName.trim()); setAuthMode('verification_sent'); setSuccessInfo( `Account created for ${email.trim()}! Please open your email inbox, click the verification link, and then sign in.` ); } else { await signInEmail(email.trim(), password); onClose(); } } catch (err: any) { if (err?.code === 'auth/verification-sent') { setAuthMode('verification_sent'); setSuccessInfo(err.message); } else if (err?.code === 'auth/unverified-email') { setAuthMode('verification_sent'); setSuccessInfo(err.message); } else { setLocalError(err?.message || 'Authentication failed. Please check your details.'); } } finally { setLoadingEmail(false); } }; return (
e.stopPropagation()} className="bg-white rounded-2xl max-w-md w-full shadow-2xl border border-[#CBD5E1] overflow-hidden flex flex-col cursor-default" > {/* Header */}
gavel

{authMode === 'signin' ? 'Sign in to CaseLoop' : 'Create Free Account'}

Sync your cases & legal notice drafts

{/* Body */}
{(localError || authError) && (
info

Notice

{localError || authError}

)} {authMode === 'verification_sent' ? (
mark_email_unread

Check Your Inbox to Verify

{successInfo || `We've sent a verification link to ${email || 'your email'}. Please click the link to activate your account before logging in.`}

check_circle 1. Open the verification email
check_circle 2. Click the confirmation link
check_circle 3. Return here and Sign In
) : ( <> {/* Option 1: Continue with Google */}
OR EMAIL LOGIN
{/* Toggle between Sign in and Sign up */}
{/* Option 2: Email Form */}
{authMode === 'signup' && (
setDisplayName(e.target.value)} placeholder="e.g. John Doe" className="w-full bg-white border border-[#CBD5E1] rounded-xl px-3.5 py-2.5 text-[14px] text-[#0F172A] outline-none focus:border-[#006c4a]" />
)}
setEmail(e.target.value)} placeholder="name@example.com" required className="w-full bg-white border border-[#CBD5E1] rounded-xl px-3.5 py-2.5 text-[14px] text-[#0F172A] outline-none focus:border-[#006c4a]" />
setPassword(e.target.value)} placeholder="••••••••" required minLength={6} className="w-full bg-white border border-[#CBD5E1] rounded-xl px-3.5 py-2.5 text-[14px] text-[#0F172A] outline-none focus:border-[#006c4a]" />
)}
{/* Footer */}
Protected with Firebase Auth
); };