diff --git a/backend/src/services/notifications.ts b/backend/src/services/notifications.ts index 3973164..0f77db0 100644 --- a/backend/src/services/notifications.ts +++ b/backend/src/services/notifications.ts @@ -1,5 +1,17 @@ import axios from 'axios'; +// Helper to get currency symbol for display +function getCurrencySymbol(currency?: string): string { + switch (currency) { + case 'EUR': return '€'; + case 'GBP': return '£'; + case 'CHF': return 'CHF '; + case 'JPY': return '¥'; + case 'INR': return '₹'; + default: return '$'; + } +} + export interface NotificationPayload { productName: string; productUrl: string; @@ -12,7 +24,7 @@ export interface NotificationPayload { } function formatMessage(payload: NotificationPayload): string { - const currencySymbol = payload.currency === 'EUR' ? '€' : payload.currency === 'GBP' ? '£' : '$'; + const currencySymbol = getCurrencySymbol(payload.currency); if (payload.type === 'price_drop') { const oldPriceStr = payload.oldPrice ? `${currencySymbol}${payload.oldPrice.toFixed(2)}` : 'N/A'; @@ -78,7 +90,7 @@ export async function sendDiscordNotification( payload: NotificationPayload ): Promise { try { - const currencySymbol = payload.currency === 'EUR' ? '€' : payload.currency === 'GBP' ? '£' : '$'; + const currencySymbol = getCurrencySymbol(payload.currency); let embed; if (payload.type === 'price_drop') { @@ -145,7 +157,7 @@ export async function sendPushoverNotification( payload: NotificationPayload ): Promise { try { - const currencySymbol = payload.currency === 'EUR' ? '€' : payload.currency === 'GBP' ? '£' : '$'; + const currencySymbol = getCurrencySymbol(payload.currency); let title: string; let message: string; diff --git a/backend/src/utils/priceParser.ts b/backend/src/utils/priceParser.ts index 97a767f..f34f7d5 100644 --- a/backend/src/utils/priceParser.ts +++ b/backend/src/utils/priceParser.ts @@ -10,6 +10,8 @@ const currencyMap: Record = { '£': 'GBP', '¥': 'JPY', '₹': 'INR', + 'Fr.': 'CHF', + 'CHF': 'CHF', 'CAD': 'CAD', 'AUD': 'AUD', 'USD': 'USD', @@ -21,8 +23,10 @@ const currencyMap: Record = { const pricePatterns = [ // $29.99 or $29,99 or $ 29.99 /(?[$€£¥₹])\s*(?[\d,]+\.?\d*)/, - // 29.99 USD or 29,99 EUR - /(?[\d,]+\.?\d*)\s*(?USD|EUR|GBP|CAD|AUD|JPY|INR)/i, + // CHF 29.99 or Fr. 29.99 (Swiss franc prefix) + /(?CHF|Fr\.)\s*(?[\d,]+\.?\d*)/i, + // 29.99 USD or 29,99 EUR or 29.99 CHF + /(?[\d,]+\.?\d*)\s*(?USD|EUR|GBP|CAD|AUD|JPY|INR|CHF)/i, // Plain number with optional decimal (fallback) /(?\d{1,3}(?:[,.\s]?\d{3})*(?:[.,]\d{2})?)/, ]; @@ -89,7 +93,7 @@ export function extractPricesFromText(html: string): ParsedPrice[] { // Match all price-like patterns in the HTML const allMatches = html.matchAll( - /(?:[$€£¥₹])\s*[\d,]+\.?\d*|[\d,]+\.?\d*\s*(?:USD|EUR|GBP|CAD|AUD)/gi + /(?:[$€£¥₹])\s*[\d,]+\.?\d*|(?:CHF|Fr\.)\s*[\d,]+\.?\d*|[\d,]+\.?\d*\s*(?:USD|EUR|GBP|CAD|AUD|CHF)/gi ); for (const match of allMatches) { diff --git a/frontend/src/components/PriceChart.tsx b/frontend/src/components/PriceChart.tsx index 5fb7ab6..e2409d0 100644 --- a/frontend/src/components/PriceChart.tsx +++ b/frontend/src/components/PriceChart.tsx @@ -59,7 +59,7 @@ export default function PriceChart({ }; const currencySymbol = - currency === 'EUR' ? '€' : currency === 'GBP' ? '£' : '$'; + currency === 'EUR' ? '€' : currency === 'GBP' ? '£' : currency === 'CHF' ? 'CHF ' : '$'; const chartData = prices.map((p) => ({ date: new Date(p.recorded_at).getTime(), diff --git a/frontend/src/components/ProductCard.tsx b/frontend/src/components/ProductCard.tsx index 902a520..9537087 100644 --- a/frontend/src/components/ProductCard.tsx +++ b/frontend/src/components/ProductCard.tsx @@ -81,7 +81,7 @@ export default function ProductCard({ product, onDelete, onRefresh, isSelected, const numPrice = typeof price === 'string' ? parseFloat(price) : price; if (isNaN(numPrice)) return 'N/A'; const currencySymbol = - currency === 'EUR' ? '€' : currency === 'GBP' ? '£' : '$'; + currency === 'EUR' ? '€' : currency === 'GBP' ? '£' : currency === 'CHF' ? 'CHF ' : '$'; return `${currencySymbol}${numPrice.toFixed(2)}`; }; diff --git a/frontend/src/pages/ProductDetail.tsx b/frontend/src/pages/ProductDetail.tsx index a45436c..a0fed55 100644 --- a/frontend/src/pages/ProductDetail.tsx +++ b/frontend/src/pages/ProductDetail.tsx @@ -157,7 +157,7 @@ export default function ProductDetail() { const numPrice = typeof price === 'string' ? parseFloat(price) : price; if (isNaN(numPrice)) return 'N/A'; const currencySymbol = - currency === 'EUR' ? '€' : currency === 'GBP' ? '£' : '$'; + currency === 'EUR' ? '€' : currency === 'GBP' ? '£' : currency === 'CHF' ? 'CHF ' : '$'; return `${currencySymbol}${numPrice.toFixed(2)}`; };