Entrar

Seu painel pessoal de leads, sem depender da roleta.

Painel do dia

Quem precisa da sua ligação hoje, em ordem de urgência.

Funil de vendas

Arraste o raciocínio, não o mouse — use os botões pra mover de etapa.

Meus leads

Toda a sua carteira, inclusive quem veio de lista fria.

NomeTelefoneTemp.EtapaOrigemPróximo contato

Meus imóveis

Cadastre o que você vende e veja quais leads combinam com cada um.

Scripts de reabordagem

Texto pronto pra cada objeção — copia, ajusta o nome, manda.

Relatório pessoal

O que está funcionando na sua captação.

Leads por origem

Leads por etapa do funil

Perdidos por motivo

Bônus

Conteúdo extra pra vender mais e usar melhor a sua comissão.

`; showReportModal(reportHtml); } // mostra o relatório dentro da própria página (evita bloqueio de pop-up em navegadores/preview que travam window.open) function showReportModal(html){ const old = document.getElementById('reportModalOverlay'); if(old) old.remove(); const overlay = document.createElement('div'); overlay.id = 'reportModalOverlay'; overlay.style.cssText = 'position:fixed; inset:0; z-index:9999; background:rgba(0,0,0,.75); display:flex; flex-direction:column; align-items:center; padding:14px; box-sizing:border-box;'; overlay.innerHTML = `
`; document.body.appendChild(overlay); const iframe = document.getElementById('reportFrame'); iframe.srcdoc = html; document.getElementById('reportCloseBtn').onclick = function(){ overlay.remove(); }; document.getElementById('reportPrintBtn').onclick = function(){ try{ iframe.contentWindow.focus(); iframe.contentWindow.print(); } catch(e){ alert('Não foi possível abrir a impressão automaticamente. Segure/toque e use o menu do navegador para imprimir ou salvar como PDF.'); } }; } /* ================= RELATORIO ================= */ function renderReport(){ const total = leads.length; const perdidos = leads.filter(l=>l.status==='perdido').length; const decisao = leads.filter(l=>l.etapa==='decisao' && l.status!=='perdido').length; const conv = total ? Math.round((decisao/total)*100) : 0; document.getElementById('reportStats').innerHTML = `
${total}
Total captado
${decisao}
Em decisão
${conv}%
Taxa até decisão
${perdidos}
Perdidos
`; const origens = ['plantao','panfleto','lista_fria','indicacao','telefone','outro']; const maxO = Math.max(1, ...origens.map(o=>leads.filter(l=>l.origem===o).length)); document.getElementById('chartOrigem').innerHTML = origens.map(o=>{ const c = leads.filter(l=>l.origem===o).length; return barRow(origemLabel(o), c, maxO); }).join(''); const maxE = Math.max(1, ...ETAPAS.map(e=>leads.filter(l=>l.etapa===e.k && l.status!=='perdido').length)); document.getElementById('chartEtapa').innerHTML = ETAPAS.map(e=>{ const c = leads.filter(l=>l.etapa===e.k && l.status!=='perdido').length; return barRow(e.l, c, maxE); }).join(''); const maxP = Math.max(1, ...MOTIVOS_PERDA.map(m=>leads.filter(l=>l.status==='perdido' && l.motivo_perda===m.k).length)); const chartPerdaEl = document.getElementById('chartPerda'); if(!perdidos){ chartPerdaEl.innerHTML = '
Nenhum lead perdido registrado ainda.
'; } else{ chartPerdaEl.innerHTML = MOTIVOS_PERDA.map(m=>{ const c = leads.filter(l=>l.status==='perdido' && l.motivo_perda===m.k).length; return barRow(m.l, c, maxP); }).join(''); } } function barRow(label, val, max){ const pct = Math.round((val/max)*100); return `
${label}
${val}
`; } /* ================= UTIL ================= */ function escapeHtml(s){ return (s||'').toString().replace(/[&<>"']/g, m=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[m])); } /* ================= BOOT ================= */ (async function boot(){ const {data:{session}} = await sb.auth.getSession(); if(session){ await initApp(); } })();