8. Batch G — Public pages (PublicLayout / PublicDetailLayout)
All public pages drop their hand-built headers for the shared PublicShell (PLAN §3.4): space brand
left; nav (Catalogue, Machines, Events, Bookings, Stats, as enabled); “Sign in” right; theme toggle and
the “space works” credit in the footer. The “Staff login” buttons in public headers go away (staff use
/admin; keep a footer link “Staff sign-in”).
G1. Landing directory (central mode) — /
Section titled “G1. Landing directory (central mode) — /”- Component
features/LandingPage.tsx. Reference: org1 (cards), att1 hero tone. - Layout:
PublicLayout(deployment-levelPublicShell: Space Works logo, “About”, “Sign in”).hero: eyebrow “Space Works” · one Unbounded accent line “Find a space. Borrow the tool.” · intro “Public catalogues from community workshops, labs and makerspaces.” · big search field “Search by name, code or place” + result count.content: space cards (cover image, colour not greyscale; avatar tile; name; location link; code; “Open catalogue →”; whole card clickable).- The left aside with “Public spaces / Live / Status access” tiles is removed (it duplicated the count and “Live” was not data).
- States: loading: skeleton cards · empty: “No public spaces yet. They appear here once a space turns on its catalogue.” · no match: “No spaces match ‘{q}’.” + “Clear search” · error: “Couldn’t load spaces. Try again.”
G2. About — /about
Section titled “G2. About — /about”- Component
features/AboutPage.tsx. Layout:PublicLayout, narrow reading column.hero: eyebrow “About” · title “Open-source makerspace management” · 2 short paragraphs (existing copy, tightened) · licence line.content: two link cards “Browse spaces →” and “Staff sign-in →” (org1 card style).
G3. Public machines — /machines, /m/:slug/machines
Section titled “G3. Public machines — /machines, /m/:slug/machines”- Component
inventory/PublicMachinesPage.tsx(+MachineIntakeForm). Reference: org2 list → card grid, att1 tone. - Layout:
PublicLayout.hero: eyebrow “Machines” · title “What you can use at {space}” · intro.toolbar: kind chips (one per group, replacing collapsible sections) + “Training required” filter chip.content: card grid. Card = image (or icon tile) · name · status pill (Available / In use / Down) · meta “{h} h logged” · “Training required” pill · queue line “3 jobs queued · about 2 h”. Primary on the card: “Request a job” when structured intake is on (opensMachineIntakeFormin a dialog, not inline in the card).
- States: “No machines listed yet.” · not enabled: “Machines aren’t public at {space}.” · throttled: “You’re going a bit fast. Wait a moment and try again.” · not found: F6-style public card.
G4. Public bookings — /bookings, /m/:slug/bookings
Section titled “G4. Public bookings — /bookings, /m/:slug/bookings”- Component
bookings/PublicBookingsPage.tsx,PublicBookingForm.tsx,SpaceDiscoveryCalendar.tsx,discovery/*. Reference: att1 (detail + sticky action card). - Layout:
PublicLayout(list of spaces) → selecting a space opensPublicDetailLayoutin place (?space={token}, no new route).- List:
hero“Book a space at {space}” ·toolbar=DiscoveryControls(search, kind chips, list/calendar toggle) · cards (image, name, location, kind pill, Capacity, “Instant” vs “Needs approval” pill, “Choose a time”). - Detail:
heroimage + name + kind + location ·maindescription, availability calendar, rules ·asidesticky booking card (date/time pickers,PublicBookingFormfields, primary “Request booking” or “Book now” per approval mode, helper “Staff confirm requests within a day” / “Confirmed instantly if free”). - Header nav “My bookings” → member Bookings tab (H2).
- List:
- States: “No bookable spaces yet.” · “No spaces match these filters.” · not enabled / throttled as G3.
G5. Public events list — /events, /m/:slug/events (only if ux-spec.md leaves it out)
Section titled “G5. Public events list — /events, /m/:slug/events (only if ux-spec.md leaves it out)”- Component
inventory/PublicEventsPage.tsx. Reference: org2 rows from the attendee side. - Layout:
PublicLayout:hero“What’s on at {space}” ·toolbardiscovery controls (list / calendar) · date-chip rows (title, time · place, price, availability pill “6 spots left” / “Waitlist”) → event page (core). - States: “No upcoming events. Check back soon.”
G6. Print request — /print, /m/:slug/print
Section titled “G6. Print request — /print, /m/:slug/print”- Component
printing/PublicPrintRequestPage.tsx,PublicPrintRequestForm.tsx,PublicPrintRequestParts.tsx(StatusResultstepper),PublicPrintRequestPanels.tsx. - Job: send a 3D-print job with files, then track it.
- Reference: att1 (main + sticky card), att9 (confirmation).
- Layout:
PublicDetailLayout.hero: eyebrow “3D printing” · title “Send a print job to {space}”.main: the form in three titled groups. Your print (Title, Project brief) · Material (filament pool select grouped by material, or Material + Colour, Quantity, Estimated grams) · Files (model files drop zone, print-time screenshots drop zone, Source link). Submit at the bottom: “Send print request”.asidesticky: “Track your job” card. Before submit: “After you send it, you’ll get a link to follow progress here.” After submit / with?token=: the status stepper (Requested → Accepted → Printing → Ready to collect → Collected) with the current step highlighted, plus “Copy tracking link”.- On success the page scrolls to the aside, and a success callout “Request sent. We’ll update this page as it moves.” replaces the form.
- States: loading service: skeleton · unavailable: “3D printing isn’t open for requests right now.” + the tracker if a token exists + “Back to catalogue” · load error: “Couldn’t reach the print service. Try again in a moment.” · upload progress: inline “Uploading 2 of 3 files…”.
G7. Public stats — /stats, /m/:slug/stats
Section titled “G7. Public stats — /stats, /m/:slug/stats”- Component
stats/PublicStatsPage.tsx,StatsSections.tsx,StatsParts.tsx. Reference: org2 stat cards. - Layout:
PublicLayoutwith aDashboardLayout-style body:heroeyebrow “Live stats” · title “{space} in numbers” · “Updated live from the public catalogue.” · sections Printing (stat cards: busiest printer, queue; bar chart by brand; filament trend; per-printer table) · Lending (most popular, tools out, recently added as cards) · Out right now (current loans list, no personal data beyond what the API already returns). - States: off/missing: “Stats aren’t public for this space.” · empty: “Nothing to show yet. Stats fill in as people borrow and print.”
G8. Public organization — /o/:organizationSlug
Section titled “G8. Public organization — /o/:organizationSlug”- Component
organizations/PublicOrganizationPage.tsx. Reference: org3 preview card → full page; att1. - Layout:
PublicLayout:heroavatar tile · org name · description · “Visit website ↗” (outline) ·content“Upcoming events across spaces”: date-chip rows (title, “{host space} · time · place”, price, availability pill, inline “Register at {host}”). This replaces large image cards; images become a small thumbnail. - States: “This organization doesn’t have a public page.” · “No upcoming events.” · events error with Try again.
G9. Event feedback — /events/:token/feedback
Section titled “G9. Event feedback — /events/:token/feedback”- Component
inventory/PublicEventFeedbackPage.tsx(+forms/CustomFormFields). Reference: auth3 (centred, focused), att9. - Layout:
PublicLayout, narrow single column (form) →CenteredCardLayoutfor the end states.hero: eyebrow = event title · title = survey title · helper: anonymous “We don’t store who sent this.” / certificate “Certificates go to people marked as attended.”- Needs sign-in: info callout “Sign in to get your certificate.” → “Sign in”.
- Form card + primary “Send feedback”.
- Thank you card: check tile · “Thank you” · server thank-you text · certificate download button if one is returned.
- Unavailable card: “Feedback is closed for this event.”
G10. Self-checkout — /checkout, /m/:slug/checkout
Section titled “G10. Self-checkout — /checkout, /m/:slug/checkout”- Component
inventory/PublicSelfCheckoutPage.tsx,PublicEvidenceUpload.tsx,PublicToolScanPanel.tsx,PublicToolResultCard.tsx,KitChecklist. - Job: on a phone at the shelf: borrow or return a QR-tagged tool with photo proof.
- Reference: att11 (scan + big result), auth3 (one thing per screen).
- Layout:
PublicLayout(minimalPublicShell), with aFlowLayoutbody that is mobile-first.- Top: segmented control Borrow · Return (replaces “Use (check out)” / “Return” tabs).
- Borrow steps: 1 Photo (“Take a photo of the tool” camera/upload tile, preview) → 2 Scan (camera frame, “Hold the tool’s QR inside the frame”) → 3 Check the kit (only if it has parts) → 4 Confirm (result card: tool name, due date, “Borrow it”).
- Return steps: 1 Photo → 2 Condition notes (required) → 3 Scan → 4 Confirm (“Return it”).
- Done: big success panel (att11 green) “You’ve got it. Due back {date}.” / “Returned. Thanks!”
- “Borrow another”.
- Hard rules unchanged: a scan and uploaded evidence stay required. The step order only makes the requirement visible.
- States: not enabled: “Self-checkout isn’t on at {space}.” + “Back to catalogue” · scan/loan error: inline danger callout on the Confirm step with the server message.
G11. Archived payments — /member/archived
Section titled “G11. Archived payments — /member/archived”- Component
members/ArchivedPayments.tsx. Reference: auth6 calm list. - Layout:
PublicLayout(deployment-level shell) narrow column:heroeyebrow “Closed spaces” · “Payments and receipts” · per-space sections (space name header, charge rows with amount + status pill- receipt download).
- States: “No archived payments. Nothing is owed to spaces that have closed.” · not signed in / not found → F6.
Part of UX spec: long-tail screens (Space Works UX across all of SpaceWorks), published from docs/ux-screens-longtail.md. Edit it there.