- 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)
165 lines
5.2 KiB
Markdown
165 lines
5.2 KiB
Markdown
# Data Model — 030-navbar-topo-ux
|
|
|
|
> Esta feature não cria entidades de banco nem migrations. O modelo abaixo descreve dados de sessão já existentes e o estado de UI necessário para a navbar.
|
|
|
|
---
|
|
|
|
## 1. Entidades Existentes Consumidas
|
|
|
|
### `AuthSession`
|
|
|
|
Fonte: `frontend/src/contexts/AuthContext.tsx`
|
|
|
|
| Campo | Tipo | Origem | Uso na navbar |
|
|
|---|---|---|---|
|
|
| `user` | `User | null` | contexto de autenticação | Decide exibição de avatar, primeiro nome e papel do usuário |
|
|
| `token` | `string | null` | `localStorage` + contexto | Não renderiza UI diretamente; sustenta estado autenticado |
|
|
| `isAuthenticated` | `boolean` | derivado do contexto | Liga/desliga ações de visitante vs cliente/admin |
|
|
| `isLoading` | `boolean` | bootstrap da sessão | Evita flicker de ações incorretas durante hidratação |
|
|
| `logout()` | `() => void` | contexto | Encerra sessão e força retorno visual ao estado visitante |
|
|
|
|
### `UserProfile`
|
|
|
|
Fonte: tipo `User` retornado pelo fluxo de auth atual.
|
|
|
|
| Campo | Tipo | Regra | Uso na navbar |
|
|
|---|---|---|---|
|
|
| `name` | `string` | obrigatório quando `user != null` | Exibe inicial e primeiro nome truncado |
|
|
| `role` | `string` | valor relevante nesta feature: `admin` ou não-admin | Controla presença do menu Admin e do menu Minha Conta |
|
|
|
|
**Invariantes**:
|
|
- `user === null` implica navbar de visitante.
|
|
- `user.role === 'admin'` implica ausência do menu de cliente padrão.
|
|
- Nome longo nunca deve quebrar layout; deve ser truncado no gatilho.
|
|
|
|
---
|
|
|
|
## 2. Entidades de Navegação
|
|
|
|
### `NavItem`
|
|
|
|
Representa um item navegável exibido em um dos grupos da navbar.
|
|
|
|
```ts
|
|
interface NavItem {
|
|
label: string
|
|
to: string
|
|
end?: boolean
|
|
visibility: 'public' | 'client' | 'admin'
|
|
group: 'primary' | 'contextual' | 'cta'
|
|
}
|
|
```
|
|
|
|
**Regras**:
|
|
- Itens `public` aparecem para todos, salvo ajustes de prioridade visual.
|
|
- Itens `client` aparecem apenas quando `isAuthenticated === true` e `role !== 'admin'`.
|
|
- Itens `admin` aparecem apenas quando `role === 'admin'`.
|
|
- `group='cta'` não substitui o grupo público; ele complementa a hierarquia do topo.
|
|
|
|
### `ProfileSection`
|
|
|
|
Agrupa ações contextuais por perfil no mobile e no desktop.
|
|
|
|
```ts
|
|
interface ProfileSection {
|
|
id: 'admin' | 'client'
|
|
title: string
|
|
items: NavItem[]
|
|
includesLogout: boolean
|
|
}
|
|
```
|
|
|
|
**Regras**:
|
|
- No mobile, cada seção deve aparecer com cabeçalho próprio.
|
|
- Logout deve permanecer visualmente separado das ações de navegação.
|
|
|
|
---
|
|
|
|
## 3. Estado Transitório de UI
|
|
|
|
### `NavUIState`
|
|
|
|
Modelo recomendado para governar interações mutuamente exclusivas.
|
|
|
|
```ts
|
|
type ActiveOverlay = 'closed' | 'mobile' | 'admin' | 'client'
|
|
|
|
interface NavUIState {
|
|
activeOverlay: ActiveOverlay
|
|
isDesktop: boolean
|
|
}
|
|
```
|
|
|
|
**Regras de transição**:
|
|
|
|
| Evento | Estado atual | Próximo estado | Observação |
|
|
|---|---|---|---|
|
|
| Clique no hambúrguer | `closed` | `mobile` | Só em mobile |
|
|
| Clique no hambúrguer | `mobile` | `closed` | Toggle padrão |
|
|
| Clique no gatilho Admin | `closed` ou `client` | `admin` | Fecha qualquer outro overlay |
|
|
| Clique no gatilho Cliente | `closed` ou `admin` | `client` | Fecha qualquer outro overlay |
|
|
| Clique fora | `mobile` / `admin` / `client` | `closed` | Requisito FR-012 |
|
|
| Mudança de rota | qualquer | `closed` | Requisito FR-013 |
|
|
| Logout confirmado | qualquer | `closed` | Navbar volta ao estado visitante |
|
|
| Escape | `mobile` / `admin` / `client` | `closed` | Recomendado para previsibilidade |
|
|
|
|
**Invariantes**:
|
|
- Apenas um contexto pode permanecer aberto por vez.
|
|
- `mobile` não pode coexistir com `admin` ou `client`.
|
|
- `admin` e `client` são mutuamente exclusivos.
|
|
|
|
---
|
|
|
|
## 4. Estados Derivados de Exibição
|
|
|
|
### `NavbarVariant`
|
|
|
|
```ts
|
|
type NavbarVariant = 'visitor' | 'client' | 'admin'
|
|
```
|
|
|
|
Derivação:
|
|
- `visitor`: `!isLoading && !isAuthenticated`
|
|
- `client`: `isAuthenticated && user?.role !== 'admin'`
|
|
- `admin`: `isAuthenticated && user?.role === 'admin'`
|
|
|
|
### `ActiveLinkState`
|
|
|
|
Estado derivado de `NavLink`/rota atual.
|
|
|
|
**Regras**:
|
|
- Links públicos devem refletir estado ativo em desktop e mobile.
|
|
- Rotas com query string, como `/imoveis?listing_type=venda`, devem manter coerência visual com a intenção do link.
|
|
- Itens contextuais devem fechar o menu após navegação bem-sucedida.
|
|
|
|
---
|
|
|
|
## 5. Regras de Validação de UX/A11y
|
|
|
|
| Regra | Aplicação |
|
|
|---|---|
|
|
| `aria-expanded` coerente | gatilhos do menu mobile e dropdowns |
|
|
| `aria-controls` presente | menu hambúrguer e, se aplicável, painéis contextuais |
|
|
| foco visível | todos os links e botões interativos |
|
|
| alvo mínimo `44x44` | hambúrguer, CTA, itens tocáveis em mobile |
|
|
| truncamento elegante | nome do usuário e gatilhos de perfil |
|
|
|
|
---
|
|
|
|
## 6. Relações Entre Entidades
|
|
|
|
```text
|
|
AuthSession
|
|
└── UserProfile
|
|
├── role ──────────────┐
|
|
└── name ───────┐ │
|
|
│ │
|
|
NavbarVariant <─────────┘ │
|
|
│
|
|
NavItem.visibility ────────────┘
|
|
|
|
NavUIState.activeOverlay
|
|
├── controls mobile menu visibility
|
|
├── controls admin dropdown visibility
|
|
└── controls client dropdown visibility
|
|
```
|