"use client"; import { useEffect, useState } from "react"; import Link from "next/link"; import { signInWithEmailAndPassword, GoogleAuthProvider, signInWithPopup } from "firebase/auth"; import { auth } from "@/lib/firebase"; import { c2api } from "@/lib/c2api"; import { useRouter } from "next/navigation"; import { useAuth } from "@/components/AuthProvider"; import { describeAuthError } from "@/lib/authErrors"; export default function LoginPage() { const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [error, setError] = useState(null); const [misconfigured, setMisconfigured] = useState(false); const [submitting, setSubmitting] = useState(false); const router = useRouter(); const { user, loading: authLoading, orgId } = useAuth(); // Do NOT navigate straight from the sign-in handlers below: signInWith* // resolves before AuthProvider's onAuthStateChanged listener has fetched // claims and set/cleared the drb_session cookie. Pushing to /dashboard // immediately races that — for a no-org account the cookie never gets // set, so middleware.ts bounces the very next request straight back to // /login, which is the ping-pong this screen used to cause. Instead, // react to AuthProvider's own settled state: this also covers a user who // arrives here already signed in (e.g. redirected from a protected route // by middleware while their Firebase session was still valid) — same // destination logic, no separate code path, no bounce. useEffect(() => { if (authLoading) return; if (!user) return; router.replace(orgId ? "/dashboard" : "/onboarding"); }, [authLoading, user, orgId, router]); async function handleSubmit(e: React.FormEvent) { e.preventDefault(); setSubmitting(true); setError(null); setMisconfigured(false); try { await signInWithEmailAndPassword(auth, email, password); c2api.recordSession().catch(() => {}); // Redirect happens via the effect above once claims are settled. } catch (err) { const info = describeAuthError(err, "Invalid email or password."); setError(info.message); setMisconfigured(info.misconfiguration); setSubmitting(false); } } async function handleGoogle() { setSubmitting(true); setError(null); setMisconfigured(false); try { await signInWithPopup(auth, new GoogleAuthProvider()); c2api.recordSession().catch(() => {}); // Redirect happens via the effect above once claims are settled. } catch (err) { const info = describeAuthError(err, "Google sign-in failed. Try again."); setError(info.message); setMisconfigured(info.misconfiguration); setSubmitting(false); } } const loading = submitting || !!user; return (
D DRB

Sign in

setEmail(e.target.value)} required autoComplete="email" className="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-indigo-500" />
setPassword(e.target.value)} required autoComplete="current-password" className="w-full bg-gray-800 border border-gray-700 rounded-lg px-3 py-2 text-white text-sm focus:outline-none focus:border-indigo-500" />
{error && (

{error}

)}
or

Don't have an account?{" "} Sign up

); }