Commit 528ee77
authored
feat(shared,admin): admin workflow polish — action grammar, members surface, explicit-save settings (#562)
## Summary
One bounded polish PR across the four admin workflows — Submit Work,
Review Work, Garden Settings, and Garden Members — so they read as one
professional cockpit instead of mixed legacy forms.
### Action grammar — one primary per mode
- Every route header now shows exactly **one mode-specific primary**;
other actions fold into the overflow kebab (`AdminViewActions maxInline`
driven by the marked primary).
- **Hub**: Work → Submit Work, Assess → Create Assessment, Certify →
Create Hypercert. **History declares no creation CTA** (no real target)
and hides the FAB.
- **Garden**: Overview → Edit garden; **Members → Add member** (opens
the real add flow); Activity and Settings keep a clean header (settings
form owns Save/Cancel).
- **Community**: Treasury → Deposit / withdraw (owner-gated, opens the
vault sheet); Governance → **New proposal now targets the hypercert
signal-pool register flow** (the existing proposal-creation write)
instead of self-navigating; Payouts has no competing header primary (the
cookie-jar panel owns Withdraw / Fund / Manage in local context); People
shows no role-management CTA.
- `useViewActions` no longer promotes an arbitrary first action: the FAB
exists only when a mode declares an explicit primary (read-only modes
hide it, per the handoff design note).
### Garden Members = the management surface
- New
[`GardenMembersPanel`](packages/admin/src/views/Garden/components/GardenMembersPanel.tsx)
on `/garden/members`: search by **ENS or address** (name queries resolve
via `useEnsAddress`), wallet display with **copy actions**, role chips,
member count.
- Existing write path wired in — header **Add member** →
`AddMemberModal`; **Manage Roles** → `GardenRolesPanel` per-role
add/remove + `MembersModal` view-all — all through
`useGardenOperations`, gated on `canManage`. **No new contract/API
behavior.**
- Removed the inert "Pending" filter (no pending-member data exists).
Fixed the filter chips to the actual `AdminFilterChip`
`label`/`onToggle` contract — they previously rendered label-less and
never attached a handler (dead controls, pre-existing).
### Community People stays engagement/read-only
- The role chips on People rows are now **static indicators** — the old
buttons navigated back to the same route (no-ops).
- Rail "Roles overview" rows render as plain counts on People (still
navigate from other modes).
- One clear **Manage members** affordance links to Garden → Members
(header overflow + section header).
### Garden Settings — explicit save with draft preview
- Rewrote
[`GardenSettingsEditor`](packages/admin/src/components/Garden/GardenSettingsEditor.tsx)
as a draft form: name, description, location, banner, open joining, max
gardeners all edit local state.
- Stable footer with a **dirty count** (`N unsaved changes` / `All
changes saved` / `Saving…`), Cancel (resets), Save changes (disabled
when clean/invalid).
- **Banner selection shows a local object-URL preview** with a "Preview
— uploads on save" badge; IPFS upload + on-chain write happen **only
during Save**. Save runs only dirty fields through their existing
per-field mutations, sequentially (one wallet confirmation at a time; a
failure stops the run with the draft intact).
- Removed "hero image" wording from admin copy; en/es/pt updated.
### Submit Work + Review Work polish
- Submit Work sheet now uses admin sheet/form anatomy: fields directly
on the sheet surface (no nested card), pinned `SheetFooter` with
`AdminButton` actions, identical grouping in page and sheet layouts.
Validation, upload requirements, query state (`sort`, `gardenAddress`),
and cancel/close are preserved (pinned by the existing submit test
suite).
- Review Work decision row uses the M3 hierarchy: **Approve = filled
primary** (disabled until confidence + method valid), **Reject =
outlined error** (clearly destructive, secondary), right-aligned row,
validation hints in a **stable block above the actions** so the buttons
never shift.
## Validation
- `bun format` / `bun lint` — 0 errors (remaining warnings pre-existing,
untouched files)
- Admin tests: **52 files / 451 passed** (incl. new
`GardenSettingsEditor.test.tsx` ×7 pinning
draft/save/cancel/banner-deferral, updated `memberRoles.test.ts`,
existing `SubmitWork.submit.test.tsx` ×7 green)
- Shared tests: **261 files / 3138 passed** (incl. expanded
`fab-config.test.ts` ×27 pinning the per-mode primary grammar and real
targets)
- `node scripts/dev/ci-local.js --quick` — all green
- `bun run check:design-md` ✅ · `check:design-tokens` ✅ (material
boundary + token guard) · `lint:vocab` ✅ (3 locales)
- `check:stories` ✅ · `check:story-quality` ✅ (149 files) ·
`test:stories:ci` 138 passed
- `bun run --filter @green-goods/admin build` ✅
## Browser proof (Brave, dev:prod against production data, mockAuth)
Captured at **1440×900 and 1280×800, light + dark** to
`.codex-artifacts/admin-polish-proof/` (18 screenshots + DOM/click
evidence; mock-auth sessions have no wallet client, so no writes were
possible):
- `/hub/work`: one Submit Work primary + overflow holding Create
Assessment / Create Hypercert; sort → submit → close preserves
`sort=oldest&gardenAddress` in URL; filled sheet with media draft
preview; required-field hold blocks submit with zero network calls.
- `/hub/work/:workId`: Approve disabled with the stable hint ("Select a
confidence level…"); selecting High enables Approve (filled, workspace
tone `rgb(37,71,208)`); Reject outlined error. Dark-mode contrast
measured on the real backdrop: reject label **4.76:1**, hint **10.1:1**
(AA).
- `/garden/settings`: edits → "3 unsaved changes" + enabled Save/Cancel
+ banner "Preview — uploads on save" badge with **no IPFS/write calls**;
Cancel restored saved values ("Mama Earth") and disabled the footer.
- `/garden/members`: ENS search `afo.eth` resolved and narrowed 30 → 1
row; address fragment `0xb1` → 1 row; copy shows the copied check; Add
member opens `AddMemberModal` ("Add Gardener"); Manage Roles opens the
per-role panel (6 add / 10 remove controls); Operators filter narrows 30
→ 9.
- `/community/members`: **48 role chips, 0 are buttons**; no header
primary; rail rows static; the one "Manage members" button lands on
`/garden/members` with garden context.
- All eight route modes asserted in live DOM for the primary/overflow
table; **no horizontal overflow** at either viewport; console clean of
app errors (only Brave-shields analytics blocks + pre-existing
IPFS-gateway 403 thumbnails).
## Out of scope, flagged separately
- **Pre-existing bug (reproduced on develop with this PR's changes
stashed)**: opening Submit Work from the Hub header leaves the LeftSheet
parked off-screen (`translateX(-427px)`, spring never runs); work-detail
opens fine and direct URL loads render in place. Spawned as its own task
with full diagnostics.
- The admin `tsc --noEmit -p tsconfig.json` gate is a no-op (`files: []`
solution config) — it's how the dead `AdminFilterChip` props survived.
Worth a follow-up on the build script.
🤖 Generated with [Claude Code](https://claude.com/claude-code)71 files changed
Lines changed: 2816 additions & 2193 deletions
File tree
- packages
- admin/src
- __tests__/components
- Garden
- components
- Garden
- Layout
- styles
- views
- Actions
- Community
- components
- Garden
- WorkDetail
- components
- Hub
- components
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 2 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | | - | |
| 2 | + | |
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | | - | |
| 16 | + | |
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
| |||
Lines changed: 43 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
27 | | - | |
28 | 27 | | |
29 | 28 | | |
30 | 29 | | |
| |||
142 | 141 | | |
143 | 142 | | |
144 | 143 | | |
145 | | - | |
146 | 144 | | |
147 | 145 | | |
148 | 146 | | |
| |||
182 | 180 | | |
183 | 181 | | |
184 | 182 | | |
185 | | - | |
186 | 183 | | |
187 | 184 | | |
188 | 185 | | |
| |||
375 | 372 | | |
376 | 373 | | |
377 | 374 | | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
378 | 418 | | |
Lines changed: 59 additions & 62 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
2 | | - | |
3 | | - | |
4 | | - | |
5 | | - | |
6 | | - | |
7 | | - | |
| 1 | + | |
8 | 2 | | |
9 | 3 | | |
10 | 4 | | |
| |||
19 | 13 | | |
20 | 14 | | |
21 | 15 | | |
22 | | - | |
| 16 | + | |
23 | 17 | | |
24 | 18 | | |
25 | 19 | | |
| |||
28 | 22 | | |
29 | 23 | | |
30 | 24 | | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
35 | | - | |
36 | | - | |
37 | | - | |
38 | | - | |
39 | | - | |
40 | | - | |
41 | | - | |
42 | | - | |
43 | | - | |
44 | | - | |
45 | | - | |
46 | | - | |
47 | | - | |
48 | | - | |
49 | | - | |
50 | | - | |
51 | | - | |
52 | | - | |
53 | | - | |
54 | | - | |
55 | | - | |
56 | | - | |
57 | | - | |
58 | | - | |
59 | | - | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
60 | 62 | | |
61 | | - | |
62 | | - | |
63 | | - | |
64 | | - | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
65 | 69 | | |
66 | 70 | | |
67 | | - | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
68 | 78 | | |
69 | 79 | | |
70 | 80 | | |
71 | | - | |
72 | | - | |
73 | | - | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
74 | 84 | | |
75 | 85 | | |
76 | 86 | | |
77 | 87 | | |
78 | | - | |
79 | | - | |
80 | | - | |
81 | | - | |
82 | | - | |
83 | | - | |
84 | | - | |
85 | | - | |
86 | | - | |
87 | | - | |
| 88 | + | |
88 | 89 | | |
89 | 90 | | |
90 | 91 | | |
91 | 92 | | |
92 | 93 | | |
93 | 94 | | |
94 | | - | |
95 | | - | |
96 | | - | |
97 | | - | |
98 | | - | |
99 | | - | |
100 | | - | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
101 | 98 | | |
102 | 99 | | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | | - | |
2 | | - | |
3 | | - | |
| 1 | + | |
4 | 2 | | |
5 | 3 | | |
6 | 4 | | |
7 | 5 | | |
8 | | - | |
9 | | - | |
10 | | - | |
11 | | - | |
12 | | - | |
13 | 6 | | |
14 | 7 | | |
15 | 8 | | |
| |||
20 | 13 | | |
21 | 14 | | |
22 | 15 | | |
23 | | - | |
24 | | - | |
25 | | - | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
26 | 20 | | |
27 | 21 | | |
28 | 22 | | |
29 | 23 | | |
30 | | - | |
| 24 | + | |
31 | 25 | | |
32 | 26 | | |
33 | | - | |
34 | | - | |
35 | | - | |
36 | | - | |
37 | | - | |
38 | | - | |
39 | | - | |
40 | 27 | | |
41 | 28 | | |
42 | 29 | | |
43 | 30 | | |
44 | 31 | | |
45 | | - | |
46 | | - | |
| 32 | + | |
47 | 33 | | |
48 | 34 | | |
49 | 35 | | |
| |||
68 | 54 | | |
69 | 55 | | |
70 | 56 | | |
71 | | - | |
72 | | - | |
73 | | - | |
74 | | - | |
75 | | - | |
76 | | - | |
77 | | - | |
78 | | - | |
79 | | - | |
80 | | - | |
81 | | - | |
82 | | - | |
83 | | - | |
84 | | - | |
85 | | - | |
86 | | - | |
87 | | - | |
88 | | - | |
89 | | - | |
90 | | - | |
91 | | - | |
92 | | - | |
93 | | - | |
94 | | - | |
95 | | - | |
96 | | - | |
97 | | - | |
98 | | - | |
99 | | - | |
100 | | - | |
101 | | - | |
102 | | - | |
103 | | - | |
104 | | - | |
105 | | - | |
106 | | - | |
107 | | - | |
108 | | - | |
109 | | - | |
110 | | - | |
111 | | - | |
112 | | - | |
113 | | - | |
114 | | - | |
115 | | - | |
116 | | - | |
117 | | - | |
118 | | - | |
119 | | - | |
120 | | - | |
121 | | - | |
122 | | - | |
123 | | - | |
124 | | - | |
125 | | - | |
126 | | - | |
127 | | - | |
128 | | - | |
129 | | - | |
130 | | - | |
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
34 | | - | |
| 34 | + | |
35 | 35 | | |
36 | 36 | | |
37 | 37 | | |
| |||
0 commit comments