'use client'; import { formatPrice } from 'brainerce'; import { Badge } from '@/components/ui/badge'; import { useCurrency } from '@/core/lib/use-currency'; import { useTranslations } from '@/core/lib/translations'; import { useStoreInfo } from '@/core/providers/store-provider'; import { cn } from '@/core/lib/utils'; interface PriceDisplayProps { price: string | number; salePrice?: string | number | null; currency?: string; className?: string; size?: 'sm' | 'md' | 'lg'; } const sizeClasses = { sm: 'text-sm', md: 'text-base', lg: 'text-xl font-semibold', }; export function PriceDisplay({ price, salePrice, currency, className, size = 'md', }: PriceDisplayProps) { const currencyCode = useCurrency(currency); const { storeInfo } = useStoreInfo(); const t = useTranslations('common'); const basePrice = typeof price === 'string' ? parseFloat(price) : price; const sale = salePrice != null ? (typeof salePrice === 'string' ? parseFloat(salePrice) : salePrice) : null; const isOnSale = sale !== null && sale < basePrice; const discountPercent = isOnSale && basePrice > 0 ? Math.round(((basePrice - sale!) / basePrice) * 100) : 0; // FX overlay disclosure (see core/lib/display-price.ts): `currency` is the // region-converted DISPLAY currency when it differs from the store's own // base currency. The shopper is still charged in the base currency at // checkout, so every converted price needs a visible "estimated" cue — // otherwise nothing on screen explains why the cart/checkout total switches // currency from what was just browsed. const isConverted = !!currency && !!storeInfo?.currency && currency !== storeInfo.currency; return ( {isOnSale ? ( <> {formatPrice(sale!, { currency: currencyCode }) as string} {formatPrice(basePrice, { currency: currencyCode }) as string} {discountPercent > 0 && ( -{discountPercent}% )} ) : ( {formatPrice(basePrice, { currency: currencyCode }) as string} )} {isConverted && ( {t('estimatedPrice')} )} ); }