📄 Card 78 [M14] — Sistema de Abas em Forms
📚 Referência Genius: Form de aluno tem abas laterais "Aluno / Pai / Mãe / Responsável / Ficha Médica / Anexos" — cada aba é uma seção do cadastro.
🎯 Objetivo
Implementar sistema de abas em formulários complexos (cadastro de aluno, funcionário, matrícula):
- Componente
<FormTabs />reutilizável com navegação lateral ou topo - Cada aba é um "step" do form (não perde dados ao trocar)
- Validação por aba (não pode avançar com erro)
- Indicador de progresso (✓ preenchido, ▶ atual, ○ pendente)
- Persistência de rascunho (auto-save) antes de submit final
- Botões "Anterior" / "Próximo" / "Salvar" no rodapé
📚 Documentação de Referência
src/components/ui/— existente- Form de aluno Genius: abas com ícones
🛠️ Especificação Técnica
Componente <FormTabs />
interface FormTabsProps {
tabs: FormTab[];
orientation?: 'horizontal' | 'vertical'; // default vertical
autoSave?: boolean; // rascunho a cada 5s
initialTab?: string;
}
interface FormTab {
id: string;
label: string;
icon?: LucideIcon;
content: React.ReactNode;
validate?: () => boolean | Promise<boolean>; // true = ok pra avançar
isComplete?: boolean; // ✓ verde
}
// Uso:
<FormTabs
tabs={[
{ id: 'aluno', label: 'Aluno', icon: User, content: <AlunoSection />, isComplete: hasAlunoData },
{ id: 'pai', label: 'Pai', icon: UserSquare, content: <PaiSection />, isComplete: hasPaiData },
{ id: 'mae', label: 'Mãe', icon: UserCircle, content: <MaeSection /> },
{ id: 'responsavel', label: 'Responsável', icon: Users, content: <ResponsavelSection /> },
{ id: 'medica', label: 'Ficha Médica', icon: HeartPulse, content: <MedicaSection /> },
{ id: 'anexos', label: 'Anexos', icon: Paperclip, content: <AnexosSection /> },
]}
autoSave
/>
Layout (vertical, padrão Genius)
┌──────────────────┬─────────────────────────────────────┐
│ ▶ Aluno │ │
│ Pai │ [conteúdo da aba Aluno] │
│ Mãe │ │
│ Responsável │ │
│ Ficha Médica │ │
│ Anexos (0) │ │
│ │ │
└──────────────────┴─────────────────────────────────────┘
[Anterior] [Próximo ▶] [Salvar]
Layout (horizontal, mobile)
[Aluno ▶] [Pai] [Mãe] [Responsável] [Médica] [Anexos]
─────────────────────────────────────────────────────
[conteúdo]
─────────────────────────────────────────────────────
[Anterior] [Próximo] [Salvar]
Auto-save
- Hook
useAutoSave(formId, data)→ salva em IndexedDB a cada 5s - Recupera ao recarregar página (banner "Rascunho recuperado")
- Limpa após submit final com sucesso
Validação por aba
validate()retorna boolean ou Promise- Se false → bloqueia botão "Próximo" + mostra erros
- Não bloqueia "Anterior"
Aplicações
- Form Aluno (Card 18): 6 abas (Aluno / Pai / Mãe / Responsável / Ficha Médica / Anexos)
- Form Funcionário (Card 74): 5 abas (Pessoal / Contrato / Documentos / Benefícios / Observações)
- Form Matrícula (Card 18): 5 abas (Aluno / Curso+Turma / Documentação / Pagamento / Contrato)
- Form Lead (Card 30): 4 abas (Dados / Interesses / Atividades / Conversão)
✅ Critérios de Aceite
- Componente
<FormTabs />reutilizável (horizontal + vertical) - Indicador visual de progresso (✓ ▶ ○)
- Validação por aba bloqueia avanço
- Auto-save em IndexedDB + recupera após reload
- Botões Anterior/Próximo/Salvar
- Aplicado em forms principais (Aluno, Funcionário, Matrícula, Lead)
- Mobile usa abas horizontais
- Build passa + lint OK
🔌 Handoff
- Componente
@/components/ui/FormTabs - Hook
@/lib/hooks/useAutoSave
🎯 Próximo
Card 79: Empty States Padronizados + Tabelas
EXECUCAO — 15/08/2026
1. O que foi implementado
- Componente FormTabs: abas verticais no desktop / horizontais no mobile (matchMedia), indicador de progresso (check = completa), contador "N/M seções completas", validação por aba bloqueando Próximo, rodapé Anterior/Próximo/Salvar.
Arquivo:
src/components/ui/FormTabs.tsx - Hook useAutoSave: rascunho em IndexedDB (db genioon-drafts) a cada 5s quando muda, expira em 7 dias, banner de recuperação (Recuperar/Descartar) e limpeza automática após submit com sucesso.
Arquivo:
src/lib/hooks/useAutoSave.ts - Aplicado no cadastro de aluno (/local/alunos/novo): 4 abas — Aluno (valida nome/e-mail/nascimento), Contato, Ficha Médica e Responsável — com auto-save e restauração de rascunho em 21 campos; foto continua na coluna lateral sticky.
Arquivo:
src/app/(dashboard)/local/alunos/novo/page.tsx
2. Critérios de aceite validados
| # | Critério | Status |
|---|---|---|
| 1 | FormTabs reutilizável (vertical + horizontal automático por breakpoint) | OK |
| 2 | Indicador visual de progresso + contador de seções | OK |
| 3 | Validação por aba bloqueia avanço (com mensagem inline) | OK |
| 4 | Auto-save em IndexedDB + recuperação após reload (banner Recuperar/Descartar) | OK |
| 5 | Botões Anterior/Próximo/Salvar no rodapé | OK |
| 6 | Aplicado no form de Aluno (4 abas + rascunho de 21 campos) | OK |
| 7 | Mobile usa abas horizontais | OK |
| 8 | Build + lint OK | OK |
3. Deploy DEV
- Commit deployado via CI/CD (GitHub Actions -> VPS Oracle): b0e6389
- 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 79: Empty States Padronizados + Tabelas