x
This commit is contained in:
1 parent
91dacd20ce
commit
27cc56abaf
14 files changed
+1757
-35
No files matched your search
@@ -7,6 +7,9 @@ import type { Category, Product } from '@homaroma/types'
|
||||
import { getCategoryImage, getCategoryMedia, resolveCategoryMediaUrl } from '@homaroma/types'
|
||||
import DynamicPageRenderer from '@/components/dynamic/DynamicPageRenderer'
|
||||
import ProductCard from '@/components/ProductCard'
|
||||
import CategoryFeaturedSeries from '@/components/category/CategoryFeaturedSeries'
|
||||
import CategoryCatalogContainer from '@/components/category/CategoryCatalogContainer'
|
||||
import CategoryUspBar from '@/components/category/CategoryUspBar'
|
||||
import { type ApiResult, fetchJsonResult, getCategoriesResult, getCmsPageResult, getStoreSettings } from '@/lib/cms'
|
||||
import { splitCmsLayoutSections } from '@/lib/cms-sections'
|
||||
import { resolveLocalized } from '@/lib/localization'
|
||||
@@ -125,6 +128,9 @@ export default async function CategoryPage({ params }: { params: Promise<{ id: s
|
||||
)}
|
||||
{heroSections.length > 0 && !(layoutType === 'editorial_hero' && hasArtDirectedHero) ? (
|
||||
<DynamicPageRenderer sections={heroSections} categories={categories} lang={lang} />
|
||||
) : layoutType === 'none' ? (
|
||||
/* ── Archetype 4: No Header (ปิดส่วนหัว Archetype) ── */
|
||||
null
|
||||
) : layoutType === 'editorial_hero' ? (
|
||||
/* ── Archetype 2: Editorial Hero Layout ── */
|
||||
<section className="relative overflow-hidden min-h-[380px] md:min-h-[460px] flex items-center justify-center border-b border-line-primary/10 bg-black">
|
||||
@@ -178,7 +184,7 @@ export default async function CategoryPage({ params }: { params: Promise<{ id: s
|
||||
</section>
|
||||
) : layoutType === 'dense_catalog' ? (
|
||||
/* ── Archetype 3: Dense Catalog Layout ── */
|
||||
<section className="relative overflow-hidden bg-surface-card border-b border-line-primary/10 pt-28 pb-6 md:pt-32 md:pb-8">
|
||||
<section className="relative overflow-hidden bg-surface-card border-b border-line-primary/10 pt-28 pb-4 md:pt-32 md:pb-5">
|
||||
<div className="mx-auto max-w-7xl px-6 flex flex-col md:flex-row md:items-center justify-between gap-4">
|
||||
<div className="space-y-1.5">
|
||||
<div className="flex items-center gap-2 text-[11px] font-semibold uppercase tracking-wider text-muted-text">
|
||||
@@ -234,42 +240,71 @@ export default async function CategoryPage({ params }: { params: Promise<{ id: s
|
||||
</section>
|
||||
)}
|
||||
|
||||
<div className="mx-auto max-w-7xl space-y-10 px-6 py-12">
|
||||
<div className={`flex flex-wrap gap-3 ${layoutType === 'editorial_hero' ? 'justify-center' : 'justify-start'}`}>
|
||||
{!categoriesResult.ok && (
|
||||
<span className="rounded-full border border-rose-100 bg-surface-card px-5 py-2 text-xs font-bold uppercase tracking-widest text-rose-500">
|
||||
Categories unavailable
|
||||
</span>
|
||||
)}
|
||||
{categories.map((item) => {
|
||||
const name = resolveLocalized(item.name, lang)
|
||||
const isActive = item.id === category.id
|
||||
<div className={`mx-auto max-w-7xl space-y-5 px-6 pb-12 ${layoutType === 'none' ? 'pt-24 md:pt-28' : 'pt-3'}`}>
|
||||
{/* Minimal Breadcrumbs when Archetype Header is disabled */}
|
||||
{layoutType === 'none' && (
|
||||
<nav aria-label="Breadcrumb" className="flex items-center gap-2 text-[11px] font-semibold uppercase tracking-wider text-muted-text">
|
||||
<Link href="/" className="transition hover:text-brand-primary">Home</Link>
|
||||
<span>/</span>
|
||||
<Link href="/shop" className="transition hover:text-brand-primary">Shop</Link>
|
||||
<span>/</span>
|
||||
<span className="text-text-main font-bold">{categoryName}</span>
|
||||
</nav>
|
||||
)}
|
||||
|
||||
return (
|
||||
<Link
|
||||
key={item.id}
|
||||
href={`/category/${item.id}`}
|
||||
className={`rounded-full px-5 py-2 text-xs font-bold uppercase tracking-widest transition ${isActive
|
||||
? 'bg-text-main text-surface-card'
|
||||
: 'border border-line-primary/20 bg-surface-card text-muted-text hover:border-brand-primary hover:text-brand-primary'
|
||||
}`}
|
||||
>
|
||||
{name}
|
||||
</Link>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
{/* Category Pills Navigation (Per-category Toggle) */}
|
||||
{category.filterConfig?.showCategoryNav !== false && (
|
||||
<div className={`flex flex-wrap gap-2.5 ${layoutType === 'editorial_hero' ? 'justify-center' : 'justify-start'}`}>
|
||||
{!categoriesResult.ok && (
|
||||
<span className="rounded-full border border-rose-100 bg-surface-card px-4 py-1.5 text-xs font-bold uppercase tracking-widest text-rose-500">
|
||||
Categories unavailable
|
||||
</span>
|
||||
)}
|
||||
{categories.map((item) => {
|
||||
const name = resolveLocalized(item.name, lang)
|
||||
const isActive = item.id === category.id
|
||||
|
||||
return (
|
||||
<Link
|
||||
key={item.id}
|
||||
href={`/category/${item.id}`}
|
||||
className={`rounded-full px-4 py-1.5 text-xs font-bold uppercase tracking-wider transition-all ${isActive
|
||||
? 'bg-text-main text-surface-card shadow-sm'
|
||||
: 'border border-line-primary/20 bg-surface-card text-muted-text hover:border-brand-primary hover:text-brand-primary'
|
||||
}`}
|
||||
>
|
||||
{name}
|
||||
</Link>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Featured Series Showcase Banner (Mockup 01 & 03) */}
|
||||
{Boolean(category.featuredSeries?.enabled) && (
|
||||
<CategoryFeaturedSeries
|
||||
featured={category.featuredSeries!}
|
||||
categoryName={categoryName}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Catalog Container (Filter Sidebar + Toolbar + Grid) */}
|
||||
{products.length === 0 ? (
|
||||
<div className="ui-panel px-6 py-20 text-center">
|
||||
<p className="text-lg font-semibold text-text-main">No products in this category yet.</p>
|
||||
<Link href="/shop" className="mt-4 inline-flex font-semibold text-brand-primary">Back to Shop</Link>
|
||||
</div>
|
||||
) : (
|
||||
<div className={getProductGridClass()}>
|
||||
{products.map((product) => <ProductCard key={product.id} product={product} />)}
|
||||
</div>
|
||||
<CategoryCatalogContainer
|
||||
products={products}
|
||||
categoryName={categoryName}
|
||||
filterConfig={category.filterConfig}
|
||||
layoutGridClass={getProductGridClass()}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Benefits & Support USP Blocks (Mockup 06) */}
|
||||
<CategoryUspBar benefits={category.uspBenefits} />
|
||||
</div>
|
||||
{bottomSections.length > 0 && (
|
||||
<DynamicPageRenderer sections={bottomSections} categories={categories} lang={lang} />
|
||||
|
||||
Reference in new issue
Block a user