import React, { useState, useEffect } from 'react'; import { Layers, Plus, Edit, Trash2, ChevronUp, ChevronDown, Loader2, X, CheckCircle2 } from 'lucide-react'; import { getFunnels, createFunnel, updateFunnel, deleteFunnel } from '../services/dataService'; import { FunnelStageDef } from '../types'; export const Funnels: React.FC = () => { const [funnels, setFunnels] = useState([]); const [loading, setLoading] = useState(true); const [isModalOpen, setIsModalOpen] = useState(false); const [editingFunnel, setEditingFunnel] = useState(null); const [formData, setFormData] = useState({ name: '', color_class: '' }); const [isSaving, setIsSaving] = useState(false); const tenantId = localStorage.getItem('ctms_tenant_id') || ''; const PRESET_COLORS = [ { label: 'Cinza (Neutro)', value: 'bg-zinc-100 text-zinc-700 border-zinc-200 dark:bg-dark-input dark:text-dark-muted dark:border-dark-border' }, { label: 'Azul (Início)', value: 'bg-blue-100 text-blue-700 border-blue-200 dark:bg-blue-900/30 dark:text-blue-400 dark:border-blue-800' }, { label: 'Roxo (Meio)', value: 'bg-purple-100 text-purple-700 border-purple-200 dark:bg-purple-900/30 dark:text-purple-400 dark:border-purple-800' }, { label: 'Laranja (Atenção)', value: 'bg-orange-100 text-orange-700 border-orange-200 dark:bg-orange-900/30 dark:text-orange-400 dark:border-orange-800' }, { label: 'Verde (Sucesso)', value: 'bg-green-100 text-green-700 border-green-200 dark:bg-green-900/30 dark:text-green-400 dark:border-green-800' }, { label: 'Vermelho (Perda)', value: 'bg-red-100 text-red-700 border-red-200 dark:bg-red-900/30 dark:text-red-400 dark:border-red-800' }, ]; const loadFunnels = async () => { setLoading(true); const data = await getFunnels(tenantId); setFunnels(data.sort((a, b) => a.order_index - b.order_index)); setLoading(false); }; useEffect(() => { loadFunnels(); }, [tenantId]); const handleSave = async (e: React.FormEvent) => { e.preventDefault(); setIsSaving(true); try { if (editingFunnel) { await updateFunnel(editingFunnel.id, formData); } else { await createFunnel({ ...formData, tenantId, order_index: funnels.length }); } setIsModalOpen(false); loadFunnels(); } catch (err) { alert("Erro ao salvar etapa."); } finally { setIsSaving(false); } }; const handleDelete = async (id: string) => { if (confirm('Tem certeza que deseja excluir esta etapa?')) { await deleteFunnel(id); loadFunnels(); } }; const handleMove = async (index: number, direction: 'up' | 'down') => { if (direction === 'up' && index === 0) return; if (direction === 'down' && index === funnels.length - 1) return; const newIndex = direction === 'up' ? index - 1 : index + 1; const newFunnels = [...funnels]; // Swap order_index const tempOrder = newFunnels[index].order_index; newFunnels[index].order_index = newFunnels[newIndex].order_index; newFunnels[newIndex].order_index = tempOrder; // Optimistic UI update setFunnels(newFunnels.sort((a, b) => a.order_index - b.order_index)); // Persist to backend await Promise.all([ updateFunnel(newFunnels[index].id, { order_index: newFunnels[index].order_index }), updateFunnel(newFunnels[newIndex].id, { order_index: newFunnels[newIndex].order_index }) ]); }; const openModal = (funnel?: FunnelStageDef) => { if (funnel) { setEditingFunnel(funnel); setFormData({ name: funnel.name, color_class: funnel.color_class }); } else { setEditingFunnel(null); setFormData({ name: '', color_class: PRESET_COLORS[0].value }); } setIsModalOpen(true); }; if (loading) return
; return (

Personalizar Funil

Crie, edite e reordene as etapas do funil de vendas da sua organização.

Etapas do Funil

{funnels.map((f, index) => (
{f.name}
))} {funnels.length === 0 && (
Nenhuma etapa configurada.
)}
{isModalOpen && (

{editingFunnel ? 'Editar Etapa' : 'Nova Etapa'}

setFormData({...formData, name: e.target.value})} placeholder="Ex: Qualificação" className="w-full bg-white dark:bg-dark-input border border-zinc-200 dark:border-dark-border p-3 rounded-lg text-sm text-zinc-900 dark:text-zinc-100 focus:ring-2 focus:ring-brand-yellow/20 outline-none transition-all" required />
{PRESET_COLORS.map((color, i) => ( ))}
)}
); };