-
JohniO34 authored
Two gaps: the menu only offered an outbound "Order on Toast" link, and the dashboard could only read. Both sides are now dynamic. Ordering - The 281-item menu board now comes from the database (new menu_sections and menu_products tables) instead of a static file, so anything edited in admin shows up on the public menu. - Basket (React Context + localStorage), keyed by product + size so a large and a small of the same pizza are separate lines. Header button carries a live count. - Checkout collects name, phone, address, delivery-vs-pickup and payment, with "rather just call?" kept as an option throughout. - Card payment is SIMULATED: no provider is connected, only the last four digits and a fake authorisation reference are stored, and the form says so. A test asserts the full number never reaches the row. - Delivery fee follows the advertised rule (free over $6). - Range-priced items can't be ordered online — there's no single price to charge — so they stay phone-only rather than the server guessing. Admin - Tabs: Overview, Takeaway orders, Catering bookings, Menu, Coupons. - Full CRUD over all 281 menu products and over the coupons, with server-side validation on both. - Deleting a product that has already been ordered archives it instead: gone from the menu, still attached to past orders, still counted in revenue. Hard delete only for items never sold. - Takeaway orders get their own table with line items, address, payment state and a kitchen workflow (new -> cooking -> out -> done). - Overview now splits takeaway from catering, including cash vs card. Orders are priced server-side here too: the browser sends only {productId, sizeLabel, qty}. Fixed a real bug found while testing: the basket and dish modal stayed mounted after navigating to another route, so three dialogs could be open at once. They now close on a route change, adjusted during render rather than in an effect so it lands in the same commit as the route. 23 new tests (123 total). `npm run seed:demo` now also loads takeaway orders so both halves of the dashboard have data to show.67d34ab1