import { Navigate, useLocation } from 'react-router'; import { useAuthStore } from '../../store/auth'; import { usePermissionStore } from '../../store/permissions'; import { saveReturnUrl } from '../../utils/token'; import PageLoader from '../common/PageLoader'; import Layout from '../layout/Layout'; interface PermissionRouteProps { children: React.ReactNode; /** Single permission to check */ permission?: string; /** Multiple permissions (OR by default, AND if requireAll is true) */ permissions?: string[]; /** When true, ALL listed permissions are required instead of ANY */ requireAll?: boolean; } export function PermissionRoute({ children, permission, permissions, requireAll = false, }: PermissionRouteProps) { const isAuthenticated = useAuthStore((state) => state.isAuthenticated); const isLoading = useAuthStore((state) => state.isLoading); const isAdmin = useAuthStore((state) => state.isAdmin); const location = useLocation(); const permissionsLoaded = usePermissionStore((state) => state.isLoaded); const hasPermission = usePermissionStore((state) => state.hasPermission); const hasAnyPermission = usePermissionStore((state) => state.hasAnyPermission); const hasAllPermissions = usePermissionStore((state) => state.hasAllPermissions); // Still loading auth state, or admin but permissions not fetched yet if (isLoading || (isAdmin && !permissionsLoaded)) { return ; } if (!isAuthenticated) { saveReturnUrl(); return ; } if (!isAdmin) { return ; } // Check permissions if specified const needsPermissionCheck = permission || (permissions && permissions.length > 0); if (needsPermissionCheck) { let hasAccess = false; if (permission) { hasAccess = hasPermission(permission); } else if (permissions && permissions.length > 0) { hasAccess = requireAll ? hasAllPermissions(...permissions) : hasAnyPermission(...permissions); } if (!hasAccess) { // Redirect back to the admin landing — unless we're already there // (would loop) or the landing itself is what we lack permission for. // Fall back to the user dashboard in that case. const target = location.pathname === '/admin' ? '/' : '/admin'; return ; } } return {children}; }