Skip to content

Staff area redesign, break game, price and admin fixes - #4

Merged
Meinianda-L merged 7 commits into
mainfrom
claude/dazzling-lovelace-9cma60
Oct 4, 2026
Merged

Meinianda-L merged 7 commits into
mainfrom
claude/dazzling-lovelace-9cma60

Conversation

@Meinianda-L

@Meinianda-L Meinianda-L commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #3. I tested the admin account end to end, plus new products, prices and discounts. This PR fixes what those tests turned up, redesigns the staff area in the same cartoon sticker style as the ordering pages, and adds a small break game for staff.

Before and after

Before is the current main; after is this branch. Same data, same viewport.

Page Before → After
Dashboard Dashboard
Waiting orders Waiting orders
Orders Orders
Order details Order details
Storefront Storefront
Product editor Product editor
Product details Product details
Users Users
User details User details
Settings Settings
Statistics (500 error on main) Statistics
Activity log Activity log
Dashboard (mobile) Waiting orders (mobile)
Dashboard, mobile Waiting orders, mobile
Storefront (mobile) Settings (mobile)
Storefront, mobile Settings, mobile

New page, the break game (摸鱼一下):

Desktop Mobile
Break game Break game, mobile

Bug fixes

Prices and discounts

  • A sale multiplier produced prices like ¥16.915 (19.9 × 0.85), which were shown, charged and stored with three decimals. WeChat Pay and Stripe only take cents. Each cup is now rounded to cents (half up) on the menu, in the cart and on the server.
  • Base prices, sale multipliers and option price changes were not validated on the server. Negative prices, multipliers of 1.5, 0 or -1, three decimals and 4abc were all saved, and 4abc broke every order that used that option. They are now validated on the server and in the admin forms, with clear error messages.

