mirror of
https://dev.azure.com/globalhealthx/EMR/_git/helix-engage
synced 2026-04-11 10:23:27 +00:00
fix: add auth guard redirect and wire logout into NavAccountCard
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -44,8 +44,9 @@ const placeholderAccounts: NavAccountType[] = [
|
||||
export const NavAccountMenu = ({
|
||||
className,
|
||||
selectedAccountId = "olivia",
|
||||
onSignOut,
|
||||
...dialogProps
|
||||
}: AriaDialogProps & { className?: string; accounts?: NavAccountType[]; selectedAccountId?: string }) => {
|
||||
}: AriaDialogProps & { className?: string; accounts?: NavAccountType[]; selectedAccountId?: string; onSignOut?: () => void }) => {
|
||||
const focusManager = useFocusManager();
|
||||
const dialogRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
@@ -115,7 +116,7 @@ export const NavAccountMenu = ({
|
||||
</div>
|
||||
|
||||
<div className="pt-1 pb-1.5">
|
||||
<NavAccountCardMenuItem label="Sign out" icon={LogOut01} shortcut="⌥⇧Q" />
|
||||
<NavAccountCardMenuItem label="Sign out" icon={LogOut01} shortcut="⌥⇧Q" onClick={onSignOut} />
|
||||
</div>
|
||||
</AriaDialog>
|
||||
);
|
||||
@@ -156,10 +157,12 @@ export const NavAccountCard = ({
|
||||
popoverPlacement,
|
||||
selectedAccountId = "olivia",
|
||||
items = placeholderAccounts,
|
||||
onSignOut,
|
||||
}: {
|
||||
popoverPlacement?: Placement;
|
||||
selectedAccountId?: string;
|
||||
items?: NavAccountType[];
|
||||
onSignOut?: () => void;
|
||||
}) => {
|
||||
const triggerRef = useRef<HTMLDivElement>(null);
|
||||
const isDesktop = useBreakpoint("lg");
|
||||
@@ -200,7 +203,7 @@ export const NavAccountCard = ({
|
||||
)
|
||||
}
|
||||
>
|
||||
<NavAccountMenu selectedAccountId={selectedAccountId} accounts={items} />
|
||||
<NavAccountMenu selectedAccountId={selectedAccountId} accounts={items} onSignOut={onSignOut} />
|
||||
</AriaPopover>
|
||||
</AriaDialogTrigger>
|
||||
</div>
|
||||
|
||||
12
src/components/layout/auth-guard.tsx
Normal file
12
src/components/layout/auth-guard.tsx
Normal file
@@ -0,0 +1,12 @@
|
||||
import { Navigate, Outlet } from 'react-router';
|
||||
import { useAuth } from '@/providers/auth-provider';
|
||||
|
||||
export const AuthGuard = () => {
|
||||
const { isAuthenticated } = useAuth();
|
||||
|
||||
if (!isAuthenticated) {
|
||||
return <Navigate to="/login" replace />;
|
||||
}
|
||||
|
||||
return <Outlet />;
|
||||
};
|
||||
@@ -8,13 +8,12 @@ import {
|
||||
faGrid2,
|
||||
faPlug,
|
||||
} from "@fortawesome/pro-regular-svg-icons";
|
||||
import { useNavigate } from "react-router";
|
||||
import { MobileNavigationHeader } from "@/components/application/app-navigation/base-components/mobile-header";
|
||||
import { NavAccountCard } from "@/components/application/app-navigation/base-components/nav-account-card";
|
||||
import { NavItemBase } from "@/components/application/app-navigation/base-components/nav-item";
|
||||
import type { NavItemType } from "@/components/application/app-navigation/config";
|
||||
|
||||
// TODO: Wire to useAuth() once auth-provider.tsx is implemented
|
||||
const isAdmin = false;
|
||||
import { useAuth } from "@/providers/auth-provider";
|
||||
|
||||
const MAIN_SIDEBAR_WIDTH = 292;
|
||||
|
||||
@@ -58,10 +57,18 @@ interface SidebarProps {
|
||||
}
|
||||
|
||||
export const Sidebar = ({ activeUrl = "/" }: SidebarProps) => {
|
||||
const { logout, isAdmin: authIsAdmin, user } = useAuth();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handleSignOut = () => {
|
||||
logout();
|
||||
navigate('/login');
|
||||
};
|
||||
|
||||
const navSections = [
|
||||
{ label: "Main", items: mainItems },
|
||||
{ label: "Insights", items: insightsItems },
|
||||
...(isAdmin ? [{ label: "Admin", items: adminItems }] : []),
|
||||
...(authIsAdmin ? [{ label: "Admin", items: adminItems }] : []),
|
||||
];
|
||||
|
||||
const content = (
|
||||
@@ -103,7 +110,7 @@ export const Sidebar = ({ activeUrl = "/" }: SidebarProps) => {
|
||||
|
||||
{/* Account card */}
|
||||
<div className="mt-auto flex flex-col gap-5 px-2 py-4 lg:gap-6 lg:px-4 lg:py-4">
|
||||
<NavAccountCard />
|
||||
<NavAccountCard onSignOut={handleSignOut} />
|
||||
</div>
|
||||
</aside>
|
||||
);
|
||||
|
||||
29
src/main.tsx
29
src/main.tsx
@@ -2,6 +2,7 @@ import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { BrowserRouter, Outlet, Route, Routes } from "react-router";
|
||||
import { AppShell } from "@/components/layout/app-shell";
|
||||
import { AuthGuard } from "@/components/layout/auth-guard";
|
||||
import { NotFound } from "@/pages/not-found";
|
||||
import { AllLeadsPage } from "@/pages/all-leads";
|
||||
import { CampaignDetailPage } from "@/pages/campaign-detail";
|
||||
@@ -24,19 +25,21 @@ createRoot(document.getElementById("root")!).render(
|
||||
<RouteProvider>
|
||||
<Routes>
|
||||
<Route path="/login" element={<LoginPage />} />
|
||||
<Route
|
||||
element={
|
||||
<AppShell>
|
||||
<Outlet />
|
||||
</AppShell>
|
||||
}
|
||||
>
|
||||
<Route path="/" element={<LeadWorkspacePage />} />
|
||||
<Route path="/leads" element={<AllLeadsPage />} />
|
||||
<Route path="/campaigns" element={<CampaignsPage />} />
|
||||
<Route path="/campaigns/:id" element={<CampaignDetailPage />} />
|
||||
<Route path="/outreach" element={<OutreachPage />} />
|
||||
<Route path="*" element={<NotFound />} />
|
||||
<Route element={<AuthGuard />}>
|
||||
<Route
|
||||
element={
|
||||
<AppShell>
|
||||
<Outlet />
|
||||
</AppShell>
|
||||
}
|
||||
>
|
||||
<Route path="/" element={<LeadWorkspacePage />} />
|
||||
<Route path="/leads" element={<AllLeadsPage />} />
|
||||
<Route path="/campaigns" element={<CampaignsPage />} />
|
||||
<Route path="/campaigns/:id" element={<CampaignDetailPage />} />
|
||||
<Route path="/outreach" element={<OutreachPage />} />
|
||||
<Route path="*" element={<NotFound />} />
|
||||
</Route>
|
||||
</Route>
|
||||
</Routes>
|
||||
</RouteProvider>
|
||||
|
||||
Reference in New Issue
Block a user