refactor: enhance ProtectedRoute and dashboard components for improved access control and user experience

- Updated the ProtectedRoute component to optimize access checking logic, preventing unnecessary re-checks and improving authentication flow.
- Enhanced the dashboard page to automatically open the login modal for authentication errors and refined loading states for better user feedback.
- Improved UI elements across various components for consistency and visual appeal, including updated tab styles and enhanced alert messages.
- Removed redundant footer from the vacation management page to streamline the interface.
This commit is contained in:
2025-11-18 06:34:55 -03:00
parent 3420872a37
commit 422dc6f022
5 changed files with 398 additions and 541 deletions

View File

@@ -21,11 +21,26 @@
let isChecking = $state(true);
let hasAccess = $state(false);
let timeoutId: ReturnType<typeof setTimeout> | null = null;
let hasCheckedOnce = $state(false);
let lastUserState = $state<typeof currentUser | undefined>(undefined);
const currentUser = useQuery(api.auth.getCurrentUser, {});
// Usar $effect para reagir às mudanças na query
// Usar $effect para reagir apenas às mudanças na query currentUser
$effect(() => {
checkAccess();
// Não verificar novamente se já tem acesso concedido e usuário está autenticado
if (hasAccess && currentUser?.data) {
lastUserState = currentUser;
return;
}
// Evitar loop: só verificar se currentUser realmente mudou
// Comparar dados, não o objeto proxy
const currentData = currentUser?.data;
const lastData = lastUserState?.data;
if (currentData !== lastData || (currentUser === undefined) !== (lastUserState === undefined)) {
lastUserState = currentUser;
checkAccess();
}
});
function checkAccess() {
@@ -42,6 +57,9 @@
return;
}
// Marcar que já verificou pelo menos uma vez
hasCheckedOnce = true;
// Se a query retornou dados, verificar autenticação
if (currentUser?.data) {
// Verificar roles
@@ -67,20 +85,29 @@
return;
}
// Se não tem dados e requer autenticação, aguardar um pouco antes de redirecionar
// (pode estar carregando ainda)
// Se não tem dados e requer autenticação
if (requireAuth && !currentUser?.data) {
// Se a query já retornou (não está mais undefined), finalizar estado
if (currentUser !== undefined) {
const currentPath = window.location.pathname;
// Evitar redirecionamento em loop - verificar se já está na URL de erro
const urlParams = new URLSearchParams(window.location.search);
if (!urlParams.has('error')) {
// Só redirecionar se não estiver em loop
if (!hasCheckedOnce || currentUser === null) {
window.location.href = `${redirectTo}?error=auth_required&redirect=${encodeURIComponent(currentPath)}`;
return;
}
}
// Se já tem erro na URL, permitir renderização para mostrar o alerta
isChecking = false;
hasAccess = true;
return;
}
// Se ainda está carregando (undefined), aguardar
isChecking = true;
hasAccess = false;
// Aguardar 3 segundos antes de redirecionar (dar tempo para a query carregar)
timeoutId = setTimeout(() => {
// Verificar novamente antes de redirecionar
if (!currentUser?.data) {
const currentPath = window.location.pathname;
window.location.href = `${redirectTo}?error=auth_required&redirect=${encodeURIComponent(currentPath)}`;
}
}, 3000);
return;
}