"use client" import { useEffect, useMemo, useState } from 'react' import Image from 'next/image' import Link from './LocalizedLink' import { Heart, Search, ShoppingBag, Star, User } from 'lucide-react' import { formatPrice, getCategoryImage, type Product, type StoreSettings } from '@homaroma/types' import { useCartStore } from '../store/cartStore' import { resolveCategoryName, resolveLocalized } from '../lib/localization' import { useLang } from '../hooks/useLang' function resolveOptionValue(val: string, options: Product['options'], lang: string): string { if (!val || !options || !Array.isArray(options)) return val for (const option of options) { if (!Array.isArray(option.values)) continue for (const item of option.values) { const base = typeof item === 'string' ? item : item.th || item.en || Object.values(item)[0] || '' if (base === val) { if (typeof item === 'string') return item return item[lang] ?? item[lang.slice(0, 2)] ?? item.th ?? item.en ?? Object.values(item)[0] ?? base } } } return val } export default function ProductStickyPurchaseBar({ product, triggerId, settings = null, }: { product: Product triggerId: string settings?: StoreSettings | null }) { const lang = useLang() const [isVisible, setIsVisible] = useState(false) const { addToCart, toggleCart } = useCartStore() const productName = resolveLocalized(product.name, lang) || product.brand.name const categoryName = resolveCategoryName(product.category, lang) const brandName = settings?.brandName || 'HomAroma' const variant = product.variants?.[0] const imageUrl = product.images?.[0]?.url || product.category.imageUrl || getCategoryImage(categoryName) const variantName = useMemo(() => { if (!variant) return '' return [variant.option1, variant.option2, variant.option3] .filter(Boolean) .map((option) => resolveOptionValue(option, product.options, lang)) .join(' / ') }, [lang, product.options, variant]) const handleAddToCart = () => { if (!variant) return addToCart({ productId: product.id, variantId: variant.id, quantity: 1, price: variant.price || 0, productName, variantName: variantName || undefined, productImage: imageUrl, }) toggleCart(true) } useEffect(() => { const updateVisibility = () => { const trigger = document.getElementById(triggerId) if (!trigger) { setIsVisible(false) if (document.documentElement.dataset.productStickyVisible !== 'false') { document.documentElement.dataset.productStickyVisible = 'false' window.dispatchEvent(new CustomEvent('product-sticky-change', { detail: false })) } return } const nextVisible = trigger.getBoundingClientRect().top <= 0 setIsVisible(nextVisible) const nextStr = nextVisible ? 'true' : 'false' if (document.documentElement.dataset.productStickyVisible !== nextStr) { document.documentElement.dataset.productStickyVisible = nextStr window.dispatchEvent(new CustomEvent('product-sticky-change', { detail: nextVisible })) } } updateVisibility() window.addEventListener('scroll', updateVisibility, { passive: true }) window.addEventListener('resize', updateVisibility) return () => { document.documentElement.dataset.productStickyVisible = 'false' window.dispatchEvent(new CustomEvent('product-sticky-change', { detail: false })) window.removeEventListener('scroll', updateVisibility) window.removeEventListener('resize', updateVisibility) } }, [triggerId]) return ( ) }