import React, { createContext, useContext, useReducer, useEffect } from 'react'; import { AuthState, AdminUser, Permission, LoginRequest } from '../types/auth'; import toast from 'react-hot-toast'; interface AuthContextType { isAuthenticated: boolean; isLoading: boolean; user: AdminUser | null; permissions: Permission[]; allPermissions: Permission[]; token: string | null; refreshToken: string | null; logout: () => void; restoreSession: () => void; hasPermission: (permissionId: number) => boolean; hasPermissionByTitle: (title: string) => boolean; } const AuthContext = createContext(undefined); type AuthAction = | { type: 'LOGIN'; payload: { user: AdminUser; permissions: Permission[]; allPermissions: Permission[]; token: string; refreshToken: string } } | { type: 'LOGOUT' } | { type: 'RESTORE_SESSION'; payload: { user: AdminUser; permissions: Permission[]; allPermissions: Permission[]; token: string; refreshToken: string } } | { type: 'SET_LOADING'; payload: boolean }; const authReducer = (state: AuthState, action: AuthAction): AuthState => { switch (action.type) { case 'LOGIN': case 'RESTORE_SESSION': return { ...state, isAuthenticated: true, isLoading: false, user: action.payload.user, permissions: action.payload.permissions, allPermissions: action.payload.allPermissions, token: action.payload.token, refreshToken: action.payload.refreshToken, }; case 'LOGOUT': return { ...state, isAuthenticated: false, isLoading: false, user: null, permissions: [], allPermissions: [], token: null, refreshToken: null, }; case 'SET_LOADING': return { ...state, isLoading: action.payload, }; default: return state; } }; const initialState: AuthState = { isAuthenticated: false, isLoading: true, user: null, permissions: [], allPermissions: [], token: null, refreshToken: null, }; export const AuthProvider = ({ children }: { children: React.ReactNode }) => { const [state, dispatch] = useReducer(authReducer, initialState); const restoreSession = () => { dispatch({ type: 'SET_LOADING', payload: true }); const token = localStorage.getItem('admin_token'); const refreshToken = localStorage.getItem('admin_refresh_token'); const userStr = localStorage.getItem('admin_user'); const permissionsStr = localStorage.getItem('admin_permissions'); if (token && userStr && permissionsStr) { try { const user = JSON.parse(userStr); const permissions = JSON.parse(permissionsStr); dispatch({ type: 'RESTORE_SESSION', payload: { user, permissions, allPermissions: permissions, token, refreshToken: refreshToken || '' } }); } catch (error) { localStorage.removeItem('admin_token'); localStorage.removeItem('admin_refresh_token'); localStorage.removeItem('admin_user'); localStorage.removeItem('admin_permissions'); dispatch({ type: 'SET_LOADING', payload: false }); } } else { dispatch({ type: 'SET_LOADING', payload: false }); } }; useEffect(() => { restoreSession(); }, []); const logout = () => { localStorage.removeItem('admin_token'); localStorage.removeItem('admin_refresh_token'); localStorage.removeItem('admin_user'); localStorage.removeItem('admin_permissions'); dispatch({ type: 'LOGOUT' }); toast.success('خروج موفقیت‌آمیز بود'); }; const hasPermission = (permissionId: number): boolean => { // اگر Super Admin (id=1) باشد، به همه چیز دسترسی دارد const isSuperAdmin = state.permissions.some(permission => permission.id === 1); if (isSuperAdmin) return true; // در غیر اینصورت چک کن permission مورد نیاز را دارد یا نه return state.permissions.some(permission => permission.id === permissionId); }; const hasPermissionByTitle = (title: string): boolean => { // اگر Super Admin (AdminAll) باشد، به همه چیز دسترسی دارد const isSuperAdmin = state.permissions.some(permission => permission.title === "AdminAll"); if (isSuperAdmin) return true; // در غیر اینصورت چک کن permission مورد نیاز را دارد یا نه return state.permissions.some(permission => permission.title === title); }; return ( {children} ); }; export const useAuth = () => { const context = useContext(AuthContext); if (context === undefined) { throw new Error('useAuth must be used within an AuthProvider'); } return context; };