← back to Omega Watches 2

src/components/charts/PriceTimeSeries.tsx

98 lines

'use client';

import { ResponsiveContainer, ComposedChart, Line, Area, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ReferenceLine } from 'recharts';
import { formatCurrency, formatDate } from '@/lib/utils';

interface TimeSeriesPoint {
  date: string;
  price?: number;
  msrp?: number;
  event_type?: string;
  source?: string;
  label?: string;
}

interface PriceTimeSeriesProps {
  data: TimeSeriesPoint[];
  title?: string;
  showMSRP?: boolean;
  currency?: string;
}

const EVENT_COLORS: Record<string, string> = {
  auction_result: '#c89b3c',
  dealer_ask: '#6366f1',
  marketplace_sold: '#22c55e',
  forum_listing: '#f59e0b',
  msrp: '#ef4444',
};

const CustomTooltip = ({ active, payload, label }: any) => {
  if (!active || !payload?.length) return null;
  return (
    <div className="bg-navy-800 border border-navy-600 rounded-lg p-3 shadow-xl">
      <p className="text-xs text-navy-300 mb-1">{formatDate(label)}</p>
      {payload.map((entry: any, i: number) => (
        <p key={i} className="text-sm" style={{ color: entry.color }}>
          {entry.name}: {formatCurrency(entry.value)}
        </p>
      ))}
    </div>
  );
};

export default function PriceTimeSeries({ data, title, showMSRP = true, currency = 'USD' }: PriceTimeSeriesProps) {
  if (!data?.length) {
    return (
      <div className="bg-navy-800/50 rounded-xl border border-navy-700 p-8 text-center">
        <p className="text-navy-400">No time series data available</p>
      </div>
    );
  }

  return (
    <div className="bg-navy-800/50 rounded-xl border border-navy-700 p-4">
      {title && <h3 className="text-lg font-semibold text-white mb-4">{title}</h3>}
      <ResponsiveContainer width="100%" height={400}>
        <ComposedChart data={data} margin={{ top: 5, right: 20, bottom: 5, left: 20 }}>
          <CartesianGrid strokeDasharray="3 3" stroke="#1e293b" />
          <XAxis
            dataKey="date"
            tickFormatter={(v) => formatDate(v)}
            stroke="#64748b"
            fontSize={11}
          />
          <YAxis
            tickFormatter={(v) => `$${(v / 1000).toFixed(0)}k`}
            stroke="#64748b"
            fontSize={11}
          />
          <Tooltip content={<CustomTooltip />} />
          <Legend />
          {showMSRP && (
            <Area
              type="monotone"
              dataKey="msrp"
              name="MSRP"
              fill="#ef444420"
              stroke="#ef4444"
              strokeWidth={2}
              strokeDasharray="5 5"
              dot={false}
            />
          )}
          <Line
            type="monotone"
            dataKey="price"
            name="Market Price"
            stroke="#c89b3c"
            strokeWidth={2}
            dot={{ fill: '#c89b3c', r: 3 }}
            activeDot={{ r: 6 }}
          />
        </ComposedChart>
      </ResponsiveContainer>
    </div>
  );
}