This commit is contained in:
Your Name committed 2026-10-03 08:15:21 +07:00
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} />