import React, { useState, useEffect } from 'react'; import axios from 'axios'; import { X, TrendingDown, TrendingUp, Minus } from 'lucide-react'; import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog'; import { Button } from '@/components/ui/button'; import { Card } from '@/components/ui/card'; const API_URL = '/api'; export function PriceHistoryModal({ open, onClose, item }) { const [priceHistory, setPriceHistory] = useState([]); const [loading, setLoading] = useState(false); useEffect(() => { if (open && item) { loadPriceHistory(); } }, [open, item]); const loadPriceHistory = async () => { if (!item) return; setLoading(true); try { const response = await axios.get(`${API_URL}/items/${item.id}/price-history`); setPriceHistory(response.data); } catch (error) { console.error('Error loading price history:', error); } finally { setLoading(false); } }; if (!item) return null; // Calculate stats const prices = priceHistory.map(h => h.price); const currentPrice = prices[prices.length - 1]; const minPrice = Math.min(...prices); const maxPrice = Math.max(...prices); const avgPrice = prices.length > 0 ? prices.reduce((a, b) => a + b, 0) / prices.length : 0; // Calculate price change const priceChange = prices.length > 1 ? ((currentPrice - prices[0]) / prices[0] * 100) : 0; // Simple chart rendering const chartHeight = 200; const chartWidth = 600; const padding = 40; const renderChart = () => { if (prices.length === 0) return null; const minY = minPrice * 0.95; const maxY = maxPrice * 1.05; const rangeY = maxY - minY; const points = priceHistory.map((point, index) => { const x = padding + (index / (priceHistory.length - 1 || 1)) * (chartWidth - 2 * padding); const y = chartHeight - padding - ((point.price - minY) / rangeY) * (chartHeight - 2 * padding); return { x, y, price: point.price, date: point.timestamp }; }); const pathData = points.map((point, index) => `${index === 0 ? 'M' : 'L'} ${point.x} ${point.y}` ).join(' '); return ( {/* Grid lines */} {[0, 0.25, 0.5, 0.75, 1].map((ratio) => { const y = padding + ratio * (chartHeight - 2 * padding); const price = maxY - ratio * rangeY; return ( {price.toFixed(2)}€ ); })} {/* Area under curve */} {/* Line */} {/* Points */} {points.map((point, index) => ( {`${new Date(point.date).toLocaleDateString('fr-FR')}: ${point.price.toFixed(2)}€`} ))} ); }; return ( Historique des prix
{/* Product Info */}

{item.name}

{new URL(item.url).hostname.replace('www.', '')}
{/* Stats Cards */}
Prix actuel
{currentPrice?.toFixed(2) || '--'}€
Prix minimum
{minPrice?.toFixed(2) || '--'}€
Prix maximum
{maxPrice?.toFixed(2) || '--'}€
Variation
0 ? 'text-red-600' : priceChange < 0 ? 'text-green-600' : ''}`}> {priceChange > 0 && } {priceChange < 0 && } {priceChange === 0 && } {Math.abs(priceChange).toFixed(1)}%
{/* Chart */} {loading ? (
) : priceHistory.length > 0 ? (
{renderChart()}
) : (
Aucun historique de prix disponible
)} {/* History Table */} {priceHistory.length > 0 && (
{priceHistory.map((entry, index) => { const prevPrice = index > 0 ? priceHistory[index - 1].price : entry.price; const change = ((entry.price - prevPrice) / prevPrice * 100); return ( ); })}
Date Prix Variation
{new Date(entry.timestamp).toLocaleString('fr-FR')} {entry.price.toFixed(2)}€ 0 ? 'text-red-600' : change < 0 ? 'text-green-600' : ''}`}> {change !== 0 ? `${change > 0 ? '+' : ''}${change.toFixed(1)}%` : '-'}
)}
); }