/* ===========================================================
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('amount', v)} prefix="R$" />
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. : (
| Descrição | Categoria | Data | Valor | |
{list.map((e) => (
| {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" />
set('qty', val)} />
set('price', val)} prefix="R$" />
set('cost', val)} prefix="R$" />
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. : (
| Produto | Canal | Data | Qtd | Venda | Custo | Lucro | |
{list.map((v) => {
const lucro = (v.price - v.cost) * v.qty;
return (
| {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;