'use client' import { useMemo } from 'react' interface StatsChartProps { data: number[] maxDataPoints?: number height?: number label: string value: string subValue?: string color: 'cyan' | 'emerald' | 'amber' | 'red' maxY?: number unit?: string } const COLORS = { cyan: { stroke: '#06b6d4', fill: 'rgba(6, 182, 212, 0.15)', text: 'text-cyan-400', bg: 'bg-cyan-500/20' }, emerald: { stroke: '#10b981', fill: 'rgba(16, 185, 129, 0.15)', text: 'text-emerald-400', bg: 'bg-emerald-500/20' }, amber: { stroke: '#f59e0b', fill: 'rgba(245, 158, 11, 0.15)', text: 'text-amber-400', bg: 'bg-amber-500/20' }, red: { stroke: '#ef4444', fill: 'rgba(239, 68, 68, 0.15)', text: 'text-red-400', bg: 'bg-red-500/20' }, } export default function StatsChart({ data, maxDataPoints = 60, height = 120, label, value, subValue, color, maxY = 100, unit = '%', }: StatsChartProps) { const theme = COLORS[color] const { linePath, areaPath } = useMemo(() => { if (data.length < 2) return { linePath: '', areaPath: '' } const w = 400 const h = height const padding = 2 const effectiveH = h - padding * 2 const clampedMax = Math.max(maxY, 1) const points = data.map((val, i) => { const x = (i / (maxDataPoints - 1)) * w const y = padding + effectiveH - (Math.min(val, clampedMax) / clampedMax) * effectiveH return { x, y } }) // Smooth the line with quadratic bezier curves let line = `M ${points[0].x},${points[0].y}` for (let i = 1; i < points.length; i++) { const prev = points[i - 1] const curr = points[i] const cpx = (prev.x + curr.x) / 2 line += ` Q ${cpx},${prev.y} ${curr.x},${curr.y}` } const lastPoint = points[points.length - 1] const firstPoint = points[0] const area = `${line} L ${lastPoint.x},${h} L ${firstPoint.x},${h} Z` return { linePath: line, areaPath: area } }, [data, maxDataPoints, height, maxY]) return (
{/* Header */}
{label}
{value} {subValue && ( {subValue} )}
{/* Chart */}
{data.length < 2 ? (
Collecting data…
) : ( {/* Grid lines */} {[0, 0.25, 0.5, 0.75, 1].map((pct) => ( ))} {/* Area fill */} {/* Line */} )} {/* Y-axis labels */}
{maxY}{unit} 0{unit}
) }