"use client"; import { Fragment, useEffect, useState, use } from 'react'; import { Tab, Menu, Transition } from '@headlessui/react'; import { UserGroupIcon, InformationCircleIcon, CreditCardIcon, ArrowLeftIcon, PlusIcon, MagnifyingGlassIcon, FunnelIcon, EllipsisVerticalIcon, PencilIcon, TrashIcon, EnvelopeIcon, PhoneIcon, TagIcon, CalendarIcon, UserIcon, ArrowDownTrayIcon, BriefcaseIcon, } from '@heroicons/react/24/outline'; import Link from 'next/link'; import { useToast } from '@/components/layout/ToastContext'; import KanbanBoard from '@/components/crm/KanbanBoard'; interface Lead { id: string; name: string; email: string; phone: string; status: string; created_at: string; tags: string[]; } interface Campaign { id: string; name: string; description: string; color: string; customer_id: string; customer_name: string; lead_count: number; created_at: string; } const STATUS_OPTIONS = [ { value: 'novo', label: 'Novo', color: 'bg-blue-100 text-blue-800 dark:bg-blue-900 dark:text-blue-200' }, { value: 'qualificado', label: 'Qualificado', color: 'bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200' }, { value: 'negociacao', label: 'Em Negociação', color: 'bg-yellow-100 text-yellow-800 dark:bg-yellow-900 dark:text-yellow-200' }, { value: 'convertido', label: 'Convertido', color: 'bg-purple-100 text-purple-800 dark:bg-purple-900 dark:text-purple-200' }, { value: 'perdido', label: 'Perdido', color: 'bg-red-100 text-red-800 dark:bg-red-900 dark:text-red-200' }, ]; function classNames(...classes: string[]) { return classes.filter(Boolean).join(' '); } export default function CampaignDetailPage({ params }: { params: Promise<{ id: string }> }) { const { id } = use(params); const toast = useToast(); const [campaign, setCampaign] = useState(null); const [leads, setLeads] = useState([]); const [loading, setLoading] = useState(true); const [searchTerm, setSearchTerm] = useState(''); const [funnels, setFunnels] = useState([]); const [selectedFunnelId, setSelectedFunnelId] = useState(''); useEffect(() => { fetchCampaignDetails(); fetchCampaignLeads(); fetchFunnels(); }, [id]); const fetchFunnels = async () => { try { const response = await fetch('/api/crm/funnels', { headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` } }); if (response.ok) { const data = await response.json(); setFunnels(data.funnels || []); if (data.funnels?.length > 0) { setSelectedFunnelId(data.funnels[0].id); } } } catch (error) { console.error('Error fetching funnels:', error); } }; const fetchCampaignDetails = async () => { try { const response = await fetch(`/api/crm/lists`, { headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}`, }, }); if (response.ok) { const data = await response.json(); const found = data.lists?.find((l: Campaign) => l.id === id); if (found) { setCampaign(found); } } } catch (error) { console.error('Error fetching campaign details:', error); } }; const fetchCampaignLeads = async () => { try { const response = await fetch(`/api/crm/lists/${id}/leads`, { headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}`, }, }); if (response.ok) { const data = await response.json(); setLeads(data.leads || []); } } catch (error) { console.error('Error fetching leads:', error); } finally { setLoading(false); } }; const filteredLeads = leads.filter(lead => (lead.name?.toLowerCase() || '').includes(searchTerm.toLowerCase()) || (lead.email?.toLowerCase() || '').includes(searchTerm.toLowerCase()) ); const handleExport = async (format: 'csv' | 'xlsx' | 'json') => { try { const token = localStorage.getItem('token'); const response = await fetch(`/api/crm/leads/export?format=${format}&campaign_id=${id}`, { headers: { 'Authorization': `Bearer ${token}` } }); if (response.ok) { const blob = await response.blob(); const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `leads-${campaign?.name || 'campaign'}.${format === 'xlsx' ? 'xlsx' : format}`; document.body.appendChild(a); a.click(); window.URL.revokeObjectURL(url); document.body.removeChild(a); toast.success('Exportado com sucesso!'); } else { toast.error('Erro ao exportar leads'); } } catch (error) { console.error('Export error:', error); toast.error('Erro ao exportar'); } }; if (loading && !campaign) { return (
); } if (!campaign) { return (

Campanha não encontrada

Voltar para Campanhas
); } return (
{/* Header */}
Voltar para Campanhas

{campaign.name}

{campaign.customer_name ? ( {campaign.customer_name} ) : ( Geral )} {leads.length} leads vinculados
Exportar
{({ active }) => ( )} {({ active }) => ( )} {({ active }) => ( )}
Importar Leads
{/* Tabs */} classNames( 'w-full rounded-lg py-2.5 text-sm font-medium leading-5 transition-all duration-200', 'ring-white ring-opacity-60 ring-offset-2 ring-offset-brand-400 focus:outline-none', selected ? 'bg-white dark:bg-zinc-900 text-brand-600 dark:text-brand-400 shadow-sm' : 'text-zinc-500 hover:text-zinc-700 dark:text-zinc-400 dark:hover:text-zinc-200 hover:bg-white/[0.12]' ) }>
Monitoramento
classNames( 'w-full rounded-lg py-2.5 text-sm font-medium leading-5 transition-all duration-200', 'ring-white ring-opacity-60 ring-offset-2 ring-offset-brand-400 focus:outline-none', selected ? 'bg-white dark:bg-zinc-900 text-brand-600 dark:text-brand-400 shadow-sm' : 'text-zinc-500 hover:text-zinc-700 dark:text-zinc-400 dark:hover:text-zinc-200 hover:bg-white/[0.12]' ) }>
Leads
classNames( 'w-full rounded-lg py-2.5 text-sm font-medium leading-5 transition-all duration-200', 'ring-white ring-opacity-60 ring-offset-2 ring-offset-brand-400 focus:outline-none', selected ? 'bg-white dark:bg-zinc-900 text-brand-600 dark:text-brand-400 shadow-sm' : 'text-zinc-500 hover:text-zinc-700 dark:text-zinc-400 dark:hover:text-zinc-200 hover:bg-white/[0.12]' ) }>
Informações
classNames( 'w-full rounded-lg py-2.5 text-sm font-medium leading-5 transition-all duration-200', 'ring-white ring-opacity-60 ring-offset-2 ring-offset-brand-400 focus:outline-none', selected ? 'bg-white dark:bg-zinc-900 text-brand-600 dark:text-brand-400 shadow-sm' : 'text-zinc-500 hover:text-zinc-700 dark:text-zinc-400 dark:hover:text-zinc-200 hover:bg-white/[0.12]' ) }>
Pagamentos
{/* Monitoramento Panel */} {funnels.length > 0 ? (

Monitoramento de Leads

Acompanhe o progresso dos leads desta campanha no funil.

) : (

Nenhum funil configurado

Configure um funil de vendas para começar a monitorar os leads desta campanha.

Configurar Funis
)}
{/* Leads Panel */}
setSearchTerm(e.target.value)} />
{filteredLeads.length === 0 ? (

Nenhum lead encontrado

{searchTerm ? 'Nenhum lead corresponde à sua busca.' : 'Esta campanha ainda não possui leads vinculados.'}

) : (
{filteredLeads.map((lead) => (

{lead.name || 'Sem nome'}

s.value === lead.status)?.color || 'bg-zinc-100 text-zinc-800' )}> {STATUS_OPTIONS.find(s => s.value === lead.status)?.label || lead.status}
{lead.email && (
{lead.email}
)} {lead.phone && (
{lead.phone}
)}
{new Date(lead.created_at).toLocaleDateString('pt-BR')}
))}
)}
{/* Info Panel */}

Detalhes da Campanha

{campaign.description || 'Nenhuma descrição fornecida para esta campanha.'}

{new Date(campaign.created_at).toLocaleDateString('pt-BR', { day: '2-digit', month: 'long', year: 'numeric' })}
{campaign.color}

Configurações de Integração

Webhook de Entrada

Use este endpoint para enviar leads automaticamente de outras plataformas (Typeform, Elementor, etc).

https://api.aggios.app/v1/webhooks/leads/{campaign.id}

Cliente Responsável

{campaign.customer_id ? (

{campaign.customer_name}

Cliente Ativo

Ver Perfil do Cliente
) : (

Esta é uma campanha geral da agência.

)}

Resumo de Performance

Total de Leads {leads.length}

+12% em relação ao mês passado

{/* Payments Panel */}

Módulo de Pagamentos

Em breve você poderá gerenciar orçamentos, faturas e pagamentos vinculados diretamente a esta campanha.

); }