x
This commit is contained in:
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>
|
||||
|
||||
|
||||
@@ -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 } })
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user