From 07e9413a6bb25f001021ec81a1adc7c3ed8603a4 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 25 Jun 2026 16:46:38 +0700 Subject: [PATCH] x --- apps/admin/src/pages/ProductEditPage.tsx | 99 ++++++----- apps/backend/.env.example | 8 + apps/backend/delete_products.ts | 24 +++ apps/backend/scratch_seed_product.ts | 10 ++ apps/backend/scratch_test.ts | 16 ++ apps/backend/scratch_test_langs.ts | 5 + apps/backend/scratch_test_menus.ts | 2 + apps/backend/scratch_test_page.ts | 14 ++ apps/backend/scratch_test_page2.ts | 10 ++ apps/backend/src/routes/products.ts | 202 +++++++++++++++++++++-- apps/mcp-server/index.ts | 128 +++++++++++++- apps/mcp-server/menu-toolkit.ts | 71 ++++++-- apps/website/.env.production | 2 +- 13 files changed, 497 insertions(+), 94 deletions(-) create mode 100644 apps/backend/delete_products.ts create mode 100644 apps/backend/scratch_seed_product.ts create mode 100644 apps/backend/scratch_test.ts create mode 100644 apps/backend/scratch_test_langs.ts create mode 100644 apps/backend/scratch_test_menus.ts create mode 100644 apps/backend/scratch_test_page.ts create mode 100644 apps/backend/scratch_test_page2.ts diff --git a/apps/admin/src/pages/ProductEditPage.tsx b/apps/admin/src/pages/ProductEditPage.tsx index c1b1007..996e2c8 100644 --- a/apps/admin/src/pages/ProductEditPage.tsx +++ b/apps/admin/src/pages/ProductEditPage.tsx @@ -40,8 +40,7 @@ export default function ProductEditPage() { const [name, setName] = useState>({}) const [description, setDescription] = useState>({}) const [details, setDetails] = useState>({}) - const [options, setOptions] = useState<{name: string, values: string[]}[]>([]) - const [optionInputs, setOptionInputs] = useState(['', '', '']) + const [options, setOptions] = useState<{name: Record, values: Record[]}[]>([]) const [variants, setVariants] = useState[]>([]) const [images, setImages] = useState[]>([]) @@ -105,7 +104,15 @@ export default function ProductEditPage() { setDescription(parseTranslatable(prodData.description)) setDetails(parseTranslatable(prodData.details)) - const parseOptions = (val: any) => Array.isArray(val) ? val : [] + const parseOptions = (val: any) => { + if (!Array.isArray(val)) return [] + return val.map(opt => ({ + name: typeof opt.name === 'string' ? { th: opt.name } : (opt.name || { th: '' }), + values: Array.isArray(opt.values) + ? opt.values.map((v: any) => typeof v === 'string' ? { th: v } : (v || { th: '' })) + : [] + })) + } setOptions(parseOptions(prodData.options)) setVariants(prodData.variants || []) setImages(prodData.images || []) @@ -138,16 +145,19 @@ export default function ProductEditPage() { setVariants(updated) } - const regenerateVariants = (newOptions: {name: string, values: string[]}[]) => { + const regenerateVariants = (newOptions: {name: Record, values: Record[]}[]) => { setVariants(prevVariants => { - const validOptions = newOptions.filter(o => o.name && o.values.length > 0) + const validOptions = newOptions.filter(o => o.name && (o.name['th'] || o.name['en']) && o.values.length > 0) if (validOptions.length === 0) { const defaultVar = prevVariants.find(v => !v.option1 || v.option1 === 'Default') return defaultVar ? [defaultVar] : [] } - const arrays = validOptions.map(o => o.values) - const cartesian = arrays.reduce((acc, curr) => + const arrays = validOptions.map(o => o.values.map(v => v['th'] || v['en'] || Object.values(v)[0] || '')) + const filteredArrays = arrays.filter(arr => arr.length > 0 && arr.some(v => v !== '')) + if (filteredArrays.length === 0) return [] + + const cartesian = filteredArrays.reduce((acc, curr) => acc.flatMap(c => curr.map(n => [...c, n])), [[]] as string[][] ) @@ -450,7 +460,7 @@ export default function ProductEditPage() { {options.length < 3 && ( ))} - { - const newInputs = [...optionInputs] - newInputs[idx] = e.target.value - setOptionInputs(newInputs) +