diff --git a/frontend/src/components/PriceChart.tsx b/frontend/src/components/PriceChart.tsx index 1168e40..f0a7ea8 100644 --- a/frontend/src/components/PriceChart.tsx +++ b/frontend/src/components/PriceChart.tsx @@ -41,13 +41,15 @@ export default function PriceChart({ const chartData = prices.map((p) => ({ date: new Date(p.recorded_at).getTime(), - price: parseFloat(p.price.toString()), + price: typeof p.price === 'string' ? parseFloat(p.price) : p.price, })); - const minPrice = Math.min(...chartData.map((d) => d.price)); - const maxPrice = Math.max(...chartData.map((d) => d.price)); - const avgPrice = - chartData.reduce((sum, d) => sum + d.price, 0) / chartData.length; + const priceValues = chartData.map((d) => d.price).filter((p) => !isNaN(p)); + const minPrice = priceValues.length > 0 ? Math.min(...priceValues) : 0; + const maxPrice = priceValues.length > 0 ? Math.max(...priceValues) : 0; + const avgPrice = priceValues.length > 0 + ? priceValues.reduce((sum, p) => sum + p, 0) / priceValues.length + : 0; const formatDate = (timestamp: number) => { const date = new Date(timestamp); @@ -55,6 +57,7 @@ export default function PriceChart({ }; const formatPrice = (value: number) => { + if (value === null || value === undefined || isNaN(value)) return 'N/A'; return `${currencySymbol}${value.toFixed(2)}`; }; diff --git a/frontend/src/components/ProductCard.tsx b/frontend/src/components/ProductCard.tsx index 9253fc4..6dd7bf5 100644 --- a/frontend/src/components/ProductCard.tsx +++ b/frontend/src/components/ProductCard.tsx @@ -7,11 +7,13 @@ interface ProductCardProps { } export default function ProductCard({ product, onDelete }: ProductCardProps) { - const formatPrice = (price: number | null, currency: string | null) => { - if (price === null) return 'N/A'; + const formatPrice = (price: number | string | null, currency: string | null) => { + if (price === null || price === undefined) return 'N/A'; + const numPrice = typeof price === 'string' ? parseFloat(price) : price; + if (isNaN(numPrice)) return 'N/A'; const currencySymbol = currency === 'EUR' ? '€' : currency === 'GBP' ? '£' : '$'; - return `${currencySymbol}${price.toFixed(2)}`; + return `${currencySymbol}${numPrice.toFixed(2)}`; }; const formatDate = (dateStr: string | null) => { diff --git a/frontend/src/pages/ProductDetail.tsx b/frontend/src/pages/ProductDetail.tsx index 11db18b..6cab046 100644 --- a/frontend/src/pages/ProductDetail.tsx +++ b/frontend/src/pages/ProductDetail.tsx @@ -71,11 +71,13 @@ export default function ProductDetail() { fetchData(days); }; - const formatPrice = (price: number | null, currency: string | null) => { - if (price === null) return 'N/A'; + const formatPrice = (price: number | string | null, currency: string | null) => { + if (price === null || price === undefined) return 'N/A'; + const numPrice = typeof price === 'string' ? parseFloat(price) : price; + if (isNaN(numPrice)) return 'N/A'; const currencySymbol = currency === 'EUR' ? '€' : currency === 'GBP' ? '£' : '$'; - return `${currencySymbol}${price.toFixed(2)}`; + return `${currencySymbol}${numPrice.toFixed(2)}`; }; if (isLoading) { @@ -105,10 +107,17 @@ export default function ProductDetail() { ); } - const priceChange = - product.stats && prices.length > 1 - ? ((product.current_price || 0) - prices[0].price) / prices[0].price - : null; + const priceChange = (() => { + if (!product.stats || prices.length < 1) return null; + const currentPrice = typeof product.current_price === 'string' + ? parseFloat(product.current_price) + : (product.current_price || 0); + const firstPrice = typeof prices[0].price === 'string' + ? parseFloat(prices[0].price) + : prices[0].price; + if (firstPrice === 0) return null; + return (currentPrice - firstPrice) / firstPrice; + })(); return (