This commit is contained in:
Your Name committed 2026-07-19 07:56:18 -04:00
1 parent b415fb2eb4
commit cfd642dee0
3 files changed
+27 -7

No files matched your search

@@ -11,7 +11,7 @@ import ProductGallery from '@/components/ProductGallery'
import ProductStickyPurchaseBar from '@/components/ProductStickyPurchaseBar'
import DynamicPageRenderer from '@/components/dynamic/DynamicPageRenderer'
import ProductCard from '@/components/ProductCard'
import { getCategoriesResult, getProduct, getProductDetailSectionsResult, getProductResult, getProductReviewsResult, getProductsResult, type ProductReview } from '@/lib/cms'
import { getCategoriesResult, getProduct, getProductDetailSectionsResult, getProductResult, getProductReviewsResult, getProductsResult, getStoreSettingsResult, type ProductReview } from '@/lib/cms'
import { resolveCategoryName, resolveLocalized } from '@/lib/localization'
import { extractIdFromSlug, generateProductSlug } from '@/lib/slugify'
import type { ProductAttribute } from '@homaroma/types'
@@ -386,15 +386,17 @@ export default async function ProductDetailPage({ params }: { params: Promise<{
const { slug, lang } = await params
const id = extractIdFromSlug(slug)
console.log(`[DEBUG-PRODUCT] slug="${slug}", id="${id}", lang="${lang}"`)
const [productResult, categoriesResult, detailSectionsResult, reviewsResult] = await Promise.all([
const [productResult, categoriesResult, detailSectionsResult, reviewsResult, settingsResult] = await Promise.all([
getProductResult(id, lang),
getCategoriesResult(lang),
getProductDetailSectionsResult(id, lang),
getProductReviewsResult(id),
getStoreSettingsResult(lang),
])
const categories = categoriesResult.ok ? categoriesResult.data : []
const cmsSections = detailSectionsResult.ok ? detailSectionsResult.data : []
const reviews = reviewsResult.ok ? reviewsResult.data : []
const settings = settingsResult.ok ? settingsResult.data : null
const activeLayoutSections = cmsSections.filter((section) => section.isActive)
if (!detailSectionsResult.ok && detailSectionsResult.status !== 404) {
@@ -553,7 +555,7 @@ export default async function ProductDetailPage({ params }: { params: Promise<{
{payload.layoutMode === 'sticky_gallery' && payload.showStickyPurchaseBarAfterMain !== false && (
<>
<div id={`product-main-end-${section.id}`} aria-hidden="true" className="h-px" />
<ProductStickyPurchaseBar product={product} triggerId={`product-main-end-${section.id}`} />
<ProductStickyPurchaseBar product={product} triggerId={`product-main-end-${section.id}`} settings={settings} />
</>
)}
</div>
@@ -4,7 +4,7 @@ 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 } from '@homaroma/types'
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'
@@ -29,15 +29,18 @@ function resolveOptionValue(val: string, options: Product['options'], lang: stri
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)
@@ -91,8 +94,19 @@ export default function ProductStickyPurchaseBar({
}`}>
<div className="relative mx-auto flex max-w-7xl items-start justify-between gap-6">
<div className="absolute left-1/2 top-0 hidden -translate-x-1/2 md:block">
<Link href="/" className="text-3xl font-bold uppercase tracking-[0.22em] text-text-main">
HomAroma
<Link href="/" className="flex h-10 items-center justify-center">
{settings?.logoUrl ? (
<Image
src={settings.logoUrl}
alt={brandName}
width={180}
height={44}
unoptimized
className="max-h-10 w-auto object-contain"
/>
) : (
<span className="text-3xl font-bold uppercase tracking-[0.22em] text-text-main">{brandName}</span>
)}
</Link>
</div>
+5 -1
View File
@@ -1,4 +1,4 @@
import type { Article, Category, Order, Page, Product, ProductDetailSection } from '@homaroma/types'
import type { Article, Category, Order, Page, Product, ProductDetailSection, StoreSettings } from '@homaroma/types'
import { API_BASE } from './api'
const isDev = process.env.NODE_ENV === 'development'
@@ -82,6 +82,10 @@ export async function getCategoriesResult(lang = 'all'): Promise<ApiResult<Categ
return await fetchJsonResult<Category[]>(`/categories?lang=${lang}`, { next: { revalidate: 0 } })
}
export async function getStoreSettingsResult(lang = 'all'): Promise<ApiResult<StoreSettings>> {
return await fetchJsonResult<StoreSettings>(`/settings?lang=${lang}`, { next: { revalidate: defaultRevalidate } })
}
export async function getCmsPage(slug: string, lang = 'all'): Promise<Page | null> {
return await fetchJson<Page>(`/pages/${slug}?lang=${lang}`, { next: { revalidate: defaultRevalidate } })
}