mport { useState, useEffect } from "react"; import { Plus, TrendingUp, AlertTriangle, DollarSign, Target, Zap, X, Check, Activity, Edit3 } from "lucide-react"; // ===== CONFIG INICIAL ===== const DEFAULT_CONFIG = { metaLiquida: 10000, }; // ===== HELPERS ===== const fmt = (n) => `R$ ${Number(n).toLocaleString("pt-BR", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`; const today = () => new Date().toISOString().slice(0, 10); const parseBRDate = (d) => { if (!d) return ""; return d.split("-").reverse().join("/"); }; export default function Dashboard() { const [loading, setLoading] = useState(true); const [config, setConfig] = useState(DEFAULT_CONFIG); const [dias, setDias] = useState([]); // { data, vendas, gasto, contasAtivas } const [tab, setTab] = useState("hoje"); const [showConfig, setShowConfig] = useState(false); const [showEditDia, setShowEditDia] = useState(false); const [editDate, setEditDate] = useState(today()); // Carregar do storage useEffect(() => { (async () => { try { const c = await window.storage.get("cerebro_v2:config"); if (c) setConfig(JSON.parse(c.value)); } catch {} try { const d = await window.storage.get("cerebro_v2:dias"); if (d) setDias(JSON.parse(d.value)); } catch {} setLoading(false); })(); }, []); // Salvar const save = async (key, val) => { try { await window.storage.set(`cerebro_v2:${key}`, JSON.stringify(val)); } catch (e) { console.error(e); } }; useEffect(() => { if (!loading) save("config", config); }, [config, loading]); useEffect(() => { if (!loading) save("dias", dias); }, [dias, loading]); // ===== CÁLCULOS ===== const hoje = today(); const inicioMes = hoje.slice(0, 7) + "-01"; const getDia = (data) => dias.find((d) => d.data === data) || { data, vendas: 0, gasto: 0, contasAtivas: 0 }; const hojeAtivo = getDia(hoje); const diasMes = dias.filter((d) => d.data >= inicioMes); const fatMes = diasMes.reduce((s, d) => s + d.vendas, 0); const gastoMes = diasMes.reduce((s, d) => s + d.gasto, 0); const lucroMes = fatMes - gastoMes; const lucroHoje = hojeAtivo.vendas - hojeAtivo.gasto; const progressoMeta = (lucroMes / config.metaLiquida) * 100; const diasNoMes = new Date(new Date().getFullYear(), new Date().getMonth() + 1, 0).getDate(); const diaAtual = new Date().getDate(); const diasRestantes = diasNoMes - diaAtual + 1; const lucroFaltando = config.metaLiquida - lucroMes; // Projeção const mediaLucroDia = diasMes.length > 0 ? (lucroMes / diasMes.length) : 0; const projecaoMes = lucroMes + (mediaLucroDia * diasRestantes); // ===== AÇÕES ===== const saveDia = (dataInput) => { const novos = dias.filter((d) => d.data !== dataInput.data); novos.push(dataInput); novos.sort((a, b) => b.data.localeCompare(a.data)); // Ordena decrescente setDias(novos); setShowEditDia(false); }; const openEdit = (data = hoje) => { setEditDate(data); setShowEditDia(true); }; if (loading) { return (
carregando cérebro...
); } return (
{/* HEADER */}
CÉREBRO.OPS
painel de comando · {new Date().toLocaleDateString("pt-BR", { weekday: "long", day: "numeric", month: "long" })}
{/* TABS */}
{/* ===== HOJE ===== */} {tab === "hoje" && ( <>
lucro hoje
{fmt(lucroHoje)}
{fmt(hojeAtivo.vendas)} faturamento · {fmt(hojeAtivo.gasto)} custo
{hojeAtivo.vendas === 0 && hojeAtivo.gasto === 0 && (
)}
resumo rápido do mês
Lucro Acumulado
{fmt(lucroMes)} ({(progressoMeta).toFixed(1)}% da meta)
)} {/* ===== META ===== */} {tab === "meta" && ( <>
progresso da meta · {fmt(config.metaLiquida)} líquido
{progressoMeta.toFixed(1)}%
{fmt(lucroMes)} de lucro · faltam {fmt(Math.max(0, lucroFaltando))}
= config.metaLiquida} />
caminho até 100k
{((lucroMes / 100000) * 100).toFixed(2)}%
de 100k líquido
no ritmo atual: {mediaLucroDia > 0 ? `~${(100000 / (mediaLucroDia * 30)).toFixed(1)} meses` : '—'} · faltam {fmt(100000 - lucroMes)}
)} {/* ===== HISTORICO ===== */} {tab === "historico" && ( <>
{dias.length}
dias registrados
histórico de dias
{dias.length === 0 ? (
nenhum registro. edite os dados de hoje para começar.
) : (
{dias.map((d) => { const l = d.vendas - d.gasto; return (
= 0 ? "#84cc16" : "#ef4444"}` }} onClick={() => openEdit(d.data)} role="button" tabIndex={0}>
{parseBRDate(d.data)} {d.data === hoje ? "(hoje)" : ""}
faturou {fmt(d.vendas)} · gastou {fmt(d.gasto)}
= 0 ? "#84cc16" : "#ef4444" }}>{fmt(l)}
{d.contasAtivas || 0} contas ativas
); })}
)}
)}
{/* MODAIS */} {showEditDia && ( setShowEditDia(false)} title={`atualizar dia`}> setShowEditDia(false)} /> )} {showConfig && ( setShowConfig(false)} title="configuração"> { setConfig(c); setShowConfig(false); }} onCancel={() => setShowConfig(false)} /> )}
); } // ===== COMPONENTES ===== function KPI({ label, value, highlight, negative }) { return (
{label}
{value}
); } function Modal({ children, onClose, title }) { return (
e.stopPropagation()}>
{title}
{children}
); } function FormDia({ dia, onSubmit, onCancel }) { const [dataInput, setDataInput] = useState(dia); useEffect(() => { setDataInput(dia); }, [dia]); return (
setDataInput({ ...dataInput, data: e.target.value })} /> setDataInput({ ...dataInput, vendas: Number(e.target.value) })} /> setDataInput({ ...dataInput, gasto: Number(e.target.value) })} /> setDataInput({ ...dataInput, contasAtivas: Number(e.target.value) })} />
); } function FormConfig({ config, onSubmit, onCancel }) { const [c, setC] = useState(config); return (
setC({ ...c, metaLiquida: Number(e.target.value) })} />
); } // ===== ESTILOS ===== const globalCSS = ` * { box-sizing: border-box; margin: 0; padding: 0; } body { background: #0a0a0a; } @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.4; } } @keyframes slideIn { from { transform: translateY(20px); opacity: 0; } to { transform: translateY(0); opacity: 1; } } button { cursor: pointer; transition: all 0.15s ease; } button:hover:not(:disabled) { transform: translateY(-1px); } button:disabled { opacity: 0.4; cursor: not-allowed; } input, select { font-family: inherit; } `; const styles = { app: { minHeight: "100vh", background: "#0a0a0a", color: "#fff", fontFamily: "'JetBrains Mono', 'IBM Plex Mono', ui-monospace, monospace", padding: 16, maxWidth: 1100, margin: "0 auto", }, header: { display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 24, paddingBottom: 16, borderBottom: "1px solid #1a1a1a", }, brand: { fontSize: 22, fontWeight: 800, letterSpacing: "-0.02em", display: "flex", alignItems: "center", gap: 8, }, brandPulse: { width: 8, height: 8, background: "#84cc16", borderRadius: "50%", animation: "pulse 2s infinite", }, subbrand: { fontSize: 11, color: "#666", marginTop: 4, textTransform: "lowercase" }, configBtn: { background: "transparent", border: "1px solid #2a2a2a", color: "#888", padding: "6px 12px", fontSize: 11, fontFamily: "inherit", borderRadius: 4, }, tabs: { display: "flex", gap: 4, marginBottom: 24, overflowX: "auto" }, tab: { background: "transparent", border: "1px solid #1a1a1a", color: "#666", padding: "8px 14px", fontSize: 12, fontFamily: "inherit", borderRadius: 4, display: "flex", alignItems: "center", gap: 6, }, tabActive: { background: "#84cc16", borderColor: "#84cc16", color: "#0a0a0a", fontWeight: 700 }, main: { animation: "slideIn 0.3s ease" }, heroCard: { background: "linear-gradient(135deg, #111 0%, #0f0f0f 100%)", border: "1px solid #1f1f1f", borderRadius: 12, padding: 24, marginBottom: 16, position: "relative", overflow: "hidden", }, heroLabel: { fontSize: 11, color: "#666", textTransform: "uppercase", letterSpacing: "0.1em", marginBottom: 12 }, heroNum: { fontSize: 56, fontWeight: 800, letterSpacing: "-0.04em", lineHeight: 1, color: "#fff" }, heroUnit: { fontSize: 18, color: "#666", marginLeft: 8, fontWeight: 400 }, heroDetail: { fontSize: 13, color: "#888", marginTop: 8 }, heroBar: { height: 4, background: "#1a1a1a", borderRadius: 2, marginTop: 16, overflow: "hidden" }, heroBarFill: { height: "100%", background: "linear-gradient(90deg, #84cc16, #a3e635)", transition: "width 0.5s ease" }, actionsGrid: { display: "grid", gridTemplateColumns: "1fr", gap: 8, marginBottom: 24 }, bigAction: { background: "#84cc16", color: "#0a0a0a", border: "none", borderRadius: 8, padding: 16, fontFamily: "inherit", display: "flex", alignItems: "center", gap: 12, textAlign: "left", }, bigActionTitle: { fontSize: 13, fontWeight: 700, textTransform: "lowercase" }, bigActionSub: { fontSize: 11, opacity: 0.7, marginTop: 2 }, section: { background: "#0f0f0f", border: "1px solid #1a1a1a", borderRadius: 8, padding: 16, marginBottom: 12, }, sectionTitle: { fontSize: 11, color: "#666", textTransform: "uppercase", letterSpacing: "0.1em", marginBottom: 12 }, empty: { color: "#555", fontSize: 12, fontStyle: "italic", padding: "12px 0" }, list: { display: "flex", flexDirection: "column", gap: 6 }, listItem: { background: "#161616", padding: "10px 12px", borderRadius: 6, display: "flex", alignItems: "center", justifyContent: "space-between", gap: 12, cursor: "pointer", transition: "background 0.1s ease", }, listItemSub: { fontSize: 11, color: "#666", marginTop: 2 }, iconBtn: { background: "transparent", border: "none", color: "#666", padding: 4, borderRadius: 4, display: "flex", }, kpiGrid: { display: "grid", gridTemplateColumns: "repeat(auto-fill, minmax(160px, 1fr))", gap: 8, marginBottom: 16 }, kpi: { background: "#0f0f0f", border: "1px solid #1a1a1a", borderRadius: 8, padding: 14 }, kpiLabel: { fontSize: 10, color: "#666", textTransform: "uppercase", letterSpacing: "0.08em", marginBottom: 6 }, kpiVal: { fontSize: 20, fontWeight: 700, letterSpacing: "-0.02em" }, contasHeader: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 16, background: "#0f0f0f", border: "1px solid #1a1a1a", borderRadius: 8, padding: 16, }, bigNum: { fontSize: 40, fontWeight: 800, letterSpacing: "-0.03em", lineHeight: 1 }, subLabel: { fontSize: 11, color: "#666", marginTop: 4 }, primaryBtn: { background: "#84cc16", color: "#0a0a0a", border: "none", padding: "8px 14px", borderRadius: 6, fontWeight: 700, fontSize: 12, fontFamily: "inherit", display: "flex", alignItems: "center", gap: 6, }, secondaryBtn: { background: "transparent", border: "1px solid #2a2a2a", color: "#888", padding: "8px 14px", borderRadius: 6, fontSize: 12, fontFamily: "inherit", }, modalBg: { position: "fixed", inset: 0, background: "rgba(0,0,0,0.7)", backdropFilter: "blur(4px)", display: "flex", alignItems: "center", justifyContent: "center", zIndex: 100, padding: 16, }, modal: { background: "#0f0f0f", border: "1px solid #2a2a2a", borderRadius: 12, padding: 20, width: "100%", maxWidth: 380, animation: "slideIn 0.2s ease", }, modalHeader: { display: "flex", justifyContent: "space-between", alignItems: "center", marginBottom: 16 }, modalTitle: { fontSize: 14, fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.05em" }, form: { display: "flex", flexDirection: "column", gap: 8 }, label: { fontSize: 11, color: "#888", textTransform: "lowercase", marginTop: 6 }, input: { background: "#161616", border: "1px solid #2a2a2a", color: "#fff", padding: "10px 12px", borderRadius: 6, fontSize: 13, outline: "none", }, formActions: { display: "flex", gap: 8, marginTop: 12, justifyContent: "flex-end" }, bigGoal: { textAlign: "center", padding: "20px 0" }, bigGoalNum: { fontSize: 48, fontWeight: 800, color: "#84cc16", letterSpacing: "-0.03em", lineHeight: 1 }, bigGoalLabel: { fontSize: 11, color: "#666", textTransform: "uppercase", marginTop: 6, letterSpacing: "0.1em" }, bigGoalDetail: { fontSize: 12, color: "#888", marginTop: 12 }, };