113 lines
3.4 KiB
TypeScript
113 lines
3.4 KiB
TypeScript
'use client';
|
|
|
|
import { BarChart, Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Legend } from 'recharts';
|
|
|
|
interface PriorityData {
|
|
priority: string;
|
|
completed: number;
|
|
pending: number;
|
|
total: number;
|
|
completionRate: number;
|
|
color: string;
|
|
}
|
|
|
|
interface PriorityBreakdownChartProps {
|
|
data: PriorityData[];
|
|
className?: string;
|
|
}
|
|
|
|
export function PriorityBreakdownChart({ data, className }: PriorityBreakdownChartProps) {
|
|
// Transformer les données pour l'affichage
|
|
const getPriorityLabel = (priority: string) => {
|
|
const labels: { [key: string]: string } = {
|
|
'high': 'Haute',
|
|
'medium': 'Moyenne',
|
|
'low': 'Basse'
|
|
};
|
|
return labels[priority] || priority;
|
|
};
|
|
|
|
const chartData = data.map(item => ({
|
|
priority: getPriorityLabel(item.priority),
|
|
'Terminées': item.completed,
|
|
'En cours': item.pending,
|
|
completionRate: item.completionRate,
|
|
total: item.total
|
|
}));
|
|
|
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
const CustomTooltip = ({ active, payload, label }: { active?: boolean; payload?: any[]; label?: string }) => {
|
|
if (active && payload && payload.length) {
|
|
const data = payload[0].payload;
|
|
return (
|
|
<div className="bg-[var(--card)] border border-[var(--border)] rounded-lg p-3 shadow-lg">
|
|
<p className="font-medium mb-2">{`Priorité ${label}`}</p>
|
|
<p className="text-sm text-green-600">
|
|
Terminées: {data['Terminées']}
|
|
</p>
|
|
<p className="text-sm text-blue-600">
|
|
En cours: {data['En cours']}
|
|
</p>
|
|
<p className="text-sm text-[var(--muted-foreground)] mt-1">
|
|
Taux: {data.completionRate.toFixed(1)}% ({data.total} total)
|
|
</p>
|
|
</div>
|
|
);
|
|
}
|
|
return null;
|
|
};
|
|
|
|
return (
|
|
<div className={className}>
|
|
<ResponsiveContainer width="100%" height={250}>
|
|
<BarChart
|
|
data={chartData}
|
|
margin={{ top: 20, right: 30, left: 20, bottom: 5 }}
|
|
>
|
|
<CartesianGrid strokeDasharray="3 3" stroke="var(--border)" />
|
|
<XAxis
|
|
dataKey="priority"
|
|
stroke="var(--muted-foreground)"
|
|
fontSize={12}
|
|
/>
|
|
<YAxis
|
|
stroke="var(--muted-foreground)"
|
|
fontSize={12}
|
|
/>
|
|
<Tooltip content={<CustomTooltip />} />
|
|
<Legend />
|
|
<Bar
|
|
dataKey="Terminées"
|
|
stackId="a"
|
|
fill="#10b981"
|
|
radius={[0, 0, 0, 0]}
|
|
/>
|
|
<Bar
|
|
dataKey="En cours"
|
|
stackId="a"
|
|
fill="#3b82f6"
|
|
radius={[2, 2, 0, 0]}
|
|
/>
|
|
</BarChart>
|
|
</ResponsiveContainer>
|
|
|
|
{/* Affichage des taux de completion */}
|
|
<div className="mt-4 grid grid-cols-3 gap-4 text-center">
|
|
{data.map((item, index) => (
|
|
<div key={index} className="p-2 bg-[var(--card)] rounded border">
|
|
<div className="text-xs text-[var(--muted-foreground)] mb-1">
|
|
{getPriorityLabel(item.priority)}
|
|
</div>
|
|
<div className="text-lg font-bold" style={{ color: item.color }}>
|
|
{item.completionRate.toFixed(0)}%
|
|
</div>
|
|
<div className="text-xs text-[var(--muted-foreground)]">
|
|
{item.completed}/{item.total}
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|