ServicesCard

The studio's menu in setup, read at a glance: each service a grey box of its own — its name, then minutes · price — with Edit and a light red Remove. Edit and Add service open the service's sheet (a bottom sheet on a phone, a dialog from sm): name, length in minutes, price, then Save or Add. A duration the source didn't give is Okami's guess, marked ◦ until the owner sets it. Removing a service asks first, then offers Undo; with nothing yet, the card can start from the craft's template.

Playground

Services

  • Manicure

    45 min · €25

  • Gel nails — new set

    ◦ 90 min · €45

  • Pedicure

    60 min · €30

◦ Okami's guess. Check these durations.

Edit a field: the patch it sends shows here.

ServicesCard

Guessed durations

Price lists often skip durations, so an import fills them from the template and marks them. The ◦ sits inside the minutes field, and one line under the list says what it means — read with each marked field. Setting the minutes clears the mark; changing the name or price doesn't.

Services

  • Manicure

    45 min · €25

  • Gel nails — new set

    ◦ 90 min · €45

  • Pedicure

    60 min · €30

◦ Okami's guess. Check these durations.

Adding, removing, undo

Edit opens a service's sheet, filled in; Add service opens it empty, at 30 minutes. Save or Add checks the row whole — a name another service has, minutes outside 5 to 480, a price past the cap — and points at the field to fix; Cancel, the X or a drag down lets it go. Remove asks first, then offers Undo in a toast that stays until it's taken or dismissed; Undo puts the service back where it was.

Services

No services yet.

Collapsed

Services3 services, from €25

API reference

PropTypeDefaultDescription
servicesDraftService[]—The draft's services, with their ids, origin and estimate marks.
onChange(patch: DraftPatch) => void—Called with the whole checked list after each saved change.
onUseTemplate() => void—Fill the list from the craft's template. Offered only while the list is empty.
labelsPartial<ServicesCardLabels>EnglishEvery word, including remove(name), removed(name) and summary(count, lowest).
localestring"en"How prices and the currency's sign are written: €25 in English, 25 € in Slovak.
currency"EUR" | "CZK""EUR"What the prices are in. Its sign heads the price column, it caps a price (10,000 € or 250,000 Kč), and the picker in the card's head switches it by sending { currency }.
collapsedbooleanfalseOne line: how many services, from the lowest price.
hideTitlebooleanfalseThe heading is read, not shown — in the conversation, where Okami's line introduces the card.

Guidelines

  • Keep the owner's words. Imported names stay as the source wrote them; only the template's are translated.
  • Don't ask the owner to confirm each guess. The mark and its one line are enough; the Summary is the last look.
  • Buffers aren't shown in setup. They come from the template and are tuned on the Services page.