Files
digitCRM/frontend/client/src/pages/Analytics.tsx

193 lines
6.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { useEffect, useState } from 'react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { analyticsAPI } from '@/lib/api';
import { BarChart, Bar, PieChart, Pie, Cell, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer, LineChart, Line } from 'recharts';
import DashboardLayout from '@/components/DashboardLayout';
const COLORS = ['#3b82f6', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6', '#ec4899'];
export default function Analytics() {
const [contactsByStatus, setContactsByStatus] = useState<any[]>([]);
const [contactsByType, setContactsByType] = useState<any[]>([]);
const [ticketsByStatus, setTicketsByStatus] = useState<any[]>([]);
const [ticketsByPriority, setTicketsByPriority] = useState<any[]>([]);
const [feedbackByRating, setFeedbackByRating] = useState<any[]>([]);
const [campaignPerformance, setCampaignPerformance] = useState<any[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetchAnalytics();
}, []);
const fetchAnalytics = async () => {
try {
setLoading(true);
const [
statusRes,
typeRes,
ticketsStatusRes,
ticketsPriorityRes,
feedbackRes,
campaignRes,
] = await Promise.all([
analyticsAPI.getContactsByStatus(),
analyticsAPI.getContactsByType(),
analyticsAPI.getTicketsByStatus(),
analyticsAPI.getTicketsByPriority(),
analyticsAPI.getFeedbackByRating(),
analyticsAPI.getCampaignPerformance(),
]);
setContactsByStatus(statusRes.data);
setContactsByType(typeRes.data);
setTicketsByStatus(ticketsStatusRes.data);
setTicketsByPriority(ticketsPriorityRes.data);
setFeedbackByRating(feedbackRes.data);
setCampaignPerformance(campaignRes.data);
} catch (error) {
console.error('Error fetching analytics:', error);
} finally {
setLoading(false);
}
};
if (loading) {
return (
<DashboardLayout>
<div className="text-center py-12">Зареждане...</div>
</DashboardLayout>
);
}
return (
<DashboardLayout>
<div className="space-y-6">
<h1 className="text-3xl font-bold">Аналитика</h1>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
{/* Contacts by Status */}
<Card>
<CardHeader>
<CardTitle>Контакти по статус</CardTitle>
</CardHeader>
<CardContent>
<ResponsiveContainer width="100%" height={300}>
<PieChart>
<Pie
data={contactsByStatus}
dataKey="Count"
nameKey="Status"
cx="50%"
cy="50%"
outerRadius={80}
label
>
{contactsByStatus.map((entry, index) => (
<Cell key={`cell-${index}`} fill={COLORS[index % COLORS.length]} />
))}
</Pie>
<Tooltip />
</PieChart>
</ResponsiveContainer>
</CardContent>
</Card>
{/* Contacts by Type */}
<Card>
<CardHeader>
<CardTitle>Контакти по тип</CardTitle>
</CardHeader>
<CardContent>
<ResponsiveContainer width="100%" height={300}>
<BarChart data={contactsByType}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="ContactType" />
<YAxis />
<Tooltip />
<Bar dataKey="Count" fill="#3b82f6" />
</BarChart>
</ResponsiveContainer>
</CardContent>
</Card>
{/* Tickets by Status */}
<Card>
<CardHeader>
<CardTitle>Билети по статус</CardTitle>
</CardHeader>
<CardContent>
<ResponsiveContainer width="100%" height={300}>
<BarChart data={ticketsByStatus}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="Status" />
<YAxis />
<Tooltip />
<Bar dataKey="Count" fill="#10b981" />
</BarChart>
</ResponsiveContainer>
</CardContent>
</Card>
{/* Tickets by Priority */}
<Card>
<CardHeader>
<CardTitle>Билети по приоритет</CardTitle>
</CardHeader>
<CardContent>
<ResponsiveContainer width="100%" height={300}>
<BarChart data={ticketsByPriority}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="Priority" />
<YAxis />
<Tooltip />
<Bar dataKey="Count" fill="#f59e0b" />
</BarChart>
</ResponsiveContainer>
</CardContent>
</Card>
{/* Feedback by Rating */}
<Card>
<CardHeader>
<CardTitle>Обратна връзка по рейтинг</CardTitle>
</CardHeader>
<CardContent>
<ResponsiveContainer width="100%" height={300}>
<BarChart data={feedbackByRating}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="Rating" />
<YAxis />
<Tooltip />
<Bar dataKey="Count" fill="#ef4444" />
</BarChart>
</ResponsiveContainer>
</CardContent>
</Card>
{/* Campaign Performance */}
<Card>
<CardHeader>
<CardTitle>Производителност на кампаниите</CardTitle>
</CardHeader>
<CardContent>
<div className="space-y-4 max-h-80 overflow-y-auto">
{campaignPerformance.map((campaign, index) => (
<div key={index} className="border-b pb-4 last:border-b-0">
<h4 className="font-semibold text-sm">{campaign.CampaignName}</h4>
<div className="grid grid-cols-2 gap-2 mt-2 text-xs text-muted-foreground">
<div>Изпратени: {campaign.Sent}</div>
<div>Отворени: {campaign.Opened}</div>
<div>Кликнати: {campaign.Clicked}</div>
<div>Open Rate: {campaign.OpenRate}%</div>
</div>
</div>
))}
</div>
</CardContent>
</Card>
</div>
</div>
</DashboardLayout>
);
}