diff --git a/frontend/components/auth/app-auth-guard.tsx b/frontend/components/auth/app-auth-guard.tsx index b25ca87..400af07 100644 --- a/frontend/components/auth/app-auth-guard.tsx +++ b/frontend/components/auth/app-auth-guard.tsx @@ -56,9 +56,14 @@ export function AppAuthGuard({ children }: { children: ReactNode }) { router.replace(defaultLandingFor(role)); return; } - // AI kill-switch: the chat home ("/") is off for this user — send them to - // patients (clinical roles always have it; non-clinical never land on "/"). - if (!aiLoading && !aiAllowed && pathname === "/") { + // AI kill-switch: the AI surfaces — chat home ("/") and Analysis — are off + // for this user (a full clinic disable also covers owners/admins). Send them + // to patients (clinical roles always have it; non-clinical never land here). + if ( + !aiLoading && + !aiAllowed && + (pathname === "/" || pathname === "/analysis") + ) { router.replace("/patients"); } }, [ready, role, pathname, router, aiAllowed, aiLoading]); diff --git a/frontend/components/command-palette.tsx b/frontend/components/command-palette.tsx index fd567ce..634f30d 100644 --- a/frontend/components/command-palette.tsx +++ b/frontend/components/command-palette.tsx @@ -76,7 +76,10 @@ export function CommandPaletteProvider({ children }: { children: ReactNode }) { // Filtered by role so reception can't jump to clinical pages, and by // the AI kill-switch so the disabled chat isn't listed. items: visibleNavItems(role) - .filter((item) => aiAllowed || item.id !== "new-chat") + .filter( + (item) => + aiAllowed || (item.id !== "new-chat" && item.id !== "analysis"), + ) .flatMap((item) => item.subs?.length ? item.subs.map((sub) => ({ diff --git a/frontend/components/sidebar-02/app-sidebar.tsx b/frontend/components/sidebar-02/app-sidebar.tsx index 9ffd6ed..9929ed6 100644 --- a/frontend/components/sidebar-02/app-sidebar.tsx +++ b/frontend/components/sidebar-02/app-sidebar.tsx @@ -33,9 +33,12 @@ export function DashboardSidebar() { const isCollapsed = state === "collapsed"; // Hide clinical nav from non-clinical roles (e.g. reception). See lib/roles.ts. - // Also drop the AI "New chat" entry when the clinic's AI kill-switch applies. + // Also drop the AI surfaces ("New chat" + "Analysis") when the clinic's AI + // kill-switch applies — a full disable hides them for owners/admins too. const dashboardRoutes: Route[] = visibleNavItems(role) - .filter((item) => aiAllowed || item.id !== "new-chat") + .filter( + (item) => aiAllowed || (item.id !== "new-chat" && item.id !== "analysis"), + ) .map((item) => ({ id: item.id, title: t(item.labelKey), diff --git a/frontend/lib/i18n/locales/en/translation.json b/frontend/lib/i18n/locales/en/translation.json index a491b6c..c6f6f48 100644 --- a/frontend/lib/i18n/locales/en/translation.json +++ b/frontend/lib/i18n/locales/en/translation.json @@ -1479,11 +1479,11 @@ "ai": { "availability": { "title": "Availability", - "description": "Control who in your clinic can use the AI assistant. When disabled, the AI page and sidebar entry are hidden and the assistant cannot be reached.", + "description": "Control who in your clinic can use the AI assistant. When disabled, every AI surface — New chat, Analysis, and the chat history — is hidden and cannot be reached.", "enabled": "Enable AI assistant", - "enabledHint": "Turn the AI assistant on for your clinic. Off hides it for everyone.", + "enabledHint": "Master switch. Turning this off disables and hides the AI for everyone in the clinic — including owners and admins.", "employeesOnly": "Disable for employees only", - "employeesOnlyHint": "Hide the AI from staff; owners and admins keep access.", + "employeesOnlyHint": "Keep the AI for owners and admins, but hide it from all other staff.", "savedTitle": "AI availability updated", "savedBody": "The change applies across your clinic.", "readonlyEnabled": "The AI assistant is enabled for your clinic.",