import { createContext, useContext, useState, useEffect, useCallback, useMemo, type ReactNode } from 'react' import { useAuth } from './AuthContext' import { api } from '../lib/api' // ── Default permissions for system roles (fallback if no DB data) ───────────── export const DEFAULT_ROLE_PERMS: Record = { hotel_admin: ['*'], manager: ['*'], receptionist: [ 'calendar', 'bookings', 'guests', 'rooms', 'availability', 'housekeeping', 'room_service', 'rental', 'pos', 'reviews', 'reports', 'documents', 'website', ], housekeeper: ['calendar', 'housekeeping', 'maintenance', 'rooms'], accountant: ['calendar', 'reports', 'pos', 'discounts', 'tariffs', 'pricing', 'loyalty', 'documents'], security: ['calendar', 'bookings'], technician: ['calendar', 'housekeeping', 'maintenance', 'rooms', 'floor_map', 'equipment', 'ttlock'], } // Default home pages per role (fallback) export const DEFAULT_HOME_PAGES: Record = { hotel_admin: '/calendar', manager: '/calendar', receptionist: '/calendar', housekeeper: '/housekeeping', accountant: '/reports', security: '/calendar', technician: '/housekeeping', } // ── Types ───────────────────────────────────────────────────────────────────── export interface SavedRolePermission { id: string hotelId: string roleKey: string name: string color: string isSystem: boolean permissions: Record homePage?: string | null notificationSettings?: Record } interface RolePermissionsContextValue { /** Check if the current user has a given permission */ can: (permission: string) => boolean /** Home page path for the current user's role */ userHomePage: string /** Raw saved permissions for all roles (used by RolesTab editor) */ savedPermissions: SavedRolePermission[] /** Re-fetch from API */ reload: () => Promise /** True while initial permissions are being fetched */ loading: boolean } // ── Context ─────────────────────────────────────────────────────────────────── const RolePermissionsContext = createContext({ can: () => false, userHomePage: '/calendar', savedPermissions: [], reload: async () => {}, loading: true, }) export function RolePermissionsProvider({ children }: { children: ReactNode }) { const { user } = useAuth() const [savedPermissions, setSavedPermissions] = useState([]) // Start as true — PermissionGuard waits before rendering, preventing permission flash const [loading, setLoading] = useState(true) const reload = useCallback(async () => { if (!user?.hotelSlug) { setLoading(false) return } setLoading(true) try { const data = await api.rolePermissions.list(user.hotelSlug) setSavedPermissions(data) } catch { // silently fall back to defaults } finally { setLoading(false) } }, [user?.hotelSlug]) useEffect(() => { reload() }, [reload]) const can = useCallback((permission: string): boolean => { const role = user?.role ?? 'housekeeper' if (role === 'super_admin') return true if (role === 'hotel_admin' || role === 'manager') return true // Check saved permissions from DB const saved = savedPermissions.find(rp => rp.roleKey === role) if (saved) { return saved.permissions[permission] === true } // Fall back to hardcoded defaults const perms = DEFAULT_ROLE_PERMS[role] ?? [] return perms.includes('*') || perms.includes(permission) }, [user?.role, savedPermissions]) const userHomePage = useMemo(() => { const role = user?.role ?? '' if (role === 'super_admin') return '/admin' if (role === 'hotel_admin' || role === 'manager') return '/calendar' // Use saved home page from DB if set const saved = savedPermissions.find(rp => rp.roleKey === role) if (saved?.homePage) return saved.homePage // Fall back to role default return DEFAULT_HOME_PAGES[role] ?? '/calendar' }, [user?.role, savedPermissions]) return ( {children} ) } export function useRolePermissions() { return useContext(RolePermissionsContext) }