Files

250 lines
11 KiB
TypeScript

"use client";
import { useEffect, useState } from 'react';
import Link from 'next/link';
import { SolutionGuard } from '@/components/auth/SolutionGuard';
import { useCRMFilter } from '@/contexts/CRMFilterContext';
import KanbanBoard from '@/components/crm/KanbanBoard';
import {
UsersIcon,
CurrencyDollarIcon,
ChartPieIcon,
ArrowTrendingUpIcon,
ListBulletIcon,
ArrowRightIcon,
MegaphoneIcon,
RectangleStackIcon,
} from '@heroicons/react/24/outline';
function CRMDashboardContent() {
const { selectedCustomerId } = useCRMFilter();
console.log('🏠 CRMPage (Content) render, selectedCustomerId:', selectedCustomerId);
const [stats, setStats] = useState([
{ name: 'Leads Totais', value: '0', icon: UsersIcon, color: 'blue' },
{ name: 'Clientes', value: '0', icon: UsersIcon, color: 'green' },
{ name: 'Campanhas', value: '0', icon: MegaphoneIcon, color: 'purple' },
{ name: 'Taxa de Conversão', value: '0%', icon: ChartPieIcon, color: 'orange' },
]);
const [loading, setLoading] = useState(true);
const [defaultFunnelId, setDefaultFunnelId] = useState<string>('');
useEffect(() => {
console.log('🔄 CRM Dashboard: selectedCustomerId changed to:', selectedCustomerId);
fetchDashboardData();
fetchDefaultFunnel();
}, [selectedCustomerId]);
const fetchDefaultFunnel = async () => {
try {
const response = await fetch('/api/crm/funnels', {
headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` }
});
if (response.ok) {
const data = await response.json();
if (data.funnels?.length > 0) {
setDefaultFunnelId(data.funnels[0].id);
}
}
} catch (error) {
console.error('Error fetching funnels:', error);
}
};
const fetchDashboardData = async () => {
try {
setLoading(true);
// Adicionando um timestamp para evitar cache agressivo do navegador
const timestamp = new Date().getTime();
const url = selectedCustomerId
? `/api/crm/dashboard?customer_id=${selectedCustomerId}&t=${timestamp}`
: `/api/crm/dashboard?t=${timestamp}`;
console.log(`📊 Fetching dashboard data from: ${url}`);
const response = await fetch(url, {
method: 'GET',
headers: {
'Authorization': `Bearer ${localStorage.getItem('token')}`,
'Cache-Control': 'no-cache',
'Pragma': 'no-cache'
},
});
if (response.ok) {
const data = await response.json();
console.log('📊 Dashboard data received:', data);
const s = data.stats;
setStats([
{ name: 'Leads Totais', value: s.total.toString(), icon: UsersIcon, color: 'blue' },
{ name: 'Clientes', value: s.total_customers.toString(), icon: UsersIcon, color: 'green' },
{ name: 'Campanhas', value: s.total_campaigns.toString(), icon: MegaphoneIcon, color: 'purple' },
{ name: 'Taxa de Conversão', value: `${s.conversionRate || 0}%`, icon: ChartPieIcon, color: 'orange' },
]);
} else {
console.error('📊 Error response from dashboard:', response.status);
}
} catch (error) {
console.error('Error fetching CRM dashboard data:', error);
} finally {
setLoading(false);
}
};
const quickLinks = [
{
name: 'Funis de Vendas',
description: 'Configure seus processos e etapas',
icon: RectangleStackIcon,
href: '/crm/funis',
color: 'blue',
},
{
name: 'Clientes',
description: 'Gerencie seus contatos e clientes',
icon: UsersIcon,
href: '/crm/clientes',
color: 'indigo',
},
{
name: 'Campanhas',
description: 'Organize leads e rastreie origens',
icon: MegaphoneIcon,
href: '/crm/campanhas',
color: 'purple',
},
{
name: 'Leads',
description: 'Gerencie potenciais clientes',
icon: UsersIcon,
href: '/crm/leads',
color: 'green',
},
];
return (
<div className="p-6 h-full overflow-auto">
<div className="space-y-6">
<div>
<h1 className="text-2xl font-bold text-gray-900 dark:text-white">
CRM
</h1>
<p className="mt-1 text-sm text-gray-600 dark:text-gray-400">
Visão geral do relacionamento com clientes
</p>
</div>
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
{stats.map((stat) => {
const Icon = stat.icon;
return (
<div
key={stat.name}
className="group relative overflow-hidden rounded-xl bg-white dark:bg-gray-900 p-4 border border-gray-200 dark:border-gray-800 transition-all"
>
<div className="flex items-center justify-between">
<div>
<p className="text-xs font-medium text-gray-600 dark:text-gray-400">
{stat.name}
</p>
<p className="mt-1 text-2xl font-bold text-gray-900 dark:text-white">
{stat.value}
</p>
</div>
<div
className={`rounded-lg p-2 bg-${stat.color}-100 dark:bg-${stat.color}-900/20`}
>
<Icon
className={`h-5 w-5 text-${stat.color}-600 dark:text-${stat.color}-400`}
/>
</div>
</div>
</div>
);
})}
</div>
{/* Quick Links */}
<div className="mb-6">
<h2 className="text-lg font-semibold text-gray-900 dark:text-white mb-4">
Acesso Rápido
</h2>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{quickLinks.map((link) => {
const Icon = link.icon;
return (
<Link
key={link.name}
href={link.href}
className="group relative overflow-hidden rounded-xl bg-white dark:bg-gray-900 p-6 border border-gray-200 dark:border-gray-800 hover:border-gray-300 dark:hover:border-gray-700 transition-all hover:shadow-lg"
>
<div className="flex items-start justify-between">
<div className="flex items-start gap-4">
<div
className={`rounded-lg p-3 bg-${link.color}-100 dark:bg-${link.color}-900/20`}
>
<Icon
className={`h-6 w-6 text-${link.color}-600 dark:text-${link.color}-400`}
/>
</div>
<div>
<h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-1">
{link.name}
</h3>
<p className="text-sm text-gray-600 dark:text-gray-400">
{link.description}
</p>
</div>
</div>
<ArrowRightIcon className="w-5 h-5 text-gray-400 group-hover:text-gray-600 dark:group-hover:text-gray-300 group-hover:translate-x-1 transition-all" />
</div>
</Link>
);
})}
</div>
</div>
<div className="space-y-6">
<div className="flex items-center justify-between">
<h2 className="text-lg font-semibold text-gray-900 dark:text-white">
Monitoramento de Leads
</h2>
<Link href="/crm/funis" className="text-sm font-medium text-brand-600 hover:underline">
Gerenciar Funis
</Link>
</div>
<div className="rounded-xl bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 p-6 min-h-[500px]">
{defaultFunnelId ? (
<KanbanBoard funnelId={defaultFunnelId} />
) : (
<div className="flex flex-col items-center justify-center h-64 text-center">
<RectangleStackIcon className="h-12 w-12 text-gray-300 mb-4" />
<p className="text-gray-500">Nenhum funil configurado.</p>
<Link href="/crm/funis" className="mt-4 px-4 py-2 bg-brand-600 text-white rounded-lg text-sm font-bold">
CRIAR PRIMEIRO FUNIL
</Link>
</div>
)}
</div>
</div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<div className="rounded-xl bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 p-6 h-64 flex items-center justify-center">
<p className="text-gray-500">Atividades Recentes (Em breve)</p>
</div>
<div className="rounded-xl bg-white dark:bg-gray-900 border border-gray-200 dark:border-gray-800 p-6 h-64 flex items-center justify-center">
<p className="text-gray-500">Metas de Vendas (Em breve)</p>
</div>
</div>
</div>
</div>
);
}
export default function CRMPage() {
return (
<SolutionGuard requiredSolution="crm">
<CRMDashboardContent />
</SolutionGuard>
);
}