feat: add countdown timer and redirect functionality on access denial in MenuProtection component; enhance Sidebar menu item styling and active state handling
This commit is contained in:
@@ -24,6 +24,7 @@
|
||||
let verificando = $state(true);
|
||||
let temPermissao = $state(false);
|
||||
let motivoNegacao = $state("");
|
||||
let segundosRestantes = $state(3);
|
||||
|
||||
// Query para verificar permissões (só executa se o usuário estiver autenticado)
|
||||
const permissaoQuery = $derived(
|
||||
@@ -85,9 +86,22 @@
|
||||
verificando = false;
|
||||
temPermissao = false;
|
||||
motivoNegacao = "access_denied";
|
||||
segundosRestantes = 3;
|
||||
|
||||
const currentPath = window.location.pathname;
|
||||
window.location.href = `${redirectTo}?error=access_denied&route=${encodeURIComponent(currentPath)}`;
|
||||
// Contador regressivo
|
||||
const intervalo = setInterval(() => {
|
||||
segundosRestantes--;
|
||||
if (segundosRestantes <= 0) {
|
||||
clearInterval(intervalo);
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
// Aguardar 3 segundos antes de redirecionar
|
||||
setTimeout(() => {
|
||||
clearInterval(intervalo);
|
||||
const currentPath = window.location.pathname;
|
||||
window.location.href = `${redirectTo}?error=access_denied&route=${encodeURIComponent(currentPath)}`;
|
||||
}, 3000);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -96,9 +110,22 @@
|
||||
verificando = false;
|
||||
temPermissao = false;
|
||||
motivoNegacao = "write_denied";
|
||||
segundosRestantes = 3;
|
||||
|
||||
const currentPath = window.location.pathname;
|
||||
window.location.href = `${redirectTo}?error=write_denied&route=${encodeURIComponent(currentPath)}`;
|
||||
// Contador regressivo
|
||||
const intervalo = setInterval(() => {
|
||||
segundosRestantes--;
|
||||
if (segundosRestantes <= 0) {
|
||||
clearInterval(intervalo);
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
// Aguardar 3 segundos antes de redirecionar
|
||||
setTimeout(() => {
|
||||
clearInterval(intervalo);
|
||||
const currentPath = window.location.pathname;
|
||||
window.location.href = `${redirectTo}?error=write_denied&route=${encodeURIComponent(currentPath)}`;
|
||||
}, 3000);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -145,8 +172,14 @@
|
||||
</div>
|
||||
<h2 class="text-2xl font-bold text-base-content mb-2">Acesso Negado</h2>
|
||||
<p class="text-base-content/70 mb-4">Você não tem permissão para acessar esta página.</p>
|
||||
<div class="flex items-center justify-center gap-2 mb-4 text-primary">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" />
|
||||
</svg>
|
||||
<p class="text-sm font-medium">Redirecionando em <span class="font-bold text-lg">{segundosRestantes}</span> segundo{segundosRestantes !== 1 ? 's' : ''}...</p>
|
||||
</div>
|
||||
<button class="btn btn-primary" onclick={() => goto(redirectTo)}>
|
||||
Voltar ao Dashboard
|
||||
Voltar Agora
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -11,6 +11,31 @@
|
||||
let { children }: { children: Snippet } = $props();
|
||||
|
||||
const convex = useConvexClient();
|
||||
|
||||
// Caminho atual da página
|
||||
const currentPath = $derived(page.url.pathname);
|
||||
|
||||
// Função para gerar classes do menu ativo
|
||||
function getMenuClasses(isActive: boolean) {
|
||||
const baseClasses = "group font-semibold flex items-center justify-center gap-2 text-center p-3.5 rounded-xl border-2 transition-all duration-300 shadow-md hover:shadow-lg hover:scale-105";
|
||||
|
||||
if (isActive) {
|
||||
return `${baseClasses} border-primary bg-primary text-white shadow-lg scale-105`;
|
||||
}
|
||||
|
||||
return `${baseClasses} border-primary/30 bg-gradient-to-br from-base-100 to-base-200 text-base-content hover:from-primary hover:to-primary/80 hover:text-white`;
|
||||
}
|
||||
|
||||
// Função para gerar classes do botão "Solicitar Acesso"
|
||||
function getSolicitarClasses(isActive: boolean) {
|
||||
const baseClasses = "group font-semibold flex items-center justify-center gap-2 text-center p-3.5 rounded-xl border-2 transition-all duration-300 shadow-md hover:shadow-lg hover:scale-105";
|
||||
|
||||
if (isActive) {
|
||||
return `${baseClasses} border-success bg-success text-white shadow-lg scale-105`;
|
||||
}
|
||||
|
||||
return `${baseClasses} border-success/30 bg-gradient-to-br from-success/10 to-success/20 text-base-content hover:from-success hover:to-success/80 hover:text-white`;
|
||||
}
|
||||
|
||||
const setores = [
|
||||
{ nome: "Recursos Humanos", link: "/recursos-humanos" },
|
||||
@@ -251,7 +276,10 @@
|
||||
<!-- Sidebar menu items -->
|
||||
<ul class="flex flex-col gap-2">
|
||||
<li class="rounded-xl">
|
||||
<a href="/" class="group font-semibold flex items-center justify-center gap-2 text-center p-3.5 rounded-xl border-2 border-primary/30 bg-gradient-to-br from-base-100 to-base-200 hover:from-primary hover:to-primary/80 active:from-primary/90 active:to-primary text-base-content hover:text-white active:text-white transition-all duration-300 shadow-md hover:shadow-lg hover:scale-105">
|
||||
<a
|
||||
href="/"
|
||||
class={getMenuClasses(currentPath === "/")}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-5 w-5 group-hover:scale-110 transition-transform"
|
||||
@@ -270,19 +298,22 @@
|
||||
</a>
|
||||
</li>
|
||||
{#each setores as s}
|
||||
{@const isActive = currentPath.startsWith(s.link)}
|
||||
<li class="rounded-xl">
|
||||
<a
|
||||
href={s.link}
|
||||
class:active={page.url.pathname.startsWith(s.link)}
|
||||
aria-current={page.url.pathname.startsWith(s.link) ? "page" : undefined}
|
||||
class="group font-semibold flex items-center justify-center gap-2 text-center p-3.5 rounded-xl border-2 border-primary/30 bg-gradient-to-br from-base-100 to-base-200 hover:from-primary hover:to-primary/80 active:from-primary/90 active:to-primary text-base-content hover:text-white active:text-white transition-all duration-300 shadow-md hover:shadow-lg hover:scale-105"
|
||||
aria-current={isActive ? "page" : undefined}
|
||||
class={getMenuClasses(isActive)}
|
||||
>
|
||||
<span>{s.nome}</span>
|
||||
</a>
|
||||
</li>
|
||||
{/each}
|
||||
<li class="rounded-xl mt-auto">
|
||||
<a href="/solicitar-acesso" class="group font-semibold flex items-center justify-center gap-2 text-center p-3.5 rounded-xl border-2 border-success/30 bg-gradient-to-br from-success/10 to-success/20 hover:from-success hover:to-success/80 active:from-success/90 active:to-success text-base-content hover:text-white active:text-white transition-all duration-300 shadow-md hover:shadow-lg hover:scale-105">
|
||||
<a
|
||||
href="/solicitar-acesso"
|
||||
class={getSolicitarClasses(currentPath === "/solicitar-acesso")}
|
||||
>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
class="h-5 w-5"
|
||||
|
||||
Reference in New Issue
Block a user