feat: features 025-032 - favoritos, contatos, trabalhe-conosco, area-cliente, navbar, hero-light-dark, performance-homepage
- 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)
This commit is contained in:
parent
6ef5a7a17e
commit
cf5603243c
106 changed files with 11927 additions and 1367 deletions
165
specs/030-navbar-topo-ux/data-model.md
Normal file
165
specs/030-navbar-topo-ux/data-model.md
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
# 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
|
||||
```
|
||||
Loading…
Add table
Add a link
Reference in a new issue