LDA RECICLAGEM

オープン
#1,144 コメント 2 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

評価

難易度
5/5
見積もり時間
1週間以上
初心者へのやさしさ
10/100
issue の種類
機能追加
明瞭さ
説明が足りない
活発さ
停滞
技術スタック
javascript, react
領域
frontend

調査の方向性

The issue body contains a large pasted React application, but it names no repository file, test, entry point, requested change, or completion criteria. First clarify whether this code belongs in the project and what outcome is expected before attempting implementation.

索引モデルが issue の本文から書いたものです。

説明

import { useState, useEffect } from "react";

const MATERIAIS = [
{ id: "ferro", nome: "Ferro", cor: "#6B7280", unidade: "kg" },
{ id: "cobre", nome: "Cobre", cor: "#D97706", unidade: "kg" },
{ id: "aluminio", nome: "Alumínio", cor: "#60A5FA", unidade: "kg" },
{ id: "bronze", nome: "Bronze", cor: "#B45309", unidade: "kg" },
{ id: "latao", nome: "Latão", cor: "#F59E0B", unidade: "kg" },
{ id: "inox", nome: "Inox", cor: "#9CA3AF", unidade: "kg" },
{ id: "radiador", nome: "Radiador", cor: "#EF4444", unidade: "kg" },
{ id: "bateria", nome: "Bateria", cor: "#7C3AED", unidade: "kg" },
{ id: "fio", nome: "Fios/Cabos", cor: "#EC4899", unidade: "kg" },
{ id: "catalisador", nome: "Catalisador", cor: "#10B981", unidade: "und" },
];

const ESTADOS = ["AC","AL","AP","AM","BA","CE","DF","ES","GO","MA","MT","MS","MG","PA","PB","PR","PE","PI","RJ","RN","RS","RO","RR","SC","SP","SE","TO"];

const formatBRL = (v) => new Intl.NumberFormat("pt-BR", { style: "currency", currency: "BRL" }).format(v || 0);
const hoje = () => new Date().toISOString().split("T")[0];
const fmtDate = (d) => d ? new Date(d + "T00:00").toLocaleDateString("pt-BR") : "-";

const initialPrecos = {
ferro: { compra: 0.45, venda: 0.60 }, cobre: { compra: 28.0, venda: 35.0 },
aluminio: { compra: 5.5, venda: 7.0 }, bronze: { compra: 18.0, venda: 23.0 },
latao: { compra: 15.0, venda: 20.0 }, inox: { compra: 4.5, venda: 6.0 },
radiador: { compra: 3.5, venda: 5.0 }, bateria: { compra: 3.0, venda: 4.5 },
fio: { compra: 8.0, venda: 12.0 }, catalisador: { compra: 120.0, venda: 180.0 },
};

const FORN_VAZIO = {
nome: "", telefone: "", whatsapp: "", email: "",
endereco: "", numero: "", bairro: "", cidade: "Belo Horizonte", estado: "MG",
cpfCnpj: "", tipo: "pessoa_fisica", tipoFornecedor: "oficina",
materiaisPrincipais: [], obs: "", ativo: true,
};

const S = {
app: { fontFamily: "'Segoe UI', sans-serif", background: "#0F172A", minHeight: "100vh", color: "#E2E8F0" },
header: { background: "linear-gradient(135deg, #1E3A5F 0%, #0F2744 100%)", padding: "16px 24px", display: "flex", alignItems: "center", gap: 12, borderBottom: "1px solid #1E40AF" },
logo: { fontSize: 26, fontWeight: 800, background: "linear-gradient(90deg, #34D399, #60A5FA)", WebkitBackgroundClip: "text", WebkitTextFillColor: "transparent" },
nav: { display: "flex", gap: 4, padding: "10px 24px", background: "#1E293B", overflowX: "auto" },
page: { padding: "24px", maxWidth: 1200, margin: "0 auto" },
card: { background: "#1E293B", borderRadius: 12, padding: 20, border: "1px solid #334155" },
cardG: { background: "linear-gradient(135deg,#064E3B,#065F46)", borderRadius: 12, padding: 20, border: "1px solid #10B981" },
cardB: { background: "linear-gradient(135deg,#1E3A8A,#1D4ED8)", borderRadius: 12, padding: 20, border: "1px solid #3B82F6" },
cardR: { background: "linear-gradient(135deg,#7F1D1D,#991B1B)", borderRadius: 12, padding: 20, border: "1px solid #EF4444" },
grid2: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(220px,1fr))", gap: 16 },
grid3: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(170px,1fr))", gap: 12 },
grid4: { display: "grid", gridTemplateColumns: "repeat(auto-fit,minmax(280px,1fr))", gap: 16 },
label: { fontSize: 11, color: "#94A3B8", marginBottom: 4, display: "block", textTransform: "uppercase", letterSpacing: "0.5px" },
bigNum: { fontSize: 26, fontWeight: 800 },
sub: { fontSize: 12, color: "#94A3B8", marginTop: 4 },
input: { width: "100%", background: "#0F172A", border: "1px solid #334155", borderRadius: 8, padding: "9px 12px", color: "#E2E8F0", fontSize: 14, boxSizing: "border-box" },
select: { width: "100%", background: "#0F172A", border: "1px solid #334155", borderRadius: 8, padding: "9px 12px", color: "#E2E8F0", fontSize: 14, boxSizing: "border-box" },
textarea: { width: "100%", background: "#0F172A", border: "1px solid #334155", borderRadius: 8, padding: "9px 12px", color: "#E2E8F0", fontSize: 13, boxSizing: "border-box", resize: "vertical", minHeight: 70 },
btn: (c) => ({ background: c || "#2563EB", color: "#fff", border: "none", borderRadius: 8, padding: "9px 18px", cursor: "pointer", fontWeight: 700, fontSize: 13 }),
btnSm: (c) => ({ background: c || "#334155", color: "#fff", border: "none", borderRadius: 6, padding: "5px 12px", cursor: "pointer", fontWeight: 600, fontSize: 12 }),
table: { width: "100%", borderCollapse: "collapse" },
th: { background: "#0F172A", color: "#64748B", padding: "10px 12px", textAlign: "left", fontSize: 11, fontWeight: 700, textTransform: "uppercase", letterSpacing: "0.5px" },
td: { padding: "10px 12px", fontSize: 13, borderBottom: "1px solid #1E293B" },
h2: { fontSize: 18, fontWeight: 700, marginBottom: 16, color: "#F1F5F9" },
h3: { fontSize: 12, fontWeight: 700, color: "#64748B", marginBottom: 10, textTransform: "uppercase", letterSpacing: "0.8px", borderBottom: "1px solid #334155", paddingBottom: 8 },
row: { display: "flex", gap: 12, flexWrap: "wrap" },
fg: { flex: 1, minWidth: 140 },
badge: (c) => ({ background: c + "25", color: c, padding: "2px 10px", borderRadius: 20, fontSize: 11, fontWeight: 700, display: "inline-block" }),
};

