diff --git a/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/01-admin-tables-crud-port-3020.png b/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/01-admin-tables-crud-port-3020.png new file mode 100644 index 00000000..b8a1be5f Binary files /dev/null and b/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/01-admin-tables-crud-port-3020.png differ diff --git a/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/01-admin-tables-crud.png b/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/01-admin-tables-crud.png new file mode 100644 index 00000000..f722702c Binary files /dev/null and b/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/01-admin-tables-crud.png differ diff --git a/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/02-admin-qr-regenerate-port-3020.png b/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/02-admin-qr-regenerate-port-3020.png new file mode 100644 index 00000000..1b33b340 Binary files /dev/null and b/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/02-admin-qr-regenerate-port-3020.png differ diff --git a/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/02-admin-qr-regenerate.png b/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/02-admin-qr-regenerate.png new file mode 100644 index 00000000..cb334428 Binary files /dev/null and b/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/02-admin-qr-regenerate.png differ diff --git a/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/03-admin-happy-hour-crud-port-3020.png b/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/03-admin-happy-hour-crud-port-3020.png new file mode 100644 index 00000000..9e905d47 Binary files /dev/null and b/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/03-admin-happy-hour-crud-port-3020.png differ diff --git a/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/04-pos-queue-display-port-3020.png b/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/04-pos-queue-display-port-3020.png new file mode 100644 index 00000000..aa4c6ec8 Binary files /dev/null and b/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/04-pos-queue-display-port-3020.png differ diff --git a/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/README.md b/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/README.md new file mode 100644 index 00000000..01275ce2 --- /dev/null +++ b/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/README.md @@ -0,0 +1,28 @@ +# Cafe Admin Table/QR/Happy-Hour Fixes - Port 3020 + +Chrome test target: `http://localhost:3020` + +Shop: `GoodGo Cafe MVP` (`0bc5ab7c-0b6d-4746-a2ef-c61307b90199`) + +## Workflow Screenshots + +1. `01-admin-tables-crud-port-3020.png` + - `/admin/shop/:shopId/tables` + - Confirms the Cafe admin route is no longer 404. + - Creates table `QA-920111` through the admin CRUD form. + +2. `02-admin-qr-regenerate-port-3020.png` + - `/admin/shop/:shopId/qr-codes` + - Selects `QR bàn QA-920111`. + - Regenerates QR from `/table/ca767ce906b94401` to `/table/c1b3754b580e419e`. + +3. `03-admin-happy-hour-crud-port-3020.png` + - `/admin/shop/:shopId/happy-hour` + - Confirms route and campaign-backed CRUD console. + - Creates campaign `Happy QA 81191`. + +4. `04-pos-queue-display-port-3020.png` + - `/pos/:shopId/cafe/queue-display` + - Confirms the active queue lane title is `Chờ pha / đang pha`, matching tickets that are still `Chờ pha`. + +Structured Chrome results are stored in `chrome-table-qr-results.json`. diff --git a/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/chrome-table-qr-results.json b/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/chrome-table-qr-results.json new file mode 100644 index 00000000..04ab6af4 --- /dev/null +++ b/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/chrome-table-qr-results.json @@ -0,0 +1,43 @@ +{ + "baseUrl": "http://localhost:3020", + "shopId": "0bc5ab7c-0b6d-4746-a2ef-c61307b90199", + "tableNumber": "QA-920111", + "happyHourName": "Happy QA 81191", + "checks": { + "tablesRoute": { + "url": "http://localhost:3020/admin/shop/0bc5ab7c-0b6d-4746-a2ef-c61307b90199/tables", + "title": "Bàn/phòng", + "hasCrud": true, + "createdVisible": true, + "successMessage": "Tạo mới thành công" + }, + "qrRoute": { + "url": "http://localhost:3020/admin/shop/0bc5ab7c-0b6d-4746-a2ef-c61307b90199/qr-codes", + "title": "QR bàn/phòng", + "selectedText": "QR bàn QA-920111 · Bàn/phòng", + "beforeToken": "/table/ca767ce906b94401", + "afterToken": "/table/c1b3754b580e419e", + "tokenChanged": true, + "successMessage": "Tạo lại QR thành công" + }, + "happyHourRoute": { + "url": "http://localhost:3020/admin/shop/0bc5ab7c-0b6d-4746-a2ef-c61307b90199/happy-hour", + "title": "Khung giờ ưu đãi", + "hasCrud": true, + "createdVisible": true, + "successMessage": "Tạo mới thành công" + }, + "queueDisplay": { + "url": "http://localhost:3020/pos/0bc5ab7c-0b6d-4746-a2ef-c61307b90199/cafe/queue-display", + "title": "Màn hình chờ lấy nước", + "activeLaneTitle": "Chờ pha / đang pha", + "titleMatchesPendingTickets": true + } + }, + "files": { + "tablesCrud": "/Users/velikho/Desktop/WORKING/pos-system/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/01-admin-tables-crud-port-3020.png", + "qrRegenerate": "/Users/velikho/Desktop/WORKING/pos-system/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/02-admin-qr-regenerate-port-3020.png", + "happyHourCrud": "/Users/velikho/Desktop/WORKING/pos-system/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/03-admin-happy-hour-crud-port-3020.png", + "queueDisplay": "/Users/velikho/Desktop/WORKING/pos-system/microservices/apps/tpos-mvp-next/output/demo-cafe-e2e-audit-3020/22-admin-table-qr-fixes/04-pos-queue-display-port-3020.png" + } +} 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 410110b9..76f59ba0 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 @@ -371,7 +371,7 @@ async function loadItems(section: string, shop?: Shop | null, allowedShopIds?: s id: String(row.id), kind: "leave-request", title: String(row.reason ?? "Nghỉ phép"), - meta: `${formatDate(row.from_date)} - ${formatDate(row.to_date)} · ${`${row.first_name ?? "Nhân viên"} ${row.last_name ?? ""}`.trim()}`, + meta: `${formatDateOnly(row.from_date)} - ${formatDateOnly(row.to_date)} · ${`${row.first_name ?? "Nhân viên"} ${row.last_name ?? ""}`.trim()}`, value: displayStatus(row.status), edit: { staffId: String(row.staff_id ?? ""), @@ -405,7 +405,18 @@ async function loadItems(section: string, shop?: Shop | null, allowedShopIds?: s if (section === "promotions" || section === "happy-hour") { const campaigns = await listCampaigns(shopId); return campaigns - .map((item) => ({ id: String(item.id), kind: "campaign", title: String(item.name), meta: String(item.description ?? "Chiến dịch"), value: displayStatus(item.status) })); + .map((item) => ({ + id: String(item.id), + kind: "campaign", + title: String(item.name), + meta: String(item.description ?? "Chiến dịch"), + value: displayStatus(item.status), + edit: { + description: String(item.description ?? ""), + amount: String(item.discount_value ?? item.face_value ?? ""), + status: String(item.status ?? "draft") + } + })); } if (section === "appointments" || section === "spa/appointments") { const appointments = shopId ? await listAppointments(shopId) : []; @@ -623,6 +634,10 @@ function displayStatus(value: unknown, fallback = "Chưa cấu hình") { draft: "Đang thiết lập", published: "Đang hoạt động", pending: "Chờ xử lý", + checked_in: "Đã check-in", + checked_out: "Đã check-out", + approved: "Đã duyệt", + rejected: "Từ chối", current: "Đang làm", next: "Tiếp theo", done: "Đã xong", @@ -715,7 +730,11 @@ function isKnownAdminSection(section: string, shop?: Shop | null) { "doctors", "history", "orders", + "tables", + "rooms", + "zones", "qr-codes", + "happy-hour", "reports/eod", "reports/revenue", "reports/staff" @@ -791,6 +810,14 @@ function formatDate(value: unknown) { return Number.isNaN(date.getTime()) ? String(value) : date.toLocaleString("vi-VN"); } +function formatDateOnly(value: unknown) { + if (!value) return ""; + const date = new Date(String(value)); + return Number.isNaN(date.getTime()) + ? String(value) + : date.toLocaleDateString("vi-VN", { day: "2-digit", month: "2-digit", year: "numeric" }); +} + function formatReportDay(value: unknown) { if (!value) return ""; const date = new Date(String(value)); diff --git a/microservices/apps/tpos-mvp-next/src/components/TposWorkflowScreen.tsx b/microservices/apps/tpos-mvp-next/src/components/TposWorkflowScreen.tsx index 705e1180..5ce91255 100644 --- a/microservices/apps/tpos-mvp-next/src/components/TposWorkflowScreen.tsx +++ b/microservices/apps/tpos-mvp-next/src/components/TposWorkflowScreen.tsx @@ -562,7 +562,7 @@ export function WorkflowScreen({ )) :