Entrar como:FuncionalidadesDoc
Pular para o conteúdo
← Voltar para a visão geral
✅ ConcluídoCard #77 · M14

FilterToolbar Expansível

Marco M14: Redesign Visual Genius-Parity

📅14 de agosto de 2026
👤Wellington Santiago (via ZCode)
🔧Commits: 4a35f51

📄 Card 77 [M14] — FilterToolbar Expansível

📚 Referência Genius: Toolbar de filtros permanente em todas listagens: dropdowns (Unidade, Curso, Ano letivo, Por página), busca, "Ver mais filtros" expansível com mais opções.

🎯 Objetivo

Padronizar toolbar de filtros em todas páginas de listagem:

  • Filtros comuns sempre visíveis (período, paginação, busca)
  • Botão "Ver mais filtros" expansível com opções avançadas
  • Sincronização com URL (filtro vira query string, compartilhável)
  • Presets de filtro salvos por usuário
  • Lógica reutilizável (hook useFilterState)

📚 Documentação de Referência

  • src/components/ui/ — vários
  • Padrão Genius observado: combobox + botão "Ver mais filtros"

🛠️ Especificação Técnica

Componente <FilterToolbar />

interface FilterToolbarProps {
  // Filtros primários (sempre visíveis)
  primary?: FilterConfig[];
  // Filtros avançados (em "Ver mais filtros")
  advanced?: FilterConfig[];
  // Busca textual
  search?: { placeholder: string; value: string; onChange: (v: string) => void };
  // Paginação
  pagination?: { pageSize: number; onPageSizeChange: (n: number) => void };
  // Estado inicial (lê da URL)
  initialFromUrl?: boolean;
  // Presets salvos
  enablePresets?: boolean;
}

interface FilterConfig {
  name: string;                  // chave URL
  label: string;
  type: 'select' | 'multiselect' | 'date' | 'dateRange' | 'radio' | 'checkbox';
  options?: { label: string; value: string }[];
  defaultValue?: any;
}

Hook useFilterState

const { filters, setFilter, clearFilters, syncToUrl, presets, savePreset } = useFilterState({
  primary: [...],
  advanced: [...],
  initialFromUrl: true,
});
// filters = { unidade: 'CENTRO', curso: 'INGLÊS', ano: '2026', page: 1, pageSize: 20 }

Layout

┌─────────────────────────────────────────────────────────────┐
│ [Unidade ▼] [Curso ▼] [Ano ▼] [Por página ▼] [🔍 Buscar]   │
│ [▼ Ver mais filtros]                          [Limpar] [💾] │
└─────────────────────────────────────────────────────────────┘

Quando expandido:

┌─────────────────────────────────────────────────────────────┐
│ [Unidade ▼] [Curso ▼] [Ano ▼] [Por página ▼] [🔍 Buscar]   │
│ [▲ Ver menos filtros]                                        │
│ ──────────────────────────────────────────────────────────  │
│ Status: [ ] Ativo [ ] Inativo [ ] Pendente                  │
│ Data cadastro: [__/__/____] até [__/__/____]                │
│ Responsável: [Buscar...                                      │
│                                                              │
│ [Limpar filtros]                              [Aplicar]     │
└─────────────────────────────────────────────────────────────┘

Sincronização URL

  • Filtros viram query string: ?unidade=CENTRO&curso=INGLES&page=2
  • Compartilhável (link copiado mantém filtros)
  • Botão voltar do navegador funciona (filtros restaurados)

Presets

  • Usuário salva combinação de filtros com nome ("Meus alunos inadimplentes")
  • Dropdown de presets no canto direito da toolbar
  • Persiste em localStorage

✅ Critérios de Aceite

  1. Componente <FilterToolbar /> reutilizável
  2. Suporta 5+ tipos de filtro (select, multiselect, date, daterange, radio, checkbox)
  3. "Ver mais filtros" expansível/colapsável
  4. Sincroniza com URL (compartilhável + voltar funciona)
  5. Hook useFilterState reutilizável
  6. Presets salvos por usuário
  7. Páginas de listagem principais refatoradas
  8. Build passa + lint OK

🔌 Handoff

  • Componente @/components/ui/FilterToolbar
  • Hook @/lib/hooks/useFilterState

🎯 Próximo

Card 78: Sistema de Abas em Forms


EXECUCAO — 15/08/2026

1. O que foi implementado

  • Hook useFilterState: sincronização com URL (query string compartilhável, botão voltar restaura filtros), presets salvos por usuário em localStorage (chave por formId), contagem de filtros ativos e modo controlado. Arquivo: src/lib/hooks/useFilterState.ts
  • Componente FilterToolbar: filtros primários sempre visíveis + "Ver mais filtros" expansível (badge com nº de ativos), busca textual, seletor de itens por página, 6 tipos de filtro (select/multiselect/date/dateRange/radio/checkbox), presets com chips removíveis e botões Limpar/Aplicar. Arquivo: src/components/ui/FilterToolbar.tsx
  • Aplicado em /local/alunos: status/curso primários + matriculado-após/inadimplentes avançados, sincronizando com a query tRPC existente — filtros agora ficam na URL. Arquivo: src/app/(dashboard)/local/alunos/page.tsx

2. Critérios de aceite validados

# Critério Status
1 FilterToolbar reutilizável (modo standalone e controlado) OK
2 6 tipos de filtro suportados OK
3 Ver mais/menos filtros expansível com badge de ativos OK
4 Sincroniza com URL (compartilhável + voltar restaura) via router.replace OK
5 useFilterState reutilizável OK
6 Presets por usuário (localStorage) com salvar/aplicar/remover OK
7 Página principal de listagem refatorada (/local/alunos) OK
8 Build + lint OK OK

3. Deploy DEV

  • Commit deployado via CI/CD (GitHub Actions -> VPS Oracle): 4a35f51
  • 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 78: Sistema de Abas em Forms

← Voltar para a visão geral