"use client"; import { useMemo } from "react"; import { AreaChart, Area, BarChart, Bar, Line, PieChart, Pie, Cell, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, } from "recharts"; type TrendData = Array<{ date: string; count: number }>; type TypeData = Array<{ type: string; count: number }>; type StatusData = Array<{ name: string; count: number }>; const PIE_COLORS: Record = { Uploaded: "hsl(38 92% 50%)", Processing: "hsl(217 91% 60%)", Analyzed: "hsl(160 84% 39%)", Failed: "hsl(0 84% 60%)", }; const FALLBACK_COLORS = [ "hsl(217 91% 60%)", "hsl(260 89% 65%)", "hsl(190 85% 50%)", "hsl(340 82% 52%)", ]; const tooltipStyle = { backgroundColor: "hsl(var(--background) / 0.95)", border: "1px solid hsl(var(--border) / 0.6)", borderRadius: "16px", color: "hsl(var(--foreground))", backdropFilter: "blur(12px)", boxShadow: "0 8px 32px rgba(0,0,0,0.12)", padding: "12px 16px", fontSize: "13px", }; const CustomTooltip = ({ active, payload, label }: any) => { if (!active || !payload?.length) return null; return (
{label && (

{label}

)} {payload.map((entry: any, index: number) => (
{entry.name}
{typeof entry.value === "number" ? entry.value.toLocaleString() : entry.value}
))}
); }; export function TrendChart({ data }: { data: TrendData }) { const trendData = useMemo( () => data.map((point, index) => { const start = Math.max(0, index - 6); const window = data.slice(start, index + 1); const average = window.reduce((sum, item) => sum + item.count, 0) / window.length; return { ...point, movingAverage: Number(average.toFixed(2)), }; }), [data], ); const xAxisInterval = trendData.length > 12 ? Math.floor(trendData.length / 8) : 0; return (
} />
); } export function ContractTypeChart({ data }: { data: TypeData }) { const sortedData = useMemo( () => [...data].sort((a, b) => b.count - a.count), [data], ); return (
} cursor={{ fill: "hsl(var(--muted) / 0.15)", radius: 8 }} /> {sortedData.map((item, index) => { const gradients = [ "url(#barGradient)", "url(#barGradient2)", "url(#barGradient3)", "url(#barGradient4)", ]; return ( ); })}
); } export function ContractStatusChart({ data }: { data: StatusData }) { const total = useMemo( () => data.reduce((sum, item) => sum + item.count, 0), [data], ); return (
{data.map((entry, index) => ( ))} {total > 0 && ( {total.toLocaleString()} Files )} } />
{data.map((item, index) => { const color = PIE_COLORS[item.name] ?? FALLBACK_COLORS[index % FALLBACK_COLORS.length]; return (
{item.name} {item.count}
); })}
); }