A kitchen management platform for professional canteens — from dish proposals to published menus.
This repository contains the React frontend for the MiseOS system. It connects to a Java 17 + Javalin backend deployed at https://miseos-api.corral.dk/api/v1.
Live: miseos.corral.dk
API documentation: corral.dk/miseos-api-doc
Backend repository: github.com/Mortenjenne/miseOS
Portfolio & development blog: corral.dk/projects/miseos
YouTube demo video: MiseOS Frontend Demo
MiseOS digitizes the full kitchen planning workflow in a professional canteen. The name comes from mise en place — having everything in its place before service starts.
In many kitchens, menu planning still relies on handwritten notes, Word files, and verbal coordination between stations. MiseOS replaces this with a structured, role-based digital workflow: line cooks submit dish proposals for their station, head chefs curate and assemble the weekly menu, ingredient needs are collected and turned into AI-normalized shopping lists, and a multilingual menu is published for guests.
The system is built around the idea that quality comes from station-level ownership and management curation — not top-down planning.
Currently being used and tested in a real kitchen environment.
The system supports 3 main user groups with distinct workflows:
Kitchen staff (LINE_COOK)
- Submit dish proposals with allergens and target week
- Track proposal status and receive feedback
- Submit and manage ingredient requests linked to specific dishes
- View the current published weekly menu
- AI-powered menu inspiration via SSE streaming
- Real-time notifications when requests or suggestions are reviewed
Management (HEAD_CHEF / SOUS_CHEF)
- Review and approve or reject dish proposals with feedback
- Build and publish the weekly menu slot by slot (DRAFT → PUBLISHED)
- Translate menus via DeepL before publishing
- Review and approve or reject ingredient requests
- Generate AI-normalized shopping lists from approved requests, mark items as ordered, and finalize lists
- Real-time dashboard with live counters via WebSocket
- Manage dishes in the dish bank (CRUD, active/inactive)
- Manage users, stations, and allergens
- Takeaway offer management — create offers from today's menu, enable/disable, track portions (in progress)
Public / guests
- Browse the current published weekly menu
- Browse daily takeaway offers and place orders
| Framework | React 19 + Vite |
| Routing | React Router v7 |
| Styling | CSS Modules + CSS custom properties |
| HTTP | Native fetch via shared apiClient.js |
| Auth | JWT stored in localStorage |
| Realtime | WebSocket (dashboard counters + staff notifications) + SSE (AI streaming) |
The frontend follows a feature-based folder structure. Each domain owns its pages, components, services, and utilities:
src/
├── api/ # apiClient.js — shared fetch wrapper + JWT + auth events
├── components/ # Shared UI components and layout pieces
├── context/ # AuthContext, NotificationContext, RealtimeNotificationsContext
├── features/
│ ├── auth/
│ ├── dashboard/
│ ├── dishes/
│ ├── menus/
│ ├── suggestions/
│ ├── ingredient-requests/
│ ├── shopping-lists/
│ ├── takeaway-offers/
│ ├── takeaway-orders/
│ ├── users/
│ ├── stations/
│ ├── allergens/
│ ├── menu-inspirations/
│ └── notifications/
├── layouts/ # PublicLayout, AuthLayout, AdminLayout, KitchenLayout
└── utils/ # Date helpers, formatters, validation
Global state is intentionally minimal — only three React Contexts are used (auth, notifications, realtime). All other data is local to the page or component that owns it.
| Role | Access |
|---|---|
HEAD_CHEF |
Full admin access |
SOUS_CHEF |
Admin access |
LINE_COOK |
Kitchen views only |
| Public | Read-only menu and takeaway |
Role-based routing is enforced via a ProtectedRoute component that wraps layout-level routes.
JWT authentication. Tokens are stored in localStorage and validated on startup. The token is attached to all API requests via the Authorization: Bearer <token> header.
Session expiry (401) triggers a global auth:unauthorized event that clears state and redirects to login. 403 responses redirect to a forbidden page without logging out.
The project is in active development and testing in a real kitchen environment. The core workflow (dish proposals → menu publishing → shopping lists) is fully implemented and functional. Some features (takeaway offers, customer ordering flow) are still in progress.
| Area | Status |
|---|---|
| Auth, dashboard, dishes, menus | Complete |
| Dish suggestions, ingredient requests | Complete |
| Shopping lists, notifications | Complete |
| Users, stations, allergens | Complete |
| Menu inspirations (AI/SSE) | Complete |
| Takeaway offers (admin) | Complete |
| Takeaway orders (customer flow) | In progress |
npm install
npm run devThe app runs at http://localhost:5173 and points to the deployed API by default.