After initial wizard completion, /dashboard/tables renders a two-column layout: left column is form floor-config-form with stacked sections; right column shows live today summary, QR install card, and numeric summary KPIs. Primary header action is Save (or Enable {entity} booking when service not yet enabled).
Restaurant layout (general section)
Section title adapts per industry (restaurants see Restaurant Layout). Intro: table count, default seats, per-resource naming.
| Field | Control | Range | Behaviour |
|---|---|---|---|
| Total tables | Number input | 1 to 100 | Changing count resyncs grid rows via normalizeTableRows |
| Default seats per table | Number input | 1 to 20 | Fallback capacity for new rows |
| Apply default to all | Text button | n/a | Sets every row capacity to default; requires Save to persist |
Table names and seat counts grid
Each resource row contains:
- TableNameInput editable label (max 40 chars), default prefix T1, T2 for restaurants or C1, S1 for clinic/salon
- TableSeatControl stepper for capacity
- Unit suffix from
layout.capacity_unit(seats, patients, clients)
Search hint row notes manager app searches by name (guest, patient, or client depending on industry).
Booking duration rules
Info alert: duration changes apply only to new reservations; confirmed bookings keep original end times.
Restaurant turn brackets (when setup.turn_brackets true):
- Small groups (1 to 4 people):
table_turn_minutes_small, default 90 - Medium groups (5 to 8 people):
table_turn_minutes_medium, default 105 - Large groups (9 or more):
table_turn_minutes_large, default 120
Single duration (clinic/salon): one slot_minutes field 30 to 240 minutes.
Gap between bookings (restaurant cleanup): select from category options (0 = No gap, 15, 30 minutes, etc.) stored as table_cleanup_minutes.
Same-day booking rules
| Field | Options | API field |
|---|---|---|
| Earliest same-day booking | No restriction; 30 min; 1 hour; 2 hours ahead | table_same_day_cutoff_minutes (0 or null = none) |
| Today only vs future | Mode toggle via BookingHorizonFields | table_same_day_only plus horizon helpers |
How far ahead can customers book
BookingHorizonFields with parts={["horizon"]}:
- Today only: same calendar day bookings (opt-in)
- Preset days: +7, +14, +30, +60, +90 days ahead — future booking is the default (restaurant 30, plumbing 14, salon 60, clinic 90)
- Custom: 1 to 90 days numeric
- Unlimited: any future date
Persisted through toHorizonApiFields(horizon) on save.
Agent message (policy note)
Optional textarea: what the phone agent says when a requested date is outside the allowed horizon, e.g. We can book you up to 30 days ahead — what day works for you? Leave it empty to use an automatic message based on your horizon. Stored as table_booking_policy_note.
No-show grace period
Embedded DashFloorGraceSettings:
- Number input 5 to 120 minutes, suffix min
- Separate Save grace period button patches
/tables/floor-settings - Default 20 minutes
After reservation time passes, manager app highlights overdue resources until staff seats, releases, or marks no-show.
Save payload
Submit posts POST /tables/setup with table_count, default_capacity, slot_minutes, horizon fields, policy note, capacities array, turn brackets when applicable, cleanup, cutoff, and floor_setup_complete: true. Success toast includes entity plural count.
Right column widgets
- DashFloorToday: live reserved/seated counts and Open floor app link
- Install manager app: FloorInstallQr card variant
- Summary KPIs: entity count, default capacity, duration label