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 */}
{/* 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 (
);
}
function Modal({ children, onClose, title }) {
return (
e.stopPropagation()}>
{children}
);
}
function FormDia({ dia, onSubmit, onCancel }) {
const [dataInput, setDataInput] = useState(dia);
useEffect(() => {
setDataInput(dia);
}, [dia]);
return (
);
}
function FormConfig({ config, onSubmit, onCancel }) {
const [c, setC] = useState(config);
return (
);
}
// ===== 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 },
};