Lane 9 page 4d: Content packs, Content notices, Plans; the legacy Admin deleted (#735) #886

Merged
claude-bot merged 6 commits from build/lane9-4d-pages into main 2026-09-27 20:26:17 +00:00
Collaborator

Part of #735 (lane 9). Stacked on #881 (4c). This PR completes the Admin rebuild. Net size: +2,515 / −5,254.

What it builds

  • ADMIN-11, Content packs (/admin/packs).
    • The list, row and load-form pieces are extracted from CampaignSettingsPacks.jsx into pages/contentPacksShared.jsx, and both pages now use them.
    • It shows the instance-scope list, a load form that defaults to "Every member" (AD-120), and a Starter packs section.
  • ADMIN-13, Content notices (/admin/notices), built on the existing server. It has:
    • the contact form;
    • the notice list, under the drawing's four words;
    • filing a notice;
    • a detail view with history and a review form;
    • "Act on it…" when a notice names a pack.
  • ADMIN-12, Plans & entitlements (/admin/plans). Hosted only (A7), with the four prices on the existing plan-pricing route.
    • It is gated by /api/me/plan in both the index and Contents.
    • Self-hosted shows the drawing's "no section, nobody is billed" state.
    • The per-feature credits table is not built, per A7.
  • #879 item 3. The kit's .kv stacks at narrow widths (Doc.css), and the local workarounds in AdminAi/AdminUsage are gone.

Deleted

  • pages/Admin.jsx (2,622 lines) and Admin.test.jsx.
  • components/AdminAiUsage.jsx and AdminHardwareProfile.jsx, with their tests. 4c ported them.
  • The dead LegacyCard.

components/ContentPacks.jsx stays until /manage goes.

Coverage moved into new test files: AdminDoc (IS-377's stop), AdminUsers (the list, delete-by-typed-name, the 409 dialog, admin toggles), AdminIndex (setup leftovers, the hosted-only gate), AdminPacks, AdminNotices, AdminPlans and useContents. There are also additions to AdminAi and AdminBackup.

Known gap: the legacy suite's retention-tab parity (there's no AdminRecording.test.jsx yet) and some AI-panel assertions weren't ported. Those tested old markup. The follow-up is filed on #879.

Bugs fixed that this PR's render check found in 4a's code

  • Three dialogs drew no buttons: Make administrator, hand the server on, and hand a campaign on.
    • They passed confirmLabel/onConfirm without tier="confirm", and Modal's default tier ignores both.
    • All three now pass tier="confirm".
  • A duplicate React key between two closed dialogs on Users.
  • The notices table now has nowrap columns, so it scrolls at 390 px rather than squeezing (D110).

Checks

  • Render check at 2560, 1440, 1024 and a true 390 px (via an iframe wrapper), in light and dark, for every page. I looked at all the shots.
  • vitest: 197 files, 2610 passed. eslint: 0 errors.
  • coverage/lane7.py: unclassified: none.
  • J1's Admin leg already has every address it needs (/admin, /admin/backup, the ?tab= redirect, IS-377). 4d doesn't change any of them.

🤖 Generated with Claude Code

Part of #735 (lane 9). **Stacked on #881 (4c).** This PR completes the Admin rebuild. Net size: +2,515 / −5,254. ## What it builds - **ADMIN-11, Content packs** (`/admin/packs`). - The list, row and load-form pieces are **extracted** from `CampaignSettingsPacks.jsx` into `pages/contentPacksShared.jsx`, and both pages now use them. - It shows the instance-scope list, a load form that defaults to "Every member" (AD-120), and a Starter packs section. - **ADMIN-13, Content notices** (`/admin/notices`), built on the existing server. It has: - the contact form; - the notice list, under the drawing's four words; - filing a notice; - a detail view with history and a review form; - "Act on it…" when a notice names a pack. - **ADMIN-12, Plans & entitlements** (`/admin/plans`). **Hosted only (A7),** with the four prices on the existing plan-pricing route. - It is gated by `/api/me/plan` in both the index and Contents. - Self-hosted shows the drawing's "no section, nobody is billed" state. - The per-feature credits table is not built, per A7. - **#879 item 3.** The kit's `.kv` stacks at narrow widths (`Doc.css`), and the local workarounds in `AdminAi`/`AdminUsage` are gone. ## Deleted - `pages/Admin.jsx` (2,622 lines) and `Admin.test.jsx`. - `components/AdminAiUsage.jsx` and `AdminHardwareProfile.jsx`, with their tests. 4c ported them. - The dead `LegacyCard`. `components/ContentPacks.jsx` stays until `/manage` goes. **Coverage moved** into new test files: `AdminDoc` (IS-377's stop), `AdminUsers` (the list, delete-by-typed-name, the 409 dialog, admin toggles), `AdminIndex` (setup leftovers, the hosted-only gate), `AdminPacks`, `AdminNotices`, `AdminPlans` and `useContents`. There are also additions to `AdminAi` and `AdminBackup`. **Known gap:** the legacy suite's retention-tab parity (there's no `AdminRecording.test.jsx` yet) and some AI-panel assertions weren't ported. Those tested old markup. The follow-up is filed on #879. ## Bugs fixed that this PR's render check found in 4a's code - **Three dialogs drew no buttons:** Make administrator, hand the server on, and hand a campaign on. - They passed `confirmLabel`/`onConfirm` without `tier="confirm"`, and `Modal`'s default tier ignores both. - All three now pass `tier="confirm"`. - **A duplicate React key** between two closed dialogs on Users. - **The notices table** now has `nowrap` columns, so it scrolls at 390 px rather than squeezing (D110). ## Checks - **Render check** at 2560, 1440, 1024 and a true 390 px (via an iframe wrapper), in light and dark, for every page. I looked at all the shots. - **vitest:** 197 files, 2610 passed. **eslint:** 0 errors. - **`coverage/lane7.py`:** unclassified: none. - **J1's Admin leg** already has every address it needs (`/admin`, `/admin/backup`, the `?tab=` redirect, IS-377). 4d doesn't change any of them. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
- ADMIN-11 Content packs: extract CampaignSettingsPacks.jsx's list/row/load-form
  pieces into contentPacksShared.jsx (and their CSS into contentPacksShared.css),
  taken rather than copied by a fresh AdminPacks.jsx with starter packs and
  AD-120's instance wording/default.
- ADMIN-13 Content notices: new AdminNotices.jsx + api/contentNotices.js
  (contact, filing, filtering, acting on a notice).
- ADMIN-12 Plans & entitlements: new AdminPlans.jsx, hosted only (A7), built on
  the existing GET/PUT /admin/settings/plan-pricing.
- Mark notices/plans built in adminSections.js; route both in App.jsx; gate
  hostedOnly sections behind GET /api/me/plan in AdminIndex.jsx and
  useContents.js's adminGroup.
- #879 item 3: a narrow-width rule on the kit's .kv (Doc.css) stacks label and
  value at phone width; remove AdminAi.jsx/AdminUsage.jsx's local workarounds.
- Delete the legacy pages/Admin.jsx + its test, and components/AdminAiUsage.jsx
  and AdminHardwareProfile.jsx + their tests (fully ported to AdminUsage.jsx in
  page 4c). Move surviving coverage (IS-377's Stop, Users' delete/admin-status
  flows, an AI capability "not configured" state, Backup's media default) to
  AdminDoc.test.jsx, AdminUsers.test.jsx, AdminAi.test.jsx and
  AdminBackup.test.jsx.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Render-checked every new/changed admin page (headless Edge, 2560/1440/1024/390,
light/dark, a genuinely-narrow phone via an iframe wrapper per the render-check
memory note) and fixed what it found:
- Two Modal dialogs (making an administrator, handing the server or a campaign
  on: AdminUsers.jsx's MakeAdminModal/HandServerModal, AdminCampaigns.jsx's
  HandOnModal) drew no buttons at all — each was missing tier="confirm", so
  Modal's default "ask" tier ignored their confirmLabel/onConfirm entirely.
- AdminUsers.jsx's DeleteUserModal and HandServerModal shared the key "closed"
  when both were closed, tripping React's duplicate-key warning; namespaced
  each modal's key.
- AdminNotices.jsx's own two dialogs (recording a notice, acting on one) had
  the same missing-tier bug, plus ActOnModal seeded packId/op from `notice`
  with no key forcing a remount, so re-opening on a different notice kept the
  first one's initial state.
- The notices table had no nowrap column, so `.tscroll` never triggered at
  390px and the table just shrank instead of scrolling (D110); added
  `.atbl__nowrap` and used it on Notice/From/Where it stands.

Added tests moved from the deleted pages/Admin.test.jsx (AdminDoc.test.jsx for
IS-377's Stop, AdminUsers.test.jsx for delete/admin-status, AdminIndex.test.jsx
for the setup-leftovers banner, AdminPacks.test.jsx for the rebuilt page, an
AdminAi.jsx "not configured" case, AdminBackup.jsx's media-default test) and
new ones for what lane 9 page 4d built fresh (AdminNotices.test.jsx,
AdminPlans.test.jsx, useContents.test.js for the hostedOnly gate). Fixed
leaveGuardCallers.test.js's pinned list for the moved useLeaveGuard call.

changelog.d/735-lane9-4d-admin-pages.changed.md per the wave 5 changelog rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude-bot changed target branch from build/lane9-4c-pages to main 2026-09-27 11:48:54 +00:00
Merge main into build/lane9-4d-pages
Some checks failed
CI / Summarisation accuracy eval harness (stub provider) (pull_request) Successful in 54s
CI / Feedback site tests (pull_request) Successful in 46s
CI / Backend lint (ruff) (pull_request) Successful in 57s
CI / Bot tests and audit (pull_request) Successful in 1m57s
CI / Bot/backend version sync (pull_request) Successful in 25s
CI / Does this change touch the recording path? (pull_request) Successful in 18s
CI / Synthetic session harness (no GPU, no LLM) (pull_request) Has been skipped
CI / Docker image build (pull_request) Successful in 55s
CI / End-to-end journeys (desktop, phone, keyboard-only) (pull_request) Failing after 2m53s
CI / Backend migration, tests, and audit (pull_request) Successful in 15m43s
CI / Frontend tests, audit, and build (pull_request) Successful in 17m58s
5fc435d61a
ci: re-run; the runner lost the journeys job's container during setup (run 1540)
All checks were successful
CI / Backend lint (ruff) (pull_request) Successful in 30s
CI / Bot/backend version sync (pull_request) Successful in 27s
CI / Summarisation accuracy eval harness (stub provider) (pull_request) Successful in 2m5s
CI / Feedback site tests (pull_request) Successful in 1m29s
CI / Does this change touch the recording path? (pull_request) Successful in 28s
CI / Synthetic session harness (no GPU, no LLM) (pull_request) Has been skipped
CI / Bot tests and audit (pull_request) Successful in 3m48s
CI / Docker image build (pull_request) Successful in 5m8s
CI / Frontend tests, audit, and build (pull_request) Successful in 19m15s
CI / Backend migration, tests, and audit (pull_request) Successful in 47m44s
CI / End-to-end journeys (desktop, phone, keyboard-only) (pull_request) Successful in 44m34s
63ecf35a69
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign in to join this conversation.
No description provided.