📄 Card 75 [M14] — Novo AdminShell (Redesign Topbar)
📚 Referência Genius: Topbar com dropdown de unidade sempre visível, busca global, mensagens, avatar, "Sair" direto.
🎯 Objetivo
Refatorar o AdminShell (atualmente 260px sidebar esquerda) para o padrão Genius:
- Topbar fixa no topo com:
- Logo GENIOON à esquerda
- Dropdown de unidade sempre visível (mesmo pra LOCAL mostra a própria filial)
- Busca global (Cmd+K) que localiza em todos os módulos
- Ícone de Mensagens com badge não lidas
- NotificationCenter (sininho)
- ThemeToggle
- Avatar + dropdown menu (perfil, /doc, Sair)
- Sidebar lateral mais estreita (200px) com ícones + labels abreviados
- Manter responsividade (mobile continua bottom-nav)
📚 Documentação de Referência
src/components/layout/AdminShell.tsx— atualdocs/DESIGN_SYSTEM.md§11.1 (AdminShell)- Observações Genius (DOM): topbar com avatar "Israel" + dropdown "CENTRO" + textbox "Pesquisar" + link "Sair"
🛠️ Especificação Técnica
Componente <AdminShellTopbar /> (novo)
// LAYOUT FINAL
┌──────────────────────────────────────────────────────────────┐
│ [Logo] [Unidade: CENTRO ▼] [🔍 Buscar...] [💬][🔔][🌙][Israel ▼] │
├──────────────────────────────────────────────────────────────┤
│ │ dashboard │
│ │ alunos │
│ │ matriculas │
│ │ ... │
Busca global
- Modal Cmd+K com React Portal
- Busca em: Alunos, Matrículas, Turmas, Usuários, Leads, Contratos, Faturas
- Atalhos de teclado (g d = ir dashboard, g a = ir alunos, etc)
- Resultados agrupados por tipo com ícone
Dropdown de unidade
- Sempre visível (não escondido em settings)
- MASTER vê "TODAS AS UNIDADES" + lista; selecionar aplica filtro global
- SUPERVISOR vê só suas filiais
- LOCAL vê fixo (desabilitado) com a própria filial
- Persiste em cookie
genioon.branchFilter(server-aware pra queries)
Estrutura final
<div className={styles.shell}>
<AdminShellTopbar /> {/* fixo topo */}
<div className={styles.body}>
<AdminShellSidebar /> {/* 200px lateral */}
<main className={styles.main}>
{children}
</main>
</div>
</div>
Procedures para busca global
public.globalSearch(query)— retorna { alunos: [...], matriculas: [...], leads: [...], users: [...] } limit 5 cada- Filtra por branchId (do cookie) + role do user
✅ Critérios de Aceite
- Topbar fixa no topo com todos elementos (logo, dropdown unidade, busca, msgs, notif, tema, avatar)
- Dropdown de unidade sempre visível + persiste seleção em cookie
- Busca global Cmd+K funcional (busca em 5+ entidades)
- Sidebar mais estreita (200px) com ícones + labels abreviados
- Mobile continua bottom-nav (não quebra)
- Avatar dropdown (perfil, /doc, /funcionalidades, Sair)
- Build passa + lint OK
🔌 Handoff
- Helper
getCurrentBranchFilter()(lê cookie/server) reutilizável em procedures - Componente
<GlobalSearchModal />reutilizável
🎯 Próximo
Card 76: PageHeader + Toolbar de Ações
EXECUCAO — 15/08/2026
1. O que foi implementado
- AdminShell refatorado para estrutura Genius-parity: topbar fixa full-width no topo (Logo GENIOON + dropdown de unidade + busca + notificações + tema + avatar) e body com sidebar estreita 200px (colapsável 64px) + main com content-max 1400px.
Arquivo:
src/components/layout/AdminShell.tsx - Dropdown de unidade sempre visível para MASTER/SUPERVISOR/LOCAL: MASTER vê "Todas as unidades" + lista completa; SUPERVISOR só as suas; LOCAL fixo e desabilitado. Seleção persiste no cookie genioon.branchFilter (1 ano, samesite=lax).
Arquivo:
src/components/layout/BranchDropdown.tsx - Busca global Cmd+K (Ctrl+K): modal React Portal com debounce 250ms, resultados agrupados (Páginas, Alunos, Usuários, Leads, Turmas, Chamados), navegação por setas/Enter/Esc e grupo local de páginas da nav (client-side, instantâneo).
Arquivo:
src/components/layout/GlobalSearch.tsx - Novo sub-router tRPC shell: shell.branches (filiais visíveis por role, respeita branch-scope) e shell.globalSearch (busca unificada em students por nome/RA, users, leads, classes, tickets — máx 5 por tipo; STUDENT/PARENT não buscam entidades por LGPD).
Arquivo:
src/server/trpc/routers/shell.ts - Helper server-side getBranchFilter(ctx) lê o cookie genioon.branchFilter com validação anti-IDOR (MASTER qualquer, SUPERVISOR restrito às suas, LOCAL ignora) — pronto para procedures filtrarem pela unidade da topbar.
Arquivo:
src/server/lib/branch-filter.ts - Nav LOCAL reordenada: dashboard primeiro, módulos M8 (notícias/chamados/documentos/enquetes) depois.
Arquivo:
src/components/layout/nav-config.ts
2. Critérios de aceite validados
| # | Critério | Status |
|---|---|---|
| 1 | Topbar fixa full-width com logo, dropdown unidade, busca Cmd+K, notificações, tema e avatar | OK |
| 2 | Dropdown de unidade sempre visível + persistência em cookie (validado: shell.branches retorna all:true + filiais no DEV) | OK |
| 3 | Busca global Cmd+K funcional — validada via tRPC: "Maria" retorna 2 alunos, "2026-1001" retorna 1 aluno por RA, "Lead" retorna 1 lead | OK |
| 4 | Sidebar 200px com ícones 18px + labels 13px + active com border-left accent | OK |
| 5 | Mobile preservado: drawer + hamburger | OK |
| 6 | Avatar dropdown mantido (UserMenu existente com perfil, /doc e sair) | OK |
| 7 | Build + lint OK | OK |
3. Deploy DEV
- Commit deployado via CI/CD (GitHub Actions -> VPS Oracle): e1d311e
- Smoke test: login MASTER OK + 17 paginas HTTP 200 (master, local, alunos, alunos/novo, noticias, nps, auditorias, chamados, documentos, enquetes, termos, professor, pais, aluno, atendimento)
- CSS novo confirmado no bundle servido (tokens de densidade ativos)
- URL: https://sistemaescolar.wellka.com.br
4. Contexto gerado
- Componentes M14 reutilizaveis para os proximos marcos (M10-M13): @/components/ui/{PageToolbar, FilterToolbar, FormTabs, EmptyState, DataTable} + @/lib/hooks/{useFilterState, useAutoSave} + sub-router tRPC shell.*
- Paginas novas (M10+) ja devem nascer com PageHeader + FilterToolbar + DataTable + EmptyState
5. Proximo card
Card 76: PageHeader + Toolbar de Ações
ADENDO — Padronização de TODAS as roles (15/08/2026, tarde)
Contexto
O Wellington identificou que PROFESSOR e STUDENT ainda usavam layouts antigos (ProfessorShell com topbar na coluna direita; StudentShell com top-nav horizontal). Correção: as 7 roles agora usam o mesmo AdminShell redesignado.
Mudanças (commit 4de0ef9)
| Arquivo | Mudança |
|---|---|
src/components/layout/AppShell.tsx |
PROFESSOR e STUDENT migram pro AdminShell; ProfessorShell/StudentShell removidos |
src/components/layout/ClassSelect.tsx |
Novo — seletor de turma do professor no padrão compacto da topbar (localStorage preservado) |
src/components/layout/AdminShell.tsx |
Prop mobileNav="bottom" — bottom-nav fixa (portal do aluno mobile) sem hamburger/drawer |
src/components/layout/nav-config.ts |
STUDENT completo: +galeria, +agenda, +perfil (9 itens; bottom-nav pega os 5 primeiros) |
messages/{pt-BR,en-US,es-ES}.json |
nav.menu.calendar + nav.menu.profile |
scripts/copy-standalone-assets.mjs |
Copia docs/execucao pro standalone deterministicamente (corrige 500 transitório no /doc a cada deploy — commit dca95c7) |
Resultado por role (desktop / mobile)
- MASTER, SUPERVISOR, LOCAL, ATTENDANT: topbar fixa + sidebar 200px / drawer
- PROFESSOR: topbar fixa + sidebar 200px + ClassSelect (turma) / drawer
- PARENT: topbar fixa + sidebar 200px + ChildSwitcher (2+ filhos) / drawer
- STUDENT: topbar fixa + sidebar 200px (9 itens) / bottom-nav fixa (5 itens)
Validação
- Build/lint/typecheck verdes; commit 4de0ef9 deployado via CI
- Smoke pós-deploy: /professor, /professor/chamada, /professor/notas, /aluno, /aluno/galeria, /aluno/agenda, /aluno/perfil, /pais, /atendimento → 200