- 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)
4.3 KiB
Research — 030-navbar-topo-ux
Decision 1: Manter uma única Navbar compartilhada por todo o produto
Decision: Evoluir o componente compartilhado frontend/src/components/Navbar.tsx em vez de criar navbars separadas para visitante, cliente e admin.
Rationale: A navbar já é consumida por páginas públicas e layouts protegidos. Um único ponto de evolução reduz divergência visual, evita duplicação de links/rotas e facilita garantir consistência de comportamento entre desktop e mobile.
Alternatives considered:
- Criar três variantes independentes de navbar: rejeitado por elevar custo de manutenção e risco de regressões cruzadas.
- Extrair uma navbar diferente para admin: rejeitado nesta fase porque a spec pede eficiência sem poluir a experiência global, não uma shell totalmente nova.
Decision 2: Consolidar o estado transitório em um único controlador de overlay
Decision: Planejar a navbar com um estado mutuamente exclusivo para closed, mobile, client e admin, mesmo que a implementação inicial parta do componente atual com múltiplos booleans.
Rationale: Os requisitos FR-011, FR-012 e FR-013 pedem previsibilidade forte. Um controlador único reduz a chance de estados simultâneos, simplifica o fechamento em mudança de rota e deixa o comportamento mais testável.
Alternatives considered:
- Manter três
useStateindependentes: rejeitado como forma final porque exige disciplina manual em todos os handlers. - Levar o estado para contexto global: rejeitado por excesso de complexidade para uma concern local de UI.
Decision 3: Não introduzir novos contratos de API nem mudanças backend
Decision: Tratar a feature como frontend/UX puro, apoiada apenas pelos dados já disponíveis em AuthContext e nas rotas existentes em App.tsx.
Rationale: A spec descreve comportamento e hierarquia visual, não novos fluxos de domínio. user, role, isAuthenticated e logout() já cobrem as condições necessárias para as três personas.
Alternatives considered:
- Criar endpoint específico para navegação por perfil: rejeitado por desnecessário e contrário ao princípio de simplicidade.
- Mover a configuração de menu para backend: rejeitado nesta fase por não haver requisito de CMS/configuração dinâmica.
Decision 4: Derivar destinos do menu a partir das rotas reais existentes
Decision: Basear o contrato de navegação nos destinos já disponíveis em frontend/src/App.tsx e na lista atual de módulos administrativos/cliente.
Rationale: Isso evita planejar links inexistentes e mantém a feature ancorada no sistema real. Também permite priorizar atalhos admin sem inventar módulos novos.
Alternatives considered:
- Redesenhar a informação da navbar a partir de destinos hipotéticos: rejeitado por abrir escopo além da spec.
- Remover rotas admin do topo nesta fase: rejeitado porque a spec exige acesso rápido para administradores.
Decision 5: Formalizar um contrato de UI da navbar
Decision: Criar um documento em contracts/navbar-ui-contract.md descrevendo comportamento por perfil, breakpoint e estado interativo.
Rationale: Embora não exista API nova, a aplicação expõe uma interface de navegação para o usuário final. O contrato de UI serve como referência objetiva para implementação, QA e futura geração de tarefas.
Alternatives considered:
- Não criar contrato algum: rejeitado porque a feature é centrada em interação e estados, e isso precisa de definição explícita.
- Modelar o contrato só dentro do plan: rejeitado para manter separação clara entre abordagem técnica e comportamento esperado.
Decision 6: Validar principalmente com build e checklist manual responsivo
Decision: Adotar npm run build como validação executável mínima e complementar com checklist manual por persona e breakpoint.
Rationale: O frontend atual não expõe uma suíte automatizada de testes de componentes/RTL. A natureza visual/interativa da navbar exige inspeção manual em desktop/mobile além da checagem de compilação.
Alternatives considered:
- Introduzir Vitest/RTL apenas para esta feature: rejeitado nesta fase de planning por ampliar escopo e dependências.
- Confiar só em validação visual manual: rejeitado porque o build ainda é o guardrail executável mínimo disponível.