Files
COMERCIAL-GTI/public/index.html
T
DESKTOP-F2O4A80\UserandClaude b8d10b210c Commit inicial: GTI Maquina Comercial
App local (Node + SQLite) para captura, tratamento e exportacao de leads
comerciais, com dashboard de gestao, login/usuarios e integracao Z-PRO.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-12 14:22:21 -03:00

361 lines
16 KiB
HTML

<!doctype html>
<html lang="pt-BR">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>GTI Máquina Comercial</title>
<link rel="stylesheet" href="/css/app.css">
<link rel="icon" href="data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><text y='.9em' font-size='90'>🎯</text></svg>">
</head>
<body>
<header class="topbar">
<div class="brand">
<span class="brand-mark">GTI</span>
<span class="brand-name">Máquina Comercial</span>
</div>
<nav class="tabs" role="tablist">
<button class="tab active" data-tab="captura" role="tab" aria-selected="true">📡 Capturar Leads</button>
<button class="tab" data-tab="tratamento" role="tab" aria-selected="false">📊 Tratar Leads</button>
</nav>
<span class="muted" id="usuario-logado"></span>
<button class="btn-ghost hidden" id="btn-usuarios" title="Usuários">👤 Usuários</button>
<button class="btn-ghost" id="btn-settings" title="Configurações">⚙️</button>
<button class="btn-ghost" id="btn-sair" title="Sair">🚪 Sair</button>
</header>
<main>
<!-- ==================== CAPTURA ==================== -->
<section id="tab-captura" class="tab-panel active">
<div class="captura-wrap">
<div class="card" id="captura-form">
<div class="row space-between">
<h2>Nova captura</h2>
<button class="btn-ghost" id="btn-ver-historico" type="button">🕓 Histórico de capturas</button>
</div>
<div class="field">
<label for="sel-uf">1. Estado (UF)</label>
<div class="row">
<select id="sel-uf"></select>
<span id="uf-status" class="chip"></span>
</div>
<div id="extracao-aviso" class="notice hidden">
<p>A base CNPJ de <strong id="extracao-uf"></strong> ainda não foi extraída neste computador.
A extração lê os arquivos da Receita Federal e demora <strong>~40 a 60 minutos</strong> (uma única vez por estado).</p>
<button class="btn" id="btn-extrair">⛏️ Extrair base agora</button>
</div>
</div>
<div class="field">
<label>2. Cidades</label>
<div class="row">
<label class="radio"><input type="radio" name="cidades-modo" value="todas" checked> Todas as cidades da UF</label>
<label class="radio"><input type="radio" name="cidades-modo" value="escolher"> Escolher cidades</label>
</div>
<div id="cidades-picker" class="picker hidden">
<input type="search" id="busca-cidade" placeholder="Digite para buscar cidade...">
<div id="cidades-sugestoes" class="sugestoes"></div>
<div id="cidades-chips" class="chips"></div>
</div>
</div>
<div class="field">
<label>3. Nichos <span class="muted" id="nichos-contagem"></span></label>
<div class="row">
<label class="radio"><input type="radio" name="nichos-modo" value="todos" checked> Todos os nichos</label>
<label class="radio"><input type="radio" name="nichos-modo" value="escolher"> Escolher nichos</label>
</div>
<div id="nichos-picker" class="picker hidden">
<div class="row">
<input type="search" id="busca-nicho" placeholder="Filtrar nichos...">
<button class="btn-ghost" id="btn-nichos-todos" type="button">Marcar visíveis</button>
<button class="btn-ghost" id="btn-nichos-nenhum" type="button">Desmarcar todos</button>
</div>
<div id="nichos-grid" class="nichos-grid"></div>
</div>
<details class="cnae-avulso">
<summary>Não achou o nicho? Buscar qualquer atividade da Receita Federal (CNAE)</summary>
<p class="muted cnae-avulso-hint">Os 57 nichos acima já vêm com mensagem e interesse configurados. Um CNAE avulso é adicionado só para a busca — ele participa da captura normalmente.</p>
<input type="search" id="busca-cnae" placeholder="Ex.: salão de beleza, transportadora, escola...">
<div id="cnae-sugestoes" class="sugestoes"></div>
<div id="cnae-chips" class="chips"></div>
</details>
</div>
<div class="field">
<label>4. Fontes de busca</label>
<div id="fontes-lista" class="fontes"></div>
</div>
<details class="field">
<summary>Opções avançadas</summary>
<div class="row">
<label>Máx. por consulta (fontes de API)
<input type="number" id="inp-max" value="10" min="1" max="60">
</label>
<label>Limite total de consultas (0 = sem limite)
<input type="number" id="inp-query-limit" value="0" min="0">
</label>
</div>
</details>
<button class="btn btn-primary btn-lg" id="btn-capturar">🚀 Iniciar captura</button>
</div>
<div class="card hidden" id="progresso-card">
<div class="row space-between">
<h2 id="progresso-titulo">Captura em andamento</h2>
<button class="btn-danger" id="btn-cancelar">Cancelar</button>
</div>
<div class="progress-bar"><div class="progress-fill" id="progresso-fill"></div></div>
<p class="progress-msg" id="progresso-msg">iniciando...</p>
<div class="stat-row" id="progresso-stats"></div>
<div class="log" id="progresso-log"></div>
</div>
</div>
</section>
<!-- ==================== TRATAMENTO ==================== -->
<section id="tab-tratamento" class="tab-panel">
<div class="card filtros-card">
<div class="filtros" id="filtros">
<select id="f-uf" data-filtro="uf"><option value="">UF: todas</option></select>
<input list="dl-cidades" id="f-cidade" data-filtro="cidade" placeholder="Cidade: todas">
<datalist id="dl-cidades"></datalist>
<select id="f-segmento" data-filtro="segmento"><option value="">Nicho: todos</option></select>
<select id="f-classificacao" data-filtro="classificacao">
<option value="">Classificação: todas</option>
<option value="excelente">🟢 Excelente</option>
<option value="bom">🟢 Bom</option>
<option value="medio">🟡 Médio</option>
<option value="baixo">🟠 Baixo</option>
<option value="muito_baixo">🔴 Muito Baixo</option>
</select>
<select id="f-prioridade" data-filtro="prioridade">
<option value="">Prioridade: todas</option>
<option value="1">P1 — atacar agora</option>
<option value="2">P2 — esta semana</option>
<option value="3">P3 — quando sobrar</option>
<option value="4">P4 — campanhas específicas</option>
</select>
<select id="f-produto" data-filtro="produto"><option value="">Produto: todos</option></select>
<select id="f-interesse" data-filtro="interesse"><option value="">Interesse: todos</option></select>
<select id="f-telefone" data-filtro="telefone_valido">
<option value="">WhatsApp: todos</option>
<option value="sim">Com WhatsApp</option>
<option value="nao">Sem WhatsApp</option>
</select>
<select id="f-website" data-filtro="website">
<option value="">Website: todos</option>
<option value="sim">Com website</option>
<option value="nao">Sem website</option>
</select>
<select id="f-email" data-filtro="email">
<option value="">E-mail: todos</option>
<option value="sim">Com e-mail</option>
<option value="nao">Sem e-mail</option>
</select>
<select id="f-exportado" data-filtro="exportado">
<option value="">Exportação: todos</option>
<option value="nao">Ainda não exportados</option>
<option value="sim">Já exportados</option>
</select>
<input type="search" id="f-busca" data-filtro="q" placeholder="🔎 empresa, CNPJ ou WhatsApp">
<button class="btn-ghost" id="btn-limpar-filtros">Limpar</button>
</div>
</div>
<div class="stat-tiles" id="stat-tiles"></div>
<div class="grid-3">
<div class="card">
<div class="row space-between">
<h2>Top cidades</h2>
</div>
<div id="rank-cidades" class="ranking"></div>
</div>
<div class="card">
<div class="row space-between">
<h2>Top nichos</h2>
</div>
<div id="rank-segmentos" class="ranking"></div>
</div>
<div class="card">
<div class="row space-between">
<h2 id="rank-produtos-titulo">Top produto recomendado</h2>
</div>
<div id="rank-produtos" class="ranking"></div>
</div>
</div>
<div class="grid-3">
<div class="card" id="card-oportunidades-dia"></div>
<div class="card" id="card-maior-oportunidade"></div>
<div class="card" id="card-evolucao-diaria"></div>
</div>
<div class="card" id="card-funil"></div>
<div class="card">
<div class="row space-between wrap">
<h2>Leads <span class="muted" id="leads-total"></span></h2>
<button class="btn btn-primary" id="btn-exportar">📤 Gerar relatório / exportação com este filtro</button>
</div>
<div class="table-wrap">
<table id="tabela-leads">
<thead>
<tr>
<th>Empresa</th><th>WhatsApp</th><th>Cidade</th><th>Nicho</th>
<th>Prioridade</th><th class="num">Geral</th>
<th>Classificação</th><th>Produto</th><th>Exportado</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
<div class="row space-between">
<button class="btn-ghost" id="pg-prev">← Anterior</button>
<span class="muted" id="pg-info"></span>
<button class="btn-ghost" id="pg-next">Próxima →</button>
</div>
</div>
<div class="card">
<h2>Exportações geradas</h2>
<div id="historico-exports" class="lista"></div>
</div>
</section>
</main>
<!-- Modal de exportação -->
<dialog id="modal-export">
<form method="dialog" class="modal-body" id="form-export">
<h2>Gerar relatório / exportação</h2>
<p class="muted" id="export-recap"></p>
<div id="export-atalhos" class="chips"></div>
<div class="field">
<label>Tipo de arquivo</label>
<label class="radio"><input type="radio" name="export-tipo" value="excel" checked>
📊 <strong>Planilha (CSV + Excel)</strong> — lista completa com score, à prova de notação científica</label>
<label class="radio"><input type="radio" name="export-tipo" value="zpro-oportunidades">
🗂️ <strong>Z-PRO: Oportunidades (JSONL)</strong> — payloads prontos para createOpportunity</label>
<label class="radio"><input type="radio" name="export-tipo" value="zpro-bulk">
📨 <strong>Z-PRO: Disparo em massa (CSV)</strong> — dataInput para BulkSendMessageWithVariable</label>
</div>
<div class="field" id="export-zpro-params">
<label>Parâmetros Z-PRO</label>
<div class="row">
<label>Pipeline <input type="number" id="zp-pipeline" min="1"></label>
<label>Etapa <input type="number" id="zp-stage" min="1"></label>
<label>Responsável <input type="number" id="zp-responsible" min="1"></label>
</div>
</div>
<div class="field hidden" id="export-mensagem-wrap">
<label>Mensagem sugerida (use {empresa}, {cidade}, {segmento})</label>
<textarea id="export-mensagem" rows="3">Olá {empresa}! Somos do Grupo GTI e ajudamos empresas de {cidade} com sistema de gestão, TI e atendimento automático no WhatsApp. Podemos conversar?</textarea>
</div>
<label class="radio"><input type="checkbox" id="export-marcar" checked>
Marcar estes leads como exportados (não aparecem de novo no filtro "ainda não exportados")</label>
<div class="row space-between">
<button class="btn-ghost" value="cancel">Cancelar</button>
<button class="btn btn-primary" id="btn-confirmar-export" value="default">Gerar arquivos</button>
</div>
</form>
</dialog>
<!-- Modal de histórico de capturas -->
<dialog id="modal-historico">
<div class="modal-body">
<div class="row space-between">
<h2>Últimas capturas</h2>
<button class="btn-ghost" id="btn-fechar-historico" type="button">Fechar</button>
</div>
<div id="historico-capturas" class="lista"></div>
</div>
</dialog>
<!-- Modal de configurações -->
<dialog id="modal-settings">
<form method="dialog" class="modal-body">
<h2>Configurações</h2>
<div class="field">
<label>Padrões Z-PRO (usados nas exportações)</label>
<div class="row">
<label>Pipeline <input type="number" id="cfg-pipeline" min="1"></label>
<label>Etapa <input type="number" id="cfg-stage" min="1"></label>
<label>Responsável <input type="number" id="cfg-responsible" min="1"></label>
</div>
<div class="row">
<label>Previsão de fechamento (dias) <input type="number" id="cfg-forecast" min="1"></label>
</div>
</div>
<div class="field zona-risco">
<label>Zona de risco</label>
<p class="muted">Apaga permanentemente todos os leads, exportações, capturas e extrações. Configurações e nichos não são afetados.</p>
<button class="btn-danger" id="btn-limpar-base" type="button">🗑️ Limpar toda a base de leads</button>
</div>
<div class="row space-between">
<button class="btn-ghost" value="cancel">Fechar</button>
<button class="btn btn-primary" id="btn-salvar-settings" value="default">Salvar</button>
</div>
</form>
</dialog>
<!-- Modal de confirmacao da limpeza total da base -->
<dialog id="modal-reset-base">
<div class="modal-body">
<h2>Limpar toda a base de leads</h2>
<p class="muted">Esta ação é <strong>irreversível</strong>: todos os leads, exportações, capturas e extrações serão apagados. Digite a senha de segurança para confirmar.</p>
<div class="field">
<label>Senha de segurança <input type="password" id="reset-base-senha" autocomplete="off"></label>
</div>
<div class="row space-between">
<button class="btn-ghost" id="btn-cancelar-reset-base" type="button">Cancelar</button>
<button class="btn-danger" id="btn-confirmar-reset-base" type="button">Confirmar limpeza</button>
</div>
</div>
</dialog>
<!-- Modal de usuarios (somente admin) -->
<dialog id="modal-usuarios">
<div class="modal-body">
<div class="row space-between">
<h2>Usuários</h2>
<button class="btn-ghost" id="btn-fechar-usuarios" type="button">Fechar</button>
</div>
<div id="lista-usuarios" class="lista"></div>
<form class="field" id="form-novo-usuario">
<label>Novo usuário</label>
<div class="row">
<input type="text" id="novo-usuario-username" placeholder="usuário" minlength="3" required>
<input type="password" id="novo-usuario-password" placeholder="senha" minlength="4" required>
<select id="novo-usuario-role">
<option value="comercial">Comercial</option>
<option value="admin">Administrador</option>
</select>
<button class="btn btn-primary" type="submit">Criar</button>
</div>
</form>
</div>
</dialog>
<!-- Modal detalhe do lead -->
<dialog id="modal-lead">
<div class="modal-body" id="lead-detalhe"></div>
</dialog>
<div id="toast" class="toast hidden"></div>
<script src="/js/api.js"></script>
<script src="/js/captura.js"></script>
<script src="/js/tratamento.js"></script>
<script src="/js/app.js"></script>
</body>
</html>