Files
towercontrol/src/components/dashboard/charts/PriorityBreakdownChart.tsx
Julien Froidefond 0ffcec7ffc refactor: update CustomTooltip types in chart components for better type safety
- Enhanced type definitions for the payload in CustomTooltip across multiple chart components to improve TypeScript support and maintainability.
2025-10-09 13:50:10 +02:00

135 lines
3.5 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,
}));
const CustomTooltip = ({
active,
payload,
label,
}: {
active?: boolean;
payload?: Array<{
payload: {
priority: string;
Terminées: number;
'En cours': number;
completionRate: number;
total: number;
};
}>;
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>
);
}