- feat(025): favoritos locais com FavoritesContext, HeartButton, PublicFavoritesPage
- feat(026): central de contatos admin (leads/contatos unificados)
- feat(027): configuração da página de contato via admin
- feat(028): trabalhe conosco - candidaturas com upload e admin
- feat(029): UX área do cliente - visitas, comparação, perfil
- feat(030): navbar UX - menu mobile, ThemeToggle, useFavorites
- feat(031): hero light/dark - imagens separadas por tema, upload, preview, seed
- feat(032): performance homepage - Promise.all parallel fetches, sessionStorage cache,
preload hero image, loading=lazy nos cards, useInView hook, will-change carrossel,
keyframes em index.css, AgentsCarousel e HomeScrollScene via props
- fix: light mode HomeScrollScene - gradiente, cores de texto, scroll hint
migrations: g1h2i3j4k5l6 (source em leads), h1i2j3k4l5m6 (contact_config),
i1j2k3l4m5n6 (job_applications), j2k3l4m5n6o7 (hero theme images)
191 lines
4.5 KiB
Markdown
191 lines
4.5 KiB
Markdown
# UI Contract — Navbar do Topo
|
|
|
|
## Objetivo
|
|
|
|
Definir o comportamento observável da navbar por perfil de usuário, breakpoint e estado interativo, sem introduzir mudanças de API.
|
|
|
|
---
|
|
|
|
## 1. Perfis suportados
|
|
|
|
### `visitor`
|
|
|
|
Condição:
|
|
- `isAuthenticated === false`
|
|
|
|
Elementos obrigatórios:
|
|
- Logo com navegação para `/`
|
|
- Links públicos principais
|
|
- CTA `Anunciar imóvel` para `/cadastro-residencia`
|
|
- Ação `Entrar` para `/login`
|
|
- Ação de favoritos públicos quando aplicável ao estado atual do produto
|
|
|
|
Elementos proibidos:
|
|
- Menu `Admin`
|
|
- Seção `Minha Conta`
|
|
|
|
### `client`
|
|
|
|
Condição:
|
|
- `isAuthenticated === true`
|
|
- `user.role !== 'admin'`
|
|
|
|
Elementos obrigatórios:
|
|
- Tudo que continua relevante da navegação pública
|
|
- Gatilho de conta com inicial/avatar e primeiro nome truncado
|
|
- Entradas contextuais: `Favoritos`, `Comparar`, `Visitas`, `Minha conta`
|
|
- Ação `Sair` separada visualmente
|
|
|
|
Elementos proibidos:
|
|
- Menu `Admin`
|
|
- Botão `Entrar`
|
|
|
|
### `admin`
|
|
|
|
Condição:
|
|
- `isAuthenticated === true`
|
|
- `user.role === 'admin'`
|
|
|
|
Elementos obrigatórios:
|
|
- Tudo que continua relevante da navegação pública
|
|
- Gatilho contextual `Admin`
|
|
- Atalhos admin prioritários para módulos existentes
|
|
- Ação `Sair`
|
|
|
|
Elementos proibidos:
|
|
- Menu padrão `Minha Conta` de cliente
|
|
- Botão `Entrar`
|
|
|
|
---
|
|
|
|
## 2. Contrato desktop
|
|
|
|
### Estrutura mínima
|
|
|
|
```text
|
|
[Logo]
|
|
[Navegação pública principal]
|
|
[Ações contextuais por perfil]
|
|
[Theme toggle]
|
|
[CTA principal]
|
|
[Ação de autenticação ou logout]
|
|
```
|
|
|
|
### Regras
|
|
|
|
- Devem existir no máximo 5 links públicos visíveis simultaneamente.
|
|
- O CTA principal deve ter destaque visual acima dos links secundários.
|
|
- Menus contextuais (`Admin` e `Conta`) não podem deslocar ou truncar a navegação principal.
|
|
- Nomes longos de usuário devem truncar sem quebrar altura ou alinhamento.
|
|
|
|
---
|
|
|
|
## 3. Contrato mobile
|
|
|
|
### Gatilho hambúrguer
|
|
|
|
Obrigatório:
|
|
- `aria-label` dinâmico entre abrir/fechar
|
|
- `aria-expanded` coerente com o estado
|
|
- `aria-controls` apontando para o painel do menu
|
|
|
|
### Conteúdo do menu
|
|
|
|
Obrigatório:
|
|
- Mesmos destinos públicos principais em ordem lógica
|
|
- CTA `Anunciar imóvel`
|
|
- Seção `Minha Conta` apenas para cliente autenticado
|
|
- Seção `Admin` apenas para admin
|
|
- Logout apenas para usuário autenticado
|
|
- `Entrar` apenas para visitante
|
|
|
|
Regras:
|
|
- Alvos tocáveis com área mínima de 44x44 px.
|
|
- Ao navegar por qualquer item, o menu deve fechar.
|
|
- O menu mobile não pode coexistir com dropdown contextual desktop.
|
|
|
|
---
|
|
|
|
## 4. Contrato de estado interativo
|
|
|
|
Estados possíveis:
|
|
|
|
```text
|
|
closed
|
|
mobile-open
|
|
client-open
|
|
admin-open
|
|
```
|
|
|
|
Invariantes:
|
|
- Apenas um estado aberto por vez.
|
|
- Abrir um contexto fecha qualquer outro.
|
|
- Clique fora fecha o contexto aberto.
|
|
- Mudança de rota fecha qualquer contexto aberto.
|
|
- Logout fecha qualquer contexto aberto e restaura a visualização de visitante.
|
|
|
|
---
|
|
|
|
## 5. Contrato de acessibilidade
|
|
|
|
Obrigatório:
|
|
- `nav` com `aria-label` descritivo
|
|
- foco visível em links e botões
|
|
- acionamento por teclado em gatilhos interativos
|
|
- contraste adequado em texto, hover, active e estados abertos nos temas suportados
|
|
|
|
Não aceitável:
|
|
- gatilhos sem nome acessível
|
|
- estados visuais dependentes apenas de cor sem contraste suficiente
|
|
- foco invisível ou escondido pelo backdrop da navbar
|
|
|
|
---
|
|
|
|
## 6. Destinos atualmente suportados
|
|
|
|
### Navegação pública
|
|
|
|
| Rótulo | Destino atual |
|
|
|---|---|
|
|
| Comprar | `/imoveis?listing_type=venda` |
|
|
| Alugar | `/imoveis?listing_type=aluguel` |
|
|
| Equipe | `/corretores` |
|
|
| Sobre | `/sobre` |
|
|
| Contato | `/contato` |
|
|
| Anunciar imóvel | `/cadastro-residencia` |
|
|
| Entrar | `/login` |
|
|
|
|
### Navegação do cliente
|
|
|
|
| Rótulo | Destino atual |
|
|
|---|---|
|
|
| Favoritos | `/area-do-cliente/favoritos` |
|
|
| Comparar | `/area-do-cliente/comparar` |
|
|
| Visitas | `/area-do-cliente/visitas` |
|
|
| Minha conta | `/area-do-cliente/conta` |
|
|
|
|
### Navegação admin
|
|
|
|
| Rótulo | Destino atual |
|
|
|---|---|
|
|
| Imóveis | `/admin/properties` |
|
|
| Corretores | `/admin/corretores` |
|
|
| Clientes | `/admin/clientes` |
|
|
| Boletos | `/admin/boletos` |
|
|
| Visitas | `/admin/visitas` |
|
|
| Favoritos | `/admin/favoritos` |
|
|
| Cidades | `/admin/cidades` |
|
|
| Amenidades | `/admin/amenidades` |
|
|
| Analytics | `/admin/analytics` |
|
|
| Leads | `/admin/leads` |
|
|
| Candidaturas | `/admin/candidaturas` |
|
|
| Conf. Contato | `/admin/contato-config` |
|
|
|
|
---
|
|
|
|
## 7. Fora de escopo
|
|
|
|
- Alterar políticas de autorização backend
|
|
- Criar novas rotas ou módulos administrativos
|
|
- Persistir preferências de navegação em banco
|
|
- Transformar a navbar em configuração dinâmica vinda da API
|