fix(App.test): reorder auth guards to fix dev mode redirect

The App.tsx auth flow had needsSetup check before dev mode redirect,
causing needsSetup to remain null in dev mode (since the setup fetch
is skipped), which made the component return null instead of redirecting.

Fix: check needsSetup only in production mode, after dev mode guards.
Dev mode redirect to /login now works regardless of needsSetup state.

This fixes the App.test.tsx "Dev login selector" test failure.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
groombook-ci[bot]
2026-03-28 21:22:13 +00:00
committed by Flea Flicker
parent d2110881b4
commit c91f29d542
2 changed files with 17 additions and 13 deletions
+8 -5
View File
@@ -236,20 +236,23 @@ export function App() {
);
}
// Still loading auth state or setup check
if (authDisabled === null || sessionLoading || needsSetup === null) return null;
// Still loading auth state or setup check (skip setup check in dev mode)
if (authDisabled === null || sessionLoading) return null;
// Dev mode: show login selector
// Dev mode: show login selector (no setup check needed in dev mode)
if (authDisabled && location.pathname === "/login") {
return <DevLoginSelector />;
}
// Dev mode: use dev login selector
// Dev mode: use dev login selector (no setup check needed in dev mode)
if (authDisabled && !getDevUser()) {
return <Navigate to="/login" replace />;
}
// Production mode: if no session, show login page (avoids redirect loops)
// Production: need setup check
if (needsSetup === null) return null;
// Production mode: if no session, redirect to Authentik sign-in
if (!authDisabled && !session) {
return <LoginPage />;
}
+9 -8
View File
@@ -122,21 +122,22 @@ export function CustomerPortal() {
const isReadOnly = session?.status === "active";
const renderSection = () => {
const sessionId = session?.id ?? null;
switch (activeSection) {
case "dashboard":
return <Dashboard onNavigate={handleNavClick} readOnly={!!isReadOnly} onReschedule={handleReschedule} />;
return <Dashboard onNavigate={handleNavClick} readOnly={!!isReadOnly} sessionId={sessionId} clientName={clientName} onReschedule={handleReschedule} />;
case "appointments":
return <AppointmentsSection readOnly={!!isReadOnly} sessionId={session?.id ?? null} />;
return <AppointmentsSection readOnly={!!isReadOnly} sessionId={sessionId} />;
case "pets":
return <PetProfiles readOnly={!!isReadOnly} />;
return <PetProfiles readOnly={!!isReadOnly} sessionId={sessionId} />;
case "reports":
return <ReportCards />;
return <ReportCards sessionId={sessionId} />;
case "billing":
return <BillingPayments readOnly={!!isReadOnly} />;
return <BillingPayments readOnly={!!isReadOnly} sessionId={sessionId} />;
case "messages":
return <Communication readOnly={!!isReadOnly} />;
return <Communication readOnly={!!isReadOnly} sessionId={sessionId} />;
case "settings":
return <AccountSettings readOnly={!!isReadOnly} />;
return <AccountSettings readOnly={!!isReadOnly} sessionId={sessionId} />;
}
};
@@ -279,7 +280,7 @@ export function CustomerPortal() {
</h1>
</div>
<div className="flex items-center gap-3">
<span className="text-sm text-stone-600">Hi, {CUSTOMER.name.split(" ")[0]}</span>
<span className="text-sm text-stone-600">Hi, {clientName.split(" ")[0] || "Guest"}</span>
<div className="w-8 h-8 rounded-full flex items-center justify-center text-white text-sm font-medium" style={{ background: branding.accentColor }}>
SM
</div>