feat(portal): replace mock data with real session-driven API calls #152
@@ -236,20 +236,23 @@ export function App() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Still loading auth state or setup check
|
// Still loading auth state or setup check (skip setup check in dev mode)
|
||||||
if (authDisabled === null || sessionLoading || needsSetup === null) return null;
|
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") {
|
if (authDisabled && location.pathname === "/login") {
|
||||||
return <DevLoginSelector />;
|
return <DevLoginSelector />;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dev mode: use dev login selector
|
// Dev mode: use dev login selector (no setup check needed in dev mode)
|
||||||
if (authDisabled && !getDevUser()) {
|
if (authDisabled && !getDevUser()) {
|
||||||
return <Navigate to="/login" replace />;
|
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) {
|
if (!authDisabled && !session) {
|
||||||
return <LoginPage />;
|
return <LoginPage />;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,21 +122,22 @@ export function CustomerPortal() {
|
|||||||
const isReadOnly = session?.status === "active";
|
const isReadOnly = session?.status === "active";
|
||||||
|
|
||||||
const renderSection = () => {
|
const renderSection = () => {
|
||||||
|
const sessionId = session?.id ?? null;
|
||||||
switch (activeSection) {
|
switch (activeSection) {
|
||||||
case "dashboard":
|
case "dashboard":
|
||||||
return <Dashboard onNavigate={handleNavClick} readOnly={!!isReadOnly} onReschedule={handleReschedule} />;
|
return <Dashboard onNavigate={handleNavClick} readOnly={!!isReadOnly} sessionId={sessionId} clientName={clientName} onReschedule={handleReschedule} />;
|
||||||
case "appointments":
|
case "appointments":
|
||||||
return <AppointmentsSection readOnly={!!isReadOnly} sessionId={session?.id ?? null} />;
|
return <AppointmentsSection readOnly={!!isReadOnly} sessionId={sessionId} />;
|
||||||
case "pets":
|
case "pets":
|
||||||
return <PetProfiles readOnly={!!isReadOnly} />;
|
return <PetProfiles readOnly={!!isReadOnly} sessionId={sessionId} />;
|
||||||
case "reports":
|
case "reports":
|
||||||
return <ReportCards />;
|
return <ReportCards sessionId={sessionId} />;
|
||||||
case "billing":
|
case "billing":
|
||||||
return <BillingPayments readOnly={!!isReadOnly} />;
|
return <BillingPayments readOnly={!!isReadOnly} sessionId={sessionId} />;
|
||||||
case "messages":
|
case "messages":
|
||||||
return <Communication readOnly={!!isReadOnly} />;
|
return <Communication readOnly={!!isReadOnly} sessionId={sessionId} />;
|
||||||
case "settings":
|
case "settings":
|
||||||
return <AccountSettings readOnly={!!isReadOnly} />;
|
return <AccountSettings readOnly={!!isReadOnly} sessionId={sessionId} />;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -279,7 +280,7 @@ export function CustomerPortal() {
|
|||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-3">
|
<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 }}>
|
<div className="w-8 h-8 rounded-full flex items-center justify-center text-white text-sm font-medium" style={{ background: branding.accentColor }}>
|
||||||
SM
|
SM
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user