"use client" import { useMemo } from 'react' import Image from 'next/image' import Link from './LocalizedLink' import type { Product, Variant } from '@homaroma/types' import { formatPrice } from '@homaroma/types' import { resolveLocalized } from '../lib/localization' import { generateProductSlug } from '../lib/slugify' import { useLang } from '../hooks/useLang' interface ProductSwatchCardProps { product: Product badgeText?: string | null } export default function ProductSwatchCard({ product, badgeText }: ProductSwatchCardProps) { const lang = useLang() const productName = resolveLocalized(product.name, lang) || product.brand?.name || 'Product' const productSlug = generateProductSlug(productName, product.id) // Find all unique color swatches from variants const colorSwatches = useMemo(() => { const swatches: { colorCode: string; variant: Variant }[] = [] const seenColors = new Set() if (Array.isArray(product.variants)) { for (const v of product.variants) { if (v.colorCode && !seenColors.has(v.colorCode.toLowerCase())) { seenColors.add(v.colorCode.toLowerCase()) swatches.push({ colorCode: v.colorCode, variant: v }) } } } return swatches }, [product.variants]) // Active selected variant const activeVariant = useMemo(() => { return colorSwatches[0]?.variant || product.variants?.[0] || null }, [colorSwatches, product.variants]) // Display Image: variant image if available, else first product image const displayImageUrl = useMemo(() => { if (activeVariant?.imageUrl) return activeVariant.imageUrl if (product.images && product.images.length > 0 && product.images[0].url) { return product.images[0].url } return product.category?.imageUrl || '/assets/hero.png' }, [activeVariant, product.images, product.category]) const displayPrice = activeVariant?.price ?? product.variants?.[0]?.price ?? 0 return (
{/* 1:1 Image Frame */} {/* Badge (e.g. NEW) */} {badgeText && (
{badgeText}
)} {/* Product Image */}
{productName}
{/* Meta (Title, Price, Swatches) */}
{/* Product Title */}

{productName}

{/* Price */}
{formatPrice(displayPrice)}
{/* Color Swatch Dots (Display Only) */} {colorSwatches.length > 0 && (
{colorSwatches.slice(0, 5).map(({ colorCode, variant }) => ( ))} {colorSwatches.length > 5 && ( +{colorSwatches.length - 5} )}
)}
) }