Sections & dishes


Opening the editor

Pick a restaurant and open the Menu section. The editor has four tabs:

  • Dishes — the menu's sections and items;
  • Modifiers — the shared group library (details);
  • Serving — the serving-set library (see below);
  • Ingredients — the product reference and dish recipes: how much of what goes into a portion and what it costs. Filling this in is optional, but without recipes the Analytics section can't show food cost or margin.

Top-right in the header: the content language switcher (Translations & languages) and the preview.

The editor always opens one particular menu. When there are several — a seasonal one, a draft, an archived one — you switch between them and activate the right one on the menu list screen.

On a wide screen the editor spreads into three panes: the category rail on the left, the selected category's dishes in the middle, and a live preview of the guest menu in a phone frame on the right (changes show up immediately). Above the phone sits the look switch (Default, Minimal, Espresso, Gold, Burgundy, Rose, Lemon): the pick is saved right away and applies to every menu of the venue (menu look). On a phone it's the same tabs, with sections as expandable cards. Until the venue is launched, the setup checklist strip sits above the editor.

Menu editor

Sections (categories)

Sections group dishes.

  • Create: the Add category button → type a name → Save.
  • Rename: edit the name in the section row and save.
  • Order: drag a section by its handle (the "⋮⋮" grip) — the order is applied to the guest menu immediately.
  • Hide/show: the eye button (active flag). A hidden section and all its dishes disappear from the guest page; re-enable it to bring them back.
  • Delete: the trash icon → confirm. Deleting cascades to the section's dishes.

{primary} A deactivated section is not sent to the guest at all (server-side filter), it isn't merely hidden visually.

Dishes

Expand a section and click Add item — the dish editor opens.

Dish editor

Fields:

  • Name (required) and Description — in the active language.
  • Price — see below.
  • Photo — upload with a 1:1 crop.
  • Modifiers — attach groups (see Modifiers).
  • Serving sets — attach serve checklists (see below).
  • Availability — on sale / stop list / hidden, plus "recommended" and diet.

{warning} Saving is blocked while the name in the active language is empty.

Price

The dish editor has a single numeric price field — it creates a fixed price (fixed). On the guest menu it's shown as an integer with a thousands separator and the currency symbol (e.g. 60 000 ₫).

{info} Range / "from" / variable prices (range/from/variable) come from the AI recognition of paper menus and are not created manually. Guests see them ("50–70k", "price on request"), but such an item can't be ordered — the editor marks it with an amber badge. Set an exact price, or sizes with prices, to make the item orderable.

Availability, the stop list and diet

Availability is one control with three positions. There are no other states: a dish is either on sale, or temporarily not orderable, or absent from the menu.

  • On sale — guests see the dish and can order it.
  • Stop list — guests see the dish but it has no Add button. On the guest card the price greys out and a "Sold out" badge appears; in the dish sheet the button stays where it is and carries the same reason. This is the state for "we ran out", "it never arrived", "off until tonight".
  • Hidden — the dish is not in the guest menu at all.

There is a fourth reason, set not by a person but by the stock: if a stock item has “Take dishes off sale when it runs out” on, the dish goes off sale by itself when the stock won't cover a portion, and comes back after a receipt. Guests see the same "Sold out" badge, the till shows "Out of stock", and in the editor the control stays on "On sale" with a "Taken off sale by stock" note under it. A stop list set by hand is not lifted by a receipt.

Beside it sits a separate Recommended switch: it marks the dish with a star on the guest menu. It is off while the dish is hidden — there is nothing to recommend.

Diet is two chips, Vegetarian and Vegan. They mark the dish with a leaf on the guest menu and switch on the filter in the menu header. A vegan dish is always vegetarian, so the second chip lights up by itself.

{info} Diet survives both the stop list and hiding: it describes the dish itself, while availability is about the shelf.

{warning} Photo recognition sets the dietary flags only where the menu explicitly says "vegan", "chay", "vegetarian" or spells out its own legend. Nothing is inferred from ingredients: a wrong "vegan" label is a risk to the guest. Mark everything else by hand.

Type: food, drinks, alcohol

Every dish counts as exactly one thing: Food, Soft drinks (non-alcoholic), Liquor or Other (shisha, souvenirs, corkage). This is for you alone: Analytics splits revenue by these groups. The guest never sees the type, and it changes nothing about ordering.

The type lives on the dish. A section has one too, but it is a template: it is filled in for new dishes and rolled out by the "Apply the type to every dish" button. That button leaves alone every dish whose type is already set — your exceptions survive it.

  • Section type — on a phone it lives in the section icon's popover, where the icon itself is picked; on a wide screen it is a row of its own under the section name. Saved immediately.
  • Dish type — the "Counts as" field on the dish card. Under it sits what the section would have filled in, and one link puts it back.
  • In the dish list every dish carries a type mark: quiet when it agrees with its section, ringed in amber when it differs — a beer inside a "Soft drinks" section stands out at once.

