diff --git a/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/01-menu-enhanced-forms/01-menu-enhanced-forms.png b/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/01-menu-enhanced-forms/01-menu-enhanced-forms.png new file mode 100644 index 00000000..3d81de2b Binary files /dev/null and b/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/01-menu-enhanced-forms/01-menu-enhanced-forms.png differ diff --git a/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/02-menu-category-created/02-menu-category-created.png b/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/02-menu-category-created/02-menu-category-created.png new file mode 100644 index 00000000..86bb475a Binary files /dev/null and b/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/02-menu-category-created/02-menu-category-created.png differ diff --git a/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/03-menu-product-created/03-menu-product-created.png b/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/03-menu-product-created/03-menu-product-created.png new file mode 100644 index 00000000..cfd52239 Binary files /dev/null and b/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/03-menu-product-created/03-menu-product-created.png differ diff --git a/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/04-menu-product-edit-prefill/04-menu-product-edit-prefill.png b/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/04-menu-product-edit-prefill/04-menu-product-edit-prefill.png new file mode 100644 index 00000000..31ed2387 Binary files /dev/null and b/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/04-menu-product-edit-prefill/04-menu-product-edit-prefill.png differ diff --git a/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/05-menu-product-updated/05-menu-product-updated.png b/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/05-menu-product-updated/05-menu-product-updated.png new file mode 100644 index 00000000..38703aa2 Binary files /dev/null and b/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/05-menu-product-updated/05-menu-product-updated.png differ diff --git a/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/06-menu-category-updated/06-menu-category-updated.png b/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/06-menu-category-updated/06-menu-category-updated.png new file mode 100644 index 00000000..113a338b Binary files /dev/null and b/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/06-menu-category-updated/06-menu-category-updated.png differ diff --git a/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/07-menu-product-hidden-after-reload/07-menu-product-hidden-after-reload.png b/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/07-menu-product-hidden-after-reload/07-menu-product-hidden-after-reload.png new file mode 100644 index 00000000..ca95850d Binary files /dev/null and b/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/07-menu-product-hidden-after-reload/07-menu-product-hidden-after-reload.png differ diff --git a/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/08-menu-category-hidden-after-reload/08-menu-category-hidden-after-reload.png b/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/08-menu-category-hidden-after-reload/08-menu-category-hidden-after-reload.png new file mode 100644 index 00000000..16069288 Binary files /dev/null and b/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/08-menu-category-hidden-after-reload/08-menu-category-hidden-after-reload.png differ diff --git a/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/10-admin-cafe-menu-after-product-category-crud.png b/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/99-diagnostics/menu-stale/10-admin-cafe-menu-after-product-category-crud.png similarity index 100% rename from microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/10-admin-cafe-menu-after-product-category-crud.png rename to microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/99-diagnostics/menu-stale/10-admin-cafe-menu-after-product-category-crud.png diff --git a/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/10h-menu-after-category-delete-reload.png b/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/99-diagnostics/menu-stale/10h-menu-after-category-delete-reload.png similarity index 100% rename from microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/01-menu/10h-menu-after-category-delete-reload.png rename to microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/99-diagnostics/menu-stale/10h-menu-after-category-delete-reload.png diff --git a/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/README.md b/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/README.md index cebf7491..b4e93e37 100644 --- a/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/README.md +++ b/microservices/apps/tpos-mvp-next/output/demo-cafe-crud-audit/README.md @@ -4,8 +4,15 @@ ## 01-menu -- `10-admin-cafe-menu-after-product-category-crud.png`: tạo/sửa sản phẩm và danh mục. -- `10h-menu-after-category-delete-reload.png`: danh mục đã ẩn sau reload. +- `01-menu-enhanced-forms/01-menu-enhanced-forms.png`: form menu mới có danh mục, SKU, barcode, tồn ban đầu, mô tả, edit category rõ field. +- `02-menu-category-created/02-menu-category-created.png`: tạo danh mục QA mới. +- `03-menu-product-created/03-menu-product-created.png`: tạo product QA gắn category, SKU, barcode, tồn ban đầu. +- `04-menu-product-edit-prefill/04-menu-product-edit-prefill.png`: form edit product prefill đúng category, SKU, barcode và `PreparedFood`. +- `05-menu-product-updated/05-menu-product-updated.png`: cập nhật product QA, giá, SKU, barcode. +- `06-menu-category-updated/06-menu-category-updated.png`: cập nhật category QA, mô tả và thứ tự. +- `07-menu-product-hidden-after-reload/07-menu-product-hidden-after-reload.png`: product QA đã ẩn sau reload. +- `08-menu-category-hidden-after-reload/08-menu-category-hidden-after-reload.png`: category QA đã ẩn sau reload. +- Ảnh `10-*` cũ đã chuyển sang `99-diagnostics/menu-stale/`, không dùng làm demo chính. ## 02-inventory @@ -62,3 +69,4 @@ ## 99-diagnostics Ảnh trong thư mục này là lỗi/case điều tra, không dùng làm demo chính. +- `menu-stale/`: ảnh menu CRUD cũ trước khi tách product/category canonical. diff --git a/microservices/apps/tpos-mvp-next/src/app/admin/[...path]/page.tsx b/microservices/apps/tpos-mvp-next/src/app/admin/[...path]/page.tsx index 4baef540..6b3a7a5c 100644 --- a/microservices/apps/tpos-mvp-next/src/app/admin/[...path]/page.tsx +++ b/microservices/apps/tpos-mvp-next/src/app/admin/[...path]/page.tsx @@ -228,8 +228,41 @@ async function loadItems(section: string, shop?: Shop | null, allowedShopIds?: s if (["menu", "products", "services", "packages", "treatments", "combos"].includes(section) && shopId) { const [categories, products] = await Promise.all([listCatalogCategoriesByShop(shopId), listCatalogProductsByShop(shopId)]); return [ - ...categories.map((category) => ({ id: category.id, kind: "category", title: category.name, meta: category.description ?? "Danh mục", value: `${category.displayOrder}`, href: `/admin/shop/${shopId}/${section}` })), - ...products.map((product) => ({ id: product.id, kind: "product", title: product.name, meta: product.categoryName ?? product.productType, value: formatMoney(product.price), href: `/admin/shop/${shopId}/${section}` })) + ...categories.map((category) => ({ + id: category.id, + kind: "category", + title: category.name, + meta: category.description ?? "Danh mục", + value: `Thứ tự ${category.displayOrder}`, + href: `/admin/shop/${shopId}/${section}`, + edit: { + description: category.description ?? "", + displayOrder: String(category.displayOrder), + isActive: true + } + })), + ...products.map((product) => ({ + id: product.id, + kind: "product", + title: product.name, + meta: [ + product.categoryName ?? "Chưa phân loại", + product.productType, + product.sku ? `SKU ${product.sku}` : null, + product.barcode ? `Barcode ${product.barcode}` : null + ].filter(Boolean).join(" · "), + value: formatMoney(product.price), + href: `/admin/shop/${shopId}/${section}`, + edit: { + description: product.description ?? "", + amount: String(product.price), + status: product.productType, + categoryId: product.categoryId ?? "", + sku: product.sku ?? "", + barcode: product.barcode ?? "", + isActive: product.isActive + } + })) ]; } if (section === "recipes" && shopId) { diff --git a/microservices/apps/tpos-mvp-next/src/components/admin/reference/sectionViews.tsx b/microservices/apps/tpos-mvp-next/src/components/admin/reference/sectionViews.tsx index bc5aacd0..32fa2905 100644 --- a/microservices/apps/tpos-mvp-next/src/components/admin/reference/sectionViews.tsx +++ b/microservices/apps/tpos-mvp-next/src/components/admin/reference/sectionViews.tsx @@ -128,10 +128,11 @@ const numericPayloadKeys = new Set([ "discountValue", "totalVouchers", "taxRate", - "byteSize" + "byteSize", + "typeId" ]); -const booleanPayloadKeys = new Set(["enabled", "isDefault", "showLogo", "showQr", "showTax", "kitchenCopy"]); +const booleanPayloadKeys = new Set(["enabled", "isDefault", "showLogo", "showQr", "showTax", "kitchenCopy", "isActive"]); function AdminCrudConsole({ section, shop, vertical, items }: { section: string; shop: Shop; vertical: VerticalKind; items: AdminSectionItem[] }) { const router = useRouter(); @@ -249,6 +250,7 @@ function AdminCrudConsole({ section, shop, vertical, items }: { section: string; const statusLabel = selectedKind === "file" ? "Quyền truy cập" : selectedKind === "folder" ? "Trạng thái" : "Trạng thái / vai trò / đơn vị"; const deleteLabel = selectedKind === "file" || selectedKind === "folder" ? "Ẩn metadata" : selectedKind === "receipt-template" ? "Tắt mẫu" : "Xóa / tắt"; const canEditAmountAndStatus = selectedKind !== "folder"; + const categoryItems = items.filter((item) => item.kind === "category" && item.id); return (
@@ -274,7 +276,74 @@ function AdminCrudConsole({ section, shop, vertical, items }: { section: string; ))} - {selectedKind === "receipt-template" ? ( + {selectedKind === "product" ? ( + <> +
+ + +
+ +
+ + +
+
+ + +
+
+ +
+ + ) : selectedKind === "category" ? ( + <> +
+ + +
+ +
+ +
+ + ) : selectedKind === "receipt-template" ? ( <>
+
+ +
+
+
diff --git a/microservices/apps/tpos-mvp-next/src/components/admin/reference/types.ts b/microservices/apps/tpos-mvp-next/src/components/admin/reference/types.ts index 2431ee55..17edb128 100644 --- a/microservices/apps/tpos-mvp-next/src/components/admin/reference/types.ts +++ b/microservices/apps/tpos-mvp-next/src/components/admin/reference/types.ts @@ -47,6 +47,11 @@ export type AdminSectionItem = { footerText?: string; taxLabel?: string; taxRate?: string; + categoryId?: string; + sku?: string; + barcode?: string; + displayOrder?: string; + isActive?: boolean; showLogo?: boolean; showQr?: boolean; showTax?: boolean;