Files
COMERCIAL-GTI/public/js/campanhas.js
T

112 lines
4.3 KiB
JavaScript

/* Aba Campanhas: criacao, fila de aprovacao, saude/variantes, estagio/agendamento. */
const Campanhas = (() => {
let carregado = false;
let variantesCount = 0;
const STATUS_LABELS = { rascunho: 'Rascunho', rodando: 'Rodando', pausado: 'Pausado', concluido: 'Concluido' };
function addVarianteRow(codigoSugerido) {
const codigo = codigoSugerido || String.fromCharCode(65 + variantesCount);
variantesCount += 1;
el('campanha-variantes').append(
h('div', { class: 'row', 'data-variante-code': codigo },
h('span', { class: 'chip' }, codigo),
h('textarea', { class: 'campanha-variante-mensagem', rows: 2, placeholder: 'Ola {empresa}, ...' }))
);
}
async function carregarProdutos() {
const { produtos } = await API.get('/api/campaigns/produtos');
el('campanha-produto').replaceChildren(
...produtos.map((p) => h('option', { value: p.value }, `${p.value} (${fmt.format(p.total)} leads)`))
);
}
async function carregarSegmentos(produto) {
const container = el('campanha-segmentos');
if (!produto) { container.replaceChildren(); return; }
const { segmentos } = await API.get(`/api/campaigns/segmentos?produto=${encodeURIComponent(produto)}`);
container.replaceChildren(...segmentos.map((s) =>
h('label', { class: 'chip' },
h('input', { type: 'checkbox', value: s.value, class: 'campanha-segmento-check' }),
` ${s.value} (${fmt.format(s.total)})`)
));
}
function segmentosSelecionados() {
return Array.from(document.querySelectorAll('.campanha-segmento-check:checked')).map((i) => i.value);
}
function variantesPreenchidas() {
return Array.from(el('campanha-variantes').children).map((row) => ({
code: row.dataset.varianteCode,
mensagem: row.querySelector('.campanha-variante-mensagem').value.trim()
})).filter((v) => v.mensagem);
}
async function abrirModalNovaCampanha() {
el('campanha-nome').value = '';
el('campanha-limite-inicial').value = 10;
el('campanha-limite-teto').value = 80;
el('campanha-erro').textContent = '';
el('campanha-variantes').replaceChildren();
variantesCount = 0;
addVarianteRow('A');
await carregarProdutos();
await carregarSegmentos(el('campanha-produto').value);
el('modal-nova-campanha').showModal();
}
function renderCampanhaCard(campanha) {
return h('div', { class: 'item' },
h('div', {},
h('strong', {}, campanha.nome),
h('span', { class: 'sub' }, ` ${campanha.produto} — ${campanha.segmentos.join(', ')}`)),
h('span', { class: `chip ${campanha.status === 'rodando' ? 'ok' : campanha.status === 'pausado' ? 'warn' : ''}` },
STATUS_LABELS[campanha.status] || campanha.status));
}
async function carregarLista() {
const { campanhas } = await API.get('/api/campaigns');
el('campanhas-lista').replaceChildren(
...(campanhas.length ? campanhas.map(renderCampanhaCard) : [h('p', { class: 'muted' }, 'Nenhuma campanha criada ainda.')])
);
}
function ativar() {
if (carregado) return;
carregado = true;
el('btn-nova-campanha').addEventListener('click', () => {
abrirModalNovaCampanha().catch((error) => toast(`Erro: ${error.message}`));
});
el('btn-cancelar-campanha').addEventListener('click', () => el('modal-nova-campanha').close());
el('btn-add-variante').addEventListener('click', () => addVarianteRow());
el('campanha-produto').addEventListener('change', (event) => {
carregarSegmentos(event.target.value).catch((error) => toast(`Erro: ${error.message}`));
});
el('btn-salvar-campanha').addEventListener('click', async () => {
try {
await API.post('/api/campaigns', {
nome: el('campanha-nome').value.trim(),
produto: el('campanha-produto').value,
segmentos: segmentosSelecionados(),
variantes: variantesPreenchidas(),
limiteDiarioInicial: Number(el('campanha-limite-inicial').value) || 10,
limiteDiarioTeto: Number(el('campanha-limite-teto').value) || 80
});
el('modal-nova-campanha').close();
toast('Campanha criada');
await carregarLista();
} catch (error) {
el('campanha-erro').textContent = error.message;
}
});
carregarLista().catch((error) => toast(`Erro: ${error.message}`));
}
return { ativar };
})();