Screens: machines, events, bookings, reports and audit
S10. Machines ← R1 cards (index), R7 detail header + tabs (type page), R5 rows (machine detail)
Section titled “S10. Machines ← R1 cards (index), R7 detail header + tabs (type page), R5 rows (machine detail)”Layout: the index is L3 ListLayout. The slots are filled as follows: body = rows,
rendered as a card grid via the ListRow card variant; callout = overdue maintenance. The type
page is L4 DetailLayout (page, identity = type icon). Its tabs = Machines / Service queue /
Consumables / Certifications / Settings, with Machines-tab main = an embedded table and status
filter tabs. The machine detail is L4 DetailLayout presentation="drawer" width=720, with
danger = Retire.
Index (/admin/machines):
Machines [■ + Add machine type ]*24 machines across 5 types · 3 running · 1 in maintenance┌ ! Maintenance is overdue on 2 machines. Review → ┐ (only if >0)┌[🖨] 3D printers ─────────┐ ┌[⚡] Laser cutters ───────┐ ┌ + Add machine type ┄┄┐ (dashed, if allowed)│ 8 machines · 3 running │ │ 2 machines · idle ││ 4 jobs in queue (Review) │ │ Next maintenance 3 Nov │└───────────────────────────┘ └──────────────────────────┘Type settings ▸ (MachineTypesPanel, shared consumables, delegated recipients) — disclosure* when canConfigureMachineTypes.
Type page (/admin/machines/12-3d-printers, an existing subpath):
← All machine types[🖨] 3D printers ( Public page ↗ ) [■ + Add machine ] 8 machines · 3 running · 1 maintenanceMachines 8 │ Service queue 4 │ Consumables │ Certifications │ SettingsMachines tab: table rows [img] Name / model · location | (Running) pill | 312 h | ⋯ + status filter tabs (All · Idle · Running · Reserved · Maintenance · Offline)- Map the stacked sections to tabs: Machines (list plus
MachineCreateFormmoved into the “+ Add machine” modal), Service queue (PrinterServiceConsole/MachineServiceConsole), Consumables (the pool form and list), Certifications (CertificationsPanel), Settings (MaterialCataloguePanel,MachineReminderPolicy). The tab state uses a query param?view=(frontend only). Tabs show only when their gate holds today. - Machine detail (
MachineDrawer, 720 px drawer):
[img] Prusa MK4 #2 (Running) · 3D printer · 312 h total [■ Mark idle ] ( Log maintenance ) ⋯ (Retire…)Overview Operators Consumables Usage Maintenance Documents Errors WarrantyOverview: stat cards (Usage hours · Jobs this month · Next maintenance · Open errors), then settings rows (photo, details, public detail)┌ Retire machine ─ Takes it out of service and off the public page. ( Retire… ) ┐ (danger, can_retire)- Replace the button-styled tablist with P3 underline tabs (keep
role=tablistand wrapping, so every tab stays visible; the current comment about clipping still applies). The header primary is the most common status transition the actor may perform (fromOverviewTab’s status block). - Empty: “No machines are registered for this type. Add the first one with Add machine.”
Keep the “requires a successful load” rule from
MachineTypePage.
S11. Events list (events) ← R2 exactly
Section titled “S11. Events list (events) ← R2 exactly”Layout: L3 ListLayout. The slots are filled as follows: header = greeting eyebrow, “New
series” secondary, “+ New event” primary; callout = collaboration invites or door-ready;
stats = 4; tabs = Upcoming / Drafts / Past / Series; body = date-chip rows; rail = recent
registrations (when data exists). New event and New series are L6 FormPageLayout, with
preview = the public event card.
Good morning, PriyaEvents ( New series ) [■ + New event ]┌ ! Laser workshop is tomorrow. Download the guest list for offline check-in. Prepare check-in → ┐┌Upcoming 3┐┌Going 46┐┌Awaiting approval 2┐┌Drafts 1┐Upcoming │ Drafts 1 │ Past │ Series 2 Recent registrationsdate-chip rows: right slot = "12 / 30 going" bar │ "Finish & publish" pill │ "No guests yet · Share"- Remove the always-open create form from the list page. “+ New event” opens a create page
(R3 layout: form left, public event card preview right) and “New series” opens the series
variant. The
useQuickCreate("event")hook opens the same page. CollaborationInboxandEventSeriesCollaborationInboxcollapse into one callout when invitations are pending (“2 venues invited you to co-host. Review →”) that opens a drawer. No callout when empty.- Stat cards use
registration_countssummed over the loaded page only if the backend has no aggregate. Flag: prefer a server count; otherwise show only Upcoming and Drafts (exact from list counts) and omit the rest rather than show page-local sums. - Rail: latest registrations if an endpoint exists; otherwise hide the rail.
- The table becomes date-chip rows. Status words: Draft (grey, dashed row), Published (green), Cancelled (red word pill), Completed (grey).
- Empty (no events): dashed “+ New event” placeholder row: “Your events will appear here.”
S12. Event detail ← R7, R8, R9, R10
Section titled “S12. Event detail ← R7, R8, R9, R10”Layout: L4 DetailLayout (page). The slots are filled as follows: identity = date chip;
actions.primary = status-driven (with targetsTab="checkin" so it hides on that tab); tabs =
the 7 tabs below; Overview aside = At a glance plus the CTA card; Settings tab main =
SettingsRows; danger = Cancel event. The series detail uses the same layout with an icon
identity.
EventDrawer becomes a full detail page reached by ?event=<id> (the param already exists). It
is too dense for a drawer: 9 stacked panels.
← All events┌OCT┐ Laser cutter induction ( View page ↗ ) [■ Open check-in ]│16 │ (Published) Public · Tomorrow, 6:30 PM · 12 / 16 placesOverview Registrations 14 Check-in Tickets & invites Feedback Team Settings| Tab | Content (existing components) |
|---|---|
| Overview | Stat cards (Going n/cap with bar · Waitlist · Awaiting approval · Invites sent), “Latest registrations” list (5 rows + “All registrations →”), an “At a glance” card (When, Where, Who can join, Price), and the door-ready CTA card when tomorrow or today and offline check-in is enabled. |
| Registrations | EventRegistrationRoster as a P14 table with status pills (Going, Waitlist, Pending) and inline Approve / Decline… for pending; EventRegisterMember as “+ Add registration” (outline). |
| Check-in | The R8 layout: progress stat plus offline callout (OfflineCheckInOperator), camera and Start scanning (EventCheckInScanner), find a guest, toggles, Recent check-ins with inline Undo only if the backend supports reversing a check-in (otherwise omit; do not fake it), and the door-station card (EventStationSettings). |
| Tickets & invites | EventTicketsPanel, EventPromosPanel, EventInvitesPanel, each a section; shown only for enabled ticketing_features. |
| Feedback | EventFeedbackPanel and responses; certificates (EventCertificateActions). |
| Team | EventOrganizers, EventCollaborators. |
| Settings | Image (ImageUploader), EventFields as settings rows, EventCategoriesField, series overrides (“Reset to series value” per field), Discard/Save; lifecycle at the end: Complete (outline) and a danger card “Cancel event… Registrants are notified and registration closes.” |
- Header primary by status: draft → “Publish…” (confirm, because it notifies the public); published → “Open check-in” (hidden on the Check-in tab); completed → “View feedback”. Cancelled or completed: a read-only banner “This event is completed. It can’t be edited.”
- Series (
EventSeriesDrawer) gets the same page treatment per R10: upcoming-date cards, details, a “Who can join” chip radio, agenda, and the “Delete series…” danger zone.
S13. Bookings (bookings) ← R2 + R7
Section titled “S13. Bookings (bookings) ← R2 + R7”Layout: L3 ListLayout. The slots are filled as follows: stats; tabs = Requests /
Upcoming / Spaces (or Spaces only in the minimum variant); body = rows. The space detail is L4
DetailLayout (page). “+ New space” is L6.
Bookings ( + New booking ) [■ + New space ]┌Awaiting approval 1┐┌Today 4┐┌This week 19┐┌Spaces 6┐ ← approval count from dashboard; others only if availableRequests 1 │ Upcoming │ Spaces 6Spaces tab rows: [tile] Woodshop bench · Workshop · (Staff approval) (Public) (Active) · "3 today" ⋯- Today the page lists spaces only; booking requests live inside each space’s
BookingDrawer. Minimum change: the spaces list as P6 rows with pills replacing the 5-column table, and the “Awaiting approval” stat linking to the first space with pending requests. Better (needs a cross-space bookings list endpoint, so flag it): the Requests and Upcoming tabs. - The space detail opens as a page (R7 pattern) with tabs Calendar, Requests, Settings (the
BookableSpaceFormrows) and Danger (deactivate). - Empty: “No bookable spaces yet. Create one to start taking bookings.”
S14. Reports (reports) ← R6 (form card) + P4
Section titled “S14. Reports (reports) ← R6 (form card) + P4”Layout: L4 DetailLayout (page) with asideSide="start". The slots are filled as follows:
aside = the grouped report list; title = the selected report; actions = Export primary and
Schedule secondary; main = filter bar, stats, chart and table. No back and no identity:
this is the one sanctioned L4 variant without them.
Reports ( Schedule… ) [■ Export ▾ ]Operations reporting for Fab Lab Kochi.┌ Report list (240) ────────┐ Loan throughput│ LENDING │ [7 days | 30 days | Quarter | Custom ▾] Grain [Day ▾] ☐ All makerspaces*│ ▣ Summary │ ┌Products┐┌Active loans┐┌Damaged┐┌Missing┐│ Taken items Active… │ chart (existing hand SVG)│ INVENTORY … MACHINES … │ table (OperationsReportTable) Saved views ▾ Columns ▾│ COMMUNITY … MONEY … SYSTEM│└───────────────────────────┘- Replace the 28-option
<select>with a grouped left list (eyebrow group labels). Unavailable reports show as disabled rows withunavailable_reasonin a tooltip and a muted “Needs Bookings module”. - Date presets as a segmented control plus custom inputs. Export is the primary because it is
the page’s output. Schedule (
ReportSchedules) opens a drawer. - Mobile: the report list becomes a select sheet at the top.
- Empty data: “No activity in this period. Try a longer range.”
S15. Audit log (audit) ← R1/R2 activity rail as a full list + P14
Section titled “S15. Audit log (audit) ← R1/R2 activity rail as a full list + P14”Layout: L3 ListLayout width="wide". The slots are filled as follows: callout =
verification status (success pill, or a danger panel if broken); filters = AuditLogFilters with
chips; body = rows (activity items grouped by day); pagination.
Audit log ( Export )†Every state change in this makerspace, append-only.(✓ Chain verified · checked 2 min ago) ← AuditVerificationStatus as a status pill/callout (danger callout if broken)[Actor ▾] [Action ▾] [Target ▾] [Date range] Sort ▾ (AuditLogFilters as a filter bar; active filters as removable chips)TODAY(PO) Priya accepted request #1042 · Meera Nair 10:57 · request:1042 ▸ details(DP) Dev uploaded return photo #182 · request #1039 10:47YESTERDAY …† only if an export endpoint exists; otherwise omit.
- The row is the activity-rail sentence (actor bold,
action_label, target as a link where a console route exists). The rawactionkey and the meta go into a “details” disclosure (monospace key–value). Keep “(some details withheld)” when redacted. - Group by day with sticky day headers. Use keyset-friendly “Load more” or keep the current pagination at the bottom (“Page 2 · 1,204 entries”).
- Empty with filters: “No entries match these filters. Clear filters.”
- No Undo or edit affordances anywhere (append-only).
Part of Space Works UX spec, published from docs/ux-spec.md. Edit it there.