← back to Wine Finder Next
components/PriceChart.tsx
130 lines
'use client'
import { LineChart, Line, XAxis, YAxis, Tooltip, ResponsiveContainer, Area, AreaChart } from 'recharts'
interface PricePoint {
date: string
price: number
source?: string
}
interface PriceChartProps {
data: PricePoint[]
currentPrice: number
trend: 'rising' | 'falling' | 'stable'
dealScore: number
}
export default function PriceChart({ data, currentPrice, trend, dealScore }: PriceChartProps) {
if (!data || data.length === 0) {
return (
<div className="bg-gray-100 rounded-lg p-4 text-center text-gray-500 text-sm">
No price history available
</div>
)
}
const prices = data.map(d => d.price)
const minPrice = Math.min(...prices)
const maxPrice = Math.max(...prices)
const avgPrice = prices.reduce((a, b) => a + b, 0) / prices.length
// Determine color based on trend
const trendColor = trend === 'rising' ? '#ef4444' : trend === 'falling' ? '#22c55e' : '#6b7280'
const fillColor = trend === 'rising' ? '#fecaca' : trend === 'falling' ? '#bbf7d0' : '#e5e7eb'
return (
<div className="bg-gradient-to-br from-slate-50 to-slate-100 rounded-lg p-4 border border-slate-200">
{/* Header */}
<div className="flex items-center justify-between mb-3">
<div>
<div className="text-xs text-gray-500 mb-1">Current Price</div>
<div className="text-2xl font-bold text-gray-900">${currentPrice.toFixed(2)}</div>
</div>
<div className="text-right">
<div className={`inline-flex items-center gap-1 px-3 py-1 rounded-full text-xs font-bold ${
dealScore >= 70 ? 'bg-green-100 text-green-700' :
dealScore >= 40 ? 'bg-yellow-100 text-yellow-700' :
'bg-red-100 text-red-700'
}`}>
{dealScore >= 70 ? '🔥' : dealScore >= 40 ? '💰' : '📊'} Deal Score: {dealScore}
</div>
<div className={`text-xs mt-1 font-semibold ${
trend === 'rising' ? 'text-red-600' : trend === 'falling' ? 'text-green-600' : 'text-gray-600'
}`}>
{trend === 'rising' && '📈 Rising'}
{trend === 'falling' && '📉 Falling'}
{trend === 'stable' && '➡️ Stable'}
</div>
</div>
</div>
{/* Chart */}
<div className="h-32 mb-3">
<ResponsiveContainer width="100%" height="100%">
<AreaChart data={data} margin={{ top: 5, right: 5, left: 5, bottom: 5 }}>
<defs>
<linearGradient id={`gradient-${trend}`} x1="0" y1="0" x2="0" y2="1">
<stop offset="5%" stopColor={trendColor} stopOpacity={0.3}/>
<stop offset="95%" stopColor={trendColor} stopOpacity={0}/>
</linearGradient>
</defs>
<XAxis
dataKey="date"
tick={{ fontSize: 10 }}
stroke="#94a3b8"
tickLine={false}
/>
<YAxis
tick={{ fontSize: 10 }}
stroke="#94a3b8"
tickLine={false}
domain={[minPrice * 0.95, maxPrice * 1.05]}
tickFormatter={(value) => `$${value.toFixed(0)}`}
/>
<Tooltip
contentStyle={{
backgroundColor: '#1e293b',
border: 'none',
borderRadius: '8px',
padding: '8px 12px'
}}
labelStyle={{ color: '#f1f5f9', fontWeight: 'bold', fontSize: '12px' }}
itemStyle={{ color: '#f1f5f9', fontSize: '11px' }}
formatter={(value: number) => [`$${value.toFixed(2)}`, 'Price']}
/>
<Area
type="monotone"
dataKey="price"
stroke={trendColor}
strokeWidth={2}
fill={`url(#gradient-${trend})`}
/>
</AreaChart>
</ResponsiveContainer>
</div>
{/* Stats */}
<div className="grid grid-cols-3 gap-2 text-center border-t border-slate-200 pt-3">
<div>
<div className="text-xs text-gray-500">Avg</div>
<div className="text-sm font-semibold text-gray-700">${avgPrice.toFixed(2)}</div>
</div>
<div>
<div className="text-xs text-gray-500">Low</div>
<div className="text-sm font-semibold text-green-600">${minPrice.toFixed(2)}</div>
</div>
<div>
<div className="text-xs text-gray-500">High</div>
<div className="text-sm font-semibold text-red-600">${maxPrice.toFixed(2)}</div>
</div>
</div>
{/* Data Points */}
<div className="mt-2 text-center text-xs text-gray-500">
{data.length} price points tracked
</div>
</div>
)
}