// AGÊNCIA LOGUE — sistema claro, funcional e persistente. // Home (Financeiro · Comercial · Produção) + CRM arrastável + edição. Exporta window.LogueHub. (function () { const { useState, useEffect, useRef } = React; const h = React.createElement; const S = () => window.LogueStore; const AC = "#FF78B0"; const PAG_COR = { pago: "#3F9E6B", pendente: "#C77D2E", atrasado: "#C9524F", permuta: "#7E6BB0" }; const PAG_BG = { pago: "#E6F3EC", pendente: "#FBEEDD", atrasado: "#F8E4E3", permuta: "#EFEAF8" }; const PAG_LABEL = { pago: "pago", pendente: "a receber", atrasado: "atrasado", permuta: "permuta" }; const STATUS_OPTS = [["pago", "Pago"], ["pendente", "A receber"], ["atrasado", "Atrasado"], ["permuta", "Permuta"]]; const brl = (n) => "R$ " + Number(n || 0).toLocaleString("pt-BR"); const ini = (nm) => (nm || "?").trim().charAt(0).toUpperCase() || "?"; const MES_ORD = ["Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"]; const mesKey = (m) => { const [nm, y] = m.split("/"); return (+y) * 100 + (MES_ORD.indexOf(nm.slice(0, 3)) + 1); }; function useLogue() { const [, force] = useState(0); useEffect(() => S().subscribe(() => force((x) => x + 1)), []); return S().get(); } // ── inputs editáveis (uncontrolled, commit no blur) ── function Inp({ val, onSave, type, placeholder, area, className }) { return h(area ? "textarea" : "input", { className: "lg-inp" + (area ? " area" : "") + (className ? " " + className : ""), type: type || "text", defaultValue: val == null ? "" : val, placeholder, rows: area ? 3 : undefined, onBlur: (e) => { const v = type === "number" ? (parseFloat(e.target.value) || 0) : e.target.value; if (v !== val) onSave(v); }, onKeyDown: (e) => { if (!area && e.key === "Enter") e.target.blur(); }, }); } function Sel({ val, opts, onSave }) { return h("select", { className: "lg-inp lg-sel", value: val, onChange: (e) => onSave(e.target.value) }, opts.map(([v, l]) => h("option", { key: v, value: v }, l))); } // ══════════════════ HUB ══════════════════ function LogueHub() { const [view, setView] = useState("home"); const [sel, setSel] = useState(null); const [lead, setLead] = useState(null); const st = useLogue(); const clientes = st.clientes, leads = st.leads; const mrr = clientes.reduce((s, c) => s + c.receita, 0); const recebido = clientes.filter((c) => c.pagamento.status_mes === "pago").reduce((s, c) => s + c.receita, 0); const receber = clientes.filter((c) => c.pagamento.status_mes === "pendente").reduce((s, c) => s + c.receita, 0); const atrasado = clientes.filter((c) => c.pagamento.status_mes === "atrasado").reduce((s, c) => s + c.receita, 0); const pagantes = clientes.filter((c) => c.receita > 0); const ticket = pagantes.length ? Math.round(mrr / pagantes.length) : 0; const byMes = {}; clientes.forEach((c) => (c.pagamento.historico || []).forEach((p) => { if (p.status === "pago") byMes[p.mes] = (byMes[p.mes] || 0) + p.valor; })); const serie = Object.entries(byMes).map(([mes, v]) => ({ mes, v })).sort((a, b) => mesKey(a.mes) - mesKey(b.mes)); const fin = { mrr, recebido, receber, atrasado, ticket, serie }; const pipeline = leads.filter((x) => x.status !== "fechado").reduce((s, x) => s + (x.valor || 0), 0); const totalIdeias = clientes.reduce((s, c) => s + (c.insights ? c.insights.length : 0), 0); const totalTarefas = clientes.reduce((s, c) => s + (c.tarefas || []).filter((t) => t.status !== "concluida").length, 0); const openCli = (c) => setSel(c.id); const selCli = sel ? clientes.find((c) => c.id === sel) : null; const leadObj = lead ? leads.find((l) => l.id === lead) : null; return h("div", { className: "lg" }, h("header", { className: "lg-top" }, h("button", { className: "lg-brand", onClick: () => setView("home") }, h("span", { className: "lg-mark" }, "L"), h("span", null, h("span", { className: "lg-brand-name" }, "Agência Logue"), h("span", { className: "lg-brand-sub" }, "CRM · Financeiro · Produção"))), view !== "home" && h("nav", { className: "lg-nav" }, [["financeiro", "Financeiro"], ["comercial", "Comercial"], ["producao", "Produção"]].map(([k, l]) => h("button", { key: k, className: "lg-nav-btn" + (view === k ? " on" : ""), onClick: () => setView(k) }, l)))), view === "home" && h(Home, { go: setView }), view === "financeiro" && h(Financeiro, { clientes, fin, onOpen: openCli }), view === "comercial" && h(Comercial, { leads, metas: st.metas, onEdit: setLead }), view === "producao" && h(Producao, { clientes, onOpen: openCli }), selCli && h(CliModal, { c: selCli, onClose: () => setSel(null) }), leadObj && h(LeadModal, { l: leadObj, onClose: () => setLead(null) }) ); } // ══════════════════ HOME ══════════════════ function Home({ go }) { const cards = [ { k: "financeiro", emoji: "💰", nome: "Financeiro", desc: "Receita, faturas e pagamentos do mês", tint: "var(--t-sage-bg)", bd: "var(--t-sage-bd)" }, { k: "comercial", emoji: "🎯", nome: "Comercial", desc: "Funil de leads e propostas em negociação", tint: "var(--t-sky-bg)", bd: "var(--t-sky-bd)" }, { k: "producao", emoji: "🎬", nome: "Produção", desc: "Ideias de conteúdo e tarefas por cliente", tint: "var(--t-pink-bg)", bd: "var(--t-pink-bd)" }, ]; return h("div", { className: "lg-home" }, h("div", { className: "lg-home-head" }, h("div", { className: "lg-eyebrow" }, "Agência Logue"), h("h1", { className: "lg-home-title" }, "Onde você quer trabalhar agora?"), h("p", { className: "lg-home-sub" }, "Escolha uma área para começar")), h("div", { className: "lg-home-grid" }, cards.map((c) => h("button", { key: c.k, className: "lg-choice", style: { background: c.tint, borderColor: c.bd }, onClick: () => go(c.k) }, h("div", { className: "lg-choice-emoji" }, c.emoji), h("div", { className: "lg-choice-nome" }, c.nome), h("div", { className: "lg-choice-desc" }, c.desc), h("div", { className: "lg-choice-go" }, "Abrir ", h("span", { "aria-hidden": true }, "→"))))) ); } // ══════════════════ FINANCEIRO ══════════════════ function Financeiro({ clientes, fin, onOpen }) { const maxV = Math.max(...fin.serie.map((s) => s.v), 1); const hoje = new Date(); const meta = 6000, metaPct = Math.min(100, Math.round((fin.mrr / meta) * 100)); return h("div", { className: "lg-page" }, h(SecHead, { title: "Financeiro", sub: "Receita, faturas e pagamentos do mês · edite o status direto na fatura" }), h("div", { className: "lg-kpis" }, [["Recorrente / mês", brl(fin.mrr), AC], ["Recebido no mês", brl(fin.recebido), PAG_COR.pago], ["A receber", brl(fin.receber), PAG_COR.pendente], ["Ticket médio", brl(fin.ticket), "#5F9BD1"]] .map(([l, v, cor]) => h("div", { key: l, className: "lg-kpi" }, h("div", { className: "lg-kpi-dot", style: { background: cor } }), h("div", { className: "lg-kpi-l" }, l), h("div", { className: "lg-kpi-v" }, v)))), h("div", { className: "lg-card" }, h("div", { className: "lg-card-t" }, "Meta de faturamento", h("span", { className: "lg-card-t-r", style: { color: AC } }, metaPct + "% de " + brl(meta))), h("div", { className: "lg-meta-bar" }, h("div", { className: "lg-meta-fill", style: { width: metaPct + "%" } }))), h("div", { className: "lg-2col" }, h("div", { className: "lg-card" }, h("div", { className: "lg-card-t" }, "Receita recebida por mês"), fin.serie.length ? h("div", { className: "lg-chart" }, fin.serie.map((s) => h("div", { key: s.mes, className: "lg-bar-col" }, h("div", { className: "lg-bar-v" }, brl(s.v).replace("R$ ", "")), h("div", { className: "lg-bar-track" }, h("div", { className: "lg-bar-fill", style: { height: Math.round((s.v / maxV) * 100) + "%" } })), h("div", { className: "lg-bar-x" }, s.mes.split("/")[0])))) : h("div", { className: "lg-fcol-empty" }, "sem pagamentos registrados")), h("div", { className: "lg-card" }, h("div", { className: "lg-card-t" }, "Faturas do mês"), h("div", { className: "lg-inv-head" }, h("span", null, "Cliente"), h("span", null, "Vencimento"), h("span", null, "Valor"), h("span", null, "Status")), clientes.slice().sort((a, b) => a.pagamento.dia - b.pagamento.dia).map((c) => { const stt = c.pagamento.status_mes, venc = daysToVenc(c.pagamento.dia, hoje); return h("div", { key: c.id, className: "lg-inv-row" }, h("span", { className: "lg-inv-cli", onClick: () => onOpen(c), style: { cursor: "pointer" } }, h("span", { className: "lg-av sm", style: { background: PAG_BG[stt] } }, ini(c.nome)), c.nome), h("span", { className: "lg-inv-venc" }, "dia " + c.pagamento.dia, (stt === "pendente" || stt === "atrasado") && venc != null && h("span", { className: "lg-inv-in" }, venc >= 0 ? " · em " + venc + "d" : " · " + Math.abs(venc) + "d atrás")), h("span", { className: "lg-inv-val" }, c.receita ? brl(c.receita) : "—"), h("span", null, h(Sel, { val: stt, opts: STATUS_OPTS, onSave: (v) => S().updatePayment(c.id, { status_mes: v }) }))); }), h("div", { className: "lg-inv-total" }, h("span", null, "Total previsto"), h("span", null, brl(fin.mrr))))) , h("div", { className: "lg-mini-label" }, "Clientes ativos"), h("div", { className: "lg-cli-grid" }, clientes.map((c) => { const stt = c.pagamento.status_mes, pend = (c.tarefas || []).filter((t) => t.status !== "concluida").length; return h("button", { key: c.id, className: "lg-cli", onClick: () => onOpen(c) }, h("div", { className: "lg-cli-top" }, h("span", { className: "lg-av", style: { background: (c.cor || AC) } }, ini(c.nome)), h("div", { className: "grow" }, h("div", { className: "lg-cli-nome" }, c.nome), h("div", { className: "lg-cli-setor" }, c.setor)), h("span", { className: "lg-pill", style: { background: PAG_BG[stt], color: PAG_COR[stt] } }, PAG_LABEL[stt])), h("div", { className: "lg-cli-row" }, h("div", { className: "lg-cli-metric" }, h("span", null, "Receita/mês"), h("b", null, c.receita ? brl(c.receita) : "permuta")), h("div", { className: "lg-cli-metric" }, h("span", null, "Vencimento"), h("b", null, "dia " + c.pagamento.dia)), h("div", { className: "lg-cli-metric" }, h("span", null, "Pendências"), h("b", null, pend))), h("div", { className: "lg-cli-pac" }, c.pacote)); }), h("button", { className: "lg-cli lg-cli-add", onClick: () => S().addClient() }, h("span", null, "+"), h("span", null, "Adicionar cliente")) ) ); } function daysToVenc(dia, hoje) { const d = new Date(hoje.getFullYear(), hoje.getMonth(), dia); return Math.round((d - new Date(hoje.getFullYear(), hoje.getMonth(), hoje.getDate())) / 86400000); } // ══════════════════ COMERCIAL (funil arrastável + editável) ══════════════════ const CRM_COLS = [["potencial", "Potencial", "#8E86A8"], ["em_contato", "Em contato", "#5F9BD1"], ["negociando", "Negociando", "#C77D2E"], ["fechado", "Fechado", "#3F9E6B"]]; // ── Metas do dia: pequenas ações pra prospectar e aumentar o lucro ── function MetasDia({ metas, editMetas, setEditMetas }) { const itens = (metas && metas.itens) || []; const feitos = itens.filter((x) => x.done).length; const pct = itens.length ? Math.round((feitos / itens.length) * 100) : 0; return h("div", { className: "lg-metas" }, h("div", { className: "lg-metas-head" }, h("div", null, h("div", { className: "lg-metas-t" }, "🎯 Metas do dia"), h("div", { className: "lg-metas-sub" }, "Pequenas ações pra prospectar todo dia e aumentar o lucro · zeram sozinhas amanhã")), h("div", { className: "lg-metas-right" }, h("div", { className: "lg-metas-count" }, feitos + "/" + itens.length), h("button", { className: "lg-metas-edit", onClick: () => setEditMetas((v) => !v) }, editMetas ? "Concluir" : "Editar"))), h("div", { className: "lg-metas-bar" }, h("div", { className: "lg-metas-fill", style: { width: pct + "%" } })), h("div", { className: "lg-metas-list" }, itens.map((m) => h("div", { key: m.id, className: "lg-meta" + (m.done ? " done" : "") }, h("button", { className: "lg-meta-chk", onClick: () => S().toggleMeta(m.id), "aria-label": "concluir" }, m.done ? "✓" : ""), editMetas ? h(Inp, { val: m.t, onSave: (v) => S().updateMeta(m.id, v) }) : h("span", { className: "lg-meta-t", onClick: () => S().toggleMeta(m.id) }, m.t), editMetas && h("button", { className: "lg-meta-del", onClick: () => S().deleteMeta(m.id), title: "remover" }, "✕"))), editMetas && h("button", { className: "lg-add-btn", onClick: () => S().addMeta() }, "+ Nova ação")), pct === 100 && itens.length > 0 && h("div", { className: "lg-metas-win" }, "Todas as metas do dia batidas — é assim que o lucro cresce 💪")); } function Comercial({ leads, metas, onEdit }) { const [drag, setDrag] = useState(null); const [over, setOver] = useState(null); const [editMetas, setEditMetas] = useState(false); const pipeline = leads.filter((x) => x.status !== "fechado").reduce((s, x) => s + (x.valor || 0), 0); const fechado = leads.filter((x) => x.status === "fechado").reduce((s, x) => s + (x.valor || 0), 0); const dropCol = (st) => { if (drag) { S().moveLead(drag, st); S().reorderLead(drag, null); } setDrag(null); setOver(null); }; const dropCard = (e, st, beforeId) => { e.stopPropagation(); if (drag) { S().moveLead(drag, st); S().reorderLead(drag, beforeId); } setDrag(null); setOver(null); }; return h("div", { className: "lg-page" }, h(SecHead, { title: "Comercial", sub: "Arraste os cards entre etapas · clique pra editar · +Novo lead em cada coluna" }), h("div", { className: "lg-kpis three" }, h("div", { className: "lg-kpi" }, h("div", { className: "lg-kpi-l" }, "Em negociação"), h("div", { className: "lg-kpi-v" }, brl(pipeline))), h("div", { className: "lg-kpi" }, h("div", { className: "lg-kpi-l" }, "Fechado"), h("div", { className: "lg-kpi-v", style: { color: PAG_COR.pago } }, brl(fechado))), h("div", { className: "lg-kpi" }, h("div", { className: "lg-kpi-l" }, "Oportunidades"), h("div", { className: "lg-kpi-v" }, leads.length))), h(MetasDia, { metas, editMetas, setEditMetas }), h("div", { className: "lg-funil" }, CRM_COLS.map(([st, label, cor]) => { const inCol = leads.filter((x) => x.status === st); return h("div", { key: st, className: "lg-fcol" + (over === st ? " over" : ""), onDragOver: (e) => { e.preventDefault(); setOver(st); }, onDragLeave: () => setOver((o) => (o === st ? null : o)), onDrop: () => dropCol(st), }, h("div", { className: "lg-fcol-head" }, h("span", { className: "lg-fdot", style: { background: cor } }), h("span", null, label), h("span", { className: "lg-fcount" }, inCol.length)), h("div", { className: "lg-fcol-body" }, inCol.map((x) => h("div", { key: x.id, className: "lg-fcard" + (drag === x.id ? " dragging" : ""), draggable: true, style: { borderLeftColor: cor }, onDragStart: () => setDrag(x.id), onDragEnd: () => { setDrag(null); setOver(null); }, onDrop: (e) => dropCard(e, st, x.id), onClick: () => onEdit(x.id), }, h("div", { className: "lg-fcard-top" }, h("span", { className: "lg-fcard-nome" }, x.nome), x.valor ? h("span", { className: "lg-fcard-val" }, brl(x.valor)) : null), x.proposta && h("div", { className: "lg-fcard-prop" }, x.proposta), x.proxima && h("div", { className: "lg-fcard-prox" }, "→ " + x.proxima), x.followup && h("div", { className: "lg-fcard-fu" }, "⏰ follow-up " + x.followup))), h("button", { className: "lg-add-btn", onClick: () => onEdit(S().addLead(st)) }, "+ Novo lead")) ); })) ); } // ══════════════════ PRODUÇÃO ══════════════════ function Producao({ clientes, onOpen }) { return h("div", { className: "lg-page" }, h(SecHead, { title: "Produção", sub: "Ideias e tarefas por cliente · arraste tarefas pra reordenar · tudo editável" }), h("div", { className: "lg-prod" }, clientes.map((c) => h(ProdCli, { key: c.id, c, onOpen }))) ); } const STORY_POOL = [ { t: "Bastidor com propósito", s: "Mostre 15s de um momento real do dia + 1 frase do porquê você faz isso. Fecha com pergunta na caixinha." }, { t: "Mini-aula de 3 slides", s: "Ensine 1 coisa útil do nicho em 3 stories. No último, convide: \"quer que eu faça isso pra você? me chama\"." }, { t: "Prova social leve", s: "Print de um elogio/resultado + sua reação humana. Sem discurso de venda — só gratidão e contexto." }, { t: "Antes & depois", s: "Um antes/depois do trabalho ou rotina. Termine com CTA suave: \"tem algo assim que você quer melhorar?\"." }, { t: "Enquete de valor", s: "Pergunte algo que revela dor do público (2 opções). Amanhã, responda com dica — vira autoridade." }, { t: "Você por dentro", s: "Conte 1 escolha/valor da marca em tom de conversa. Aproxima sem parecer institucional." }, { t: "Oferta sem peso", s: "Mostre um detalhe do serviço/produto em uso + \"tem vaga essa semana\". Uma vez só, natural." }, ]; function storyOfDay(cid) { const seed = new Date().getDate() + (cid || "").split("").reduce((a, ch) => a + ch.charCodeAt(0), 0); return STORY_POOL[seed % STORY_POOL.length]; } function ProdCli({ c, onOpen }) { const [drag, setDrag] = useState(null); const pend = (c.tarefas || []).filter((t) => t.status !== "concluida"); const tasks = c.tarefas || []; const story = storyOfDay(c.id); return h("div", { className: "lg-prod-cli" }, h("div", { className: "lg-prod-head" }, h("span", { className: "lg-av", style: { background: (c.cor || AC) } }, ini(c.nome)), h("div", { className: "grow" }, h("div", { className: "lg-cli-nome" }, c.nome), h("div", { className: "lg-cli-setor" }, c.pacote)), h("button", { className: "lg-prod-open", onClick: () => onOpen(c) }, "Ver cliente →")), h("div", { className: "lg-story" }, h("div", { className: "lg-story-l" }, h("span", { className: "lg-story-ic" }, "🎬"), h("span", null, "Roteiro de story do dia")), h("div", { className: "lg-story-t" }, story.t), h("p", { className: "lg-story-s" }, story.s), h("div", { className: "lg-story-tag" }, "autoridade + monetização · tom leve, nada comercial demais")), h("div", { className: "lg-prod-cols" }, h("div", null, h("div", { className: "lg-prod-col-t" }, "💡 Ideias de conteúdo", h("span", { className: "lg-fcount" }, (c.insights || []).length)), h("div", { className: "lg-fmt-hint" }, "Base é vídeo (6/mês), mas varie: 🎥 vídeo · 🖼️ estático · 🎠 carrossel"), (c.insights || []).map((ins, i) => h("div", { key: i, className: "lg-idea lg-idea-edit" }, h("div", { className: "lg-idea-top" }, h(Inp, { val: ins.titulo, className: "lg-idea-tt", onSave: (v) => S().updateIdea(c.id, i, { titulo: v }) }), h(Inp, { val: ins.custo, className: "lg-idea-cc", onSave: (v) => S().updateIdea(c.id, i, { custo: v }) }), h("button", { className: "lg-x", title: "excluir", onClick: () => S().deleteIdea(c.id, i) }, "✕")), h(Inp, { val: ins.ideia, area: true, placeholder: "descreva a ideia…", onSave: (v) => S().updateIdea(c.id, i, { ideia: v }) }))), h("button", { className: "lg-add-btn", onClick: () => S().addIdea(c.id) }, "+ Nova ideia")), h("div", null, h("div", { className: "lg-prod-col-t" }, "📋 Tarefas", h("span", { className: "lg-fcount" }, pend.length)), h("div", null, tasks.map((t) => h("div", { key: t.id, className: "lg-ptask" + (drag === t.id ? " dragging" : "") + (t.status === "concluida" ? " done" : ""), draggable: true, onDragStart: () => setDrag(t.id), onDragEnd: () => setDrag(null), onDragOver: (e) => e.preventDefault(), onDrop: (e) => { e.preventDefault(); if (drag && drag !== t.id) S().reorderTask(c.id, drag, t.id); setDrag(null); }, }, h("span", { className: "lg-drag" }, "⠿"), h("button", { className: "lg-chk" + (t.status === "concluida" ? " on" : ""), onClick: () => S().toggleTask(c.id, t.id) }, t.status === "concluida" ? "✓" : ""), h(Inp, { val: t.titulo, className: "grow lg-task-tt", onSave: (v) => S().updateTask(c.id, t.id, { titulo: v }) }), h(Inp, { val: t.deadline, className: "lg-task-dd", placeholder: "dd/mm", onSave: (v) => S().updateTask(c.id, t.id, { deadline: v }) }), h("button", { className: "lg-x", title: "excluir", onClick: () => S().deleteTask(c.id, t.id) }, "✕")))), h("button", { className: "lg-add-btn", onClick: () => S().addTask(c.id) }, "+ Nova tarefa")) ) ); } function SecHead({ title, sub }) { return h("div", { className: "lg-sec-head" }, h("h2", { className: "lg-sec-title" }, title), h("p", { className: "lg-sec-sub" }, sub)); } // ══════════════════ MODAL DE LEAD (editável) ══════════════════ const TIPO_OPTS = [["marca", "Marca"], ["influencer", "Influencer"], ["collab", "Collab"]]; const LEAD_STATUS = CRM_COLS.map(([v, l]) => [v, l]); function LeadModal({ l, onClose }) { const [edit, setEdit] = useState(false); const up = (patch) => S().updateLead(l.id, patch); const stLabel = (LEAD_STATUS.find(([v]) => v === l.status) || ["", l.status])[1]; const tpLabel = (TIPO_OPTS.find(([v]) => v === l.tipo) || ["", l.tipo])[1]; const ro = (label, val) => h("div", { className: "lg-frow" }, h("span", { className: "lg-frow-l" }, label), h("div", { className: "lg-ro" }, val || "—")); return h("div", { className: "lg-modal-bg", onClick: onClose }, h("div", { className: "lg-modal", onClick: (e) => e.stopPropagation() }, h("button", { className: "lg-modal-x", onClick: onClose }, "✕"), h("div", { className: "lg-modal-head" }, h("h2", { className: "lg-modal-title" }, edit ? "Editar lead" : l.nome), !edit && h("button", { className: "lg-edit-btn", onClick: () => setEdit(true) }, "✎ Editar")), edit ? h("div", { className: "lg-form" }, h(FRow, { label: "Nome" }, h(Inp, { val: l.nome, onSave: (v) => up({ nome: v }) })), h("div", { className: "lg-form-2" }, h(FRow, { label: "Etapa" }, h(Sel, { val: l.status, opts: LEAD_STATUS, onSave: (v) => up({ status: v }) })), h(FRow, { label: "Tipo" }, h(Sel, { val: l.tipo, opts: TIPO_OPTS, onSave: (v) => up({ tipo: v }) }))), h(FRow, { label: "Valor (R$)" }, h(Inp, { val: l.valor, type: "number", onSave: (v) => up({ valor: v }) })), h(FRow, { label: "Proposta" }, h(Inp, { val: l.proposta, area: true, onSave: (v) => up({ proposta: v }) })), h(FRow, { label: "Próxima ação" }, h(Inp, { val: l.proxima, onSave: (v) => up({ proxima: v }) })), h(FRow, { label: "Follow-up" }, h(Inp, { val: l.followup, placeholder: "ex: amanhã", onSave: (v) => up({ followup: v }) })), h(FRow, { label: "Notas" }, h(Inp, { val: l.notas, area: true, onSave: (v) => up({ notas: v }) }))) : h("div", { className: "lg-form" }, h("div", { className: "lg-form-2" }, ro("Etapa", stLabel), ro("Tipo", tpLabel)), ro("Valor", l.valor ? brl(l.valor) : "—"), ro("Proposta", l.proposta), ro("Próxima ação", l.proxima), ro("Follow-up", l.followup), ro("Notas", l.notas)), h("div", { className: "lg-form-foot" }, h("button", { className: "lg-del", onClick: () => { S().deleteLead(l.id); onClose(); } }, "Excluir lead"), edit ? h("button", { className: "lg-done", onClick: () => setEdit(false) }, "Salvar") : h("button", { className: "lg-done", onClick: onClose }, "Fechar")) ) ); } function FRow({ label, children }) { return h("label", { className: "lg-frow" }, h("span", { className: "lg-frow-l" }, label), children); } // ══════════════════ MODAL DE CLIENTE (editável) ══════════════════ function CliModal({ c, onClose }) { const stt = c.pagamento.status_mes; const up = (patch) => S().updateClient(c.id, patch); const upP = (patch) => S().updatePayment(c.id, patch); return h("div", { className: "lg-modal-bg", onClick: onClose }, h("div", { className: "lg-modal", onClick: (e) => e.stopPropagation() }, h("button", { className: "lg-modal-x", onClick: onClose }, "✕"), h("div", { className: "lg-modal-head" }, h("span", { className: "lg-av lg-big", style: { background: (c.cor || AC) } }, ini(c.nome)), h("div", { className: "grow" }, h(Inp, { val: c.nome, className: "lg-modal-name", onSave: (v) => up({ nome: v }) }), h(Inp, { val: c.setor, className: "lg-modal-setor", placeholder: "setor / segmento", onSave: (v) => up({ setor: v }) }))), h("div", { className: "lg-form-2" }, h(FRow, { label: "Receita / mês (R$)" }, h(Inp, { val: c.receita, type: "number", onSave: (v) => up({ receita: v }) })), h(FRow, { label: "Status do mês" }, h(Sel, { val: stt, opts: STATUS_OPTS, onSave: (v) => upP({ status_mes: v }) }))), h("div", { className: "lg-form-2" }, h(FRow, { label: "Dia de vencimento" }, h(Inp, { val: c.pagamento.dia, type: "number", onSave: (v) => upP({ dia: v }) })), h(FRow, { label: "Cliente desde" }, h(Inp, { val: c.inicio, onSave: (v) => up({ inicio: v }) }))), h(FRow, { label: "Contato / respons\u00e1veis" }, h(Inp, { val: c.contato, placeholder: "nome dos respons\u00e1veis", onSave: (v) => up({ contato: v }) })), h(FRow, { label: "Pacote" }, h(Inp, { val: c.pacote, onSave: (v) => up({ pacote: v }) })), h("div", { className: "lg-msec", style: { marginTop: 20 } }, h("div", { className: "lg-msec-t" }, "Histórico de pagamento"), (c.pagamento.historico || []).length ? (c.pagamento.historico || []).map((p, i) => h("div", { key: i, className: "lg-pay" }, h("span", null, p.mes), h("span", { className: "lg-pay-v" }, p.valor ? brl(p.valor) : "—"), h("span", { className: "lg-pill", style: { background: PAG_BG[p.status], color: PAG_COR[p.status] } }, PAG_LABEL[p.status]), h("span", { className: "lg-pay-d" }, p.data))) : h("div", { className: "lg-fcol-empty" }, "sem histórico ainda")), c.influencers && h("div", { className: "lg-msec" }, h("div", { className: "lg-msec-t" }, "Agenda de influencers"), h("div", { className: "lg-inf-grid" }, c.influencers.map((x, i) => h("div", { key: i, className: "lg-inf" + (x.vazio ? " empty" : "") }, h("div", { className: "lg-inf-dia" }, x.dia), x.vazio ? h("div", { className: "lg-inf-livre" }, "livre") : h("div", null, h("div", { className: "lg-inf-nome" }, x.nome), h("div", { className: "lg-inf-tipo" }, x.tipo)))))), h("div", { className: "lg-msec" }, h("div", { className: "lg-msec-t" }, "Tarefas"), (c.tarefas || []).map((t) => h("div", { key: t.id, className: "lg-task" }, h("button", { className: "lg-chk" + (t.status === "concluida" ? " on" : ""), onClick: () => S().toggleTask(c.id, t.id) }, t.status === "concluida" ? "✓" : ""), h(Inp, { val: t.titulo, className: "grow lg-task-tt", onSave: (v) => S().updateTask(c.id, t.id, { titulo: v }) }), h(Inp, { val: t.deadline, className: "lg-task-dd", placeholder: "dd/mm", onSave: (v) => S().updateTask(c.id, t.id, { deadline: v }) }), h("button", { className: "lg-x", onClick: () => S().deleteTask(c.id, t.id) }, "✕"))), h("button", { className: "lg-add-btn", onClick: () => S().addTask(c.id) }, "+ Nova tarefa")), h("div", { className: "lg-form-foot" }, h("button", { className: "lg-del", onClick: () => { if (confirm("Excluir " + c.nome + "?")) { S().deleteClient(c.id); onClose(); } } }, "Excluir cliente"), h("button", { className: "lg-done", onClick: onClose }, "Concluído")) ) ); } Object.assign(window, { LogueHub }); })();