156 lines
4.6 KiB
TypeScript
156 lines
4.6 KiB
TypeScript
import { useState, useEffect, useCallback } from 'react';
|
|
import { useRouter } from 'next/navigation';
|
|
import { UserRole, UserData, AuthContextType, ROLE_PERMISSIONS, ROLE_ROUTES } from '@/types/auth';
|
|
|
|
/**
|
|
* Hook personalizado para gerenciar autenticação e autorização baseada em roles
|
|
*/
|
|
export const useAuth = (): AuthContextType => {
|
|
const router = useRouter();
|
|
const [user, setUser] = useState<UserData | null>(null);
|
|
const [userRole, setUserRole] = useState<UserRole | null>(null);
|
|
const [loading, setLoading] = useState(true);
|
|
const [isAuthenticated, setIsAuthenticated] = useState(false);
|
|
const normalizeRole = useCallback((role?: string | null): UserRole | null => {
|
|
if (!role) return null;
|
|
const normalized = role.toLowerCase();
|
|
if (normalized === UserRole.SUPERADMIN) return UserRole.SUPERADMIN;
|
|
if (normalized === UserRole.ADMIN) return UserRole.ADMIN;
|
|
if (normalized === UserRole.COLABORADOR) return UserRole.COLABORADOR;
|
|
if (normalized === UserRole.ENTREGADOR) return UserRole.ENTREGADOR;
|
|
return null;
|
|
}, []);
|
|
|
|
/**
|
|
* Verifica se o usuário tem um role específico
|
|
*/
|
|
const hasRole = useCallback((role: UserRole): boolean => {
|
|
return userRole === role;
|
|
}, [userRole]);
|
|
|
|
/**
|
|
* Verifica se o usuário tem qualquer um dos roles especificados
|
|
*/
|
|
const hasAnyRole = useCallback((roles: UserRole[]): boolean => {
|
|
return userRole ? roles.includes(userRole) : false;
|
|
}, [userRole]);
|
|
|
|
/**
|
|
* Verifica se o usuário pode acessar uma funcionalidade baseada nos roles requeridos
|
|
*/
|
|
const canAccess = useCallback((requiredRoles: UserRole[]): boolean => {
|
|
if (!userRole) return false;
|
|
return requiredRoles.includes(userRole);
|
|
}, [userRole]);
|
|
|
|
/**
|
|
* Verifica se o usuário pode acessar uma rota específica
|
|
*/
|
|
const canAccessRoute = useCallback((route: string): boolean => {
|
|
if (!userRole) return false;
|
|
|
|
const allowedRoutes = ROLE_ROUTES[userRole];
|
|
return allowedRoutes.some(allowedRoute =>
|
|
route.startsWith(allowedRoute) || route === allowedRoute
|
|
);
|
|
}, [userRole]);
|
|
|
|
/**
|
|
* Obtém as permissões do usuário baseadas no seu role
|
|
*/
|
|
const getUserPermissions = useCallback(() => {
|
|
if (!userRole) return null;
|
|
return ROLE_PERMISSIONS[userRole];
|
|
}, [userRole]);
|
|
|
|
/**
|
|
* Redireciona o usuário para a rota apropriada baseada no seu role
|
|
*/
|
|
const redirectToDefaultRoute = useCallback(() => {
|
|
if (!userRole) return;
|
|
|
|
switch (userRole) {
|
|
case UserRole.SUPERADMIN:
|
|
case UserRole.ADMIN:
|
|
router.push('/dashboard');
|
|
break;
|
|
case UserRole.COLABORADOR:
|
|
router.push('/entregas');
|
|
break;
|
|
default:
|
|
router.push('/');
|
|
}
|
|
}, [userRole, router]);
|
|
|
|
/**
|
|
* Verifica autenticação e busca dados do usuário
|
|
*/
|
|
useEffect(() => {
|
|
const checkAuth = async () => {
|
|
try {
|
|
setLoading(true);
|
|
|
|
// Verificar se há token BFF armazenado
|
|
const storedToken = localStorage.getItem('access_token');
|
|
|
|
if (!storedToken) {
|
|
setIsAuthenticated(false);
|
|
setUser(null);
|
|
setUserRole(null);
|
|
setLoading(false);
|
|
return;
|
|
}
|
|
|
|
// Marcar como autenticado se há token
|
|
setIsAuthenticated(true);
|
|
|
|
const storedUser = localStorage.getItem('user');
|
|
if (storedUser) {
|
|
try {
|
|
const parsedUser = JSON.parse(storedUser) as UserData;
|
|
setUser(parsedUser);
|
|
const storedRole =
|
|
parsedUser?.nivel ||
|
|
(parsedUser as unknown as { role?: string; userRole?: string })?.role ||
|
|
(parsedUser as unknown as { role?: string; userRole?: string })?.userRole;
|
|
setUserRole(normalizeRole(storedRole));
|
|
} catch (parseError) {
|
|
console.error('Erro ao ler usuário salvo:', parseError);
|
|
setUser(null);
|
|
setUserRole(null);
|
|
}
|
|
} else {
|
|
setUser(null);
|
|
setUserRole(null);
|
|
}
|
|
|
|
} catch (error) {
|
|
console.error('Erro na verificação de autenticação:', error);
|
|
setIsAuthenticated(false);
|
|
setUser(null);
|
|
setUserRole(null);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
};
|
|
|
|
checkAuth();
|
|
}, [router]);
|
|
|
|
return {
|
|
user,
|
|
userRole,
|
|
loading,
|
|
isAuthenticated,
|
|
hasRole,
|
|
hasAnyRole,
|
|
canAccess,
|
|
canAccessRoute,
|
|
getUserPermissions,
|
|
redirectToDefaultRoute
|
|
} as AuthContextType & {
|
|
canAccessRoute: (route: string) => boolean;
|
|
getUserPermissions: () => typeof ROLE_PERMISSIONS[UserRole] | null;
|
|
redirectToDefaultRoute: () => void;
|
|
};
|
|
};
|