// Disparo em massa — WhatsApp blast dedicado
const DisparoPage = () => {
const [step, setStep] = React.useState("compor"); // compor | revisar | enviando | concluido
const [tipo, setTipo] = React.useState("texto-imagem"); // texto | texto-imagem | botao
const [msg, setMsg] = React.useState("Oi {primeiro_nome}! 💛\n\nTem live nova hoje às 20h — peças de Verão 26 com preço exclusivo de live.\n\nGuarda já no carrinho ⬇️\n👉 {link_live}");
const [segmentos, setSegmentos] = React.useState(["champions", "leais", "live60"]);
const [intervalo, setIntervalo] = React.useState(15);
const [agora, setAgora] = React.useState(true);
const [sent, setSent] = React.useState(0);
const toggleSeg = (s) => setSegmentos(prev => prev.includes(s) ? prev.filter(x => x !== s) : [...prev, s]);
// Estimativa de destinatários (mock)
const calcDestinatarios = () => {
const m = { champions: 142, leais: 318, potencial: 89, risco: 204, novos: 64, perdidos: 487, live60: 312, loja30: 89, aniver: 28, cashback: 84 };
return segmentos.reduce((s, k) => s + (m[k] || 0), 0);
};
const dest = calcDestinatarios();
const custo = dest * 0.05;
const tempoMin = Math.ceil(dest * intervalo / 60);
// Simula envio
React.useEffect(() => {
if (step !== "enviando") return;
setSent(0);
const start = Date.now();
const id = setInterval(() => {
const elapsed = (Date.now() - start) / 1000;
const target = Math.min(dest, Math.floor(elapsed / 1.5 * dest * 0.08));
setSent(target);
if (target >= dest) {
clearInterval(id);
setTimeout(() => setStep("concluido"), 600);
}
}, 80);
return () => clearInterval(id);
}, [step, dest]);
return (
WhatsApp em massa
Disparo em massa
Envio direto via API WhatsApp Business · até 5.000 destinatários por disparo.
{/* Stepper */}
{step === "compor" && (
Tipo de mensagem
setTipo("texto")} icon="send" label="Texto simples"/>
setTipo("texto-imagem")} icon="eye" label="Texto + imagem"/>
setTipo("botao")} icon="arrowRight" label="Texto + botão CTA"/>
Mensagem
{tipo === "texto-imagem" && (
Arraste imagem ou clique para enviar
JPEG · PNG · até 5MB
)}
}/>
}/>
}/>
{/* Preview */}
Preview · WhatsApp
como Beatriz verá
EA
Estúdio Aurora
oficial · online
{tipo === "texto-imagem" && (
)}
{msg.replace(/{primeiro_nome}/g, "Bia").replace(/{valor_cashback}/g, "R$ 142,50").replace(/{link_live}/g, "vendanalive.com/aurora-48").replace(/{link_carrinho}/g, "vendanalive.com/c/8472")}
{tipo === "botao" && (
Ver Live agora
)}
20:42
Custo estimado
- Destinatários atuais
- {numFmt(dest)}
- Custo por mensagem
- R$ 0,05
- Custo total
- {brl(custo)}
- Tempo de envio
- ~{tempoMin} min
)}
{step === "revisar" && (
Selecione os segmentos
{numFmt(dest)} destinatários
SEGMENTOS RFM
toggleSeg("champions")} color="var(--green)"/>
toggleSeg("leais")} color="var(--cyan)"/>
toggleSeg("potencial")} color="var(--accent)"/>
toggleSeg("risco")} color="var(--pink)"/>
toggleSeg("novos")} color="var(--purple)"/>
toggleSeg("perdidos")} color="var(--text-3)"/>
COMPORTAMENTO
toggleSeg("live60")} color="var(--accent)"/>
toggleSeg("loja30")} color="var(--cyan)"/>
toggleSeg("cashback")} color="var(--green)"/>
toggleSeg("aniver")} color="var(--pink)"/>
{}} color="var(--purple)"/>
{}} color="var(--text-3)" addMore/>
| Cliente | @ | Cidade | RFM | Cashback | Última compra |
{CLIENTES.slice(0,8).map(c => (
| {c.nome.split(" ").slice(0,2).join(" ")} |
{c.instagram} |
{c.cidade} |
{c.rfm} |
{c.cashback > 0 ? brl(c.cashback) : "—"} |
{c.ultimaCompra} |
))}
Resumo do disparo
QUANDO ENVIAR
{!agora && (
)}
{28.40 - custo < 0 && (
⚠️ Saldo insuficiente. Recarregue antes de disparar.
)}
)}
{step === "enviando" && (
ENVIANDO
{numFmt(sent)} / {numFmt(dest)}
mensagens enviadas com sucesso
)}
{step === "concluido" && (
Disparo concluído!
{numFmt(dest)} mensagens enviadas em ~{tempoMin} minutos
)}
{/* Histórico colapsado */}
{step === "compor" && (
| Nome | Quando | Destinatários | Entrega | Conversões | Receita atribuída | ROI |
| Convite Live #47 | 12/05 18:00 | 2.108 | 94.2% | 218 | {brl(14820)} | 28.1× |
| Champions — Pré-venda | 10/05 14:30 | 87 | 97.7% | 42 | {brl(8420)} | 42.8× |
| Cashback expirando | 12/05 09:00 | 64 | 95.3% | 18 | {brl(3240)} | 21.0× |
| Aniversariantes Maio | 01/05 09:00 | 142 | 97.2% | 38 | {brl(5240)} | 14.4× |
| Reativação 60d sem compra | 19/05 14:00 | 312 | em curso | 12 | {brl(840)} | apurando |
)}
);
};
const StepIndicator = ({ num, label, active, done }) => (
);
const TipoChip = ({ active, onClick, icon, label }) => (
);
const SegChip = ({ label, count, desc, active, onClick, color, addMore }) => (
);
const ConfigRow = ({ label, hint, control }) => (
);
Object.assign(window, { DisparoPage });