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:
75
apps/frontend/src/lib/campaign-types.ts
Normal file
75
apps/frontend/src/lib/campaign-types.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
export type CampaignStatus = "DRAFT" | "READY" | "WAITING_SCHEDULE" | "RUNNING" | "PAUSED" | "DRAINING" | "STOPPED" | "COMPLETED" | "ERROR";
|
||||
|
||||
export interface Campaign {
|
||||
id: string;
|
||||
tenantId: string;
|
||||
name: string;
|
||||
description: string | null;
|
||||
queueId: string;
|
||||
trunkId: string;
|
||||
callerIdName: string | null;
|
||||
callerIdNumber: string | null;
|
||||
timezone: string;
|
||||
startDate: string | null;
|
||||
endDate: string | null;
|
||||
daysOfWeek: number[];
|
||||
startTime: string | null;
|
||||
endTime: string | null;
|
||||
maxCps: number | null;
|
||||
maxConcurrentCalls: number | null;
|
||||
pacingInitial: number;
|
||||
pacingMin: number;
|
||||
pacingMax: number;
|
||||
targetAbandonRate: number;
|
||||
ringTimeout: number;
|
||||
maxAttempts: number;
|
||||
recordingEnabled: boolean;
|
||||
avmdEnabled: boolean;
|
||||
aiTranscriptionEnabled: boolean;
|
||||
aiAnalysisEnabled: boolean;
|
||||
status: CampaignStatus;
|
||||
createdAt: string;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
export interface CampaignStats {
|
||||
status: CampaignStatus;
|
||||
stats: {
|
||||
answerProbability: number | null;
|
||||
averageAnswerDelay: number | null;
|
||||
averageTalkTime: number | null;
|
||||
abandonRate: number | null;
|
||||
pacingFactor: number;
|
||||
};
|
||||
agentsByState: Record<string, number>;
|
||||
callsInFlight: number;
|
||||
}
|
||||
|
||||
export interface LeadImportSummary {
|
||||
total: number;
|
||||
valid: number;
|
||||
invalid: number;
|
||||
duplicates: number;
|
||||
imported: number;
|
||||
suppressed: number;
|
||||
}
|
||||
|
||||
export interface QueueOption {
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface TrunkOption {
|
||||
id: string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export const DAYS_OF_WEEK_LABELS: Record<number, string> = {
|
||||
1: "Seg",
|
||||
2: "Ter",
|
||||
3: "Qua",
|
||||
4: "Qui",
|
||||
5: "Sex",
|
||||
6: "Sáb",
|
||||
7: "Dom",
|
||||
};
|
||||
Reference in New Issue
Block a user