import React, { createContext, useContext, useMemo, useCallback, ReactNode } from 'react'; import { useQuery, useQueryClient } from '@tanstack/react-query'; import { useAuth } from './AuthContext'; import { permissionsApi } from '../services/permissions'; interface PermissionContextType { permissions: Set; maintenance: Record; isAdmin: boolean; isLoading: boolean; hasPermission: (perm: string) => boolean; hasAnyPermission: (...perms: string[]) => boolean; isFeatureEnabled: (featureGroup: string) => boolean; refetch: () => void; } const PermissionContext = createContext(undefined); interface PermissionProviderProps { children: ReactNode; } export const PermissionProvider: React.FC = ({ children }) => { const { isAuthenticated } = useAuth(); const queryClient = useQueryClient(); const { data, isLoading } = useQuery({ queryKey: ['my-permissions'], queryFn: permissionsApi.getMyPermissions, enabled: isAuthenticated, staleTime: 5 * 60 * 1000, }); const permissions = useMemo( () => new Set(data?.permissions ?? []), [data?.permissions] ); const maintenance = data?.maintenance ?? {}; const isAdmin = data?.isAdmin ?? false; const isFeatureEnabled = useCallback( (featureGroup: string): boolean => { if (isAdmin) return true; return !maintenance[featureGroup]; }, [isAdmin, maintenance] ); const hasPermission = useCallback( (perm: string): boolean => { if (isAdmin) return true; const featureGroup = perm.split(':')[0]; if (!isFeatureEnabled(featureGroup)) return false; return permissions.has(perm); }, [isAdmin, permissions, isFeatureEnabled] ); const hasAnyPermission = useCallback( (...perms: string[]): boolean => { return perms.some(p => hasPermission(p)); }, [hasPermission] ); const refetch = useCallback(() => { queryClient.invalidateQueries({ queryKey: ['my-permissions'] }); }, [queryClient]); const value = useMemo( (): PermissionContextType => ({ permissions, maintenance, isAdmin, isLoading: isAuthenticated ? isLoading : false, hasPermission, hasAnyPermission, isFeatureEnabled, refetch, }), [permissions, maintenance, isAdmin, isAuthenticated, isLoading, hasPermission, hasAnyPermission, isFeatureEnabled, refetch] ); return ( {children} ); }; export const usePermissionContext = (): PermissionContextType => { const context = useContext(PermissionContext); if (context === undefined) { throw new Error('usePermissionContext must be used within a PermissionProvider'); } return context; };