You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(dashboard): wire updateTeam/inviteMember/listInvitations + email-verify gate + PAT copy fallback
BUGBASH 2026-05-20 — B6/B8 P0/P1 dashboard funnel fixes.
B6-P0 003 (Resource detail nav): VERIFIED already fixed in main at 8f6a3f9.
ResourcesPage.tsx:188 uses r.token. No-op in this PR.
B6-P0 008 (email-verified UX on upgrade): added src/components/VerifyEmailBanner.tsx
with isEmailVerifiedError() detector. Wired into CheckoutPage and BillingPage
catch blocks so a 403 email_not_verified renders an actionable "Resend magic
link" banner instead of a generic "checkout failed" toast. The server fix
(auto-verify on claim) is the durable solution; this banner is the UI escape
hatch for the window where api hasn't shipped that yet, and a permanent
fallback for any other path that lands an unverified user on Upgrade.
B8-P1 F1 (updateTeam): wired the no-op stub at src/api/index.ts:445 to
PATCH /api/v1/team. Body shape matches openapi.json (required: {name},
1-200 chars). Response merges TeamSelf into the cached DashboardTeam so
consumers reading slug/owner_id/member_count keep working.
B8-P1 F2 (listInvitations): wired the empty-stub at src/api/index.ts:489 to
GET /api/v1/team/invitations (owner-only). 401/403 fail open to [] so
non-owners see the empty pending-invites section instead of a broken page.
B8-P1 F3 (inviteMember): wired the no-op stub at src/api/index.ts:496 to
POST /api/v1/team/members/invite. Returns the created invitation row.
Side change: src/api/types.ts Role gains 'member' so the listInvitations
adapter cast is honest — the server's invite enum is
{admin, developer, viewer, member}.
B8-P1 F5 (DeployTtlPolicyCard admin gate): added a listMembers() probe in
src/pages/SettingsPage.tsx that derives the caller's role and renders
null for non-owner/admin. Server still enforces 403 on PATCH
/api/v1/team/settings — this is UX cleanup so devs/viewers don't see a
Save button they can't use. Fails closed: hides while role is unknown.
B8-P1 F21 (PAT copy fallback): replaced the inline PAT-mint-result block
in SettingsPage with PatCreatedBanner. The token now lives in a
textarea (selectable + select() on copy failure) and a loud red toast
fires when navigator.clipboard.writeText() refuses (insecure context,
blocked permission). The user can keyboard-copy from the textarea
instead of losing the one-time-shown token to a silent console.warn.
Gates:
- tsc --noEmit: green
- vitest run: 662 passed, 3 skipped (38 test files)
- npm run build: green (vite + prerender both pass)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
0 commit comments