Skip to content

4. Batch C — Configuration (SettingsLayout)

  • Route /admin/api-access · ApiClientsPanel.tsx, ApiClientCreateCard.tsx, ApiClientListCard.tsx, ApiClientScopePicker.tsx, ApiClientsAccessSummary.tsx, ApiClientsTelegramSettings.tsx.
  • Job: let your own tools read and write this space without sharing a login; or request access.
  • Reference: org6 directly.
  • Layout: SettingsLayout with an org6 body (cards, not label-left rows, because this is a create surface).
    • title “API access”, subtitle “Let your own tools work with {space}, without sharing anyone’s login.”
    • Section “New API client” (card): Client label, Allowed browser origins (one per line), “What can it do?” scope check-cards (label + scope:key in small mono, as in org6), primary “Create client”. Non-managers get “Request API access” (Label, Reason, Origins, then “Send request”).
    • One-time secret: yellow strip “Copy the secret now. It’s shown once.” + dark code block + Copy + “Done”.
    • Section “Clients”: rows (label · client_id mono · origins as meta · scope count pill). Inline “Edit scopes” (drawer with the scope cards and Save). [...] “Rotate secret…” and “Delete…” (red, confirm).
    • Section “Your requests” (non-managers): rows with a status pill.
    • Section “Developer reference”: yellow strip “Keep keys in a secret manager…” + key-value card “Makerspace code · Allowed browser origins” (from ApiClientsAccessSummary).
  • Merge/split: move ApiClientsTelegramSettings (Telegram chat ID and bot token, superadmin) out of API access into Makerspace settings › Notifications / Integrations (core settings sub-nav; tell the core-spec owner). It is not an API-client concern.
  • States: clients empty (dashed card): “No clients yet. The secret appears once, right after you create one.” · scopes load error inline in the scope grid.
  • Route /admin/modules · ModulesPanel.tsx (superadmin). SpacePacksPanel is mounted inside Makerspace settings today.
  • Job: switch whole feature families on or off for a space.
  • Reference: org5 (rows + helper text), org6 (accordion reference).
  • Layout: SettingsLayout.
    • title “Modules”, subtitle “Switch features on for {space}. Turning one off keeps its data; turning it back on restores everything.”
    • subnav: the module groups (Lending, Machines, Events, Community, Money, Platform …) as the in-page sub-nav, with “{installed} of {total}” counts. This replaces the accordion.
    • sections: one SettingsRow per module. Left: module name, description, “Turns on: …”, “Also installs: …”, “Needed by: …”. Right: a switch (Core → a locked “Always on” pill). Toggling applies immediately (the API is per-action today) with toast “Events installed.” + Undo (= uninstall; safe because uninstall keeps data). Uninstall that is blocked by dependents shows a disabled switch with helper “Turn off {dependents} first.”
    • dangerZone: none here. Deleting data is a CLI step; say so in the subtitle helper.
    • Bottom section “Deployment” (read-only, superadmin): shipped/removed app rows + the env line in a dark code block with Copy.
  • States: load error: standard. Install error inline on the row.
  • Route /admin/platform · PlatformEmailPanel.tsx, PlatformSocialAuthPanel.tsx, PlatformStripeConnectPanel.tsx (stacked today).
  • Job: set deployment-wide email, sign-in providers and Stripe Connect.
  • Reference: org5.
  • Layout: SettingsLayout with subnav: Email · Sign-in providers · Stripe Connect (the last only when platform_hosting). ?section= query.
    • Email: rows SMTP host / port / username / password (“Saved — leave blank to keep”), From email, TLS/SSL toggles. Footer Discard / Save.
    • Sign-in providers: two groups “Google” and “Apple” as row groups. Footer Discard / Save.
    • Stripe Connect: rows Publishable key, Secret key, Webhook secret (each with a “Saved” pill when set), Connect client ID, Application fee (basis points, helper “100 = 1%”). Footer Discard / Save. dangerZone: “Clear publishable key”, “Clear secret key”, “Clear webhook secret”. These are three red outline buttons with one confirm each, and they replace the three neutral buttons beside Save.
  • States: each section loads independently with skeleton rows; a save error appears inline above the footer.
  • Route /admin/backup-restore · BackupRestorePanel.tsx (+ RestoreDecision). Gate manage_makerspace; deployment part superadmin.
  • Job: make and download backups; superadmins schedule full backups and restore.
  • Reference: org5 (rows + danger zone), org2 (archive list).
  • Layout: SettingsLayout with subnav: This space · Deployment (superadmin).
    • This space: yellow callout “Backups contain live member data. Store downloads somewhere private.” · primary “Create backup” · archive list rows (scope · date · size · status pill · inline “Download”). If the module is off: info callout “The backup module isn’t installed for this space. Deployment backups still cover it.”
    • Deployment: settings rows “Daily full backup” (switch, helper “Last success {date}”), “Keep archives for” (days), Save. Primary “Create full backup”. Archive list with inline Download. Restore moves into the danger zone: “Restore from a backup” → picks an archive and a kind (Roll back in place / Disaster recovery) in a confirm dialog that requires typing the space or deployment name.
    • Active restore: a red-outlined callout card at the top, “Restore waiting for your decision — {seconds}s left”, with Proceed / Reset / Abort (RestoreDecision, restyled).
  • States: empty archives: “No backups yet. Create one before you change anything big.” · failure detail inline per row · the global error line (“A backup operation failed…”) becomes per-control messages.

