/* global React */ const { useState, useEffect, useRef } = React; // ===================================================================== // MODAL DE LOGIN (fullscreen, bloqueante) // ===================================================================== function LoginModal({ onSuccess }) { const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [err, setErr] = useState(''); const [busy, setBusy] = useState(false); const emailRef = useRef(null); useEffect(() => { setTimeout(() => emailRef.current?.focus(), 100); }, []); const submit = async () => { if (!email || !password) { setErr('Informe email e senha.'); return; } setErr(''); setBusy(true); try { await window.sb.signIn(email, password); setPassword(''); onSuccess(); } catch (e) { setErr(e.message || 'Credenciais inválidas.'); } finally { setBusy(false); } }; const onKey = (e) => { if (e.key === 'Enter') submit(); }; return (
af
Calculadora Fiscal
Acesso restrito · Lucro Real
setEmail(e.target.value)} onKeyDown={onKey} placeholder="usuario@agenflex.com" />
setPassword(e.target.value)} onKeyDown={onKey} placeholder="••••••••" />
{err &&
{err}
}
); } window.LoginModal = LoginModal; // ===================================================================== // LOADING OVERLAY GLOBAL // ===================================================================== function LoadingOverlay({ text }) { return (
{text || 'Carregando…'}
); } window.LoadingOverlay = LoadingOverlay; // ===================================================================== // MODAL DE CONFIRMAÇÃO GENÉRICO (substitui confirm() nativo) // ===================================================================== function ConfirmModal({ open, title, message, okLabel = 'Confirmar', cancelLabel = 'Cancelar', danger = false, onOk, onCancel }) { useEffect(() => { if (!open) return; const onKey = (e) => { if (e.key === 'Escape') onCancel?.(); if (e.key === 'Enter') onOk?.(); }; document.addEventListener('keydown', onKey); return () => document.removeEventListener('keydown', onKey); }, [open, onOk, onCancel]); if (!open) return null; return (
{title}
{message}
); } window.ConfirmModal = ConfirmModal; // ===================================================================== // CLOUD HELPERS: salvar, listar, visualizar, deletar // ===================================================================== window.cloud = { // --- Salvar simulação --- async saveSim(state, calc) { const v = state.venda; const c = calc; const prod = state.produtos.find(p => p.id === v.produtoId); const payload = { produto_nome: prod?.nome || '(sem produto)', produto_snapshot_id: null, qtd: v.qtd || 0, valor_total: v.valor || 0, uf_destino: v.uf, contribuinte: v.contrib === 'SIM', marketplace: v.mkt === 'SIM', comissao_pct: v.mkt === 'SIM' ? v.comissao : null, com_ipi: v.ipi === 'SIM', cmv_unit: +(c.cmvUn || 0).toFixed(4), lucro_liq: +(c.dre.lucroLiq || 0).toFixed(2), margem_liq: +(c.kpi.margemLiq || 0).toFixed(4), carga_trib: +(c.kpi.cargaTrib || 0).toFixed(4), tributos_total: +(c.kpi.tributos || 0).toFixed(2), dre_snapshot: { valorNota: c.dre.valorNota, ipi: c.dre.ipi, receitaBruta: c.dre.receitaBruta, icmsDeb: c.dre.icmsDeb, pis: c.dre.pis, cofins: c.dre.cofins, difal: c.dre.difal, receitaLiq: c.dre.receitaLiq, cmvTotal: c.dre.cmvTotal, lucroBruto: c.dre.lucroBruto, comissao: c.dre.comissao, custosFixos: c.dre.custosFixos, lucroAntesIR: c.dre.lucroAntesIR, irpj: c.dre.irpj, csll: c.dre.csll, lucroLiq: c.dre.lucroLiq, isNaoContrib: c.isNaoContrib, baseICMS: c.baseICMS, basePisCofins: c.basePisCofins, aliqICMS: c.aliqICMS, aliqInterna: c.aliqInterna, }, params_snapshot: { ...state.params }, versao_payload: 1, notas: null, }; const data = await window.sb.insert('simulations', payload); return data && data[0]; }, // --- Salvar versão de produto --- async saveProduto(produto, params) { const c = window.calcProduto(produto, params); const ncmDoXml = (produto.nf.xmlInfo && Array.isArray(produto.nf.xmlInfo.ncms) && produto.nf.xmlInfo.ncms.length > 0) ? produto.nf.xmlInfo.ncms[0] : null; const payload = { nome: produto.nome, ncm: ncmDoXml, mp_kg_dia: produto.prod.mpKg || 0, qtd_dia: produto.prod.qtd || 0, nf_valor: produto.nf.valor || 0, nf_kg: produto.nf.kg || 0, nf_icms: produto.nf.icms || 0, nf_ipi: produto.nf.ipi || 0, nf_simples: produto.nf.simples === 'SIM', nf_frete: produto.nf.frete || 0, nf_seguro: produto.nf.seguro || 0, nf_outras: produto.nf.outras || 0, nf_desconto: produto.nf.desconto || 0, nf_xml_info: produto.nf.xmlInfo || null, insumos: (produto.insumos || []).map(i => ({ nome: i.nome, valor: i.valor || 0, credPC: !!i.credPC, credICMS: !!i.credICMS, aliqICMS: i.aliqICMS || 0, nota: i.nota || '', custom: !!i.custom, })), cmv_calc: +(c.cmv.cmvUn || 0).toFixed(4), versao_payload: 1, notas: null, }; const data = await window.sb.insert('product_versions', payload); return data && data[0]; }, // --- Listar simulações --- async listSims() { return window.sb.select('simulations', 'select=id,seq,produto_nome,qtd,valor_total,uf_destino,marketplace,cmv_unit,lucro_liq,margem_liq,carga_trib,created_at&order=seq.desc&limit=200'); }, async getSim(simId) { const arr = await window.sb.select('simulations', `id=eq.${simId}&select=*`); if (!arr || !arr.length) throw new Error('Simulação não encontrada'); return arr[0]; }, async deleteSim(simId) { return window.sb.del('simulations', `id=eq.${simId}`); }, // --- Listar produtos --- async listProds() { return window.sb.select('product_versions', 'select=id,seq,nome,ncm,mp_kg_dia,qtd_dia,nf_valor,nf_kg,cmv_calc,created_at&order=seq.desc&limit=200'); }, async getProd(prodId) { const arr = await window.sb.select('product_versions', `id=eq.${prodId}&select=*`); if (!arr || !arr.length) throw new Error('Produto não encontrado'); return arr[0]; }, async deleteProd(prodId) { return window.sb.del('product_versions', `id=eq.${prodId}`); }, };