Repository navigation
[Web] Menu editor — food item list, availability toggle, and add/edit modal #184
Description
Overview
Build the Menu Editor page inside the restaurant dashboard. This is the primary tool restaurant owners use to manage their food items day-to-day: adding new dishes, editing details, toggling availability, and reviewing what customers see.
Dependencies: Issue #181 (Food Item API) and Issue #182 (Upload pipeline).
Figma Reference
📐 Figma: [Menu editor — item list, add/edit modal, availability toggle, empty state — placeholder, link to be added by design lead]
Route
```
/dashboard/menu
```
Protected — requires authenticated user with an active restaurant.
Page Layout
Header
- Page title "Menu"
- "Add item" button (opens modal)
- Item count badge
Item List (table or card grid — follow Figma)
Columns:
| Column | Notes |
|---|---|
| Image thumbnail | 48 × 48 px, fallback placeholder if no image |
| Name | |
| Category | |
| Price | Formatted as currency (e.g. $12.50) — divide cents by 100 for display |
| Availability | Toggle switch — calls PATCH immediately on change |
| Actions | Edit (opens modal), Delete (confirmation prompt) |
- List is sorted by category, then name
- Show empty state illustration + "Add your first item" CTA when the list is empty
Add / Edit Modal
Triggered by "Add item" button or row edit action.
Fields:
- Name (required)
- Description (optional, textarea)
- Price (required, number input — user enters dollars, store as cents)
- Category (text input with autocomplete from existing categories in this restaurant)
- Dietary tags (multi-select from `DietaryTag` enum)
- Images (up to 5, using the `ImageUploader` component from the onboarding issue)
File Structure
```
apps/web/app/dashboard/menu/
page.tsx
MenuItemTable.tsx
MenuItemModal.tsx # Add / edit form in a modal
AvailabilityToggle.tsx # Inline toggle with optimistic update
```
Acceptance Criteria
- Item list fetches from `GET /api/restaurants/:id/food-items?includeUnavailable=true` (owners see all items)
- Availability toggle calls `PATCH /api/restaurants/:id/food-items/:itemId` with `{ isAvailable: boolean }` immediately on change (optimistic UI — revert on error)
- Add modal validates all fields with Zod before submitting; shows inline field errors
- Edit modal pre-fills all existing values
- Price input accepts dollars (e.g. `12.50`) and converts to cents before sending to API
- Price is displayed as formatted currency in the table
- Deleting an item shows a confirmation dialog ("Are you sure? This will hide the item from customers.")
- After successful add/edit/delete, the list refreshes without a full page reload
- Image uploads in the modal use `POST /api/upload` immediately on file selection; show previews
- Modal closes and resets form state on cancel
- All actions show loading states; error messages are shown inline (not as browser alerts)
- The page is responsive and usable on tablet-sized screens (≥ 768 px)
State Management
Use React Query (or SWR) for list fetching and cache invalidation after mutations. Do not use a global store for this page.
API Calls
| Action | Endpoint |
|---|---|
| Fetch items | `GET /api/restaurants/:id/food-items?includeUnavailable=true` |
| Create item | `POST /api/restaurants/:id/food-items` |
| Update item | `PATCH /api/restaurants/:id/food-items/:itemId` |
| Delete item | `DELETE /api/restaurants/:id/food-items/:itemId` |
| Upload image | `POST /api/upload` |
Out of Scope
- Item customisation / modifiers (Sprint 4)
- Bulk operations beyond availability toggle (Sprint 6)
- CSV export (Sprint 6)
Activity
ibdevlawal commentedon Jun 27, 2026
Hi, I’d like to contribute to this project by working on open issues. I have experience with javascript, and I’m comfortable collaborating, following guidelines, and submitting clean pull requests. Please let me know if there’s a good issue for me to start with. Thanks!
grantfox-oss commentedon Jun 27, 2026
🦊 GrantFox — @ibdevlawal has been assigned to this issue as part of the Official Campaign campaign!
Next steps:
Closes #184)Good luck! Track your progress on GrantFox.
grantfox-oss commentedon Jun 27, 2026
🎉 This issue has been marked as completed on GrantFox as part of the Official Campaign campaign!
@ibdevlawal's PR #198 was approved and merged by @zakkiyyat.
🏆 @ibdevlawal: You earned 35 FoxPoints for this contribution! Your current tier: Explorer (48 total points). Track your full progress on GrantFox.
👏 Great work, @ibdevlawal! Keep contributing to MixMatch-Inc.