Files
towercontrol/src/components/charts/VelocityChart.tsx
Julien Froidefond 4152b0bdfc chore: refactor project structure and clean up unused components
- Updated `TODO.md` to reflect new testing tasks and final structure expectations.
- Simplified TypeScript path mappings in `tsconfig.json` for better clarity.
- Revised business logic separation rules in `.cursor/rules` to align with new directory structure.
- Deleted unused client components and services to streamline the codebase.
- Adjusted import paths in scripts to match the new structure.
2025-09-21 10:26:35 +02:00

95 lines
3.1 KiB
TypeScript

'use client';
import { Bar, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, Line, ComposedChart } from 'recharts';
import { Card } from '@/components/ui/Card';
interface VelocityData {
week: string;
completed: number;
average: number;
}
interface VelocityChartProps {
data: VelocityData[];
title?: string;
}
export function VelocityChart({ data, title = "Vélocité Hebdomadaire" }: VelocityChartProps) {
// Tooltip personnalisé
const CustomTooltip = ({ active, payload, label }: {
active?: boolean;
payload?: Array<{ dataKey: string; value: number; color: string }>;
label?: string
}) => {
if (active && payload && payload.length) {
return (
<div className="bg-[var(--card)] border border-[var(--border)] rounded-lg p-3 shadow-lg">
<p className="text-sm font-medium mb-2">{label}</p>
{payload.map((entry, index: number) => (
<p key={index} className="text-sm" style={{ color: entry.color }}>
{entry.dataKey === 'completed' ? 'Terminées' : 'Moyenne'}: {entry.value}
{entry.dataKey === 'completed' ? ' tâches' : ' tâches/sem'}
</p>
))}
</div>
);
}
return null;
};
return (
<Card className="p-6">
<h3 className="text-lg font-semibold mb-4">{title}</h3>
<div className="h-64">
<ResponsiveContainer width="100%" height="100%">
<ComposedChart data={data} margin={{ top: 5, right: 30, left: 20, bottom: 5 }}>
<CartesianGrid
strokeDasharray="3 3"
stroke="var(--border)"
opacity={0.3}
/>
<XAxis
dataKey="week"
stroke="var(--muted-foreground)"
fontSize={12}
tick={{ fill: 'var(--muted-foreground)' }}
/>
<YAxis
stroke="var(--muted-foreground)"
fontSize={12}
tick={{ fill: 'var(--muted-foreground)' }}
/>
<Tooltip content={<CustomTooltip />} />
<Bar
dataKey="completed"
fill="#3b82f6"
radius={[4, 4, 0, 0]}
opacity={0.8}
/>
<Line
type="monotone"
dataKey="average"
stroke="#f59e0b"
strokeWidth={3}
dot={{ fill: '#f59e0b', strokeWidth: 2, r: 5 }}
activeDot={{ r: 7, stroke: '#f59e0b', strokeWidth: 2 }}
/>
</ComposedChart>
</ResponsiveContainer>
</div>
{/* Légende */}
<div className="flex items-center justify-center gap-6 mt-4 text-sm">
<div className="flex items-center gap-2">
<div className="w-3 h-3 bg-blue-500 rounded-sm opacity-80"></div>
<span className="text-[var(--muted-foreground)]">Tâches terminées</span>
</div>
<div className="flex items-center gap-2">
<div className="w-3 h-0.5 bg-amber-500"></div>
<span className="text-[var(--muted-foreground)]">Moyenne mobile</span>
</div>
</div>
</Card>
);
}