Files
towercontrol/components/charts/CompletionTrendChart.tsx
Julien Froidefond 3c7f5ca2fa feat: update package dependencies and integrate Recharts
- Changed project name from "towercontrol-temp" to "towercontrol" in package-lock.json and package.json.
- Added Recharts library for data visualization in the dashboard.
- Updated TODO.md to reflect completion of analytics and metrics integration tasks.
- Enhanced RecentTasks component to utilize TaskPriority type for better type safety.
- Minor layout adjustments in RecentTasks for improved UI.
2025-09-18 12:48:06 +02:00

109 lines
3.5 KiB
TypeScript

'use client';
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts';
import { Card } from '@/components/ui/Card';
interface CompletionTrendData {
date: string;
completed: number;
created: number;
total: number;
}
interface CompletionTrendChartProps {
data: CompletionTrendData[];
title?: string;
}
export function CompletionTrendChart({ data, title = "Tendance de Completion" }: CompletionTrendChartProps) {
// Formatter pour les dates
const formatDate = (dateStr: string) => {
const date = new Date(dateStr);
return date.toLocaleDateString('fr-FR', {
day: 'numeric',
month: 'short'
});
};
// Tooltip personnalisé
const CustomTooltip = ({ active, payload, label }: {
active?: boolean;
payload?: Array<{ name: 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 ? formatDate(label) : ''}</p>
{payload.map((entry, index: number) => (
<p key={index} className="text-sm" style={{ color: entry.color }}>
{entry.name === 'completed' ? 'Terminées' :
entry.name === 'created' ? 'Créées' : 'Total'}: {entry.value}
</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%">
<LineChart data={data} margin={{ top: 5, right: 30, left: 20, bottom: 5 }}>
<CartesianGrid
strokeDasharray="3 3"
stroke="var(--border)"
opacity={0.3}
/>
<XAxis
dataKey="date"
tickFormatter={formatDate}
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 />} />
<Line
type="monotone"
dataKey="completed"
stroke="#10b981"
strokeWidth={2}
dot={{ fill: '#10b981', strokeWidth: 2, r: 4 }}
activeDot={{ r: 6, stroke: '#10b981', strokeWidth: 2 }}
/>
<Line
type="monotone"
dataKey="created"
stroke="#3b82f6"
strokeWidth={2}
strokeDasharray="5 5"
dot={{ fill: '#3b82f6', strokeWidth: 2, r: 4 }}
activeDot={{ r: 6, stroke: '#3b82f6', strokeWidth: 2 }}
/>
</LineChart>
</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-0.5 bg-green-500"></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-blue-500 border-dashed border-t"></div>
<span className="text-[var(--muted-foreground)]">Tâches créées</span>
</div>
</div>
</Card>
);
}