// App principal — Metal Padrão Sistema de Vendas
const TWEAK_DEFAULTS = /*EDITMODE-BEGIN*/{
"sidebarMode": "expanded",
"listView": "table",
"density": "regular",
"accent": "#ffc431"
}/*EDITMODE-END*/;
function App() {
const [user, setUser] = React.useState(null);
const [route, setRoute] = React.useState("vendas");
const [vendas, setVendas] = React.useState(() => window.MP_DATA.vendas);
const [openVenda, setOpenVenda] = React.useState(null);
const [newOpen, setNewOpen] = React.useState(false);
const [mobileNav, setMobileNav] = React.useState(false);
const [t, setTweak] = useTweaks(TWEAK_DEFAULTS);
// Sync tweaks to DOM
React.useEffect(() => {
document.documentElement.dataset.density = t.density;
document.documentElement.style.setProperty("--mp-yellow", t.accent);
}, [t.density, t.accent]);
const handleAddEntrada = (op, payload) => {
setVendas(vs => vs.map(v => v.op === op
? { ...v, entradas: [...v.entradas, { id: Date.now(), ...payload }] }
: v));
setOpenVenda(curr => {
if (!curr || curr.op !== op) return curr;
return { ...curr, entradas: [...curr.entradas, { id: Date.now(), ...payload }] };
});
};
const handleAddFat = (op, payload) => {
setVendas(vs => vs.map(v => v.op === op
? { ...v, faturamentos: [...v.faturamentos, payload] }
: v));
setOpenVenda(curr => {
if (!curr || curr.op !== op) return curr;
return { ...curr, faturamentos: [...curr.faturamentos, payload] };
});
};
const handleNova = (payload) => {
const op = payload.op;
const venda = { ...payload, faturamentos: [], entradas: [] };
setVendas(vs => [venda, ...vs]);
setNewOpen(false);
setOpenVenda(venda);
};
if (!user) return ;
// Next OP (sequencial)
const maxOp = Math.max(0, ...vendas.map(v => parseInt(v.op, 10)));
const proxOp = String(maxOp + 1).padStart(3, "0");
const routes = {
vendas: {
title: "Vendas",
crumb: "Módulo · vendas",
content: setNewOpen(true)} view={t.listView} />
},
clientes: { title: "Clientes", crumb: "Cadastros", content: },
vendedores: { title: "Vendedores", crumb: "Cadastros", content: },
producao: { title: "Produção", crumb: "Em breve", content: },
relatorios: { title: "Relatórios", crumb: "Em breve", content: },
};
const current = routes[route];
return (
{ setRoute(r); setMobileNav(false); }} user={user} onLogout={() => setUser(null)} />
setMobileNav(v => !v)} />
{current.content}
setOpenVenda(null)}
onAddEntrada={handleAddEntrada}
onAddFaturamento={handleAddFat}
/>
setNewOpen(false)}
onSave={handleNova}
proxOp={proxOp}
/>
setTweak("sidebarMode", v)}
/>
setTweak("listView", v)}
/>
setTweak("density", v)}
/>
setTweak("accent", v)}
/>
setUser(null)}>Sair (voltar ao login)
);
}
ReactDOM.createRoot(document.getElementById("root")).render();