{info} A dashed question mark means "type not set". Right after photo recognition most sections look like that — it is a working state, nothing is broken. Revenue from those dishes lands in the "Not classified" row in Analytics.

Next to a section's type you may see "Labelled by AI · review": the type came from recognition, not from you. It is a prompt, not an error — most of the time the guess is right. To clear it, press the type that is already selected: that is you confirming it, and the section becomes yours. If the type is wrong, just pick the right one — the note goes with it.

{warning} "Soft drinks" means non-alcoholic drinks. Mark beer, wine, cocktails and spirits as "Liquor": otherwise there is no separate alcohol reporting, and hotel accounting counts only alcohol as the bar.

Serving sets

The Serving tab is the library of serving sets — short checklists for the waiter ("chopsticks and soy sauce", "warm the plate", "offer ice").

  • A set is created once in the library and attached to dishes in the dish editor — just like modifiers.
  • The waiter sees the set on an order as a serve checklist on the Hall screen — what to bring with the dish, nothing to keep in their head.
  • Sets are single-language (they're an internal crib sheet for staff, guests never see them) and don't affect the price.

Ingredients and recipes

The Ingredients tab holds the menu's product library and the recipes.

  • An ingredient is a name, a unit (g / ml / pcs) and an optional purchase price. The price is per pack — "205,000 ₫ per 250 g", the way it is bought, with no mental division by the kilogram. Piece-counted products can keep the kitchen's own word: "5 con" rather than "5 pcs".
  • A recipe is lines of "ingredient + amount per portion". Cost and food cost come from them; without prices the composition still earns its place — the cook and the waiter see it.
  • Seasoning & other is a menu-wide percentage. Paper cost sheets carry it as the last row of every dish; without it our cost disagrees with the kitchen's.
  • Target food cost is the share of the price you aim for (usually 30–35%). Set it and the goal appears next to the computed food cost, with anything above it highlighted — both in the dish recipe and in the analytics. Until it is set, nothing extra is shown.

Importing recipes from a file

Import from Excel on the Ingredients tab brings over the cost sheet the kitchen already uses, whole.

How it goes:

  1. Upload. .xlsx, .xls, .ods and .csv up to 5 MB. You do not have to explain how the file is laid out.
  2. Reading. We work out its layout — where the dish names are, the ingredients, the amounts and the prices. Up to a minute.
  3. Review. We show what came out: how many dishes and lines, which matched the menu on their own, which need your choice, and which are not on the menu at all. Our total per dish sits next to the one the file states, so a disagreement is visible at once.
  4. Apply. Only then are ingredients created and recipes filled in.

{info} Nothing changes until you press "Apply the import". Until then the file is read but the menu is untouched.

Worth knowing:

  • An unmatched dish is not imported. A row that found no dish on the menu is skipped rather than attached to something similar.
  • How the match is found. By spelling first — case, diacritics and punctuation do not get in the way, and the comparison runs against every language the menu has, so a Vietnamese sheet finds a dish written in English. Whatever is left over is shown to a model once, which recognises a dish that was renamed or is simply called something else («Gà chiên karage» and «Gà rán kiểu Nhật» are one dish). Those rows are marked "by meaning" in the review and filled in ahead of you — a suggestion worth checking, not a decision.
  • An existing recipe survives unless you tick "overwrite" — the box sits on each matched dish separately. Tick it deliberately: overwriting replaces the whole composition rather than adding to it, so an ingredient you added by hand and the sheet does not know about disappears. A dish with no recipe yet is filled in either way; there the box changes nothing.
  • Prices are optional — untick "Import purchase prices" and only the amounts come over.
  • Two prices for one product are not averaged: if the sheet has asparagus at both 50,000 and 150,000, we take the commoner one and show you both.
  • The file is deleted once the import is applied or abandoned.

If the sheet is laid out in a way we cannot read, a manual mapping form opens: name the column letters and the header row, and that is enough.

Photo, clone, delete

  • Photo: the upload is asynchronous — after the dish is saved it appears on the guest menu (with a cache refresh).
  • Clone: the copy icon on a dish row → confirm. A copy is created with the same attributes, translations and attached modifier groups. The copy's photo is its own file: delete the copy and the original keeps its picture.
  • Delete: from the dish editor (the trash icon in the header) → confirm.
  • Reorder dishes: drag within the section; the order applies to the guest menu.