This commit is contained in:
Your Name committed 2026-06-27 23:59:16 -04:00
1 parent 1c0313495f
commit ac387185e0
15 files changed
+1855 -12

No files matched your search

@@ -10,6 +10,19 @@ import ProductCard from '@/components/ProductCard'
import { getCategoriesResult, getCmsPageResult, getProduct, getProductResult, getProductsResult } from '@/lib/cms'
import { splitCmsLayoutSections } from '@/lib/cms-sections'
import { resolveCategoryName, resolveLocalized } from '@/lib/localization'
import type { ProductAttribute } from '@homaroma/types'
function formatAttributeValue(attribute: ProductAttribute): string {
const value = attribute.value
if (value === null || value === undefined || value === '') return ''
if (typeof value === 'boolean') return value ? 'Yes' : 'No'
if (typeof value === 'number') {
const unit = attribute.attributeDefinition.unit ? ` ${attribute.attributeDefinition.unit}` : ''
return `${value}${unit}`
}
if (typeof value === 'string') return value
return JSON.stringify(value)
}
async function getRelated(categoryId: number, excludeId: number, lang: string): Promise<Product[]> {
const result = await getProductsResult(`categoryId=${categoryId}`, lang)
@@ -80,6 +93,7 @@ export default async function ProductDetailPage({ params }: { params: Promise<{
const categoryName = resolveCategoryName(product.category, lang)
const details = resolveLocalized(product.details, lang)
const imageUrl = product.images?.[0]?.url || product.category.imageUrl || getCategoryImage(categoryName)
const visibleAttributes = (product.attributes || []).filter((attribute) => formatAttributeValue(attribute))
return (
<div className="min-h-screen bg-surface-page pb-24 text-text-main md:pb-0">
@@ -128,6 +142,25 @@ export default async function ProductDetailPage({ params }: { params: Promise<{
</section>
)}
{visibleAttributes.length > 0 && (
<section className="ui-panel p-8 md:p-12">
<h2 className="mb-6 text-3xl font-semibold text-text-main">Specifications</h2>
<div className="grid gap-3">
{visibleAttributes.map((attribute) => {
const label = typeof attribute.attributeDefinition.label === 'string'
? attribute.attributeDefinition.label
: resolveLocalized(attribute.attributeDefinition.label, lang)
return (
<div key={attribute.id} className="flex flex-col gap-2 rounded-2xl border border-line-primary/10 bg-surface-card px-5 py-4 md:flex-row md:items-center md:justify-between">
<span className="text-sm font-semibold text-text-main">{label}</span>
<span className="text-sm text-muted-text">{formatAttributeValue(attribute)}</span>
</div>
)
})}
</div>
</section>
)}
{related.length > 0 && (
<section className="space-y-8">
<div className="flex flex-col gap-4 border-b border-line-primary/20 pb-6 md:flex-row md:items-end md:justify-between">