the-tip-top-frontend/contexts/AuthContext.tsx
2025-11-17 23:38:02 +01:00

188 lines
5.6 KiB
TypeScript

'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<void>;
register: (data: RegisterData) => Promise<void>;
logout: () => Promise<void>;
googleLogin: (token: string) => Promise<void>;
facebookLogin: (token: string) => Promise<void>;
refreshUser: () => Promise<void>;
}
const AuthContext = createContext<AuthContextType | undefined>(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<AuthProviderProps> = ({ children }) => {
const [user, setUser] = useState<User | null>(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 <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
};