'use client' import React, { createContext, useContext, useState, useEffect } from 'react' import { useRouter } from 'next/navigation' const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:5001/api/v1' interface User { id: string employeeId: string username: string email: string isActive: boolean role?: { id: string name: string nameEn: string permissions: Permission[] } } interface Permission { id: string module: string actions?: string[] canView?: boolean canCreate?: boolean canEdit?: boolean canDelete?: boolean canExport?: boolean canApprove?: boolean } interface AuthContextType { user: User | null login: (email: string, password: string) => Promise logout: () => void isLoading: boolean isAuthenticated: boolean hasPermission: (module: string, action: 'view' | 'create' | 'edit' | 'delete' | 'export' | 'approve') => boolean } const AuthContext = createContext(undefined) export function AuthProvider({ children }: { children: React.ReactNode }) { const [user, setUser] = useState(null) const [isLoading, setIsLoading] = useState(true) const router = useRouter() // Check for existing token on mount useEffect(() => { const token = localStorage.getItem('accessToken') if (token) { // Verify token and get user data fetchUserData(token) } else { setIsLoading(false) } }, []) // Transform backend permissions format to frontend format // Backend uses actions: ['*'] or ['read','create',...] - wildcard grants all const transformPermissions = (permissions: any[]): Permission[] => { const hasWildcard = (actions: string[] | any) => { const arr = Array.isArray(actions) ? actions : [] return arr.includes('*') || arr.includes('all') } return permissions.map(p => { const wildcard = hasWildcard(p.actions) return { id: p.id, module: p.module, actions: p.actions, canView: wildcard || p.actions?.includes('read') || false, canCreate: wildcard || p.actions?.includes('create') || false, canEdit: wildcard || p.actions?.includes('update') || false, canDelete: wildcard || p.actions?.includes('delete') || false, canExport: wildcard || p.actions?.includes('export') || false, canApprove: wildcard || p.actions?.includes('approve') || false, } }) } const fetchUserData = async (token: string) => { try { const response = await fetch(`${API_URL}/auth/me`, { headers: { 'Authorization': `Bearer ${token}` } }) if (response.ok) { const userData = await response.json() const user = userData.data if (user.role?.permissions) { user.role.permissions = transformPermissions(user.role.permissions) } setUser(user) } else { localStorage.removeItem('accessToken') } } catch (error) { console.error('Failed to fetch user data:', error) localStorage.removeItem('accessToken') } finally { setIsLoading(false) } } const login = async (email: string, password: string) => { try { const response = await fetch(`${API_URL}/auth/login`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, password }) }) const data = await response.json() if (!response.ok) { throw new Error(data.message || 'فشل تسجيل الدخول') } // Store token localStorage.setItem('accessToken', data.data.accessToken) localStorage.setItem('refreshToken', data.data.refreshToken) // Transform permissions and set user data const userData = data.data.user if (userData.role?.permissions) { userData.role.permissions = transformPermissions(userData.role.permissions) } setUser(userData) // Redirect to dashboard router.push('/dashboard') } catch (error: any) { throw new Error(error.message || 'فشل تسجيل الدخول') } } const logout = () => { localStorage.removeItem('accessToken') localStorage.removeItem('refreshToken') setUser(null) router.push('/') } const hasPermission = (module: string, action: 'view' | 'create' | 'edit' | 'delete' | 'export' | 'approve'): boolean => { if (!user?.role?.permissions) return false const permission = user.role.permissions.find(p => p.module.toLowerCase() === module.toLowerCase()) if (!permission) return false const actionMap = { view: 'canView', create: 'canCreate', edit: 'canEdit', delete: 'canDelete', export: 'canExport', approve: 'canApprove' } return permission[actionMap[action] as keyof Permission] as boolean } return ( {children} ) } export function useAuth() { const context = useContext(AuthContext) if (context === undefined) { throw new Error('useAuth must be used within an AuthProvider') } return context }