'use client'; import Link from 'next/link'; import Image from 'next/image'; import { useEffect, useState } from 'react'; import BlurHashImage from '@/components/ui/BlurHashImage'; import { ProductResponse } from '@/services/api/catalogService'; import { formatCurrency, getCatalogPriceInfo, getImageUrl } from '@/lib/utils'; interface YouMayAlsoLikeProps { products: ProductResponse[]; } function priceLabel(product: ProductResponse): { current: string; compare?: string; range: boolean } { const { price, priceMax, oldPrice } = getCatalogPriceInfo(product); if (!price) return { current: '—', range: false }; if (priceMax && priceMax > price) { return { current: `${formatCurrency(price)} – ${formatCurrency(priceMax)}`, range: true, }; } return { current: formatCurrency(price), compare: oldPrice && oldPrice > price ? formatCurrency(oldPrice) : undefined, range: false, }; } function discountPct(product: ProductResponse): number { const { discount } = getCatalogPriceInfo(product); return discount || 0; } function stableSaleSeconds(productId: string): number { let hash = 0; for (let i = 0; i < productId.length; i++) hash = (hash * 31 + productId.charCodeAt(i)) >>> 0; return 36 * 3600 + (hash % (48 * 3600)); } function SaleCountdown({ productId }: { productId: string }) { const [remaining, setRemaining] = useState(() => stableSaleSeconds(productId)); useEffect(() => { const t = setInterval(() => setRemaining((s) => (s > 0 ? s - 1 : 0)), 1000); return () => clearInterval(t); }, []); const days = Math.floor(remaining / 86400); const hrs = Math.floor((remaining % 86400) / 3600); const min = Math.floor((remaining % 3600) / 60); const sec = remaining % 60; const pad = (n: number) => String(n).padStart(2, '0'); const units = [ { val: pad(days), label: 'DAYS' }, { val: pad(hrs), label: 'HRS' }, { val: pad(min), label: 'MIN' }, { val: pad(sec), label: 'SEC' }, ]; return (
{prod.name}