saveinmed/saveinmed-frontend/src/hooks/useAuth.ts
2025-12-23 08:46:07 -03:00

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;
};
};