Screens: home, requests and handout
3. Screen-by-screen spec
Section titled “3. Screen-by-screen spec”Conventions for every staff screen: the app shell from §2, a 36 px gutter, content max-width
1120 (wider pages such as Inventory and Reports may go full width), and a PageHeader from P2 or
P3. “Primary” means the single filled button. States: Loading = skeleton in the final layout
shape (never “Loading…” text alone); Error = an inline error block in place of the content
region with “Couldn’t load X. Try again.” and a Retry button; Empty = P17 dashed card.
Mobile defaults (<768): stat grids become 2 columns; the activity rail drops below the main column, limited to 3 items with “See all”; row cards keep the chip and stack the right slot under the meta; header actions collapse to the primary plus an overflow “⋯”; underline tabs scroll horizontally with the active tab scrolled into view; drawers open full screen.
S1. Staff Home / Dashboard (dashboard) ← R1 + R2
Section titled “S1. Staff Home / Dashboard (dashboard) ← R1 + R2”Layout: L1 AppShell + L2 DashboardLayout. The slots are filled as follows:
header = date eyebrow, “Dashboard” h1 (greeting as eyebrow), Quick add primary;
callout = the top-severity alert; progress = SetupChecklist; stats = the top 4 tiles;
overflowStats = the remaining tiles; main = [Coming up]; rail = audit or notifications
activity.
Wednesday, 14 OctoberGood morning, Priya ( View public page ↗ ) [■ + Quick add ▾]┌ ! 3 loans are overdue. Remind borrowers or record a return. Review overdue → ┐ (only if >0)└─────────────────────────────────────────────────────────────────────────────────────┘┌Pending requests┐┌Ready for handover┐┌Overdue loans┐┌Bookings to approve┐ ← max 4 "needs action"│ 4 ││ 2 ││ 3 ││ 1 │└────────────────┘└──────────────────┘└─────────────┘└───────────────────┘Coming up Recent activity┌OCT┐ Meera Nair returns 3 items Due tomorrow (Remind) (PO) Priya accepted request│15 │ Request #1042 · Arduino kit ×2… #1042 · 2 min ago┌OCT┐ Laser cutter induction 12 / 16 going (DP) Dev returned Multimeter│16 │ Event · 6:30 PM · Main hall · 1 hr ago┌OCT┐ Woodshop bench booked Awaiting approval …│17 │ Booking · 10:00–12:00 · Sana Khan (Review) See all activity →Everything else ▸ (disclosure: remaining non-zero tiles as a compact 2-col list)[ Setup checklist card — only while incomplete, above "Coming up" ]- Data: the existing
/admin/makerspace/{id}/dashboardcounts. “Coming up” merges three existing endpoints: active loans orderedreturn_due_at(next 5 due), upcoming events (useEvents, if the module and permission allow) and pending/upcoming bookings. Activity comes from/admin/audit-logs?makerspace=…(page size 6) whencanViewAudit, otherwise from the notification inbox, otherwise the rail is hidden and the main column goes full width. - Stat cards: pick up to 4 tiles by priority: those with
actionNeeded && value>0first (danger tones, then warn), then fill with in-flight counts. All other permitted tiles move to the “Everything else” disclosure. This keeps all 17 reachable without the current wall of tiles. Each card is a link (existingdashboardHref). The tone shows on the number, never as a fill (aligns with the currentreststyle). - Callout: at most one, chosen by severity: overdue loans, then failed emails, then problem reports, then maintenance overdue. It has an action link.
- Primary: “Quick add” with a menu of the existing
useQuickCreatetargets (item, event, booking) the actor can use. If only one is permitted it becomes a direct button. If none, no primary. SetupChecklistbecomes a progress card (“Set up Space Works · 4 of 7 done”, a bar, the next step as a link) placed above “Coming up”. It is dismissible once complete.- Empty: “Nothing needs you right now. New requests and due-backs will show up here.”
Loading: 4 card skeletons plus 3 row skeletons. Machine scope (
scope_mode:"machine"): the cards use machine tiles and “Coming up” shows maintenance due and prints ready. - The panel heading “Dashboard” is a test pin. Keep an
h1with the visible text “Dashboard” and the greeting as the eyebrow, or update the pin deliberately in Phase 4. Recommendation:h1“Dashboard” with the greeting above it.
S2. Requests list (requests) ← R2 (tabs + rows) + R8 (inline actions)
Section titled “S2. Requests list (requests) ← R2 (tabs + rows) + R8 (inline actions)”Layout: L3 ListLayout. The slots are filled as follows: header = “Requests”, with the
subtitle and a conditional primary; tabs = Pending / Ready / On loan / History with counts;
filters = search plus sort and saved views; body = rows (ListRow with date/avatar chip and
an inline next step); empty/filteredEmpty per tab; pagination per queue; detail = S3
drawer.
Requests ( Export ) [■ Start handover ]*Borrow requests from members, from review to return.Pending 4 │ Ready 2 │ On loan 7 │ History [ Search name, email, purpose ⌕ ] [Sort ▾] [Views ▾]━━━━━━━━━┌ (MN) Meera Nair ⏱ Requested 2 h ago (Pending) [ Review ] ⋯ ┐│ #1042 · 3 items · Arduino kit ×2, Multimeter ×1 · "Robotics club demo" │└─────────────────────────────────────────────────────────────────────────────────────────────┘┌OCT┐ Dev Patel (Ready tab) Box not assigned yet [■ Start handover ] ⋯ ┐│15 │ #1039 · 1 item · Soldering station · due back 22 Oct │┌OCT┐ Sana Khan (On loan tab; chip = due date, band red if overdue) Overdue 2 days [ Return ] ⋯* The header primary is shown only on the Ready tab, and only when exactly one request is ready (it opens it). Otherwise there is no header primary and the per-row action carries it.
- Tabs (P8) map to the existing queries: Pending =
pending-requests(hidden forguestOnly), Ready =accepted-requests, On loan =active-loans, History =request-history. Counts come from each query’scount. The three live queries already run together today, so showing their counts is free; History shows no count. URL: extend the existingqueuelist-state value topending|accepted|active|history(frontend only). The default tab is the first non-empty of Ready (handout-only) or Pending (others). - Row (P6 adapted): chip = requester avatar on Pending, due-date chip on Ready and On loan
(red band and “Overdue n days” when past due; the word is always present). Title = requester.
Meta =
#id · n items · first two items · "purpose"with a “+n more” overflow. Status pill. One inline next step: Pending → “Review” (opens detail; Accept/Reject live there), Ready → “Start handover” (guided wizard), On loan → “Return” (guided return). Shelf location shows in the detail only (staff-only, but it adds noise to the row). - “⋯” row menu: Set due date, Renew (when
loans.renewals), View timeline (whencanViewAudit), View issue/return photo(s), Copy link. - The StatusStepper moves out of the row into the detail drawer (rows stay 82 tall).
- Empty per tab: Pending: “No requests waiting for review.” Ready: “Nothing to hand over. Accepted requests land here.” On loan: “Nothing is out on loan.” History: “Returned and closed requests will appear here.”
- Search empty: “No requests match “x”. Clear search” (link).
- Error: inline block per tab with Retry. Loading: 4 row skeletons (
RequestListSkeletonrestyled). - Mobile: rows stack; the inline action becomes a full-width button at the bottom of the card (44 tall).
S3. Request detail + issue/return flow ← R7 (detail header, at-a-glance) + R8/R28 (scan workspace)
Section titled “S3. Request detail + issue/return flow ← R7 (detail header, at-a-glance) + R8/R28 (scan workspace)”Layout: the detail is L4 DetailLayout presentation="drawer". The slots are filled as
follows: back = Requests; identity = requester avatar; title = “Request #id”; status;
meta; tabs = Overview / Evidence / Timeline; main = items plus stepper; aside = At a
glance; footer = the status-driven primary. The handover is L7 FlowLayout presentation="task" with 5 steps; work = camera, borrower card, item steppers or evidence tile;
result = the success card.
Detail opens as a 640 px right drawer over the list, deep-linkable with ?request=<id>
(new param, like Events’ ?event=). Full screen on mobile.
← Requests ✕(MN) Request #1042 (Ready for handover) Meera Nair · requested 14 Oct, 9:12 · due back 22 Oct○──●──○──○ Requested · Accepted · Issued · Returned (StatusStepper)Overview Evidence Timeline──────────────────────────────────────────────────Items At a glance┌ Arduino kit ×2 Shelf B3 (QR-tracked) ┐ Purpose Robotics club demo│ Multimeter ×1 Shelf A1 │ Contact meera@… · +91…└────────────────────────────────────────────────┘ Box Not assigned Accepted by Priya (Space Manager)─────────────────────────────────── sticky footer ─────────────────────( Set due date ) [■ Start handover ]- Footer primary by status: pending → “Accept…” (opens the accept-quantities modal; Reject as an outline secondary; Set due in “⋯”); accepted → “Start handover”; issued or partially_returned → “Record return”; terminal → none.
- Evidence tab: issue and return photos as thumbnails loaded on demand through the existing signed-URL fetch, labelled with type, actor and time, never as public URLs. Empty: “No photos yet. The issue photo is taken during handover.”
- Timeline tab:
RequestTimelineBlockas an activity list (P12 style) whencanViewAudit. - Damaged, missing and to-fix outcomes show as a danger-tinted advisory under Items.
Handover flow (HandoverWizard, issue and return). One component for both. It replaces the
side-by-side “Assign + issue” modal and “Guided issue” button, which are two buttons for one job.
The non-guided AssignIssueModal / ReturnRequestModal / IssueDialog / ReturnDialog become
a “Compact view” toggle of the same flow (all steps on one scroll page) for experienced staff.
Hard rules are unchanged: box QR, borrower check, items and assets, an issue photo
(mandatory), a return photo plus a remark (mandatory), the kit checklist and the receipt.
Desktop: full-screen task mode (no sidebar), 2 columns┌ Issue request #1042 · Meera Nair ─────────────────────────────── ( Cancel ) ┐│ ① Scan box ✓ BOX-0042 │ ││ ② Check borrower ✓ │ ┌──────── camera (dark, r16) ────────┐ ││ ③ Items 2 / 3 assets │ │ ⌜ ⌝ │ ││ ④ Photo & remark ● required │ │ Hold the asset QR in the frame │ ││ ⑤ Receipt │ └────────────────────────────────────┘ ││ │ Can't scan? [ Type the QR code ] (Check)││ │ Scanned ✓ ARD-0091 ✓ ARD-0092 Remove ││ │ ( Back ) [■ Next ] │└────────────────────────────────┴────────────────────────────────────────────┘- Left rail: 5 steps with state (done ✓ plus its captured value, current ●, locked). Done steps are clickable to go back. Mobile: the rail becomes a top progress bar with “Step 3 of 5 · Items” and the camera fills the width.
- Step 1 Scan box: the camera block (P21 and P29) starts on entry because scanning is
the task. Manual entry sits beneath it. A success shows the box label inline with a green check
and auto-advances after 600 ms (an announced
role=status). - Step 2 Borrower: an identity card (avatar, name, membership status pill, waiver status),
the optional member-card scan (
ScanCardBox), and the confirmation checkbox “I checked the borrower against this request” (keep the wording; it is the accountability statement). - Step 3 Items: issue mode shows an asset counter as a progress stat (“Assets scanned 2 / 3”)
with continuous scanning in the same camera block and the scanned list with Remove. Return
mode shows per-item rows with three steppers (Returned / Damaged / Missing) and a live “of n
remaining” check (reuse
QuantityInputvalidation copy). - Step 4 Photo & remark: the evidence tile (see §5) is large (16:9 placeholder, “Take photo” primary, “Upload from device” link). After upload it shows the thumbnail, “Photo #182 attached” and “Retake”. The remark field is labelled “Return remark” with a “Required” chip in return mode and “Remark · Optional” in issue mode. The kit checklist follows. The step footer primary reads “Confirm issue” / “Confirm return” and is disabled with the reason (“Add the return photo and a remark to continue.”), never silently disabled.
- Step 5 Receipt: a full-panel success result (P29 green card): “Issued to Meera Nair”, the summary (box, items, photo #, time), “Print receipt” (outline) and “Done” (primary). No Undo. Handover records are immutable and audited, so the summary-before-confirm in step 4 is the safety net.
- Partial-failure copy is kept verbatim in intent (“Box assigned, but issue failed: … The request still needs the issue step; retry with the assigned box.”) and shown as a danger callout above the footer.
- Escape: “Cancel” is disabled while saving. Closing with captured evidence asks “Leave handover? The uploaded photo stays unattached and will be cleaned up.” Copy needs owner sign-off: the abandoned-upload cleanup is default-off, so the claim must match the deployment.
S4. Direct handout (direct) ← R2 list + S3 flow
Section titled “S4. Direct handout (direct) ← R2 list + S3 flow”Layout: L3 ListLayout. The slots are filled as follows: header = “+ New handout”
primary; tabs = On loan / Returned / Claim codes; body = rows with inline Return. New handout
and Return are L7 FlowLayout (4 and 3 steps).
Direct handout [■ + New handout ]Lend tools straight from the shelf, without a request.On loan 5 │ Returned │ Claim codes┌OCT┐ Arjun Rao Due 20 Oct [ Return ] ⋯│20 │ Handout #88 · Multimeter, Probe set · 2 tool QRs · by Priya- “+ New handout” opens the guided
DirectHandoverWizardin task mode (borrower card, then tools, then photo, then receipt; the same shell as S3). The always-visible inline issue form currently on the page moves into that flow’s “Compact view”. The page itself becomes the list of direct loans with inline Return (the existingDirectLoanReturnModalrestyled as the S3 return steps). - The “Claim codes” tab hosts
MemberClaimCodes. - Empty: “No tools are out on direct handout. Start one with New handout above.”
- Mobile: the primary becomes a full-width sticky bottom button above the bottom tab bar (handout console).
Part of Space Works UX spec, published from docs/ux-spec.md. Edit it there.