Design de Dashboard
Regras
- Layout de sidebar + conteúdo principal: sidebar fixa (w-64), área principal fluida com padding
- Navegação da sidebar: links de ícone + rótulo, destaque do estado ativo, colapsável em dispositivos móveis
- Linha de cards KPI no topo: 3-4 cards em uma grade responsiva — nome da métrica, valor, tendência (cima/baixo %), sparkline opcional
- Tabelas de dados: colunas ordenáveis, filtráveis por pesquisa/status, paginadas (padrão de 10 a 25 linhas)
- Use
@tanstack/react-table para lógica de tabela headless — combine com componentes de Tabela do shadcn/ui
- Responsivo: a sidebar colapsa em menu hambúrguer no breakpoint
md, os cards empilham em 1-2 colunas
- Estados de carregamento: placeholders de esqueleto que correspondem às formas dos cards/tabelas — nunca ocorra layout shift
- Seletor de período de datas para filtrar dados do dashboard — padrão para os últimos 30 dias
Estrutura de Layout
┌──────────┬────────────────────────────┐
│ Sidebar │ Cabeçalho / Breadcrumbs │
│ ├────────────────────────────┤
│ Links │ Cards KPI (grade 3-4) │
│ de ├────────────────────────────┤
│ Naveg. │ Gráficos / Visualizações │
│ ├────────────────────────────┤
│ │ Tabela de Dados │
└──────────┴────────────────────────────┘
Padrões
function KPICard({ title, value, change }: { title: string; value: string; change: number }) {
return (
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-sm font-medium text-muted-foreground">{title}</CardTitle>
</CardHeader>
<CardContent>
<div className="text-2xl font-bold">{value}</div>
<p className={cn("text-xs", change >= 0 ? "text-green-600" : "text-red-600")}>
{change >= 0 ? "+" : ""}{change}% em relação ao período anterior
</p>
</CardContent>
</Card>
);
}
Evitar
- Conteúdo principal com largura fixa — sempre use layout fluido que preenche o espaço disponível
- Tabelas sem paginação — grandes conjuntos de dados prejudicam desempenho e usabilidade
- Estados de carregamento/vazio ausentes — sempre mostre esqueletos ou mensagens "Nenhum dado"
- Sidebar que não pode ser colapsada — usuários móveis precisam da largura total da viewport
- Spinners de carregamento para atualizações parciais de página — use esqueletos para seções específicas
- Colocar KPIs demais — destaque de 3 a 5 métricas críticas, coloque o restante em seções expansíveis
- Sidebar personalizada do zero — use o componente de sidebar do shadcn
- Estados vazios sem ações — sempre inclua um CTA ("Nenhuma campanha ainda. Crie a sua primeira →")