// CRM — Kanban pipeline with drag & drop const CRM = ({ onNavigate }) => { const initialLeads = { novo: [ { id: 'l1', name: 'Giovanna Prado', company: 'Padaria Sol Nascente', value: 4800, churn: 8, owner: 'Camila Rocha', source: 'Google Maps', days: 1, tags: ['Simples Nacional'] }, { id: 'l2', name: 'Rodrigo Alves', company: 'Restaurante do Zé', value: 7200, churn: 12, owner: 'Bruno Tavares', source: 'WhatsApp', days: 2, tags: ['MEI'] }, { id: 'l3', name: 'Fernanda Lima', company: 'Loja Vila Nova', value: 3200, churn: 6, owner: 'Camila Rocha', source: 'Site', days: 1, tags: [] }, ], qualificacao: [ { id: 'l4', name: 'Marcos Souza', company: 'Oficina Souza Motors', value: 11400, churn: 22, owner: 'Camila Rocha', source: 'Indicação', days: 4, tags: ['Lucro Presumido'] }, { id: 'l5', name: 'Juliana Xavier', company: 'Clínica Vida Plena', value: 18900, churn: 15, owner: 'Bruno Tavares', source: 'Google Ads', days: 3, tags: ['15 funcionários'] }, ], proposta: [ { id: 'l6', name: 'Eduardo Barreto', company: 'Supermercado Barreto', value: 26500, churn: 18, owner: 'Camila Rocha', source: 'Indicação', days: 7, tags: ['PDV', '28 funcionários'] }, { id: 'l7', name: 'Patrícia Reis', company: 'Hamburgueria 22', value: 12400, churn: 9, owner: 'João Pedro', source: 'Instagram', days: 5, tags: [] }, { id: 'l8', name: 'Gustavo Pinheiro', company: 'Pet Shop Amigo Fiel', value: 6800, churn: 11, owner: 'Camila Rocha', source: 'Site', days: 4, tags: ['Simples Nacional'] }, ], negociacao: [ { id: 'l9', name: 'Renata Colucci', company: 'Distribuidora RC', value: 38900, churn: 42, owner: 'Bruno Tavares', source: 'Indicação', days: 12, tags: ['ALTO VALOR', '50+ funcionários'] }, { id: 'l10', name: 'Anderson Viana', company: 'Construtora AV', value: 24000, churn: 28, owner: 'Camila Rocha', source: 'Google Ads', days: 9, tags: [] }, ], ganho: [ { id: 'l11', name: 'Letícia Fonseca', company: 'Farmácia Bem Estar', value: 9600, churn: 3, owner: 'Bruno Tavares', source: 'Indicação', days: 0, tags: [] }, { id: 'l12', name: 'Carlos Mendonça', company: 'Padaria São João', value: 14800, churn: 5, owner: 'Camila Rocha', source: 'Site', days: 0, tags: [] }, ], perdido: [ { id: 'l13', name: 'Sérgio Paiva', company: 'Mecânica Rápida', value: 5400, churn: 78, owner: 'João Pedro', source: 'WhatsApp', days: 14, tags: ['Preço'] }, ], }; const columns = [ { id: 'novo', label: 'Novo lead', color: 'var(--ink-500)' }, { id: 'qualificacao', label: 'Qualificação', color: 'var(--blue-500)' }, { id: 'proposta', label: 'Proposta enviada', color: 'var(--amber-500)' }, { id: 'negociacao', label: 'Negociação', color: 'var(--coral-500)' }, { id: 'ganho', label: 'Fechado — Ganho', color: 'var(--green-500)' }, { id: 'perdido', label: 'Perdido', color: 'var(--red-500)' }, ]; const [leads, setLeads] = React.useState(initialLeads); const [selected, setSelected] = React.useState(initialLeads.negociacao[0]); const [dragging, setDragging] = React.useState(null); const [dragOver, setDragOver] = React.useState(null); const [filterOwner, setFilterOwner] = React.useState('todos'); const [filterPeriod, setFilterPeriod] = React.useState('30d'); const onDragStart = (lead, colId) => setDragging({ lead, from: colId }); const onDragEnd = () => { setDragging(null); setDragOver(null); }; const onDrop = (toCol) => { if (!dragging || dragging.from === toCol) { setDragging(null); setDragOver(null); return; } setLeads(prev => { const next = { ...prev }; next[dragging.from] = next[dragging.from].filter(l => l.id !== dragging.lead.id); next[toCol] = [dragging.lead, ...next[toCol]]; return next; }); setDragging(null); setDragOver(null); }; const totalValue = Object.values(leads).flat().reduce((s, l) => s + l.value, 0); const wonValue = leads.ganho.reduce((s, l) => s + l.value, 0); const churnColor = (c) => c > 40 ? 'var(--red-500)' : c > 20 ? 'var(--amber-500)' : 'var(--green-500)'; const churnLabel = (c) => c > 40 ? 'Alto' : c > 20 ? 'Médio' : 'Baixo'; return (
Pipeline de vendas
CRM · 13 leads ativos · arraste para mover entre etapas
Pipeline total{BRL(totalValue)}
Fechados em abril{BRL(wonValue)}
Taxa conversão32,4%
Filtros
setFilterOwner('todos')}> Vendedor: Todos
Etapa: Todas
Período: 30 dias
Score churn
{columns.map(col => { const items = leads[col.id] || []; const sum = items.reduce((s, l) => s + l.value, 0); return (
{ e.preventDefault(); setDragOver(col.id); }} onDragLeave={() => setDragOver(null)} onDrop={() => onDrop(col.id)} >
{col.label} {items.length}
{BRL(sum)}
{items.map(lead => (
onDragStart(lead, col.id)} onDragEnd={onDragEnd} onClick={() => setSelected(lead)} >
{lead.name}
{lead.company}
{BRLShort(lead.value)}
{lead.tags.length > 0 && (
{lead.tags.map(t => ( {t} ))}
)}
Churn {lead.churn}% · {churnLabel(lead.churn)}
))}
); })}
{selected && ( )}
); }; Object.assign(window, { CRM });