Specification: Group CMS Sidebar Menu — Sections "Booking", "Minigame", "Membership" & "Voucher"
Last Updated: 15/07/2026
Type: CMS Navigation — Menu Grouping
System: Saleor CMS — Sidebar Menu under "Golden Lotus" Section
Feedback Screenshots:
- Screenshot 1: Spin History and Lucky Spin are flat list items → Group under Minigame
- Screenshot 2: Membership settings and Membership tiers are flat → Group under Membership
- Screenshot 3: Voucher redemptions and Vouchers are flat → Group under Voucher
- Screenshot 4: Booking list and Spa services are flat → Group under Booking
1. Current Issue
In the CMS sidebar (under the Golden Lotus section), several menu items are displayed in a flat alphabetical list without sub-groups. This makes navigation cumbersome for the Admin:
Minigame Section (no parent group):
Lịch sử quay(Spin History) → mid-listVòng quay(Lucky Spin) → end-listReport vòng quay(Spin Report) → missing
Membership Section (no parent group):
Membership settings→ mid-listMembership tiers→ right below settings, but no parent node
Voucher Section (no parent group):
Voucher redemptions→ bottom listVouchers→ bottom list, no parent nodeReport voucher→ missing
Booking Section (no parent group):
Danh sách booking(Booking List) → top listDịch vụ spa(Spa Services) → top list, no parent nodeLịch hẹn(Schedules) → top list, no parent nodeReport booking→ missing
2. Minigame Grouping Requirements
Create a new parent section named "Minigame" containing 3 sub-menu items:
📁 Minigame
├── 🎡 Vòng quay (Lucky Spin) (prizes, win rate%, enable/disable toggle)
├── 📊 Report vòng quay (Spin Report) (statistics, prizes distributed)
└── 📋 Lịch sử quay (Spin History) (user logs per spin)
🎡 Vòng quay (Lucky Spin Config)
- Function: Configure the lucky spin wheel parameters.
- Config Fields:
- Enable/Disable Lucky Spin module (
luckySpinEnabled) - Enable/Disable daily popup trigger (
dailyPopupEnabled) - Daily free spins per user (
dailyFreeSpins) — Default:1 - Max automatic popups per day (
maxPopupPerDay) — Default:1 - Campaign start/end dates (
startDate,endDate) - Prize wheel segments list: segment name, prize type (Point/Voucher), win rate %, inventory stock limit.
- Enable/Disable Lucky Spin module (
📊 Report vòng quay (Spin Report)
- Function: High-level campaign performance metrics.
- Data to display:
- Total spins played during the period
- Total prizes distributed (grouped by type: Point vs Voucher)
- Actual win rate vs configured win rate %
- Remaining stock per prize segment
- Daily/Weekly spin frequency charts
📋 Lịch sử quay (Spin History)
- Function: Audit log of all spins.
- Data columns:
- Member Name / Phone Number
- Timestamp
- Prize Won (prize segment name, value)
- Spin Ticket Type:
default(daily free spin) vsmarketing(added via campaign) - Status: Success / Failed
3. Implementation in Saleor CMS Navigation
To group navigation nodes in Saleor:
Step 1 — Define groups in navigation config
// File: saleor-app/src/navigation.ts or similar
export const GOLDEN_LOTUS_NAV_ITEMS = [
// ... existing items ...
// === MINIGAME GROUP ===
{
label: "Minigame",
icon: "🎮",
type: "group",
children: [
{
label: "Vòng quay",
url: "/apps/golden-lotus/lucky-spin/config",
icon: SpinIcon,
},
{
label: "Report vòng quay",
url: "/apps/golden-lotus/lucky-spin/report",
icon: ChartIcon,
},
{
label: "Lịch sử quay",
url: "/apps/golden-lotus/lucky-spin/history",
icon: HistoryIcon,
},
],
},
];
Step 2 — Relocate nodes
- Remove the flat nodes for
Vòng quayandLịch sử quay. - Add them under the
childrenarray of the newMinigameparent node. - Implement the new
Report vòng quayroute.
4. Membership Grouping Requirements
Create a parent section named "Membership" containing the 2 existing nodes:
📁 Membership
├── ⚙️ Membership settings (tier logic: points accrued multiplier, tier boundaries)
└── 🏅 Membership tiers (tier listing: Silver, Gold, Platinum, Diamond list)
Code Implementation
// Add to GOLDEN_LOTUS_NAV_ITEMS
// === MEMBERSHIP GROUP ===
{
label: "Membership",
icon: MembershipIcon,
type: "group",
children: [
{
label: "Membership settings",
url: "/apps/golden-lotus/membership/settings",
icon: SettingsIcon,
},
{
label: "Membership tiers",
url: "/apps/golden-lotus/membership/tiers",
icon: TiersIcon,
},
],
},
5. Voucher Grouping Requirements
Create a parent section named "Voucher" containing the 2 existing nodes + 1 new report node:
📁 Voucher
├── 🎫 Vouchers (create/manage templates)
├── 🔁 Voucher redemptions (history of point conversions)
└── 📊 Report voucher (voucher performance KPIs — new)
Voucher Report — Required KPIs
Summary Cards
| KPI | Description | Sample |
|---|---|---|
| Vouchers Created | Total voucher templates configured | 12 |
| Total Distributed | Total individual vouchers issued to users | 1,540 |
| Used | Count of claimed vouchers marked redeemed | 420 (27%) |
| Unused | Count of active, unredeemed vouchers | 890 (58%) |
| Expired | Count of expired vouchers that were never used | 230 (15%) |
Filters
- Date range: From date → To date
- Voucher Template (dropdown): All / specific template
- Distribution Source: All / Point Redemption / Lucky Spin / Marketing Campaign / Birthday Gift
- Status: All / Used / Unused / Expired
Detailed Data Table
| Column | Description |
|---|---|
| Voucher Name | Template title (e.g., "Voucher 50K Healing World") |
| Total Distributed | Total count issued |
| Used | Redeemed count + % |
| Unused | Active count + % |
| Expired | Expired count + % |
| Source | Distribution method |
| Validity Period | Start date → End date |
Code Implementation
// Add to GOLDEN_LOTUS_NAV_ITEMS
// === VOUCHER GROUP ===
{
label: "Voucher",
icon: VoucherIcon,
type: "group",
children: [
{
label: "Vouchers",
url: "/apps/golden-lotus/vouchers",
icon: TicketIcon,
},
{
label: "Voucher redemptions",
url: "/apps/golden-lotus/vouchers/redemptions",
icon: SwapIcon,
},
{
label: "Report voucher",
url: "/apps/golden-lotus/vouchers/report",
icon: ChartIcon,
},
],
},
6. Booking Grouping Requirements
Create a parent section named "Booking" containing 3 existing nodes + 1 new report node:
📁 Booking
├── 📅 Danh sách booking (Booking List)
├── 💆 Dịch vụ spa (Spa Services)
├── ⏰ Lịch hẹn (Schedules)
└── 📊 Report booking (Booking Report — new)
Booking Report Specification — KPIs & Charts
Global Time Filter
[!IMPORTANT] The date/time filter is global — when adjusted, ALL charts, KPI blocks, and data tables on the screen update simultaneously.
[ Today ] [ Last 7 Days ] [ Last 30 Days ] [ This Month ] [ This Quarter ] [ Custom: From ___ → To ___ ]
Sub-filters:
- Branch: All / TP.HCM / Da Nang / Ha Noi / Phu Quoc
- Service: All / specific category
- Status: All / Attended / No-show / Cancelled
KPI Summary Blocks
| KPI Block | Description | Unit |
|---|---|---|
| Total Bookings | Total appointments booked in period | Bookings |
| Attended | Appointments checked-in and served | Bookings + % |
| No-show | Active/pending bookings not checked-in | Bookings + % |
| Cancelled | Bookings cancelled by client or system | Bookings + % |
Monthly Booking Chart by Branch
Chart Type: Grouped Bar Chart or Stacked Bar Chart
- X-axis: Month/Week depending on the date range selected
- Y-axis: Number of bookings
- Color Legend representing branches:
- 🟤 TP.HCM
- 🔵 Da Nang
- 🟠 Ha Noi
- 🟢 Phu Quốc
- Hover tooltip showing: branch name, booking count, % contribution
- Interactive legend to toggle branch visibility
Detailed Table by Branch
| Column | Description |
|---|---|
| Branch | Branch location name |
| Total Bookings | Sum of bookings |
| Attended | Attended count + % |
| No-show | No-show/Unused count + % |
| Cancelled | Cancelled count + % |
| Top Service | Most booked service at location |
Code Implementation
// Add to GOLDEN_LOTUS_NAV_ITEMS
// === BOOKING GROUP ===
{
label: "Booking",
icon: CalendarIcon,
type: "group",
children: [
{
label: "Danh sách booking",
url: "/apps/golden-lotus/booking/list",
icon: ListIcon,
},
{
label: "Dịch vụ spa",
url: "/apps/golden-lotus/booking/services",
icon: SpaIcon,
},
{
label: "Lịch hẹn",
url: "/apps/golden-lotus/booking/schedule",
icon: ScheduleIcon,
},
{
label: "Report booking",
url: "/apps/golden-lotus/booking/report",
icon: ChartIcon,
},
],
},
7. Resulting Sidebar Structure
📁 Golden Lotus
├── 📁 Booking ← NEW GROUP
│ ├── Danh sách booking
│ ├── Dịch vụ spa
│ ├── Lịch hẹn
│ └── Report booking ← NEW PAGE
├── BFF Admin ↗
├── Chi nhánh
├── 📁 Membership ← NEW GROUP
│ ├── Membership settings
│ └── Membership tiers
├── 📁 Minigame ← NEW GROUP
│ ├── Vòng quay
│ ├── Report vòng quay ← NEW PAGE
│ └── Lịch sử quay
├── Notifications
├── Point transfers
├── POS Sync
├── Provider Settings
├── Tổng quan
└── 📁 Voucher ← NEW GROUP
├── Vouchers
├── Voucher redemptions
└── Report voucher ← NEW PAGE
Technical Checklist
Minigame Group:
- Create the
Minigameparent group with 3 child links:Vòng quay,Report vòng quay,Lịch sử quay. - Remove
Lịch sử quayandVòng quayfrom their old positions in the flat list. - Create the routes and views for the new
Report vòng quayscreen. - Add the following settings fields to the
Vòng quayconfiguration view:dailyFreeSpins,maxPopupPerDay,startDate,endDate. - Verify collapse/expand styling of the group node in the sidebar.
Membership Group:
- Create the
Membershipparent group with 2 child links:Membership settings,Membership tiers. - Remove
Membership settingsandMembership tiersfrom the flat list. - Verify navigation works correctly on child nodes.
Voucher Group:
- Create the
Voucherparent group with 3 child links:Vouchers,Voucher redemptions,Report voucher. - Remove
Voucher redemptionsandVouchersfrom the flat list. - Build the
Report voucherview displaying the 5 core KPIs: Vouchers Created, Total Distributed, Used, Unused, and Expired. - Ensure filters (date range, template, source, status) work on the report page.
Booking Group:
- Create the
Bookingparent group with 4 child links:Danh sách booking,Dịch vụ spa,Lịch hẹn,Report booking. - Remove
Danh sách booking,Dịch vụ spa, andLịch hẹnfrom the flat list. - Build the
Report bookingview implementing the global time filter. - Implement the branch comparison grouped bar chart and KPIs.
General:
- Modify the Saleor plugin configuration file to apply these groupings in a single commit.
- Verify that no sidebar menu items are duplicated or omitted.