'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 (
{units.map((u) => (
{u.val} {u.label}
))}
); } function Stars({ rating }: { rating: number }) { const filled = Math.round(rating || 5); return (
{Array.from({ length: 5 }).map((_, i) => ( ))}
); } export function YouMayAlsoLike({ products }: YouMayAlsoLikeProps) { if (!products.length) return null; return (

You may also like...

{products.slice(0, 5).map((prod, index) => { const img = getImageUrl(prod.images?.[0]?.image_url || prod.variants?.[0]?.images?.[0]?.image_url); const off = discountPct(prod); const pricing = priceLabel(prod); const onSale = off > 0; return ( 0 ? 'border-l border-gray-200' : '' }`} > {off > 0 && ( -{off}% )}
{onSale ? :
}

{prod.name}

{pricing.compare && ( {pricing.compare} )} {pricing.current}
); })}
); }