import { LineChart, Line, XAxis, YAxis, CartesianGrid, ResponsiveContainer } from 'recharts'; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "~/components/ui/card"; import { useState } from "react"; interface LegendPayload { value: string; color: string; } interface CustomLegendProps { payload: LegendPayload[]; onHover: (dataKey: string | null) => void; onLeave: () => void; } function CustomLegend({ payload, onHover, onLeave }: CustomLegendProps) { return (
{payload.map((entry) => (
onHover(entry.value)} onMouseLeave={onLeave} role="button" aria-label={`Toggle ${entry.value} line`} tabIndex={0} onKeyDown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onHover(entry.value); } }} onKeyUp={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); onLeave(); } }} >
))}
); } interface Team { id: string; name: string; } export interface ChartDataPoint { date: string; [teamName: string]: string | number; } interface PointProgressionChartProps { chartData: ChartDataPoint[]; teams: Team[]; } // Color palette for team lines const COLORS = [ '#3b82f6', // blue '#ef4444', // red '#10b981', // green '#f59e0b', // amber '#8b5cf6', // violet '#ec4899', // pink '#06b6d4', // cyan '#f97316', // orange '#84cc16', // lime '#6366f1', // indigo ]; function formatDate(dateStr: string) { const date = new Date(dateStr); return date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }); } export function PointProgressionChart({ chartData, teams }: PointProgressionChartProps) { const [hoveredLine, setHoveredLine] = useState(null); if (chartData.length === 0) { return ( Point Progression Track how team standings evolved over time

No historical data available yet.

Point progression will appear once daily snapshots are recorded.

); } const latestData = chartData[chartData.length - 1]; const teamsByRank = [...teams].toSorted((a, b) => { const aPoints = (typeof latestData[a.name] === 'number' ? latestData[a.name] : 0) as number; const bPoints = (typeof latestData[b.name] === 'number' ? latestData[b.name] : 0) as number; return bPoints - aPoints; }); return ( Point Progression Track how team standings evolved over time ({chartData.length} day{chartData.length !== 1 ? 's' : ''} of data)
{teams.map((team, index) => ( ))}
({ value: team.name, color: COLORS[teams.findIndex(t => t.id === team.id) % COLORS.length] }))} onHover={setHoveredLine} onLeave={() => setHoveredLine(null)} />
); }