From 0d10c7a071c1072f94381013ac5514e6f00904c9 Mon Sep 17 00:00:00 2001
From: Your Name
Date: Sat, 13 Jun 2026 23:22:40 -0400
Subject: [PATCH] x
---
.../migration.sql | 19 +++++++++++++++++++
apps/spa/src/pages/ProductDetailPage.tsx | 18 +++++++++++++-----
2 files changed, 32 insertions(+), 5 deletions(-)
create mode 100644 apps/backend/prisma/migrations/20260614000000_add_product_translation/migration.sql
diff --git a/apps/backend/prisma/migrations/20260614000000_add_product_translation/migration.sql b/apps/backend/prisma/migrations/20260614000000_add_product_translation/migration.sql
new file mode 100644
index 0000000..ddd8c8d
--- /dev/null
+++ b/apps/backend/prisma/migrations/20260614000000_add_product_translation/migration.sql
@@ -0,0 +1,19 @@
+-- CreateTable
+CREATE TABLE "ProductTranslation" (
+ "id" SERIAL NOT NULL,
+ "productId" INTEGER NOT NULL,
+ "langCode" TEXT NOT NULL,
+ "name" TEXT NOT NULL,
+ "description" TEXT,
+ "details" TEXT,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL,
+
+ CONSTRAINT "ProductTranslation_pkey" PRIMARY KEY ("id")
+);
+
+-- CreateIndex
+CREATE UNIQUE INDEX "ProductTranslation_productId_langCode_key" ON "ProductTranslation"("productId", "langCode");
+
+-- AddForeignKey
+ALTER TABLE "ProductTranslation" ADD CONSTRAINT "ProductTranslation_productId_fkey" FOREIGN KEY ("productId") REFERENCES "Product"("id") ON DELETE CASCADE ON UPDATE CASCADE;
diff --git a/apps/spa/src/pages/ProductDetailPage.tsx b/apps/spa/src/pages/ProductDetailPage.tsx
index d7ca45b..0130cd0 100644
--- a/apps/spa/src/pages/ProductDetailPage.tsx
+++ b/apps/spa/src/pages/ProductDetailPage.tsx
@@ -7,9 +7,17 @@ import ProductCard from '../components/ProductCard'
import ProductReviews from '../components/ProductReviews'
import ProductImageGallery from '../components/ProductImageGallery'
import DynamicPageRenderer from '../components/DynamicPageRenderer'
-import { API_BASE, getCategoryImage, formatPrice, type Category, type Product, type PageSection } from '../types'
+import { API_BASE, getCategoryImage, formatPrice, type Category, type Product, type PageSection, type TranslatableString } from '../types'
import { useCartStore } from '../store/cartStore'
+/** แปลง TranslatableString (string | Record) เป็น string ตาม locale */
+function resolveTranslatable(value: TranslatableString | null | undefined, lang: string): string {
+ if (!value) return ''
+ if (typeof value === 'string') return value
+ // Record: ลอง lang เต็ม → ลอง prefix 2 ตัว → fallback 'th'/'en'
+ return value[lang] ?? value[lang.slice(0, 2)] ?? value['th'] ?? value['en'] ?? Object.values(value)[0] ?? ''
+}
+
export default function ProductDetailPage() {
const { id } = useParams<{ id: string }>()
@@ -176,8 +184,8 @@ export default function ProductDetailPage() {
- {product.description && (
- {product.description}
+ {resolveTranslatable(product.description, i18n.language) && (
+ {resolveTranslatable(product.description, i18n.language)}
)}
{/* Price */}
@@ -250,12 +258,12 @@ export default function ProductDetailPage() {
{/* Full Details Section */}
- {product.details && (
+ {resolveTranslatable(product.details, i18n.language) && (
)}