x
This commit is contained in:
1 parent
07e9413a6b
commit
46d504e483
4 files changed
+112
-38
No files matched your search
@@ -16,10 +16,28 @@ import DOMPurify from 'dompurify'
|
||||
function resolveTranslatable(value: TranslatableString | null | undefined, lang: string): string {
|
||||
if (!value) return ''
|
||||
if (typeof value === 'string') return value
|
||||
// Record<string, string>: ลอง lang เต็ม → ลอง prefix 2 ตัว → fallback 'th'/'en'
|
||||
// Record<string, string>: ลอง lang เต็ม → ลอง prefix 2 double-char → fallback 'th'/'en'
|
||||
return value[lang] ?? value[lang.slice(0, 2)] ?? value['th'] ?? value['en'] ?? Object.values(value)[0] ?? ''
|
||||
}
|
||||
|
||||
function resolveOptionValue(val: string, options: any[] | null | undefined, lang: string): string {
|
||||
if (!val) return '';
|
||||
if (!options || !Array.isArray(options)) return val;
|
||||
|
||||
for (const option of options) {
|
||||
if (!option.values || !Array.isArray(option.values)) continue;
|
||||
for (const v of option.values) {
|
||||
const baseStr = typeof v === 'string' ? v : (v['th'] || v['en'] || Object.values(v)[0] || '');
|
||||
if (baseStr === val) {
|
||||
if (typeof v === 'string') return v;
|
||||
return v[lang] ?? v[lang.slice(0, 2)] ?? v['th'] ?? v['en'] ?? Object.values(v)[0] ?? baseStr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
export default function ProductDetailPage() {
|
||||
const { id } = useParams<{ id: string }>()
|
||||
|
||||
@@ -134,7 +152,7 @@ export default function ProductDetailPage() {
|
||||
quantity: 1,
|
||||
price: currentVariant.price || product.price || 0,
|
||||
productName: displayName,
|
||||
variantName: [currentVariant.option1, currentVariant.option2, currentVariant.option3].filter(Boolean).join(' / '),
|
||||
variantName: [currentVariant.option1, currentVariant.option2, currentVariant.option3].filter(Boolean).map(opt => resolveOptionValue(opt, product.options, i18n.language)).join(' / '),
|
||||
productImage: product.images?.[0]?.url || getCategoryImage(typeof product.category.name === 'string' ? product.category.name : (product.category.name as any)?.en || '')
|
||||
})
|
||||
}
|
||||
@@ -204,7 +222,7 @@ export default function ProductDetailPage() {
|
||||
{formatPrice(currentVariant?.price)}
|
||||
</span>
|
||||
{currentVariant && (
|
||||
<span className="text-spa-stone/60 text-sm font-semibold">/ {[currentVariant.option1, currentVariant.option2, currentVariant.option3].filter(Boolean).join(' / ')}</span>
|
||||
<span className="text-spa-stone/60 text-sm font-semibold">/ {[currentVariant.option1, currentVariant.option2, currentVariant.option3].filter(Boolean).map(opt => resolveOptionValue(opt, product.options, i18n.language)).join(' / ')}</span>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -224,7 +242,7 @@ export default function ProductDetailPage() {
|
||||
: 'bg-spa-light text-spa-stone border-spa-stone/20 hover:border-spa-forest hover:text-spa-forest shadow-sm'
|
||||
}`}
|
||||
>
|
||||
{[v.option1, v.option2, v.option3].filter(Boolean).join(' / ')}
|
||||
{[v.option1, v.option2, v.option3].filter(Boolean).map(opt => resolveOptionValue(opt, product.options, i18n.language)).join(' / ')}
|
||||
<span className={`block text-[10px] mt-0.5 ${selectedVariant === i ? 'text-spa-light' : 'text-spa-stone/60'}`}>
|
||||
{formatPrice(v.price)}
|
||||
</span>
|
||||
@@ -337,7 +355,7 @@ export default function ProductDetailPage() {
|
||||
: 'bg-spa-light border-spa-stone/20 text-spa-stone'
|
||||
}`}
|
||||
>
|
||||
{[v.option1, v.option2, v.option3].filter(Boolean).join(' / ')}
|
||||
{[v.option1, v.option2, v.option3].filter(Boolean).map(opt => resolveOptionValue(opt, product.options, i18n.language)).join(' / ')}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
@@ -346,7 +364,7 @@ export default function ProductDetailPage() {
|
||||
<div className="flex items-center justify-between gap-4">
|
||||
<div className="flex flex-col">
|
||||
<span className="text-[10px] uppercase tracking-widest text-spa-stone/60 font-semibold">
|
||||
{product.variants && product.variants.length > 1 ? [currentVariant?.option1, currentVariant?.option2, currentVariant?.option3].filter(Boolean).join(' / ') : t('cart.totalPrice')}
|
||||
{product.variants && product.variants.length > 1 ? [currentVariant?.option1, currentVariant?.option2, currentVariant?.option3].filter(Boolean).map(opt => resolveOptionValue(opt, product.options, i18n.language)).join(' / ') : t('cart.totalPrice')}
|
||||
</span>
|
||||
<span className="text-xl font-bold text-rose-500">
|
||||
{formatPrice(currentVariant?.price)}
|
||||
|
||||
Reference in new issue
Block a user