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:
310
AJUSTES_UX_COMPLETOS.md
Normal file
310
AJUSTES_UX_COMPLETOS.md
Normal file
@@ -0,0 +1,310 @@
|
||||
# ✅ AJUSTES DE UX IMPLEMENTADOS
|
||||
|
||||
## 📋 RESUMO DAS MELHORIAS
|
||||
|
||||
Implementei dois ajustes importantes de experiência do usuário (UX) no sistema SGSE:
|
||||
|
||||
---
|
||||
|
||||
## 🎯 AJUSTE 1: TEMPO DE EXIBIÇÃO "ACESSO NEGADO"
|
||||
|
||||
### Problema Anterior:
|
||||
A mensagem "Acesso Negado" aparecia por muito pouco tempo antes de redirecionar para o dashboard, não dando tempo suficiente para o usuário ler.
|
||||
|
||||
### Solução Implementada:
|
||||
✅ **Tempo aumentado de ~1 segundo para 3 segundos**
|
||||
|
||||
### Melhorias Adicionais:
|
||||
1. **Contador Regressivo Visual**
|
||||
- Exibe quantos segundos faltam para o redirecionamento
|
||||
- Exemplo: "Redirecionando em **3** segundos..."
|
||||
- Atualiza a cada segundo: 3 → 2 → 1
|
||||
|
||||
2. **Botão "Voltar Agora"**
|
||||
- Permite que o usuário não precise esperar os 3 segundos
|
||||
- Redireciona imediatamente ao clicar
|
||||
|
||||
3. **Ícone de Relógio**
|
||||
- Visual profissional com ícone de relógio
|
||||
- Indica claramente que é um redirecionamento temporizado
|
||||
|
||||
### Arquivo Modificado:
|
||||
- `apps/web/src/lib/components/MenuProtection.svelte`
|
||||
|
||||
### Código Implementado:
|
||||
```typescript
|
||||
// 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);
|
||||
```
|
||||
|
||||
### Interface:
|
||||
```svelte
|
||||
<div class="flex items-center justify-center gap-2 mb-4 text-primary">
|
||||
<svg><!-- Ícone de relógio --></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 Agora
|
||||
</button>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎯 AJUSTE 2: HIGHLIGHT DO MENU ATIVO NO SIDEBAR
|
||||
|
||||
### Problema Anterior:
|
||||
Não havia indicação visual clara de qual menu/página o usuário estava visualizando no momento.
|
||||
|
||||
### Solução Implementada:
|
||||
✅ **Menu ativo destacado com cor azul (primary)**
|
||||
|
||||
### Características da Solução:
|
||||
|
||||
#### Para Menus Normais (Setores):
|
||||
- **Menu Inativo:**
|
||||
- Background: Gradiente cinza claro
|
||||
- Borda: Azul transparente (30%)
|
||||
- Texto: Cor padrão
|
||||
- Hover: Azul
|
||||
|
||||
- **Menu Ativo:**
|
||||
- Background: **Azul sólido (primary)**
|
||||
- Borda: **Azul sólido**
|
||||
- Texto: **Branco**
|
||||
- Sombra: Mais pronunciada
|
||||
- Escala: Levemente aumentada (105%)
|
||||
|
||||
#### Para Dashboard:
|
||||
- Mesma lógica aplicada
|
||||
- Ativo quando `pathname === "/"`
|
||||
|
||||
#### Para "Solicitar Acesso":
|
||||
- Cores verdes (success) ao invés de azul
|
||||
- Mesma lógica de highlight quando ativo
|
||||
|
||||
### Arquivo Modificado:
|
||||
- `apps/web/src/lib/components/Sidebar.svelte`
|
||||
|
||||
### Código Implementado:
|
||||
|
||||
#### Dashboard:
|
||||
```svelte
|
||||
<a
|
||||
href="/"
|
||||
class="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"
|
||||
class:border-primary/30={page.url.pathname !== "/"}
|
||||
class:bg-gradient-to-br={page.url.pathname !== "/"}
|
||||
class:from-base-100={page.url.pathname !== "/"}
|
||||
class:to-base-200={page.url.pathname !== "/"}
|
||||
class:text-base-content={page.url.pathname !== "/"}
|
||||
class:hover:from-primary={page.url.pathname !== "/"}
|
||||
class:hover:to-primary/80={page.url.pathname !== "/"}
|
||||
class:hover:text-white={page.url.pathname !== "/"}
|
||||
class:border-primary={page.url.pathname === "/"}
|
||||
class:bg-primary={page.url.pathname === "/"}
|
||||
class:text-white={page.url.pathname === "/"}
|
||||
class:shadow-lg={page.url.pathname === "/"}
|
||||
class:scale-105={page.url.pathname === "/"}
|
||||
>
|
||||
```
|
||||
|
||||
#### Setores:
|
||||
```svelte
|
||||
{#each setores as s}
|
||||
{@const isActive = page.url.pathname.startsWith(s.link)}
|
||||
<li class="rounded-xl">
|
||||
<a
|
||||
href={s.link}
|
||||
aria-current={isActive ? "page" : undefined}
|
||||
class="... transition-all duration-300 ..."
|
||||
class:border-primary/30={!isActive}
|
||||
class:bg-gradient-to-br={!isActive}
|
||||
class:from-base-100={!isActive}
|
||||
class:to-base-200={!isActive}
|
||||
class:text-base-content={!isActive}
|
||||
class:border-primary={isActive}
|
||||
class:bg-primary={isActive}
|
||||
class:text-white={isActive}
|
||||
class:shadow-lg={isActive}
|
||||
class:scale-105={isActive}
|
||||
>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🎨 ASPECTOS PROFISSIONAIS DA IMPLEMENTAÇÃO
|
||||
|
||||
### 1. Acessibilidade (a11y):
|
||||
- ✅ Uso de `aria-current="page"` para leitores de tela
|
||||
- ✅ Contraste adequado de cores (azul com branco)
|
||||
- ✅ Transições suaves sem causar náusea
|
||||
|
||||
### 2. Feedback Visual:
|
||||
- ✅ Transições animadas (300ms)
|
||||
- ✅ Efeito de escala no menu ativo
|
||||
- ✅ Sombra mais pronunciada
|
||||
- ✅ Cores semânticas (azul = primary, verde = success)
|
||||
|
||||
### 3. Responsividade:
|
||||
- ✅ Funciona em desktop e mobile
|
||||
- ✅ Drawer mantém o mesmo comportamento
|
||||
- ✅ Touch-friendly (botões mantêm tamanho adequado)
|
||||
|
||||
### 4. Performance:
|
||||
- ✅ Uso de classes condicionais (não cria elementos duplicados)
|
||||
- ✅ Transições CSS (aceleração por GPU)
|
||||
- ✅ Reatividade eficiente do Svelte
|
||||
|
||||
---
|
||||
|
||||
## 📊 COMPARAÇÃO ANTES/DEPOIS
|
||||
|
||||
### Acesso Negado:
|
||||
| Aspecto | Antes | Depois |
|
||||
|---------|-------|--------|
|
||||
| Tempo visível | ~1 segundo | 3 segundos |
|
||||
| Contador | ❌ Não | ✅ Sim (3, 2, 1) |
|
||||
| Botão imediato | ❌ Não | ✅ Sim ("Voltar Agora") |
|
||||
| Ícone visual | ✅ Apenas erro | ✅ Erro + Relógio |
|
||||
|
||||
### Menu Ativo:
|
||||
| Aspecto | Antes | Depois |
|
||||
|---------|-------|--------|
|
||||
| Indicação visual | ❌ Nenhuma | ✅ Background azul |
|
||||
| Texto destacado | ❌ Igual aos outros | ✅ Branco (alto contraste) |
|
||||
| Escala | ❌ Normal | ✅ Levemente aumentado |
|
||||
| Sombra | ❌ Padrão | ✅ Mais pronunciada |
|
||||
| Transição | ✅ Sim | ✅ Suave e profissional |
|
||||
|
||||
---
|
||||
|
||||
## 🎯 CASOS DE USO
|
||||
|
||||
### Cenário 1: Usuário Sem Permissão
|
||||
1. Usuário tenta acessar "/financeiro" sem permissão
|
||||
2. **Antes:** Tela de "Acesso Negado" por ~1s → Redirecionamento
|
||||
3. **Depois:**
|
||||
- Tela de "Acesso Negado"
|
||||
- Contador: "Redirecionando em 3 segundos..."
|
||||
- Usuário tem tempo para ler e entender
|
||||
- Pode clicar em "Voltar Agora" se quiser
|
||||
|
||||
### Cenário 2: Navegação entre Setores
|
||||
1. Usuário está no Dashboard (/)
|
||||
2. **Antes:** Todos os menus parecem iguais
|
||||
3. **Depois:** Dashboard está destacado em azul
|
||||
4. Usuário clica em "Recursos Humanos"
|
||||
5. **Antes:** Sem indicação visual clara
|
||||
6. **Depois:** "Recursos Humanos" fica azul, Dashboard volta ao cinza
|
||||
|
||||
---
|
||||
|
||||
## ✅ TESTES RECOMENDADOS
|
||||
|
||||
Para validar as alterações:
|
||||
|
||||
1. **Teste de Acesso Negado:**
|
||||
```
|
||||
- Fazer login com usuário limitado
|
||||
- Tentar acessar página sem permissão
|
||||
- Verificar:
|
||||
✓ Contador aparece e decrementa (3, 2, 1)
|
||||
✓ Redirecionamento ocorre após 3 segundos
|
||||
✓ Botão "Voltar Agora" funciona imediatamente
|
||||
```
|
||||
|
||||
2. **Teste de Menu Ativo:**
|
||||
```
|
||||
- Navegar para Dashboard (/)
|
||||
- Verificar: Dashboard está azul
|
||||
- Navegar para Recursos Humanos
|
||||
- Verificar: RH está azul, Dashboard voltou ao normal
|
||||
- Navegar para sub-rota (/recursos-humanos/funcionarios)
|
||||
- Verificar: RH continua azul
|
||||
```
|
||||
|
||||
3. **Teste de Responsividade:**
|
||||
```
|
||||
- Abrir em desktop → Verificar sidebar
|
||||
- Abrir em mobile → Verificar drawer
|
||||
- Testar em ambos os tamanhos
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 ARQUIVOS MODIFICADOS
|
||||
|
||||
### 1. `apps/web/src/lib/components/MenuProtection.svelte`
|
||||
**Linhas modificadas:** 24-130, 165-186
|
||||
|
||||
**Principais alterações:**
|
||||
- Adicionado variável `segundosRestantes`
|
||||
- Implementado `setInterval` para contador
|
||||
- Implementado `setTimeout` de 3 segundos
|
||||
- Atualizado template com contador visual
|
||||
- Adicionado botão "Voltar Agora"
|
||||
|
||||
### 2. `apps/web/src/lib/components/Sidebar.svelte`
|
||||
**Linhas modificadas:** 253-348
|
||||
|
||||
**Principais alterações:**
|
||||
- Dashboard: Adicionado classes condicionais para estado ativo
|
||||
- Setores: Criado `isActive` constante e classes condicionais
|
||||
- Solicitar Acesso: Adicionado mesmo padrão com cores verdes
|
||||
- Melhorado `aria-current` para acessibilidade
|
||||
|
||||
---
|
||||
|
||||
## 🎉 RESULTADO FINAL
|
||||
|
||||
### Benefícios para o Usuário:
|
||||
1. ✅ **Melhor compreensão** de onde está no sistema
|
||||
2. ✅ **Mais tempo** para ler mensagens importantes
|
||||
3. ✅ **Mais controle** sobre redirecionamentos
|
||||
4. ✅ **Interface mais profissional** e polida
|
||||
|
||||
### Benefícios Técnicos:
|
||||
1. ✅ **Código limpo** e manutenível
|
||||
2. ✅ **Sem dependências** extras
|
||||
3. ✅ **Performance otimizada**
|
||||
4. ✅ **Acessível** (a11y)
|
||||
|
||||
---
|
||||
|
||||
## 🚀 PRÓXIMOS PASSOS SUGERIDOS
|
||||
|
||||
Se quiser melhorar ainda mais a UX:
|
||||
|
||||
1. **Animações de Entrada/Saída:**
|
||||
- Adicionar fade-in na mensagem de "Acesso Negado"
|
||||
- Slide-in suave no menu ativo
|
||||
|
||||
2. **Breadcrumbs:**
|
||||
- Mostrar caminho: Dashboard > Recursos Humanos > Funcionários
|
||||
|
||||
3. **Histórico de Navegação:**
|
||||
- Botão "Voltar" que lembra a página anterior
|
||||
|
||||
4. **Atalhos de Teclado:**
|
||||
- Alt+1 = Dashboard
|
||||
- Alt+2 = Primeiro setor
|
||||
- etc.
|
||||
|
||||
---
|
||||
|
||||
**✨ Implementação concluída com sucesso! Sistema SGSE ainda mais profissional e user-friendly.**
|
||||
|
||||
Reference in New Issue
Block a user