export default function App() {
const [aba, setAba] = useState("dashboard");
const [precos, setPrecos] = useState(initialPrecos);
const [compras, setCompras] = useState([]);
const [vendas, setVendas] = useState([]);
const [despesas, setDespesas] = useState([]);
const [estoque, setEstoque] = useState({});
const [fornecedores, setFornecedores] = useState([]);
const [formForn, setFormForn] = useState(FORN_VAZIO);
const [editFornId, setEditFornId] = useState(null);
const [buscaForn, setBuscaForn] = useState("");
const [filtroAtivo, setFiltroAtivo] = useState("todos");
const [detalhe, setDetalhe] = useState(null);
const [formCompra, setFormCompra] = useState({ data: hoje(), material: "ferro", quantidade: "", fornecedorId: "", obs: "" });
const [formVenda, setFormVenda] = useState({ data: hoje(), material: "ferro", quantidade: "", cliente: "", obs: "" });
const [formDespesa, setFormDespesa] = useState({ data: hoje(), descricao: "", valor: "", categoria: "operacional" });

useEffect(() => {
const est = {};
MATERIAIS.forEach(m => { est[m.id] = 0; });
compras.forEach(c => { est[c.material] = (est[c.material] || 0) + Number(c.quantidade); });
vendas.forEach(v => { est[v.material] = (est[v.material] || 0) - Number(v.quantidade); });
setEstoque(est);
}, [compras, vendas]);

const toggleMat = (mid) => {
const a = formForn.materiaisPrincipais || [];
setFormForn({ ...formForn, materiaisPrincipais: a.includes(mid) ? a.filter(x => x !== mid) : [...a, mid] });
};

const saveForn = () => {
if (!formForn.nome.trim()) return alert("Informe o nome!");
if (editFornId) {
setFornecedores(fornecedores.map(f => f.id === editFornId ? { ...formForn, id: editFornId } : f));
setEditFornId(null);
} else {
setFornecedores([...fornecedores, { ...formForn, id: Date.now(), cadastradoEm: hoje() }]);
}
setFormForn(FORN_VAZIO);
};

const editarForn = (f) => { setFormForn({ ...f }); setEditFornId(f.id); setDetalhe(null); };
const cancelarEdicao = () => { setFormForn(FORN_VAZIO); setEditFornId(null); };
const deletarForn = (id) => { if (!window.confirm("Excluir fornecedor?")) return; setFornecedores(fornecedores.filter(f => f.id !== id)); if (detalhe?.id === id) setDetalhe(null); };
const toggleAtivoForn = (id) => setFornecedores(fornecedores.map(f => f.id === id ? { ...f, ativo: !f.ativo } : f));
const comprasDeForn = (id) => compras.filter(c => Number(c.fornecedorId) === id);
const totalDeForn = (id) => comprasDeForn(id).reduce((s, c) => s + c.total, 0);

const fornFiltrados = fornecedores.filter(f => {
const ok = f.nome.toLowerCase().includes(buscaForn.toLowerCase()) ||
(f.telefone || "").includes(buscaForn) ||
(f.cidade || "").toLowerCase().includes(buscaForn.toLowerCase()) ||
(f.cpfCnpj || "").includes(buscaForn);
if (filtroAtivo === "ativos") return ok && f.ativo;
if (filtroAtivo === "inativos") return ok && !f.ativo;
return ok;
});

const addCompra = () => {
if (!formCompra.quantidade || Number(formCompra.quantidade) <= 0) return alert("Informe a quantidade!");
const preco = precos[formCompra.material]?.compra || 0;
const forn = fornecedores.find(f => f.id === Number(formCompra.fornecedorId));
setCompras([...compras, { ...formCompra, id: Date.now(), preco, total: preco * Number(formCompra.quantidade), fornecedorNome: forn?.nome || "Avulso" }]);
setFormCompra({ data: hoje(), material: "ferro", quantidade: "", fornecedorId: "", obs: "" });
};

const addVenda = () => {
if (!formVenda.quantidade || Number(formVenda.quantidade) <= 0) return alert("Informe a quantidade!");
const disp = estoque[formVenda.material] || 0;
if (Number(formVenda.quantidade) > disp) return alert("Estoque insuficiente! Disponível: " + disp.toFixed(2));
const preco = precos[formVenda.material]?.venda || 0;
setVendas([...vendas, { ...formVenda, id: Date.now(), preco, total: preco * Number(formVenda.quantidade) }]);
setFormVenda({ data: hoje(), material: "ferro", quantidade: "", cliente: "", obs: "" });
};

const addDespesa = () => {
if (!formDespesa.valor || !formDespesa.descricao) return alert("Preencha todos os campos!");
setDespesas([...despesas, { ...formDespesa, id: Date.now(), valor: Number(formDespesa.valor) }]);
setFormDespesa({ data: hoje(), descricao: "", valor: "", categoria: "operacional" });
};

const filtrarHoje = (arr) => arr.filter(i => i.data === hoje());
const filtrarMes = (arr) => arr.filter(i => i.data?.startsWith(hoje().slice(0, 7)));
const tch = filtrarHoje(compras).reduce((s, c) => s + c.total, 0);
const tvh = filtrarHoje(vendas).reduce((s, v) => s + v.total, 0);
const tdh = filtrarHoje(despesas).reduce((s, d) => s + d.valor, 0);
const lh = tvh - tch - tdh;
const tcm = filtrarMes(compras).reduce((s, c) => s + c.total, 0);
const tvm = filtrarMes(vendas).reduce((s, v) => s + v.total, 0);
const tdm = filtrarMes(despesas).reduce((s, d) => s + d.valor, 0);
const lm = tvm - tcm - tdm;
const diasNoMes = new Date(new Date().getFullYear(), new Date().getMonth() + 1, 0).getDate();
const diaAtual = new Date().getDate();
const fator = diasNoMes / Math.max(diaAtual, 1);
const ganhoMaterial = MATERIAIS.map(m => {
const vm = filtrarMes(vendas).filter(v => v.material === m.id);
const cm = filtrarMes(compras).filter(c => c.material === m.id);
const tv = vm.reduce((s, v) => s + v.total, 0);
const tc = cm.reduce((s, c) => s + c.total, 0);
return { ...m, tv, tc, lucro: tv - tc, qtyV: vm.reduce((s, v) => s + Number(v.quantidade), 0), qtyC: cm.reduce((s, c) => s + Number(c.quantidade), 0) };
}).filter(m => m.tv > 0 || m.tc > 0);

const matLabel = (id) => MATERIAIS.find(m => m.id === id);
const navBtn = (a) => ({ padding: "8px 14px", borderRadius: 8, border: "none", cursor: "pointer", fontWeight: 600, fontSize: 12, background: aba === a ? "#2563EB" : "transparent", color: aba === a ? "#fff" : "#94A3B8", whiteSpace: "nowrap" });

const TIPO_LABEL = { oficina: "🔧 Oficina", desmanche: "🏭 Desmanche", particular: "👤 Particular", empresa: "🏢 Empresa", coletor: "🚛 Coletor", outro: "📦 Outro" };

const abas = [
{ id: "dashboard", label: "📊 Dashboard" },
{ id: "fornecedores", label: 🏭 Fornecedores (${fornecedores.length}) },
{ id: "compras", label: "📥 Compras" },
{ id: "vendas", label: "📤 Vendas" },
{ id: "estoque", label: "📦 Estoque" },
{ id: "despesas", label: "💸 Despesas" },
{ id: "projecao", label: "📈 Projeção" },
{ id: "precos", label: "⚙️ Preços" },
];

return (



♻ LDA

<div style={{ fontWeight: 700, fontSize: 15 }}>Sistema de Controle — Reciclagem
<div style={{ fontSize: 11, color: "#94A3B8" }}>LDA Reciclagem • CNPJ 61.846.483/0001-34 • {new Date().toLocaleDateString("pt-BR", { weekday: "long", day: "2-digit", month: "long", year: "numeric" })}


{abas.map(a => <button key={a.id} style={navBtn(a.id)} onClick={() => setAba(a.id)}>{a.label})}

    {/* DASHBOARD */}
    {aba === "dashboard" && (
      <div>
        <h2 style={S.h2}>Resumo do Dia — {new Date().toLocaleDateString("pt-BR")}</h2>
        <div style={S.grid2}>
          <div style={S.cardB}><span style={S.label}>💰 Compras Hoje</span><div style={S.bigNum}>{formatBRL(tch)}</div><div style={S.sub}>{filtrarHoje(compras).length} operações</div></div>
          <div style={S.cardG}><span style={S.label}>🤑 Vendas Hoje</span><div style={S.bigNum}>{formatBRL(tvh)}</div><div style={S.sub}>{filtrarHoje(vendas).length} operações</div></div>
          <div style={S.cardR}><span style={S.label}>💸 Despesas Hoje</span><div style={S.bigNum}>{formatBRL(tdh)}</div><div style={S.sub}>{filtrarHoje(despesas).length} lançamentos</div></div>
          <div style={{ ...S.card, border: "1px solid " + (lh >= 0 ? "#10B981" : "#EF4444") }}>
            <span style={S.label}>📊 Lucro Hoje</span>
            <div style={{ ...S.bigNum, color: lh >= 0 ? "#34D399" : "#F87171" }}>{formatBRL(lh)}</div>
            <div style={S.sub}>Margem: {tvh > 0 ? ((lh / tvh) * 100).toFixed(1) : 0}%</div>
          </div>
        </div>
        <h2 style={{ ...S.h2, marginTop: 28 }}>Resumo do Mês</h2>
        <div style={S.grid2}>
          <div style={S.card}><span style={S.label}>📥 Compras Mês</span><div style={{ fontSize: 22, fontWeight: 700, color: "#60A5FA" }}>{formatBRL(tcm)}</div></div>
          <div style={S.card}><span style={S.label}>📤 Vendas Mês</span><div style={{ fontSize: 22, fontWeight: 700, color: "#34D399" }}>{formatBRL(tvm)}</div></div>
          <div style={S.card}><span style={S.label}>💸 Despesas Mês</span><div style={{ fontSize: 22, fontWeight: 700, color: "#F87171" }}>{formatBRL(tdm)}</div></div>
          <div style={S.card}><span style={S.label}>📊 Lucro Líquido Mês</span><div style={{ fontSize: 22, fontWeight: 700, color: lm >= 0 ? "#34D399" : "#F87171" }}>{formatBRL(lm)}</div></div>
        </div>
        {ganhoMaterial.length > 0 && (
          <><h2 style={{ ...S.h2, marginTop: 28 }}>Ganho por Material (Mês)</h2>
            <div style={S.card}><table style={S.table}><thead><tr>{["Material","Kg Comprado","Kg Vendido","Custo","Receita","Lucro"].map(h => <th key={h} style={S.th}>{h}</th>)}</tr></thead>
              <tbody>{ganhoMaterial.map(m => (
                <tr key={m.id}>
                  <td style={{ ...S.td, fontWeight: 700, color: m.cor }}>{m.nome}</td>
                  <td style={S.td}>{m.qtyC.toFixed(2)} {m.unidade}</td>
                  <td style={S.td}>{m.qtyV.toFixed(2)} {m.unidade}</td>
                  <td style={{ ...S.td, color: "#F87171" }}>{formatBRL(m.tc)}</td>
                  <td style={{ ...S.td, color: "#34D399" }}>{formatBRL(m.tv)}</td>
                  <td style={{ ...S.td, fontWeight: 700, color: m.lucro >= 0 ? "#34D399" : "#F87171" }}>{formatBRL(m.lucro)}</td>
                </tr>
              ))}</tbody>
            </table></div></>
        )}
        {ganhoMaterial.length === 0 && <div style={{ ...S.card, textAlign: "center", padding: 40, color: "#64748B", marginTop: 24 }}><div style={{ fontSize: 48 }}>♻️</div><div style={{ marginTop: 8 }}>Nenhuma movimentação ainda. Cadastre fornecedores e registre compras!</div></div>}
      </div>
    )}

    {/* FORNECEDORES */}
    {aba === "fornecedores" && (
      <div>
        {/* FORMULÁRIO CADASTRO */}
        <div style={{ ...S.card, marginBottom: 24, borderColor: editFornId ? "#F59E0B" : "#334155" }}>
          <h2 style={{ ...S.h2, color: editFornId ? "#F59E0B" : "#F1F5F9", marginBottom: 20 }}>
            {editFornId ? "✏️ Editando Fornecedor" : "➕ Novo Fornecedor"}
          </h2>

          <div style={S.h3}>📋 Identificação</div>
          <div style={{ ...S.row, marginBottom: 16 }}>
            <div style={{ ...S.fg, flex: 3 }}>
              <label style={S.label}>Nome / Razão Social *</label>
              <input type="text" style={S.input} placeholder="Nome completo ou razão social..." value={formForn.nome} onChange={e => setFormForn({ ...formForn, nome: e.target.value })} />
            </div>
            <div style={S.fg}>
              <label style={S.label}>Tipo de Pessoa</label>
              <select style={S.select} value={formForn.tipo} onChange={e => setFormForn({ ...formForn, tipo: e.target.value })}>
                <option value="pessoa_fisica">Pessoa Física</option>
                <option value="pessoa_juridica">Pessoa Jurídica</option>
              </select>
            </div>
            <div style={S.fg}>
              <label style={S.label}>{formForn.tipo === "pessoa_juridica" ? "CNPJ" : "CPF"}</label>
              <input type="text" style={S.input} placeholder={formForn.tipo === "pessoa_juridica" ? "00.000.000/0001-00" : "000.000.000-00"} value={formForn.cpfCnpj} onChange={e => setFormForn({ ...formForn, cpfCnpj: e.target.value })} />
            </div>
            <div style={S.fg}>
              <label style={S.label}>Tipo de Fornecedor</label>
              <select style={S.select} value={formForn.tipoFornecedor} onChange={e => setFormForn({ ...formForn, tipoFornecedor: e.target.value })}>
                <option value="oficina">🔧 Oficina Mecânica</option>
                <option value="desmanche">🏭 Desmanche</option>
                <option value="particular">👤 Particular</option>
                <option value="empresa">🏢 Empresa</option>
                <option value="coletor">🚛 Coletor Independente</option>
                <option value="outro">📦 Outro</option>
              </select>
            </div>
          </div>

          <div style={S.h3}>📞 Contato</div>
          <div style={{ ...S.row, marginBottom: 16 }}>
            <div style={S.fg}>
              <label style={S.label}>Telefone</label>
              <input type="text" style={S.input} placeholder="(31) 99999-9999" value={formForn.telefone} onChange={e => setFormForn({ ...formForn, telefone: e.target.value })} />
            </div>
            <div style={S.fg}>
              <label style={S.label}>WhatsApp</label>
              <input type="text" style={S.input} placeholder="(31) 99999-9999" value={formForn.whatsapp} onChange={e => setFormForn({ ...formForn, whatsapp: e.target.value })} />
            </div>
            <div style={{ ...S.fg, flex: 2 }}>
              <label style={S.label}>E-mail</label>
              <input type="email" style={S.input} placeholder="email@exemplo.com" value={formForn.email} onChange={e => setFormForn({ ...formForn, email: e.target.value })} />
            </div>
          </div>

          <div style={S.h3}>📍 Endereço</div>
          <div style={{ ...S.row, marginBottom: 16 }}>
            <div style={{ ...S.fg, flex: 3 }}>
              <label style={S.label}>Logradouro</label>
              <input type="text" style={S.input} placeholder="Rua, Avenida..." value={formForn.endereco} onChange={e => setFormForn({ ...formForn, endereco: e.target.value })} />
            </div>
            <div style={{ minWidth: 80 }}>
              <label style={S.label}>Número</label>
              <input type="text" style={S.input} placeholder="Nº" value={formForn.numero} onChange={e => setFormForn({ ...formForn, numero: e.target.value })} />
            </div>
            <div style={{ ...S.fg, flex: 2 }}>
              <label style={S.label}>Bairro</label>
              <input type="text" style={S.input} placeholder="Bairro" value={formForn.bairro} onChange={e => setFormForn({ ...formForn, bairro: e.target.value })} />
            </div>
            <div style={{ ...S.fg, flex: 2 }}>
              <label style={S.label}>Cidade</label>
              <input type="text" style={S.input} placeholder="Cidade" value={formForn.cidade} onChange={e => setFormForn({ ...formForn, cidade: e.target.value })} />
            </div>
            <div style={{ minWidth: 80 }}>
              <label style={S.label}>UF</label>
              <select style={S.select} value={formForn.estado} onChange={e => setFormForn({ ...formForn, estado: e.target.value })}>
                {ESTADOS.map(e => <option key={e} value={e}>{e}</option>)}
              </select>
            </div>
          </div>

          <div style={S.h3}>♻️ Materiais que Fornece</div>
          <div style={{ display: "flex", flexWrap: "wrap", gap: 8, marginBottom: 16 }}>
            {MATERIAIS.map(m => {
              const sel = formForn.materiaisPrincipais?.includes(m.id);
              return (
                <button key={m.id} onClick={() => toggleMat(m.id)} style={{
                  padding: "6px 14px", borderRadius: 20, border: "2px solid " + (sel ? m.cor : "#334155"),
                  background: sel ? m.cor + "30" : "transparent", color: sel ? m.cor : "#64748B",
                  cursor: "pointer", fontSize: 12, fontWeight: 600, transition: "all 0.15s"
                }}>{m.nome}</button>
              );
            })}
          </div>

          <div style={S.h3}>📝 Observações e Status</div>
          <div style={{ ...S.row, marginBottom: 16 }}>
            <div style={{ ...S.fg, flex: 4 }}>
              <label style={S.label}>Observações</label>
              <textarea style={S.textarea} placeholder="Horário de atendimento, localização de referência, observações importantes..." value={formForn.obs} onChange={e => setFormForn({ ...formForn, obs: e.target.value })} />
            </div>
            <div style={S.fg}>
              <label style={S.label}>Status</label>
              <select style={S.select} value={formForn.ativo ? "ativo" : "inativo"} onChange={e => setFormForn({ ...formForn, ativo: e.target.value === "ativo" })}>
                <option value="ativo">✅ Ativo</option>
                <option value="inativo">⛔ Inativo</option>
              </select>
            </div>
          </div>

          <div style={{ display: "flex", gap: 10 }}>
            <button style={S.btn(editFornId ? "#D97706" : "#059669")} onClick={saveForn}>
              {editFornId ? "💾 Salvar Alterações" : "✅ Cadastrar Fornecedor"}
            </button>
            {editFornId && <button style={S.btn("#475569")} onClick={cancelarEdicao}>✕ Cancelar</button>}
          </div>
        </div>

        {/* BUSCA */}
        <div style={{ display: "flex", gap: 12, marginBottom: 16, flexWrap: "wrap", alignItems: "center" }}>
          <div style={{ flex: 1, minWidth: 240 }}>
            <input type="text" style={S.input} placeholder="🔍 Buscar nome, telefone, cidade, CPF/CNPJ..." value={buscaForn} onChange={e => setBuscaForn(e.target.value)} />
          </div>
          <div style={{ display: "flex", gap: 6 }}>
            {["todos", "ativos", "inativos"].map(f => (
              <button key={f} style={S.btnSm(filtroAtivo === f ? "#2563EB" : "#334155")} onClick={() => setFiltroAtivo(f)}>
                {f.charAt(0).toUpperCase() + f.slice(1)}
              </button>
            ))}
          </div>
          <div style={{ fontSize: 13, color: "#64748B" }}>{fornFiltrados.length} fornecedor(es)</div>
        </div>

        {/* CARDS FORNECEDORES */}
        {fornFiltrados.length === 0 ? (
          <div style={{ ...S.card, textAlign: "center", padding: 48, color: "#64748B" }}>
            <div style={{ fontSize: 44, marginBottom: 12 }}>🏭</div>
            <div style={{ fontSize: 16, marginBottom: 4 }}>{buscaForn ? "Nenhum resultado encontrado." : "Nenhum fornecedor cadastrado."}</div>
            <div style={{ fontSize: 13 }}>Use o formulário acima para cadastrar fornecedores.</div>
          </div>
        ) : (
          <div style={S.grid4}>
            {fornFiltrados.map(f => {
              const total = totalDeForn(f.id);
              const nComp = comprasDeForn(f.id).length;
              const isOpen = detalhe?.id === f.id;
              return (
                <div key={f.id} style={{ ...S.card, cursor: "pointer", borderColor: isOpen ? "#3B82F6" : f.ativo ? "#334155" : "#7F1D1D", opacity: f.ativo ? 1 : 0.65, transition: "border-color 0.2s" }} onClick={() => setDetalhe(isOpen ? null : f)}>
                  <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 10 }}>
                    <div style={{ flex: 1 }}>
                      <div style={{ fontWeight: 700, fontSize: 15, color: "#F1F5F9", lineHeight: 1.3, marginBottom: 3 }}>{f.nome}</div>
                      <div style={{ fontSize: 12, color: "#64748B" }}>{TIPO_LABEL[f.tipoFornecedor] || f.tipoFornecedor}</div>
                    </div>
                    <span style={S.badge(f.ativo ? "#10B981" : "#EF4444")}>{f.ativo ? "Ativo" : "Inativo"}</span>
                  </div>

                  {f.telefone && <div style={{ fontSize: 12, color: "#94A3B8", marginBottom: 3 }}>📞 {f.telefone}</div>}
                  {f.whatsapp && f.whatsapp !== f.telefone && <div style={{ fontSize: 12, color: "#94A3B8", marginBottom: 3 }}>💬 {f.whatsapp}</div>}
                  {(f.cidade || f.estado) && <div style={{ fontSize: 12, color: "#94A3B8", marginBottom: 3 }}>📍 {[f.bairro, f.cidade, f.estado].filter(Boolean).join(", ")}</div>}
                  {f.cpfCnpj && <div style={{ fontSize: 12, color: "#64748B", marginBottom: 3 }}>🪪 {f.cpfCnpj}</div>}

                  {f.materiaisPrincipais?.length > 0 && (
                    <div style={{ display: "flex", flexWrap: "wrap", gap: 4, marginTop: 8 }}>
                      {f.materiaisPrincipais.map(mid => {
                        const m = MATERIAIS.find(x => x.id === mid);
                        return m ? <span key={mid} style={{ ...S.badge(m.cor), fontSize: 10 }}>{m.nome}</span> : null;
                      })}
                    </div>
                  )}

                  <div style={{ borderTop: "1px solid #334155", paddingTop: 10, marginTop: 10, display: "flex", justifyContent: "space-between", alignItems: "center" }}>
                    <div style={{ textAlign: "center" }}>
                      <div style={{ fontSize: 18, fontWeight: 800, color: "#60A5FA" }}>{nComp}</div>
                      <div style={{ fontSize: 10, color: "#64748B" }}>compras</div>
                    </div>
                    <div style={{ textAlign: "center" }}>
                      <div style={{ fontSize: 15, fontWeight: 700, color: "#34D399" }}>{formatBRL(total)}</div>
                      <div style={{ fontSize: 10, color: "#64748B" }}>total fornecido</div>
                    </div>
                    {f.cadastradoEm && <div style={{ textAlign: "center" }}>
                      <div style={{ fontSize: 12, color: "#94A3B8" }}>{fmtDate(f.cadastradoEm)}</div>
                      <div style={{ fontSize: 10, color: "#64748B" }}>cadastrado</div>
                    </div>}
                  </div>

                  <div style={{ display: "flex", gap: 6, marginTop: 12, flexWrap: "wrap" }} onClick={e => e.stopPropagation()}>
                    <button style={S.btnSm("#2563EB")} onClick={() => editarForn(f)}>✏️ Editar</button>
                    <button style={S.btnSm(f.ativo ? "#7F1D1D" : "#064E3B")} onClick={() => toggleAtivoForn(f.id)}>{f.ativo ? "⛔ Inativar" : "✅ Ativar"}</button>
                    {nComp === 0 && <button style={S.btnSm("#7F1D1D")} onClick={() => deletarForn(f.id)}>🗑️</button>}
                    <button style={S.btnSm("#1E40AF")} onClick={() => { setAba("compras"); setFormCompra({ ...formCompra, fornecedorId: String(f.id) }); }}>+ Compra</button>
                  </div>

                  {isOpen && (
                    <div style={{ marginTop: 14, borderTop: "1px solid #334155", paddingTop: 14 }}>
                      {f.endereco && <div style={{ fontSize: 12, color: "#94A3B8", marginBottom: 4 }}>🏠 {[f.endereco, f.numero, f.bairro, f.cidade + "/" + f.estado].filter(Boolean).join(", ")}</div>}
                      {f.email && <div style={{ fontSize: 12, color: "#94A3B8", marginBottom: 4 }}>✉️ {f.email}</div>}
                      {f.obs && <div style={{ fontSize: 12, background: "#0F172A", padding: "8px 10px", borderRadius: 8, color: "#94A3B8", marginTop: 6 }}>💬 {f.obs}</div>}
                      {nComp > 0 && (
                        <div style={{ marginTop: 12 }}>
                          <div style={{ fontSize: 11, fontWeight: 700, color: "#64748B", marginBottom: 8 }}>ÚLTIMAS COMPRAS</div>
                          {comprasDeForn(f.id).slice(-4).reverse().map(c => (
                            <div key={c.id} style={{ display: "flex", justifyContent: "space-between", fontSize: 12, padding: "5px 0", borderBottom: "1px solid #1E293B" }}>
                              <span style={{ color: matLabel(c.material)?.cor, fontWeight: 600 }}>{matLabel(c.material)?.nome}</span>
                              <span style={{ color: "#94A3B8" }}>{Number(c.quantidade).toFixed(1)} {matLabel(c.material)?.unidade}</span>
                              <span style={{ color: "#34D399", fontWeight: 700 }}>{formatBRL(c.total)}</span>
                              <span style={{ color: "#64748B" }}>{fmtDate(c.data)}</span>
                            </div>
                          ))}
                        </div>
                      )}
                    </div>
                  )}
                </div>
              );
            })}
          </div>
        )}
      </div>
    )}

    {/* COMPRAS */}
    {aba === "compras" && (
      <div>
        <h2 style={S.h2}>Registrar Compra</h2>
        <div style={S.card}>
          <div style={S.row}>
            <div style={S.fg}><label style={S.label}>Data</label><input type="date" style={S.input} value={formCompra.data} onChange={e => setFormCompra({ ...formCompra, data: e.target.value })} /></div>
            <div style={S.fg}><label style={S.label}>Material</label>
              <select style={S.select} value={formCompra.material} onChange={e => setFormCompra({ ...formCompra, material: e.target.value })}>
                {MATERIAIS.map(m => <option key={m.id} value={m.id}>{m.nome}</option>)}
              </select>
            </div>
            <div style={S.fg}><label style={S.label}>Qtd ({matLabel(formCompra.material)?.unidade})</label><input type="number" style={S.input} placeholder="0,00" value={formCompra.quantidade} onChange={e => setFormCompra({ ...formCompra, quantidade: e.target.value })} /></div>
            <div style={S.fg}><label style={S.label}>R$/unit</label><input style={{ ...S.input, background: "#1E293B" }} value={formatBRL(precos[formCompra.material]?.compra || 0)} readOnly /></div>
            <div style={S.fg}><label style={S.label}>Total</label><input style={{ ...S.input, background: "#1E293B", color: "#60A5FA" }} value={formatBRL((precos[formCompra.material]?.compra || 0) * (formCompra.quantidade || 0))} readOnly /></div>
          </div>
          <div style={{ ...S.row, marginTop: 12 }}>
            <div style={{ ...S.fg, flex: 2 }}><label style={S.label}>Fornecedor</label>
              <select style={S.select} value={formCompra.fornecedorId} onChange={e => setFormCompra({ ...formCompra, fornecedorId: e.target.value })}>
                <option value="">— Avulso / Sem cadastro —</option>
                {fornecedores.filter(f => f.ativo).map(f => <option key={f.id} value={f.id}>{f.nome}{f.cidade ? " (" + f.cidade + ")" : ""}</option>)}
              </select>
            </div>
            <div style={{ ...S.fg, flex: 2 }}><label style={S.label}>Observação</label><input type="text" style={S.input} placeholder="Obs..." value={formCompra.obs} onChange={e => setFormCompra({ ...formCompra, obs: e.target.value })} /></div>
            <div style={{ display: "flex", alignItems: "flex-end" }}><button style={S.btn("#059669")} onClick={addCompra}>+ Registrar</button></div>
          </div>
        </div>
        <h2 style={{ ...S.h2, marginTop: 24 }}>Histórico de Compras</h2>
        <div style={S.card}>
          {compras.length === 0 ? <div style={{ textAlign: "center", color: "#64748B", padding: 32 }}>Nenhuma compra registrada.</div> :
            <table style={S.table}><thead><tr>{["Data", "Material", "Qtd", "R$/unit", "Total", "Fornecedor", "Obs", ""].map(h => <th key={h} style={S.th}>{h}</th>)}</tr></thead>
              <tbody>{[...compras].reverse().map(c => (
                <tr key={c.id}>
                  <td style={S.td}>{fmtDate(c.data)}</td>
                  <td style={{ ...S.td, color: matLabel(c.material)?.cor, fontWeight: 600 }}>{matLabel(c.material)?.nome}</td>
                  <td style={S.td}>{Number(c.quantidade).toFixed(2)} {matLabel(c.material)?.unidade}</td>
                  <td style={S.td}>{formatBRL(c.preco)}</td>
                  <td style={{ ...S.td, color: "#F87171", fontWeight: 700 }}>{formatBRL(c.total)}</td>
                  <td style={S.td}>{c.fornecedorNome || "Avulso"}</td>
                  <td style={S.td}>{c.obs || "-"}</td>
                  <td style={S.td}><button style={{ ...S.btn("#991B1B"), padding: "4px 10px", fontSize: 12 }} onClick={() => setCompras(compras.filter(x => x.id !== c.id))}>✕</button></td>
                </tr>
              ))}</tbody>
            </table>}
        </div>
      </div>
    )}

    {/* VENDAS */}
    {aba === "vendas" && (
      <div>
        <h2 style={S.h2}>Registrar Venda</h2>
        <div style={S.card}>
          <div style={S.row}>
            <div style={S.fg}><label style={S.label}>Data</label><input type="date" style={S.input} value={formVenda.data} onChange={e => setFormVenda({ ...formVenda, data: e.target.value })} /></div>
            <div style={S.fg}><label style={S.label}>Material</label>
              <select style={S.select} value={formVenda.material} onChange={e => setFormVenda({ ...formVenda, material: e.target.value })}>
                {MATERIAIS.map(m => <option key={m.id} value={m.id}>{m.nome} (est: {(estoque[m.id] || 0).toFixed(2)} {m.unidade})</option>)}
              </select>
            </div>
            <div style={S.fg}><label style={S.label}>Qtd ({matLabel(formVenda.material)?.unidade})</label><input type="number" style={S.input} placeholder="0,00" value={formVenda.quantidade} onChange={e => setFormVenda({ ...formVenda, quantidade: e.target.value })} /></div>
            <div style={S.fg}><label style={S.label}>R$/unit</label><input style={{ ...S.input, background: "#1E293B" }} value={formatBRL(precos[formVenda.material]?.venda || 0)} readOnly /></div>
            <div style={S.fg}><label style={S.label}>Total</label><input style={{ ...S.input, background: "#1E293B", color: "#34D399" }} value={formatBRL((precos[formVenda.material]?.venda || 0) * (formVenda.quantidade || 0))} readOnly /></div>
          </div>
          <div style={{ ...S.row, marginTop: 12 }}>
            <div style={{ ...S.fg, flex: 2 }}><label style={S.label}>Cliente</label><input type="text" style={S.input} placeholder="Nome do cliente..." value={formVenda.cliente} onChange={e => setFormVenda({ ...formVenda, cliente: e.target.value })} /></div>
            <div style={{ ...S.fg, flex: 2 }}><label style={S.label}>Observação</label><input type="text" style={S.input} placeholder="Obs..." value={formVenda.obs} onChange={e => setFormVenda({ ...formVenda, obs: e.target.value })} /></div>
            <div style={{ display: "flex", alignItems: "flex-end" }}><button style={S.btn("#2563EB")} onClick={addVenda}>+ Registrar</button></div>
          </div>
        </div>
        <h2 style={{ ...S.h2, marginTop: 24 }}>Histórico de Vendas</h2>
        <div style={S.card}>
          {vendas.length === 0 ? <div style={{ textAlign: "center", color: "#64748B", padding: 32 }}>Nenhuma venda registrada.</div> :
            <table style={S.table}><thead><tr>{["Data", "Material", "Qtd", "R$/unit", "Total", "Cliente", "Obs", ""].map(h => <th key={h} style={S.th}>{h}</th>)}</tr></thead>
              <tbody>{[...vendas].reverse().map(v => (
                <tr key={v.id}>
                  <td style={S.td}>{fmtDate(v.data)}</td>
                  <td style={{ ...S.td, color: matLabel(v.material)?.cor, fontWeight: 600 }}>{matLabel(v.material)?.nome}</td>
                  <td style={S.td}>{Number(v.quantidade).toFixed(2)} {matLabel(v.material)?.unidade}</td>
                  <td style={S.td}>{formatBRL(v.preco)}</td>
                  <td style={{ ...S.td, color: "#34D399", fontWeight: 700 }}>{formatBRL(v.total)}</td>
                  <td style={S.td}>{v.cliente || "-"}</td>
                  <td style={S.td}>{v.obs || "-"}</td>
                  <td style={S.td}><button style={{ ...S.btn("#991B1B"), padding: "4px 10px", fontSize: 12 }} onClick={() => setVendas(vendas.filter(x => x.id !== v.id))}>✕</button></td>
                </tr>
              ))}</tbody>
            </table>}
        </div>
      </div>
    )}

    {/* ESTOQUE */}
    {aba === "estoque" && (
      <div>
        <h2 style={S.h2}>Estoque Atual</h2>
        <div style={S.grid3}>
          {MATERIAIS.map(m => {
            const qty = estoque[m.id] || 0;
            const vc = qty * (precos[m.id]?.compra || 0);
            const vv = qty * (precos[m.id]?.venda || 0);
            return (
              <div key={m.id} style={{ ...S.card, borderLeft: "4px solid " + m.cor }}>
                <div style={{ fontWeight: 700, color: m.cor, fontSize: 15, marginBottom: 8 }}>{m.nome}</div>
                <div style={{ fontSize: 22, fontWeight: 800, color: qty > 0 ? "#F1F5F9" : "#64748B" }}>{qty.toFixed(2)} <span style={{ fontSize: 12, fontWeight: 400 }}>{m.unidade}</span></div>
                <div style={{ marginTop: 8, fontSize: 12, color: "#94A3B8" }}>
                  <div>Custo: {formatBRL(vc)}</div>
                  <div style={{ color: "#34D399" }}>Venda: {formatBRL(vv)}</div>
                  {qty > 0 && <div style={{ color: "#F59E0B", fontWeight: 600 }}>Margem: {formatBRL(vv - vc)}</div>}
                </div>
              </div>
            );
          })}
        </div>
        <div style={{ ...S.card, marginTop: 20 }}>
          <div style={{ display: "flex", justifyContent: "space-between", flexWrap: "wrap", gap: 16 }}>
            <div><span style={S.label}>Total em Custo</span><div style={{ fontSize: 22, fontWeight: 700, color: "#F87171" }}>{formatBRL(MATERIAIS.reduce((s, m) => s + (estoque[m.id] || 0) * (precos[m.id]?.compra || 0), 0))}</div></div>
            <div><span style={S.label}>Total Valor Venda</span><div style={{ fontSize: 22, fontWeight: 700, color: "#34D399" }}>{formatBRL(MATERIAIS.reduce((s, m) => s + (estoque[m.id] || 0) * (precos[m.id]?.venda || 0), 0))}</div></div>
            <div><span style={S.label}>Margem Potencial</span><div style={{ fontSize: 22, fontWeight: 700, color: "#F59E0B" }}>{formatBRL(MATERIAIS.reduce((s, m) => s + (estoque[m.id] || 0) * ((precos[m.id]?.venda || 0) - (precos[m.id]?.compra || 0)), 0))}</div></div>
          </div>
        </div>
      </div>
    )}

    {/* DESPESAS */}
    {aba === "despesas" && (
      <div>
        <h2 style={S.h2}>Lançar Despesa</h2>
        <div style={S.card}>
          <div style={S.row}>
            <div style={S.fg}><label style={S.label}>Data</label><input type="date" style={S.input} value={formDespesa.data} onChange={e => setFormDespesa({ ...formDespesa, data: e.target.value })} /></div>
            <div style={{ ...S.fg, flex: 3 }}><label style={S.label}>Descrição</label><input type="text" style={S.input} placeholder="Ex: combustível, aluguel container..." value={formDespesa.descricao} onChange={e => setFormDespesa({ ...formDespesa, descricao: e.target.value })} /></div>
            <div style={S.fg}><label style={S.label}>Categoria</label>
              <select style={S.select} value={formDespesa.categoria} onChange={e => setFormDespesa({ ...formDespesa, categoria: e.target.value })}>
                <option value="operacional">Operacional</option>
                <option value="transporte">Transporte</option>
                <option value="pessoal">Pessoal</option>
                <option value="administrativo">Administrativo</option>
                <option value="outros">Outros</option>
              </select>
            </div>
            <div style={S.fg}><label style={S.label}>Valor (R$)</label><input type="number" style={S.input} placeholder="0,00" value={formDespesa.valor} onChange={e => setFormDespesa({ ...formDespesa, valor: e.target.value })} /></div>
            <div style={{ display: "flex", alignItems: "flex-end" }}><button style={S.btn("#DC2626")} onClick={addDespesa}>+ Lançar</button></div>
          </div>
        </div>
        <h2 style={{ ...S.h2, marginTop: 24 }}>Histórico de Despesas</h2>
        <div style={S.card}>
          {despesas.length === 0 ? <div style={{ textAlign: "center", color: "#64748B", padding: 32 }}>Nenhuma despesa lançada.</div> :
            <table style={S.table}><thead><tr>{["Data", "Descrição", "Categoria", "Valor", ""].map(h => <th key={h} style={S.th}>{h}</th>)}</tr></thead>
              <tbody>{[...despesas].reverse().map(d => (
                <tr key={d.id}>
                  <td style={S.td}>{fmtDate(d.data)}</td>
                  <td style={S.td}>{d.descricao}</td>
                  <td style={S.td}><span style={{ background: "#0F172A", padding: "2px 8px", borderRadius: 12, fontSize: 11 }}>{d.categoria}</span></td>
                  <td style={{ ...S.td, color: "#F87171", fontWeight: 700 }}>{formatBRL(d.valor)}</td>
                  <td style={S.td}><button style={{ ...S.btn("#991B1B"), padding: "4px 10px", fontSize: 12 }} onClick={() => setDespesas(despesas.filter(x => x.id !== d.id))}>✕</button></td>
                </tr>
              ))}</tbody>
            </table>}
        </div>
      </div>
    )}

    {/* PROJEÇÃO */}
    {aba === "projecao" && (
      <div>
        <h2 style={S.h2}>Projeção — {new Date().toLocaleDateString("pt-BR", { month: "long", year: "numeric" })}</h2>
        <div style={{ ...S.card, background: "linear-gradient(135deg,#0F2744,#1E3A5F)", marginBottom: 24, borderColor: "#1D4ED8" }}>
          <div style={{ fontSize: 13, color: "#94A3B8", marginBottom: 16 }}>📅 Dia {diaAtual} de {diasNoMes} | Projeção proporcional ao mês completo</div>
          <div style={S.grid2}>
            <div><span style={S.label}>📤 Projeção Vendas</span><div style={{ fontSize: 26, fontWeight: 800, color: "#34D399" }}>{formatBRL(tvm * fator)}</div><div style={S.sub}>Real até hoje: {formatBRL(tvm)}</div></div>
            <div><span style={S.label}>📊 Projeção Lucro</span><div style={{ fontSize: 26, fontWeight: 800, color: lm * fator >= 0 ? "#F59E0B" : "#F87171" }}>{formatBRL(lm * fator)}</div><div style={S.sub}>Real até hoje: {formatBRL(lm)}</div></div>
            <div><span style={S.label}>💰 Projeção Compras</span><div style={{ fontSize: 26, fontWeight: 800, color: "#60A5FA" }}>{formatBRL(tcm * fator)}</div><div style={S.sub}>Real até hoje: {formatBRL(tcm)}</div></div>
            <div><span style={S.label}>💸 Projeção Despesas</span><div style={{ fontSize: 26, fontWeight: 800, color: "#F87171" }}>{formatBRL(tdm * fator)}</div><div style={S.sub}>Real até hoje: {formatBRL(tdm)}</div></div>
          </div>
        </div>
        <h2 style={S.h2}>Por Material</h2>
        <div style={S.card}>
          {ganhoMaterial.length === 0 ? <div style={{ textAlign: "center", color: "#64748B", padding: 32 }}>Registre movimentações para ver a projeção por material.</div> :
            <table style={S.table}><thead><tr>{["Material", "Lucro Real", "Projeção Mês", "Média/dia"].map(h => <th key={h} style={S.th}>{h}</th>)}</tr></thead>
              <tbody>{ganhoMaterial.map(m => (
                <tr key={m.id}>
                  <td style={{ ...S.td, color: m.cor, fontWeight: 600 }}>{m.nome}</td>
                  <td style={{ ...S.td, color: m.lucro >= 0 ? "#34D399" : "#F87171" }}>{formatBRL(m.lucro)}</td>
                  <td style={{ ...S.td, color: "#F59E0B", fontWeight: 700 }}>{formatBRL(m.lucro * fator)}</td>
                  <td style={S.td}>{formatBRL(m.lucro / diaAtual)}/dia</td>
                </tr>
              ))}</tbody>
            </table>}
        </div>
      </div>
    )}

    {/* PREÇOS */}
    {aba === "precos" && (
      <div>
        <h2 style={S.h2}>⚙️ Configurar Preços</h2>
        <div style={{ ...S.card, marginBottom: 12, fontSize: 13, color: "#94A3B8" }}>Os preços são aplicados automaticamente nas compras e vendas.</div>
        <div style={S.card}>
          <table style={S.table}><thead><tr>{["Material", "Preço Compra", "Preço Venda", "Margem R$", "% Margem"].map(h => <th key={h} style={S.th}>{h}</th>)}</tr></thead>
            <tbody>{MATERIAIS.map(m => {
              const pc = precos[m.id]?.compra || 0;
              const pv = precos[m.id]?.venda || 0;
              const mg = pv - pc;
              const pct = pc > 0 ? ((mg / pc) * 100).toFixed(1) : 0;
              return (
                <tr key={m.id}>
                  <td style={{ ...S.td, color: m.cor, fontWeight: 600 }}>{m.nome} ({m.unidade})</td>
                  <td style={S.td}><input type="number" step="0.01" style={{ ...S.input, width: 120 }} value={pc} onChange={e => setPrecos({ ...precos, [m.id]: { ...precos[m.id], compra: parseFloat(e.target.value) || 0 } })} /></td>
                  <td style={S.td}><input type="number" step="0.01" style={{ ...S.input, width: 120 }} value={pv} onChange={e => setPrecos({ ...precos, [m.id]: { ...precos[m.id], venda: parseFloat(e.target.value) || 0 } })} /></td>
                  <td style={{ ...S.td, color: mg >= 0 ? "#34D399" : "#F87171" }}>{formatBRL(mg)}</td>
                  <td style={{ ...S.td, color: "#F59E0B", fontWeight: 600 }}>{pct}%</td>
                </tr>
              );
            })}</tbody>
          </table>
        </div>
      </div>
    )}

  </div>
</div>

);
}

主要言語
JavaScript
スター
538
フォーク
324
PR マージ指標
30日以内にマージされた PR はありません

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

reactjs/pt-br.react.dev のほかの issue

reactjs/pt-br.react.dev の issue をすべて見る

似ている issue

JavaScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。