feat(frontend): Discador > Campanhas — wizard de 7 passos, ciclo de vida, leads

Tela completa de campanhas do discador preditivo: listagem com busca/
filtro/status, wizard de criacao em 7 passos exatamente como a
especificacao nomeia (Geral -> Telefonia -> Discagem -> Horarios ->
Gravacao e IA -> Leads -> Revisao, agente.md secao 170) — nada e criado
ate confirmar na revisao, upload de CSV de leads na mesma acao de
criacao — e detalhe com acoes de ciclo de vida (iniciar/pausar/drenar/
parar, cada botao so aparece quando a transicao e valida pro status
atual), pacing ao vivo, previa de leads com import adicional, e remover.

Corrige de quebra um erro real de build: Server Actions exportadas como
arrow function que so repassam argumentos pra outra funcao quebram
("Server Actions must be async functions") — precisam ser declaradas
como async function de verdade.

Testado ponta a ponta com fila+tronco reais: os 7 passos preenchidos e
revisados, campanha criada com CSV de 3 leads importado, ciclo de vida
completo start->pause->drain->stop->delete via API, e confirmado que uma
campanha iniciada de verdade e pega pelo PredictiveDialerEngine real
rodando em Docker (stats deixam de ser null depois de alguns segundos).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EWHKmcVJtstQFErbZ1AanY
This commit is contained in:
2026-08-29 10:55:08 -03:00
parent 34ef408f00
commit 927a2623c2
22 changed files with 1375 additions and 10 deletions

View File

@@ -11,14 +11,14 @@ import {
} from "lucide-react";
import type { NavSection } from "../shell/nav-types";
/** IA fixa do menu Tenant (agente.md secao 169) — "Dashboard" (PHASE 23) e
* "Telefonia > Ramais" (PHASE 25) têm página construída até agora, o
* resto existe pra provar a arquitetura completa (Product Principle #5
* em PRODUCT.md), renderizado como indisponível em vez de virar link
* morto. "Itens sem permissão não aparecem" (secao 169) ainda não é
* aplicado aqui — este primeiro corte mostra a IA inteira pra qualquer
* usuário tenant autenticado; filtrar por permission real fica pra
* quando mais telas existirem pra testar contra. */
/** IA fixa do menu Tenant (agente.md secao 169) — "Dashboard" (PHASE 23),
* "Telefonia > Ramais" (PHASE 25) e "Discador > Campanhas" (PHASE 26) têm
* página construída até agora, o resto existe pra provar a arquitetura
* completa (Product Principle #5 em PRODUCT.md), renderizado como
* indisponível em vez de virar link morto. "Itens sem permissão não
* aparecem" (secao 169) ainda não é aplicado aqui — este primeiro corte
* mostra a IA inteira pra qualquer usuário tenant autenticado; filtrar por
* permission real fica pra quando mais telas existirem pra testar contra. */
export const TENANT_NAV: NavSection[] = [
{
label: "Dashboard",
@@ -30,7 +30,11 @@ export const TENANT_NAV: NavSection[] = [
label: "Discador",
icon: PhoneOutgoing,
children: [
{ label: "Campanhas" },
{
label: "Campanhas",
href: "/app/discador/campanhas",
description: "Discador preditivo — campanhas deste tenant",
},
{ label: "Leads" },
{ label: "Importações" },
{ label: "Callbacks" },