@@ -70,6 +89,7 @@ export default async function AppLayout({ children }: { children: React.ReactNod
roleName={roleName}
taskBadge={taskCount ?? 0}
paymentBadge={paymentCount ?? 0}
+ navPerms={navPerms}
/>
{children}
diff --git a/components/app-sidebar.tsx b/components/app-sidebar.tsx
index 16a0253..d544751 100644
--- a/components/app-sidebar.tsx
+++ b/components/app-sidebar.tsx
@@ -107,13 +107,23 @@ interface AppSidebarProps {
taskBadge?: number
commsBadge?: number
paymentBadge?: number
+ navPerms?: Record
}
-export function AppSidebar({ member, roleName, taskBadge = 0, commsBadge = 0, paymentBadge = 0 }: AppSidebarProps) {
+export function AppSidebar({ member, roleName, taskBadge = 0, commsBadge = 0, paymentBadge = 0, navPerms = {} }: AppSidebarProps) {
const pathname = usePathname()
const space = member.spaces
const initials = (member.display_name || 'U').split(' ').map(n => n[0]).join('').toUpperCase().slice(0, 2)
const isAdmin = member.role === 'admin' || member.role === 'board'
+ // Feature-management links: admin/board see all; a member with a delegated
+ // *.manage permission sees just that one (matches the page guards).
+ const can = (perm: string) => isAdmin || !!navPerms[perm]
+ const canForms = can('forms.manage')
+ const canCerts = can('certifications.manage')
+ const canClasses = can('classes.manage')
+ const canEquip = can('equipment.manage')
+ const canDoor = can('door.manage')
+ const showAdminSection = isAdmin || canForms || canCerts || canClasses || canEquip || canDoor
const [drawerOpen, setDrawerOpen] = useState(false)
const menuButtonRef = useRef(null)
const drawerCloseRef = useRef(null)
@@ -174,6 +184,8 @@ export function AppSidebar({ member, roleName, taskBadge = 0, commsBadge = 0, pa
+ {/* Classes/Equipment use exact-match (not isActive) so /classes/manage
+ and /equipment/manage highlight only the Admin link, not both. */}
@@ -199,16 +211,16 @@ export function AppSidebar({ member, roleName, taskBadge = 0, commsBadge = 0, pa
- {isAdmin && (
+ {showAdminSection && (
-
-
-
-
-
-
-
-
+ {isAdmin && }
+ {canForms && }
+ {canCerts && }
+ {canClasses && }
+ {canEquip && }
+ {canDoor && }
+ {isAdmin && }
+ {isAdmin && }
)}