'use client'; import { Card } from '@/components/ui/Card'; import { StatCard, ProgressBar } from '@/components/ui'; import { getDashboardStatColors } from '@/lib/status-config'; import { useTasksContext } from '@/contexts/TasksContext'; import { useMemo } from 'react'; import { PieChart, Pie, Cell, ResponsiveContainer, Tooltip, Legend, PieLabelRenderProps } from 'recharts'; interface DashboardStatsProps { selectedSources?: string[]; hiddenSources?: string[]; } export function DashboardStats({ selectedSources = [], hiddenSources = [] }: DashboardStatsProps) { const { regularTasks } = useTasksContext(); // Calculer les stats filtrées selon les sources const filteredStats = useMemo(() => { let filteredTasks = regularTasks; // Si on a des sources sélectionnées, ne garder que celles-ci if (selectedSources.length > 0) { filteredTasks = filteredTasks.filter(task => selectedSources.includes(task.source) ); } else if (hiddenSources.length > 0) { // Sinon, retirer les sources masquées filteredTasks = filteredTasks.filter(task => !hiddenSources.includes(task.source) ); } return { total: filteredTasks.length, todo: filteredTasks.filter(t => t.status === 'todo').length, inProgress: filteredTasks.filter(t => t.status === 'in_progress').length, completed: filteredTasks.filter(t => t.status === 'done').length, cancelled: filteredTasks.filter(t => t.status === 'cancelled').length, backlog: filteredTasks.filter(t => t.status === 'backlog').length, freeze: filteredTasks.filter(t => t.status === 'freeze').length, archived: filteredTasks.filter(t => t.status === 'archived').length }; }, [regularTasks, selectedSources, hiddenSources]); // Données pour le graphique des statuts const statusChartData = useMemo(() => { const totalTasks = filteredStats.total; if (totalTasks === 0) return []; const data = []; if (filteredStats.backlog > 0) { data.push({ status: 'Backlog', count: filteredStats.backlog, percentage: Math.round((filteredStats.backlog / totalTasks) * 100), color: '#6b7280' }); } if (filteredStats.todo > 0) { data.push({ status: 'À Faire', count: filteredStats.todo, percentage: Math.round((filteredStats.todo / totalTasks) * 100), color: '#eab308' }); } if (filteredStats.inProgress > 0) { data.push({ status: 'En Cours', count: filteredStats.inProgress, percentage: Math.round((filteredStats.inProgress / totalTasks) * 100), color: '#3b82f6' }); } if (filteredStats.freeze > 0) { data.push({ status: 'Gelé', count: filteredStats.freeze, percentage: Math.round((filteredStats.freeze / totalTasks) * 100), color: '#8b5cf6' }); } if (filteredStats.completed > 0) { data.push({ status: 'Terminé', count: filteredStats.completed, percentage: Math.round((filteredStats.completed / totalTasks) * 100), color: '#10b981' }); } if (filteredStats.cancelled > 0) { data.push({ status: 'Annulé', count: filteredStats.cancelled, percentage: Math.round((filteredStats.cancelled / totalTasks) * 100), color: '#ef4444' }); } if (filteredStats.archived > 0) { data.push({ status: 'Archivé', count: filteredStats.archived, percentage: Math.round((filteredStats.archived / totalTasks) * 100), color: '#9ca3af' }); } return data; }, [filteredStats]); // Données pour le graphique des sources const sourceChartData = useMemo(() => { const totalTasks = filteredStats.total; if (totalTasks === 0) return []; const jiraCount = regularTasks.filter(task => task.source === 'jira').length; const tfsCount = regularTasks.filter(task => task.source === 'tfs').length; const manualCount = regularTasks.filter(task => task.source === 'manual').length; const data = []; if (jiraCount > 0) { data.push({ source: 'Jira', count: jiraCount, percentage: Math.round((jiraCount / totalTasks) * 100), color: '#2563eb' }); } if (tfsCount > 0) { data.push({ source: 'TFS', count: tfsCount, percentage: Math.round((tfsCount / totalTasks) * 100), color: '#7c3aed' }); } if (manualCount > 0) { data.push({ source: 'Manuel', count: manualCount, percentage: Math.round((manualCount / totalTasks) * 100), color: '#059669' }); } return data; }, [filteredStats, regularTasks]); // Tooltip personnalisé pour les statuts const StatusTooltip = ({ active, payload }: { active?: boolean; payload?: Array<{ payload: { status: string; count: number; percentage: number } }> }) => { if (active && payload && payload.length) { const data = payload[0].payload; return (

{data.status}

{data.count} tâches ({data.percentage}%)

); } return null; }; // Tooltip personnalisé pour les sources const SourceTooltip = ({ active, payload }: { active?: boolean; payload?: Array<{ payload: { source: string; count: number; percentage: number } }> }) => { if (active && payload && payload.length) { const data = payload[0].payload; return (

{data.source}

{data.count} tâches ({data.percentage}%)

); } return null; }; // Légende personnalisée const CustomLegend = ({ payload }: { payload?: Array<{ value: string; color: string }> }) => { return (
{payload?.map((entry, index: number) => (
{entry.value}
))}
); }; // Label personnalisé pour afficher les pourcentages const renderLabel = (props: PieLabelRenderProps) => { const percentage = typeof props.percent === 'number' ? props.percent * 100 : 0; return percentage > 5 ? `${Math.round(percentage)}%` : ''; }; const totalTasks = filteredStats.total; const completionRate = totalTasks > 0 ? Math.round((filteredStats.completed / totalTasks) * 100) : 0; const inProgressRate = totalTasks > 0 ? Math.round((filteredStats.inProgress / totalTasks) * 100) : 0; const statCards = [ { title: 'Total Tâches', value: filteredStats.total, icon: '📋', color: 'default' as const }, { title: 'À Faire', value: filteredStats.todo + filteredStats.backlog, icon: '⏳', color: 'warning' as const }, { title: 'En Cours', value: filteredStats.inProgress + filteredStats.freeze, icon: '🔄', color: 'primary' as const }, { title: 'Terminées', value: filteredStats.completed + filteredStats.cancelled + filteredStats.archived, icon: '✅', color: 'success' as const } ]; return (
{statCards.map((stat, index) => ( ))} {/* Cartes de pourcentage */}

Taux de Completion

{/* Distribution détaillée par statut */}

Distribution par Statut

{/* Graphique en camembert avec Recharts */}
{statusChartData.map((entry, index) => ( ))} } /> } />
{/* Insights rapides */}

Aperçu Rapide

{filteredStats.completed} tâches terminées sur {totalTasks}
{filteredStats.inProgress} tâches en cours de traitement
{filteredStats.todo} tâches en attente
{totalTasks > 0 && (
Productivité: {completionRate}% de completion
)}
{/* Distribution par sources */}

Distribution par Sources

{/* Graphique en camembert avec Recharts */}
{sourceChartData.map((entry, index) => ( ))} } /> } />
); }