function ScreenNewQuotation({ setRoute }) { const { CATEGORIES, BRL } = window.SCP; const [step, setStep] = useState(1); const [title, setTitle] = useState('Cotação Semanal · ' + new Date().toLocaleDateString('pt-BR', { day: '2-digit', month: 'short' })); const [items, setItems] = useState([]); // [{ id (uuid), qty }] const [selectedSups, setSelectedSups] = useState([]); // [uuid] const [deadline, setDeadline] = useState(new Date(Date.now() + 2 * 86400000).toISOString().slice(0, 16)); const [obs, setObs] = useState('Pagamento 28 dias · Entrega na Rua Carlos Gomes, 1244 · Receber entre 8h e 11h'); const [channels, setChannels] = useState({ email: true, whats: true, link: true }); const [aiSuggest, setAiSuggest] = useState(true); const [showProductPicker, setShowProductPicker] = useState(false); const [allProducts, setAllProducts] = useState([]); const [allSuppliers, setAllSuppliers] = useState([]); const [loading, setLoading] = useState(true); const [submitting, setSubmitting] = useState(false); // Aliases p/ produto vindo do banco (compatibilidade com a JSX existente) const adaptProduct = (p) => ({ ...p, lastPrice: Number(p.last_price ?? p.lastPrice ?? 0), min: p.min_stock ?? p.min ?? 0, photo: p.photo_url ?? p.photo ?? null, supplier: p.preferred_supplier?.name || p.supplier || '—', }); useEffect(() => { let mounted = true; (async () => { try { const [prods, sups] = await Promise.all([ window.scpDb.products.list(), window.scpDb.suppliers.list(), ]); if (!mounted) return; setAllProducts(prods.map(adaptProduct)); setAllSuppliers(sups); } catch (e) { if (mounted) window.scpToast('Falha ao carregar dados', { kind: 'coral', sub: e.message }); } finally { if (mounted) setLoading(false); } })(); return () => { mounted = false; }; }, []); const PRODUCTS = allProducts; const SUPPLIERS = allSuppliers; const itemsFull = items.map(it => { const p = PRODUCTS.find(p => p.id === it.id); return p ? { ...p, qty: it.qty } : null; }).filter(Boolean); const handleSubmit = async () => { if (!title.trim()) { window.scpToast('Defina um título', { kind: 'amber' }); setStep(1); return; } if (items.length === 0) { window.scpToast('Adicione produtos', { kind: 'amber' }); setStep(2); return; } if (selectedSups.length === 0) { window.scpToast('Selecione fornecedores', { kind: 'amber' }); setStep(3); return; } setSubmitting(true); try { const created = await window.scpDb.quotations.create({ title: title.trim(), deadline: deadline ? new Date(deadline).toISOString() : null, obs: obs.trim() || null, items: itemsFull.map(p => ({ product_id: p.id, name: p.name, unit: p.unit, qty: p.qty, last_price: p.lastPrice, })), supplier_ids: selectedSups, }); window.scpToast('Cotação enviada', { kind: 'emerald', sub: `${created.code} · ${selectedSups.length} fornecedores` }); setTimeout(() => setRoute('quotations'), 600); } catch (e) { window.scpToast('Erro ao criar cotação', { kind: 'coral', sub: e.message }); } finally { setSubmitting(false); } }; return (
} onClick={() => setRoute('quotations')}>Cancelar
{[ { n: 1, t: 'Informações', i: }, { n: 2, t: 'Produtos', i: }, { n: 3, t: 'Fornecedores', i: }, { n: 4, t: 'Envio & revisão', i: }, ].map(s => (
s.n && 'done')}> {step > s.n ? : s.n}
{s.t}
))}

Resumo

Itens{items.length}
Fornecedores{selectedSups.length}
Estimativa{BRL(itemsFull.reduce((s, i) => s + i.lastPrice * i.qty, 0))}
Prazo{deadline.split('T')[0].split('-').reverse().join('/')}
{step === 1 && (

Configure a cotação

Defina título, prazo e observações que aparecerão para todos os fornecedores.