'use client'; import React, { createContext, useContext, useState, useEffect, useCallback } from 'react'; import { useRouter } from 'next/navigation'; import { User, LoginCredentials, RegisterData, AuthResponse } from '@/types'; import { authService } from '@/services/auth.service'; import { setToken, removeToken, getToken, storage } from '@/utils/helpers'; import { STORAGE_KEYS, ROUTES } from '@/utils/constants'; import toast from 'react-hot-toast'; interface AuthContextType { user: User | null; isLoading: boolean; isAuthenticated: boolean; login: (credentials: LoginCredentials) => Promise; register: (data: RegisterData) => Promise; logout: () => Promise; googleLogin: (token: string) => Promise; facebookLogin: (token: string) => Promise; refreshUser: () => Promise; } const AuthContext = createContext(undefined); export const useAuth = () => { const context = useContext(AuthContext); if (!context) { throw new Error('useAuth must be used within an AuthProvider'); } return context; }; interface AuthProviderProps { children: React.ReactNode; } export const AuthProvider: React.FC = ({ children }) => { const [user, setUser] = useState(null); const [isLoading, setIsLoading] = useState(true); const router = useRouter(); const loadUser = useCallback(async () => { const token = getToken(); if (!token) { setIsLoading(false); return; } try { const userData = await authService.getCurrentUser(); setUser(userData); storage.set(STORAGE_KEYS.USER, JSON.stringify(userData)); } catch (error) { console.error('Error loading user:', error); removeToken(); storage.remove(STORAGE_KEYS.USER); } finally { setIsLoading(false); } }, []); useEffect(() => { loadUser(); }, [loadUser]); const login = async (credentials: LoginCredentials) => { try { const response: AuthResponse = await authService.login(credentials); setToken(response.token); setUser(response.user); storage.set(STORAGE_KEYS.USER, JSON.stringify(response.user)); toast.success('Connexion réussie !'); // Redirect based on role (support both uppercase and lowercase) const role = response.user.role.toUpperCase(); if (role === 'ADMIN') { router.push(ROUTES.ADMIN_DASHBOARD); } else if (role === 'EMPLOYEE') { router.push(ROUTES.EMPLOYEE_DASHBOARD); } else { router.push(ROUTES.CLIENT_DASHBOARD); } } catch (error: any) { toast.error(error.message || 'Erreur lors de la connexion'); throw error; } }; const register = async (data: RegisterData) => { try { const response: AuthResponse = await authService.register(data); setToken(response.token); setUser(response.user); storage.set(STORAGE_KEYS.USER, JSON.stringify(response.user)); toast.success('Inscription réussie !'); router.push(ROUTES.CLIENT_DASHBOARD); } catch (error: any) { toast.error(error.message || 'Erreur lors de l\'inscription'); throw error; } }; const logout = async () => { try { await authService.logout(); } catch (error) { console.error('Error during logout:', error); } finally { removeToken(); storage.remove(STORAGE_KEYS.USER); setUser(null); toast.success('Déconnexion réussie'); router.push(ROUTES.LOGIN); } }; const googleLogin = async (token: string) => { try { const response: AuthResponse = await authService.googleLogin(token); setToken(response.token); setUser(response.user); storage.set(STORAGE_KEYS.USER, JSON.stringify(response.user)); toast.success('Connexion avec Google réussie !'); // Redirect based on role (support both uppercase and lowercase) const role = response.user.role.toUpperCase(); if (role === 'ADMIN') { router.push(ROUTES.ADMIN_DASHBOARD); } else if (role === 'EMPLOYEE') { router.push(ROUTES.EMPLOYEE_DASHBOARD); } else { router.push(ROUTES.CLIENT_DASHBOARD); } } catch (error: any) { toast.error(error.message || 'Erreur lors de la connexion avec Google'); throw error; } }; const facebookLogin = async (token: string) => { try { const response: AuthResponse = await authService.facebookLogin(token); setToken(response.token); setUser(response.user); storage.set(STORAGE_KEYS.USER, JSON.stringify(response.user)); toast.success('Connexion avec Facebook réussie !'); // Redirect based on role (support both uppercase and lowercase) const role = response.user.role.toUpperCase(); if (role === 'ADMIN') { router.push(ROUTES.ADMIN_DASHBOARD); } else if (role === 'EMPLOYEE') { router.push(ROUTES.EMPLOYEE_DASHBOARD); } else { router.push(ROUTES.CLIENT_DASHBOARD); } } catch (error: any) { toast.error(error.message || 'Erreur lors de la connexion avec Facebook'); throw error; } }; const refreshUser = async () => { try { const userData = await authService.getCurrentUser(); setUser(userData); storage.set(STORAGE_KEYS.USER, JSON.stringify(userData)); } catch (error) { console.error('Error refreshing user:', error); throw error; } }; const value: AuthContextType = { user, isLoading, isAuthenticated: !!user, login, register, logout, googleLogin, facebookLogin, refreshUser, }; return {children}; };