// Tela: Oportunidades — pipeline + tabela / kanban const { useState: useOpState } = React; /* ─── Modal criar / editar oportunidade ─────────────────── */ function OportunidadeModal({ stages, onClose, onCreate, onUpdate, initialData }) { const isEdit = !!initialData; const [conta, setConta] = useOpState(initialData?.conta || ''); const [valor, setValor] = useOpState(initialData?.valor ? String(initialData.valor) : ''); const [etapa, setEtapa] = useOpState(initialData?.etapa || 'Qualificado'); const [prob, setProb] = useOpState(initialData?.prob ?? 50); const [fecha, setFecha] = useOpState(initialData?.fecha || ''); const toast = useToast(); const valid = conta.trim().length > 0; const submit = () => { if (!valid) return; const dados = { conta: conta.trim(), valor: parseInt(String(valor).replace(/\D/g,'')) || 0, etapa, prob, fecha: fecha || 'A definir', dono: initialData?.dono || CONTATOS[0], }; if (isEdit) { if (onUpdate) onUpdate(dados); toast(`"${conta.trim()}" atualizada ✓`); } else { if (onCreate) onCreate({ ...dados, id: Date.now() }); toast(`Oportunidade "${conta.trim()}" criada ✓`); } onClose(); }; return (
| ${h} | `).join('')}
|---|
| ${c} | `).join('')}
${rows.length} negócios · exportado em ${new Date().toLocaleDateString('pt-BR')}
| ${h} | `).join('')}
|---|
| ${i===1?'R$ '+Number(c).toLocaleString('pt-BR'):c} | `).join('')}
| Responsável | ||||||
|---|---|---|---|---|---|---|
| {o.conta} | R$ {o.valor.toLocaleString('pt-BR')} | {o.etapa} |
|
{o.fecha} |
onOpenContact && onOpenContact(o.dono.id)}
style={{cursor: onOpenContact ? 'pointer' : 'default'}}>
|
|
| Nenhuma oportunidade bate com os filtros. | ||||||