'use client'; import { useEffect } from 'react'; import { useRouter } from 'next/navigation'; import { ShieldOff } from 'lucide-react'; import { useAuthStore } from '@/lib/auth-store'; interface Props { /** * A single key, or several of which the user needs **any one**. The any-of form * is how a report page accepts either its own key or the `reports:view` * umbrella — mirroring the OR semantics of the API's `PassengerPermissionGuard`. */ permission?: string | string[]; children: React.ReactNode; } /** * Wraps a page to enforce auth + optional permission check. * - Not logged in → redirect to /login * - Missing permission → render an explanation (see below) * * This used to redirect a user without the permission to /dashboard. That is a * dead end for anyone lacking `dashboard:view`, since that page renders nothing * either — they got a blank screen with no explanation. Saying what happened is * both kinder and easier to support. */ export function PermissionGuard({ permission, children }: Props) { const router = useRouter(); const isAuthenticated = useAuthStore((s) => s.isAuthenticated); const hasPermission = useAuthStore((s) => s.hasPermission); useEffect(() => { if (!isAuthenticated) router.replace('/login'); }, [isAuthenticated, router]); if (!isAuthenticated) return null; const keys = permission === undefined ? [] : Array.isArray(permission) ? permission : [permission]; const allowed = keys.length === 0 || keys.some((key) => hasPermission(key)); if (!allowed) { return (
Your account is missing the permission this page requires. Ask an administrator to grant it if you need access.