C5. Organizations — tab organizations (global)

Section titled “C5. Organizations — tab organizations (global)”
  • Route /admin/organizations · panels/OrganizationsPanel.tsx, OrganizationSetup.tsx (OrganizationCreate, OrganizationLinks), OrganizationProfileForm.tsx, OrganizationMemberships.tsx, OrganizationInvitations.tsx.
  • Job: run an organization: its public profile, people, invitations and (superadmin) linked spaces.
  • Reference: organiser workspace boards directly — org1 (org cards), org3 (create with preview), org4 (members + invite card), org5 (settings + danger zone).
  • Layout: two levels.
    1. Index — DashboardLayout-style card grid (org1 “Your organisations”): one card per org (avatar tile, name, your role, “{n} spaces”), plus a dashed “+ New organisation” card (superadmin only). This replaces the <select> and Prev/Next pager. If there is exactly one org, skip the index and open it.
    2. Organization — SettingsLayout with subnav Profile · People · Invitations · Spaces (superadmin), selected via ?org={id}&section=.
      • Profile (org5): rows Name, Public slug (as “spaceworks…/o/{slug}” with Copy), Website, Description, “Listed publicly” switch. Discard / Save. Outline header action “View public page ↗”.
      • People (org4): table Person (avatar, name, email) · Role pill · Joined. Empty dashed: “It’s just you so far. Create an invitation to bring in your team.”
      • Invitations (org4 invite card): “Invite someone” card (governance actions + granted actions as check-cards, “Expires in” days, primary “Create invite link”). The created link shows as a field with Copy and an “Unused” pill. Below, an invitations list with state pills and inline “Revoke”.
      • Spaces: rows “{space} · {relationship}” with inline “Change” and [...] “Unlink…” (confirm, existing copy). Primary “Link a space” (dialog: Space, Relationship).
    • Create org (superadmin): FlowLayout page using org3’s pattern (Name, Slug with an “Available” check if derivable, Description, then “Create organisation” + Cancel), with a live public-page preview in aside.
  • States: no access: “You’re not part of an organization yet. Ask an organization admin for an invite.” · load error with “Try again”.

C6. Member account — /member/account, /m/:slug/member/account

Section titled “C6. Member account — /member/account, /m/:slug/member/account”
  • Route features/members/MemberAccountPage.tsx, MemberAccountProfile.tsx, MemberAccountSessions.tsx, MemberAccountMembership.tsx, MemberAccountExports.tsx.
  • Job: manage my profile, sign-in security, membership (cancel renewal / leave) and data export.
  • Reference: auth6 + auth7 directly.
  • Layout: member AppShell + SettingsLayout.
    • title “Account”, subtitle “Your personal profile and sign-in security.” (replaces “Your account” + “Back to membership” button; the back link becomes the shell’s nav).
    • Underline tabs (as section switcher): Profile · Security · Membership · Your data.
    • Profile: rows Display name, First / last name, Contact phone. Footer Save.
    • Security (auth7): callout “Two-step sign-in is off. Add an authenticator so a stolen password isn’t enough.” → “Set up authenticator” (links to /mfa). Section “Sessions and devices”: rows (device/session · last used · “This device” pill) with inline “Sign out”. dangerZone-style row “Sign out everywhere” (if the API offers it; otherwise per-row only).
    • Membership: key-value card (plan, status, renews / ends) and, in the dangerZone, “Cancel renewal…” and “Leave {space}…” (each with the existing required-reason dialog; the button is “Confirm cancellation” / “Leave {space}”).
    • Your data: “Request a copy of your data” (primary in the section), then a jobs list with inline “Prepare download” → “Download ZIP” (+ “Link expires {time}”).
  • Merge: the member portal “Account” tab (/member/account-portal) and this page are two “account” surfaces today. Keep both routes and make them one area: /member/account-portal holds the space-specific identity (maker profile, card, directory, referrals, certifications, see H6), and this page holds personal account security. Cross-link them with a sub-tab row so the user never has to know there are two. Final naming (“Account” vs “Profile & card”) is an owner decision.
  • States: self-service disabled: info callout “Account self-service is turned off for this space. Ask staff to update your details.” · claim session: “Sign in with a full account to manage your profile, sessions or data.” + “Sign in” · left: success callout “You’ve left {space}. Your Space Works account is still here.”
  • Route features/auth/MfaAccountPage.tsx (standalone route; reused by members via “Manage two-step sign-in”).
  • Reference: auth7 (security tab), auth2 (centred card).
  • Layout: CenteredCardLayout (this route renders outside any shell, for staff and members alike).
    • Not signed in: icon tile (shield) · “Two-step sign-in” · “Sign in to manage your authenticator.” · two links “Staff sign-in” / “Member sign-in”.
    • Signed in, off: title “Turn on two-step sign-in” · body “Confirm your password, then scan a QR code with your authenticator app.” · Current password · primary “Continue” → MfaFlow enrol (C-F2).
    • Signed in, on: title “Two-step sign-in is on” + success pill · password field · primary “New recovery codes” · secondary red link “Turn off two-step sign-in” (hidden when required).
    • After a change: success callout “Done. You’ve been signed out everywhere — sign in again to continue.”
  • Recovery codes display: a 2-column mono grid in a bordered box + “Copy all” + “Download .txt”, then primary “I’ve saved my codes”.