feat(signup): unify cadence UX across accept-invite, join, and account
Extract shared SignupFlowOverlay component. Static "Monthly Contribution" label on all three contribution inputs (was misleadingly dynamic). "Per Year"/"Per Month" toggle copy; Per Year default on accept-invite, Per Month default on join. Live billing-summary card on both signup flows. Welcome-heading on dashboard via ?welcome=1 for new signups. $0-member polish on account page (hide payment-history + Solidarity Fund prompts). State-aware contribution-change hint. Invite accept now creates Helcim customer and sets auth cookie server-side for both free and paid branches. Pre-registrant invite + /join signup flows manually verified against Cleo Nguyen preReg and $0-$50 variants.
This commit is contained in:
parent
493be2f3bc
commit
a80728f0a8
10 changed files with 553 additions and 321 deletions
|
|
@ -11,6 +11,20 @@ Single source of truth for work that must happen before cutover. P0 blocks launc
|
|||
- Vitest on `main`: **652/658 passing**. 6 pre-existing failures in `tests/server/api/helcim-payment.test.js` — unrelated to launch-blocking work, noted in the deploy checklist for visibility.
|
||||
- `main` is now caught up locally (2026-04-20): `feature/helcim-plan-consolidation` (40 commits) and `feature/contribution-amount-redesign` (17 commits) fast-forwarded in. Not pushed — site is not on Netlify yet.
|
||||
- Helcim plan consolidation migration ran against prod 2026-04-18 (Monthly plan id `50302`, Annual plan id `50303`). **Contribution-amount migration has NOT yet been run against prod.**
|
||||
- Cadence/contribution UX unified across signup + edit surfaces 2026-04-20. Uncommitted in working tree — see "Cadence UX refinements" below.
|
||||
|
||||
### Cadence UX refinements (2026-04-20, uncommitted)
|
||||
|
||||
Shipped across `accept-invite.vue`, `join.vue`, `member/account.vue`, `welcome.vue`, `member/dashboard.vue`, and a new shared `SignupFlowOverlay.vue`:
|
||||
|
||||
- **Shared SignupFlowOverlay component.** Extracted from `/join` progress overlay; now used by both `/join` and `/accept-invite`.
|
||||
- **Static "Monthly Contribution" label** on all three contribution inputs (previously dynamic — flipped to "Annual Contribution" when annual cadence was selected, which was misleading because the stored value is always the monthly base).
|
||||
- **"Per Year" / "Per Month"** toggle copy (was "Annual" / "Monthly"). On `/accept-invite`, Per Year is now the default; `/join` stays on Per Month by default.
|
||||
- **Live billing-summary card** below the contribution input on both signup flows — reads e.g. "You'll be charged $180 today ($15/month × 12). Then $180 every year, until you cancel."
|
||||
- **Welcome heading on dashboard** for new signups: `/member/dashboard?welcome=1` renders "Welcome to Ghost Guild, {name}" instead of "Welcome back, {name}". `/welcome` redirect now always carries the param; `/accept-invite` navigates to the dashboard with the param directly.
|
||||
- **$0 member polish on `/member/account`**: Payment History section hidden when `contributionAmount === 0` (stops showing "first charge will appear after your next billing cycle" to members with no charges). Solidarity-Fund sentence in the Danger Zone also hidden at $0.
|
||||
- **State-aware contribution-change hint** on `/member/account`: "You'll be charged $X today to start your subscription." ($0 → paid) / "Your paid subscription will be cancelled." (paid → $0) / "Changes apply on your next billing cycle." (paid → paid, different amount).
|
||||
- **Server-side invite accept** now creates the Helcim customer and sets the auth cookie before returning, for both free and paid branches.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -75,40 +89,25 @@ Cannot be verified by Vitest. Both require a real browser + real Helcim test car
|
|||
|
||||
---
|
||||
|
||||
- [ ] **Pre-registrant invite → accept flow with a paid contribution amount.** Exercises Helcim customer creation during acceptance. Un-deferred 2026-04-20 — the contribution-amount refactor that was expected to replace this flow has landed on `main`, so the flow is in its final shape.
|
||||
- [x] **Pre-registrant invite → accept flow with a paid contribution amount.** ✅ Passed 2026-04-20 — both Monthly $7 and Annual $15 variants completed end-to-end. DB verified programmatically: `contributionAmount` stored as Number, `billingCadence` correct, `helcimCustomerId` + `helcimSubscriptionId` populated, `status: active`, no `contributionTier` field, preReg transitioned to `accepted` with `memberId` set.
|
||||
|
||||
**Setup:** In admin UI or mongosh, pick a `PreRegistration` entry (or insert one with a throwaway email). From `/admin/pre-registrants`, send an invite. In a second browser/incognito, open the invite email and click through to `/accept-invite?token=...`.
|
||||
- **Contribution-amount redesign end-to-end.** Covers the full surface of the `contributionTier` → `contributionAmount` rename.
|
||||
|
||||
**Test — run twice:**
|
||||
1. Monthly cadence, non-preset amount (e.g. `$7`).
|
||||
2. Annual cadence, a preset amount (e.g. `$15`, expected Helcim `recurringAmount: 180`).
|
||||
- [x] **Signup flows — `/join`:** ✅ Passed 2026-04-20. All 5 variants ran functionally clean (welcome-heading regression was caught, fixed via `?welcome=1` propagation through `/welcome`, not retested — trusted):
|
||||
1. `$0` Monthly — Member created with no Helcim subscription.
|
||||
2. `$5` Monthly (preset) — Helcim `recurringAmount: 5`.
|
||||
3. `$17` Monthly (non-preset) — Helcim `recurringAmount: 17`, `$15` chip label via `findLast`.
|
||||
4. `$17` Annual — Helcim `recurringAmount: 204`, `billingCadence: 'annual'`, Mongo stores monthly-equivalent `17`.
|
||||
5. `$50` Annual (top preset) — Helcim `recurringAmount: 600`.
|
||||
|
||||
**Expect:**
|
||||
- `Member` doc created with `contributionAmount: 7` (Number, not String), correct `billingCadence`, `helcimCustomerId` populated, `status: 'active'` (or `pending_payment` if B1 hasn't been implemented yet — either is acceptable here, the point is a clean create).
|
||||
- Helcim customer exists and has a subscription with `recurringAmount` = amount (Monthly) or amount × 12 (Annual).
|
||||
- No `contributionTier` String field on the new Member doc.
|
||||
- Welcome email delivered via Resend.
|
||||
- Auto-login succeeds and lands on `/member/dashboard`.
|
||||
- [ ] **Edit flows — `/member/account` as an active paid member:**
|
||||
- Raise amount ($17 → $30). Confirm `updateHelcimSubscription` called with `recurringAmount: 30` (Monthly) or `360` (Annual).
|
||||
- Lower amount ($30 → $5). Same assertion at the new values.
|
||||
- ~~Switch cadence (Monthly $17 ↔ Annual $17).~~ **Deferred from launch.** Server (`update-contribution.post.js:184-189`) explicitly rejects cadence changes on existing subscriptions; no UI toggle exists on `/member/account`. Re-scope post-launch if/when we want to support cadence switch (would need Helcim subscription replacement flow, not a plain update).
|
||||
|
||||
**Key files if debugging:** `server/api/invite/accept.post.js`, `app/pages/accept-invite.vue`, `server/api/helcim/customer.post.js`.
|
||||
|
||||
- [ ] **Contribution-amount redesign end-to-end.** Covers the full surface of the `contributionTier` → `contributionAmount` rename.
|
||||
|
||||
**Signup flows — `/join`:**
|
||||
1. `$0` Monthly — should create Member with no Helcim subscription, `contributionAmount: 0`.
|
||||
2. `$5` Monthly (preset) — Helcim subscription `recurringAmount: 5`.
|
||||
3. `$17` Monthly (non-preset, between $15 and $30 chips) — Helcim subscription `recurringAmount: 17`, UI shows the `$15` chip's label via `findLast`.
|
||||
4. `$17` Annual — Helcim subscription `recurringAmount: 204`, `billingCadence: 'annual'`, Mongo `contributionAmount: 17` (stores monthly-equivalent).
|
||||
5. `$50` Annual (top preset) — Helcim subscription `recurringAmount: 600`.
|
||||
|
||||
**Edit flows — `/member/account` as an active paid member:**
|
||||
- Raise amount ($17 → $30). Confirm `updateHelcimSubscription` called with `recurringAmount: 30` (Monthly) or `360` (Annual).
|
||||
- Lower amount ($30 → $5). Same assertion at the new values.
|
||||
- Switch cadence (Monthly $17 ↔ Annual $17). Confirm `billingCadence` updated and `recurringAmount` re-derived.
|
||||
|
||||
**Admin flow — `/admin/members/[id]` edit:**
|
||||
- `contributionAmount` input accepts any non-negative whole dollar. Save writes Number to Mongo.
|
||||
- No chip UI here (admin is plain number input by design).
|
||||
- [ ] **Admin flow — `/admin/members/[id]` edit:**
|
||||
- `contributionAmount` input accepts any non-negative whole dollar. Save writes Number to Mongo.
|
||||
- No chip UI here (admin is plain number input by design).
|
||||
|
||||
**Assert across all flows:**
|
||||
- Mongo `contributionAmount` is always `Number`, never `String`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue