← back to Wine Finder Next

src/components/PriceHistoryChart.tsx

100 lines

'use client';

import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend, ResponsiveContainer } from 'recharts';
import { PriceHistoryPoint } from '../types/wine';

interface PriceHistoryChartProps {
  history: PriceHistoryPoint[];
  wineName?: string;
}

export default function PriceHistoryChart({ history, wineName }: PriceHistoryChartProps) {
  if (history.length === 0) {
    return (
      <div className="bg-white rounded-lg shadow-lg p-12 text-center text-gray-500">
        <div className="text-4xl mb-4">📈</div>
        <div className="text-lg font-semibold">No price history available</div>
        <div className="text-sm mt-2">Price tracking will begin once you search for wines</div>
      </div>
    );
  }

  // Format data for recharts
  const chartData = history.map((point) => ({
    timestamp: new Date(point.timestamp).toLocaleDateString(),
    price: point.price,
    source: point.source,
  }));

  // Calculate stats
  const currentPrice = history[history.length - 1]?.price || 0;
  const minPrice = Math.min(...history.map(h => h.price));
  const maxPrice = Math.max(...history.map(h => h.price));
  const avgPrice = history.reduce((sum, h) => sum + h.price, 0) / history.length;

  return (
    <div className="bg-white rounded-lg shadow-lg p-6">
      {wineName && (
        <h3 className="text-2xl font-bold text-gray-900 mb-4">{wineName} - Price History</h3>
      )}

      {/* Price Stats */}
      <div className="grid grid-cols-4 gap-4 mb-6">
        <div className="text-center p-4 bg-purple-50 rounded-lg">
          <div className="text-sm text-gray-600 mb-1">Current</div>
          <div className="text-2xl font-bold text-purple-600">${currentPrice.toFixed(2)}</div>
        </div>
        <div className="text-center p-4 bg-green-50 rounded-lg">
          <div className="text-sm text-gray-600 mb-1">Lowest</div>
          <div className="text-2xl font-bold text-green-600">${minPrice.toFixed(2)}</div>
        </div>
        <div className="text-center p-4 bg-red-50 rounded-lg">
          <div className="text-sm text-gray-600 mb-1">Highest</div>
          <div className="text-2xl font-bold text-red-600">${maxPrice.toFixed(2)}</div>
        </div>
        <div className="text-center p-4 bg-blue-50 rounded-lg">
          <div className="text-sm text-gray-600 mb-1">Average</div>
          <div className="text-2xl font-bold text-blue-600">${avgPrice.toFixed(2)}</div>
        </div>
      </div>

      {/* Chart */}
      <ResponsiveContainer width="100%" height={400}>
        <LineChart data={chartData}>
          <CartesianGrid strokeDasharray="3 3" />
          <XAxis
            dataKey="timestamp"
            tick={{ fontSize: 12 }}
            angle={-45}
            textAnchor="end"
            height={80}
          />
          <YAxis
            tick={{ fontSize: 12 }}
            label={{ value: 'Price ($)', angle: -90, position: 'insideLeft' }}
          />
          <Tooltip
            contentStyle={{
              backgroundColor: 'white',
              border: '2px solid #9333ea',
              borderRadius: '8px',
              padding: '12px',
            }}
            formatter={(value: number) => [`$${value.toFixed(2)}`, 'Price']}
          />
          <Legend />
          <Line
            type="monotone"
            dataKey="price"
            stroke="#9333ea"
            strokeWidth={3}
            dot={{ fill: '#9333ea', r: 5 }}
            activeDot={{ r: 8 }}
            name="Price"
          />
        </LineChart>
      </ResponsiveContainer>
    </div>
  );
}