diff --git a/apps/web/app/dashboard/settings/staff/page.tsx b/apps/web/app/dashboard/settings/staff/page.tsx index 06f864a..91e76d4 100644 --- a/apps/web/app/dashboard/settings/staff/page.tsx +++ b/apps/web/app/dashboard/settings/staff/page.tsx @@ -5,6 +5,8 @@ import { z } from "zod"; import { useForm } from "react-hook-form"; import { zodResolver } from "@hookform/resolvers/zod"; import { apiFetch } from "@/lib/api-client"; +import { UnauthorizedNotice } from "@/components/auth/UnauthorizedNotice"; +import { useAuth } from "@/providers/AuthProvider"; import { useSubscription } from "@/providers/SubscriptionProvider"; type StaffRole = @@ -88,7 +90,9 @@ function StatusBadge({ isActive }: { isActive: boolean }) { } export default function StaffManagementPage() { + const { user } = useAuth(); const { isWriteLocked } = useSubscription(); + const canManageStaff = user?.role === "SUPER_ADMIN" || user?.role === "CLINIC_ADMIN"; const [staff, setStaff] = useState([]); const [isLoading, setIsLoading] = useState(true); const [isCreateOpen, setIsCreateOpen] = useState(false); @@ -114,6 +118,11 @@ export default function StaffManagementPage() { }); useEffect(() => { + if (!canManageStaff) { + setIsLoading(false); + return; + } + const loadStaff = async () => { setIsLoading(true); setToast(null); @@ -135,7 +144,15 @@ export default function StaffManagementPage() { }; void loadStaff(); - }, []); + }, [canManageStaff]); + + if (!canManageStaff) { + return ( +
+ +
+ ); + } const pagedStaff = useMemo(() => { const start = (page - 1) * PAGE_SIZE; diff --git a/apps/web/components/auth/UnauthorizedNotice.tsx b/apps/web/components/auth/UnauthorizedNotice.tsx new file mode 100644 index 0000000..912c48e --- /dev/null +++ b/apps/web/components/auth/UnauthorizedNotice.tsx @@ -0,0 +1,14 @@ +"use client"; + +export const UnauthorizedNotice = ({ + title = "Access Restricted", + message, +}: { + title?: string; + message: string; +}) => ( +
+

{title}

+

{message}

+
+); diff --git a/apps/web/layouts/DashboardLayout.tsx b/apps/web/layouts/DashboardLayout.tsx index 4681c58..c281fd0 100644 --- a/apps/web/layouts/DashboardLayout.tsx +++ b/apps/web/layouts/DashboardLayout.tsx @@ -21,7 +21,8 @@ const NAV = [ export const DashboardLayout = ({ children }: { children: React.ReactNode }) => { const pathname = usePathname(); - const { logout } = useAuth(); + const { logout, user } = useAuth(); + const visibleNav = NAV.filter((item) => item.roles === "ALL" || item.roles.includes(user?.role ?? "")); return ( @@ -32,28 +33,19 @@ export const DashboardLayout = ({ children }: { children: React.ReactNode }) => LumenHealth