Admin pages

  • The statistics page returned 500: ApexCharts and the dark-mode check touched window during server rendering.
  • Non-admins opening /user/manage/* got a 500 page, or the settings form. Every admin page now redirects them to their dashboard. Data was already protected by the server actions.
  • The "force open/close today" switch in settings compared an unpadded date with the padded one the queue saves, so it showed as off on most days. Turning it off saved an empty value that the settings validation rejects, which left the save button stuck.
  • Order and log times used toLocaleString(), which formats differently on the server and in the browser and caused hydration errors. They now use a fixed format in the store's time zone.
  • The user dashboard had no Chinese translation and showed English.

Ordering

  • Checkout had a hydration error: the cart was read from browser storage before React hydrated. The cart now loads after mount, and the empty-cart redirect and the WeChat pay page wait for it.
  • Login links are no longer prefetched. The prefetch followed the redirect to OneLogin and failed as a cross-origin request.

Staff area redesign

  • New dashboard layout: a sticker sidebar with a "mine" group, a store group for staff, and the break game. Phones get a top bar and a slide-in drawer.
  • Dashboard: a greeting from the beluga, balance and points tiles, and a "today at the store" overview for staff.
  • Waiting orders shown as paper tickets. The wait timer turns butter after 5 minutes and tomato after 10.
  • Storefront: chip tabs with counts, coupons drawn as tickets, tag colour dots and ad thumbnails.
  • The product editor shows a live preview of the menu card and the price the customer pays per cup.
  • Settings are grouped into opening hours, cup limits and payment. Users are shown as cards, user details as a profile with tiles, and the stats tiles and charts use the palette.
  • Tables, tabs, pagination, breadcrumbs and form fields are restyled once in the Flowbite theme. Detail pages use a shared label/value sheet. See docs/DESIGN.md.

Break game

/user/manage/break, for admins only. The beluga catches coffee beans (+1) and cups (+5) and dodges alarm clocks (the manager checking in). It works with the keyboard and with touch, pauses when the tab is hidden, keeps the best score in localStorage, and B is a boss key that jumps to the order queue.

Docs

  • The README now shows only final screenshots, with desktop and mobile in separate sections.
  • The README explains that uploads must be served by the web server in production, because next start only serves files that were in public/ at build time.

Testing

  • Lint, typecheck and unit tests (81, including new price rounding and validation tests) pass.
  • End-to-end admin workflow against a production build (44 checks):
    • Creating, editing and deleting categories, tags, option types, products (with image upload), coupons and ads.
    • Settings and the queue's open/close toggle.
    • A customer order, marking it done, and the refund.
    • Users: points, block, admin role.
    • Statistics, logs, and non-admin redirects.
  • End-to-end pricing (21 checks):
    • Sale and option prices on the menu, in the cart and at checkout.
    • The server-charged total and the balance and points changes.
    • Coupon usage limits, and a coupon larger than the total.
    • Refunds.
    • Rejection of invalid admin input.
    • Checkout reload with a saved cart.
  • Break game played automatically on desktop and mobile: scoring, pause, game over, best score after reload, and the boss key.
  • No page has horizontal overflow at 390 px.

- Statistics page returned 500: ApexCharts and the dark mode check touched
  `window` during server rendering. Load the chart in the browser only.
- Settings: the "force open/close today" switch compared an unpadded date
  with the padded one the order queue saves, so it showed as off on most
  days. Turning it off saved an empty value, which the settings validation
  rejects, leaving the save button stuck. It now resets to the default.
- Non-admins opening /user/manage/* got a 500 page (or the settings form).
  Every admin page now redirects them to their dashboard.
- Order and log times used toLocaleString(), which formats differently on
  the server and in the browser and caused hydration errors. Use a fixed
  format in the store's time zone.
- README: explain that uploads must be served by the web server in
  production, since `next start` only serves files present at build time.
…r hydration

Pricing
- A sale multiplier could produce prices like 16.915, which were shown,
  charged and stored with three decimals. Each cup is now rounded to cents
  (half up) on the menu, in the cart and on the server.
- Base prices, sale multipliers and option price changes were not checked on
  the server: negative prices, a multiplier of 1.5, 0 or -1, three decimals
  or "4abc" were saved, and "4abc" broke every order using that option. The
  server and the admin forms now validate them.

Cart hydration
- The cart and last order were read from browser storage before React
  hydrated, so the checkout page rendered differently from the server HTML.
  The stores now load after mount; the empty-cart redirect and the WeChat
  pay page wait for them.
- Login links are no longer prefetched; the prefetch followed the redirect
  to OneLogin and failed as a cross-origin request.
- New dashboard layout with a sticker sidebar: a "mine" group, a store group
  for staff, and the break game. Phones get a top bar and a slide-in drawer.
- Dashboard: greeting from the beluga, balance and points tiles, and a
  "today at the store" overview for staff (queue, cups left, hours).
- Waiting orders queue shown as paper tickets with a wait timer that turns
  butter after 5 minutes and tomato after 10, next to a store status card.
- Storefront: chip tabs with counts, coupons drawn as tickets, tag colour
  dots, ad thumbnails and an empty state with the sleepy beluga.
- Product editor shows a live preview of the menu card and the price the
  customer pays.
- Settings grouped into hours, cup limits and payment; users as cards; user
  details as a profile with tiles; stats tiles and charts in the palette.
- Tables, tabs, pagination, breadcrumbs and form fields restyled in the
  Flowbite theme; detail pages use a shared label/value sheet.
- Break game (摸鱼一下): the beluga catches coffee beans and cups and dodges
  alarm clocks. Keyboard and touch controls, pause, local best score, and a
  boss key that jumps to the order queue.
- Chinese translations for the dashboard, which were missing; localized
  pagination and the stats date picker; greeting hour uses the store's time
  zone so it renders the same on the server and in the browser.
- Order items without options no longer show a trailing "/".
@Meinianda-L
Meinianda-L merged commit b49fe2b into main Oct 4, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant