118 lines
2.9 KiB
TypeScript
118 lines
2.9 KiB
TypeScript
import React, { createContext, useContext, useState, useEffect, type ReactNode } from 'react';
|
|
import {
|
|
getAdminToken, setAdminToken as storeAdminToken,
|
|
setAdminUsername, removeAdminUsername,
|
|
setRole as storeRole, getRole,
|
|
clearAllAuth,
|
|
} from './tokenStorage';
|
|
import { extractUsernameFromToken, extractRoleFromToken, isTokenExpired } from './jwtUtils';
|
|
|
|
export type UserRole = 'admin' | 'cabine' | 'livreur' | null;
|
|
|
|
interface AuthState {
|
|
token: string | null;
|
|
username: string | null;
|
|
role: UserRole;
|
|
isLoading: boolean;
|
|
isAuthenticated: boolean;
|
|
}
|
|
|
|
interface AuthContextType extends AuthState {
|
|
loginAdmin: (token: string, role: 'admin' | 'cabine' | 'livreur') => Promise<void>;
|
|
logout: () => Promise<void>;
|
|
}
|
|
|
|
const AuthContext = createContext<AuthContextType | undefined>(undefined);
|
|
|
|
export function AuthProvider({ children }: { children: ReactNode }) {
|
|
const [state, setState] = useState<AuthState>({
|
|
token: null,
|
|
username: null,
|
|
role: null,
|
|
isLoading: true,
|
|
isAuthenticated: false,
|
|
});
|
|
|
|
useEffect(() => {
|
|
const restore = async () => {
|
|
try {
|
|
const savedRole = await getRole();
|
|
|
|
if (savedRole === 'admin' || savedRole === 'cabine' || savedRole === 'livreur') {
|
|
const token = await getAdminToken();
|
|
if (token && !isTokenExpired(token)) {
|
|
const uname = extractUsernameFromToken(token);
|
|
setState({
|
|
token,
|
|
username: uname,
|
|
role: savedRole as UserRole,
|
|
isLoading: false,
|
|
isAuthenticated: true,
|
|
});
|
|
return;
|
|
}
|
|
}
|
|
|
|
await clearAllAuth();
|
|
setState({
|
|
token: null,
|
|
username: null,
|
|
role: null,
|
|
isLoading: false,
|
|
isAuthenticated: false,
|
|
});
|
|
} catch {
|
|
await clearAllAuth();
|
|
setState({
|
|
token: null,
|
|
username: null,
|
|
role: null,
|
|
isLoading: false,
|
|
isAuthenticated: false,
|
|
});
|
|
}
|
|
};
|
|
|
|
restore();
|
|
}, []);
|
|
|
|
const loginAdmin = async (token: string, role: 'admin' | 'cabine' | 'livreur') => {
|
|
const uname = extractUsernameFromToken(token);
|
|
await storeAdminToken(token);
|
|
if (uname) await setAdminUsername(uname);
|
|
await storeRole(role);
|
|
setState({
|
|
token,
|
|
username: uname,
|
|
role,
|
|
isLoading: false,
|
|
isAuthenticated: true,
|
|
});
|
|
};
|
|
|
|
const logout = async () => {
|
|
await clearAllAuth();
|
|
setState({
|
|
token: null,
|
|
username: null,
|
|
role: null,
|
|
isLoading: false,
|
|
isAuthenticated: false,
|
|
});
|
|
};
|
|
|
|
return (
|
|
<AuthContext.Provider value={{ ...state, loginAdmin, logout }}>
|
|
{children}
|
|
</AuthContext.Provider>
|
|
);
|
|
}
|
|
|
|
export function useAuth() {
|
|
const context = useContext(AuthContext);
|
|
if (!context) {
|
|
throw new Error('useAuth must be used within an AuthProvider');
|
|
}
|
|
return context;
|
|
}
|