diff --git a/apps/admin/src/pages/ProductEditPage.tsx b/apps/admin/src/pages/ProductEditPage.tsx index 37c01a9..06c0891 100644 --- a/apps/admin/src/pages/ProductEditPage.tsx +++ b/apps/admin/src/pages/ProductEditPage.tsx @@ -566,7 +566,7 @@ export default function ProductEditPage() { {variants.length > 0 ? variants.map((v, idx) => ( - {options.length > 0 ? options.map((opt, i) => { + {options.length > 0 ? options.map((_, i) => { const optVal = i === 0 ? v.option1 : i === 1 ? v.option2 : v.option3 return ( {optVal || '-'} diff --git a/apps/admin/src/pages/ProductsPage.tsx b/apps/admin/src/pages/ProductsPage.tsx index 7b01dab..50c28d7 100644 --- a/apps/admin/src/pages/ProductsPage.tsx +++ b/apps/admin/src/pages/ProductsPage.tsx @@ -81,7 +81,7 @@ export default function ProductsPage() { headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ categoryId: selectedProduct.categoryId, - variants: selectedProduct.variants.map(v => ({ size: v.size, price: v.price })), + variants: selectedProduct.variants.map(v => ({ option1: v.option1, option2: v.option2, option3: v.option3, sku: v.sku, barcode: v.barcode, stock: v.stock, price: v.price })), images: updatedImages }) }) @@ -145,7 +145,7 @@ export default function ProductsPage() { headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ categoryId: selectedProduct.categoryId, - variants: selectedProduct.variants.map(v => ({ size: v.size, price: v.price })), + variants: selectedProduct.variants.map(v => ({ option1: v.option1, option2: v.option2, option3: v.option3, sku: v.sku, barcode: v.barcode, stock: v.stock, price: v.price })), images: updatedImages }) }) @@ -324,9 +324,9 @@ export default function ProductsPage() { -

{product.variants?.length || 0} Sizes

+

{product.variants?.length || 0} Variants

- {product.variants?.map(v => v.size).join(', ') || '-'} + {product.variants?.map(v => [v.option1, v.option2, v.option3].filter(Boolean).join('/')).join(', ') || '-'}

diff --git a/apps/spa/src/components/ProductCard.tsx b/apps/spa/src/components/ProductCard.tsx index c34e8d7..078f920 100644 --- a/apps/spa/src/components/ProductCard.tsx +++ b/apps/spa/src/components/ProductCard.tsx @@ -26,7 +26,7 @@ export default function ProductCard({ product, enableQuickShop = false, category const { i18n, t } = useTranslation(); const isWished = isInWishlist(product.id); const [selectedVariant, setSelectedVariant] = useState(product.variants?.[0] || null); - const displayName = resolveStr(product.name, i18n.language) || product.scent.name; + const displayName = resolveStr(product.name, i18n.language) || (product.brand ? product.brand.name : ''); const displayCategoryName = categoryNameOverride || resolveStr(product.category.name, i18n.language); const handleWishlistClick = (e: React.MouseEvent) => { @@ -52,7 +52,7 @@ export default function ProductCard({ product, enableQuickShop = false, category {product.scent.name} { (e.target as HTMLImageElement).style.display = 'none'; }} @@ -100,7 +100,7 @@ export default function ProductCard({ product, enableQuickShop = false, category : 'border-pop-black/10 bg-transparent text-pop-black/70 hover:border-pop-black/30 hover:bg-pop-black/5' }`} > - {variant.size} + {[variant.option1, variant.option2, variant.option3].filter(Boolean).join(' / ')} ); })} @@ -131,7 +131,7 @@ export default function ProductCard({ product, enableQuickShop = false, category quantity: 1, price: selectedVariant.price || 0, productName: displayName, - variantSize: selectedVariant.size, + variantSize: [selectedVariant.option1, selectedVariant.option2, selectedVariant.option3].filter(Boolean).join(' / '), productImage: product.images?.[0]?.url || getCategoryImage(displayCategoryName) }); }} diff --git a/apps/spa/src/locales/en/translation.json b/apps/spa/src/locales/en/translation.json index 24be2f5..780fb04 100644 --- a/apps/spa/src/locales/en/translation.json +++ b/apps/spa/src/locales/en/translation.json @@ -56,6 +56,7 @@ "selectSize": "Select Size", "details": "Product Details", "scent": "Scent", + "brand": "Brand", "category": "Category", "relatedProducts": "Related Products", "moreRelated": "More {{category}}", diff --git a/apps/spa/src/locales/ja/translation.json b/apps/spa/src/locales/ja/translation.json index 25678e1..87b9d01 100644 --- a/apps/spa/src/locales/ja/translation.json +++ b/apps/spa/src/locales/ja/translation.json @@ -53,6 +53,7 @@ "selectSize": "サイズを選択", "details": "商品詳細", "scent": "香り", + "brand": "ブランド", "category": "カテゴリー", "relatedProducts": "関連商品", "moreRelated": "関連する {{category}}", diff --git a/apps/spa/src/locales/ko/translation.json b/apps/spa/src/locales/ko/translation.json index e09f800..64a803e 100644 --- a/apps/spa/src/locales/ko/translation.json +++ b/apps/spa/src/locales/ko/translation.json @@ -53,6 +53,7 @@ "selectSize": "사이즈 선택", "details": "상품 상세 정보", "scent": "향기", + "brand": "브랜드", "category": "카테고리", "relatedProducts": "관련 상품", "moreRelated": "더 많은 {{category}}", diff --git a/apps/spa/src/locales/th/translation.json b/apps/spa/src/locales/th/translation.json index 525db63..d887ac0 100644 --- a/apps/spa/src/locales/th/translation.json +++ b/apps/spa/src/locales/th/translation.json @@ -56,6 +56,7 @@ "selectSize": "เลือกขนาด", "details": "รายละเอียดสินค้า", "scent": "กลิ่น", + "brand": "แบรนด์", "category": "หมวดหมู่", "relatedProducts": "สินค้าที่เกี่ยวข้อง", "moreRelated": "เพิ่มเติมในหมวด {{category}}", diff --git a/apps/spa/src/locales/vi/translation.json b/apps/spa/src/locales/vi/translation.json index ebd1136..0c2bbb7 100644 --- a/apps/spa/src/locales/vi/translation.json +++ b/apps/spa/src/locales/vi/translation.json @@ -53,6 +53,7 @@ "selectSize": "Chọn kích thước", "details": "Chi tiết sản phẩm", "scent": "Mùi hương", + "brand": "Thương hiệu", "category": "Danh mục", "relatedProducts": "Sản phẩm liên quan", "moreRelated": "Thêm {{category}}", diff --git a/apps/spa/src/locales/zh/translation.json b/apps/spa/src/locales/zh/translation.json index daca676..4848599 100644 --- a/apps/spa/src/locales/zh/translation.json +++ b/apps/spa/src/locales/zh/translation.json @@ -53,6 +53,7 @@ "selectSize": "选择尺寸", "details": "商品详情", "scent": "香气", + "brand": "品牌", "category": "类别", "relatedProducts": "相关商品", "moreRelated": "更多 {{category}}", diff --git a/apps/spa/src/pages/ProductDetailPage.tsx b/apps/spa/src/pages/ProductDetailPage.tsx index 157f062..2b2e875 100644 --- a/apps/spa/src/pages/ProductDetailPage.tsx +++ b/apps/spa/src/pages/ProductDetailPage.tsx @@ -40,7 +40,7 @@ export default function ProductDetailPage() { return v[lang] ?? v[lang.slice(0, 2)] ?? v['th'] ?? v['en'] ?? Object.values(v)[0] ?? '' } - const displayName = resolveStr(product?.name, i18n.language) || product?.scent?.name || '' + const displayName = resolveStr(product?.name, i18n.language) || product?.brand?.name || '' useEffect(() => { fetch(`${API_BASE}/categories?lang=${i18n.language}`) @@ -134,7 +134,7 @@ export default function ProductDetailPage() { quantity: 1, price: currentVariant.price || product.price || 0, productName: displayName, - variantSize: currentVariant.size, + variantSize: [currentVariant.option1, currentVariant.option2, currentVariant.option3].filter(Boolean).join(' / '), productImage: product.images?.[0]?.url || getCategoryImage(typeof product.category.name === 'string' ? product.category.name : (product.category.name as any)?.en || '') }) } @@ -175,7 +175,7 @@ export default function ProductDetailPage() { @@ -204,7 +204,7 @@ export default function ProductDetailPage() { {formatPrice(currentVariant?.price)} {currentVariant && ( - / {currentVariant.size} + / {[currentVariant.option1, currentVariant.option2, currentVariant.option3].filter(Boolean).join(' / ')} )} @@ -224,7 +224,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.size} + {[v.option1, v.option2, v.option3].filter(Boolean).join(' / ')} {formatPrice(v.price)} @@ -251,8 +251,8 @@ export default function ProductDetailPage() { {/* Meta */}
- {t('product.scent')} - {product.scent.name} + {t('product.brand', 'Brand')} + {product.brand?.name || ''}
{t('product.category')} @@ -337,7 +337,7 @@ export default function ProductDetailPage() { : 'bg-spa-light border-spa-stone/20 text-spa-stone' }`} > - {v.size} + {[v.option1, v.option2, v.option3].filter(Boolean).join(' / ')} ))}
@@ -346,7 +346,7 @@ export default function ProductDetailPage() {
- {product.variants && product.variants.length > 1 ? currentVariant?.size : t('cart.totalPrice')} + {product.variants && product.variants.length > 1 ? [currentVariant?.option1, currentVariant?.option2, currentVariant?.option3].filter(Boolean).join(' / ') : t('cart.totalPrice')} {formatPrice(currentVariant?.price)}