/* =========================================================== Forja 3D — Gastos & Vendas =========================================================== */ const EXP_CATS = ['Filamento', 'Energia', 'Embalagem', 'Manutenção', 'Marketing', 'Equipamento', 'Impostos', 'Outro']; const CHANNELS = ['Shopee', 'Mercado Livre', 'Elo7', 'Instagram', 'Encomenda', 'Venda direta', 'Outro']; /* ---------------- GASTOS ---------------- */ function ExpenseForm({ onClose }) { const [e, setE] = useState({ date: today(), description: '', category: 'Filamento', amount: '' }); const set = (k, v) => setE((p) => ({ ...p, [k]: v })); return ( <> set('description', v)} placeholder="Ex: Filamento PLA+ 1kg" />
set('date', ev.target.value)} />
); } function Expenses() { const s = useStore(); const [modal, setModal] = useState(false); const [cat, setCat] = useState('Todas'); const list = s.expenses.filter((e) => cat === 'Todas' || e.category === cat).sort((a, b) => (b.date > a.date ? 1 : -1)); const total = list.reduce((a, e) => a + e.amount, 0); const totalMes = s.expenses.filter((e) => isThisMonth(e.date)).reduce((a, e) => a + e.amount, 0); return (
setModal(true)}>Novo gasto} />
{['Todas', ...EXP_CATS].map((c) => )}
{list.length === 0 ? setModal(true)}>Lançar gasto}>Registre suas despesas para acompanhar o caixa. : ( {list.map((e) => ( ))}
DescriçãoCategoriaDataValor
{e.description}
{e.category} {fmt.dateFull(e.date)} −{fmt.brl(e.amount)} store.removeExpense(e.id)} />
)}
setModal(false)} title="Novo gasto"> setModal(false)} />
); } window.Expenses = Expenses; /* ---------------- VENDAS ---------------- */ function SaleForm({ onClose, products }) { const [v, setV] = useState({ date: today(), product: '', channel: 'Shopee', qty: 1, price: '', cost: '' }); const set = (k, val) => setV((p) => ({ ...p, [k]: val })); function pick(name) { const p = products.find((x) => x.name === name); setV((s) => ({ ...s, product: name, price: p ? p.price : s.price })); } const lucro = (Number(v.price) || 0 - 0) ? (Number(v.price) - Number(v.cost || 0)) * (Number(v.qty) || 1) : 0; return ( <> pick(e.target.value)} placeholder="Ex: Vaso geométrico G" /> {products.map((p) =>
set('date', e.target.value)} />
Lucro estimado {fmt.brl(((Number(v.price) || 0) - (Number(v.cost) || 0)) * (Number(v.qty) || 1))}
); } function Sales() { const s = useStore(); const [modal, setModal] = useState(false); const list = [...s.sales].sort((a, b) => (b.date > a.date ? 1 : -1)); const mesList = s.sales.filter((x) => isThisMonth(x.date)); const fatMes = mesList.reduce((a, x) => a + x.price * x.qty, 0); const lucroMes = mesList.reduce((a, x) => a + (x.price - x.cost) * x.qty, 0); return (
setModal(true)}>Registrar venda} />
{list.length === 0 ? setModal(true)}>Registrar venda}>Comece a registrar suas vendas para acompanhar o lucro. : ( {list.map((v) => { const lucro = (v.price - v.cost) * v.qty; return ( ); })}
ProdutoCanalDataQtdVendaCustoLucro
{v.product} {v.channel} {fmt.dateFull(v.date)} {v.qty} {fmt.brl(v.price * v.qty)} {fmt.brl(v.cost * v.qty)} +{fmt.brl(lucro)} store.removeSale(v.id)} />
)}
setModal(false)} title="Registrar venda"> setModal(false)} />
); } window.Sales = Sales;