diff --git a/app/(app)/layout.tsx b/app/(app)/layout.tsx index d102a50..6bbab55 100644 --- a/app/(app)/layout.tsx +++ b/app/(app)/layout.tsx @@ -1,6 +1,7 @@ import { createClient } from '@/lib/supabase/server' import { redirect } from 'next/navigation' import { AppSidebar } from '@/components/app-sidebar' +import { CommandPalette } from '@/components/command-palette' import { ConfirmProvider } from '@/components/ui/confirm' import { getRoleLabelMap } from '@/lib/role-labels' @@ -77,6 +78,7 @@ export default async function AppLayout({ children }: { children: React.ReactNod return ( +
+}) { + const router = useRouter() + const [open, setOpen] = useState(false) + + useEffect(() => { + const onKey = (e: KeyboardEvent) => { + if ((e.metaKey || e.ctrlKey) && e.key.toLowerCase() === 'k') { + e.preventDefault() + setOpen(o => !o) + } + } + document.addEventListener('keydown', onKey) + return () => document.removeEventListener('keydown', onKey) + }, []) + + const allowed = useCallback( + (d: Dest) => { + if (d.adminOnly) return isAdmin + if (d.perm) return isAdmin || !!navPerms[d.perm] + return true + }, + [isAdmin, navPerms], + ) + + const go = (href: string) => { + setOpen(false) + router.push(href) + } + + return ( + + + + No matches. + {NAV.map(section => { + const items = section.items.filter(allowed) + if (items.length === 0) return null + return ( + + {items.map(d => ( + go(d.href)}> + {d.label} + + ))} + + ) + })} + + + ) +}