Skip to content

feat(billing): align plan modal, paywall, and trial UX end-to-end#56

Merged
ABB65 merged 1 commit into
mainfrom
feat/billing-paywall-e2e
Jun 11, 2026
Merged

feat(billing): align plan modal, paywall, and trial UX end-to-end#56
ABB65 merged 1 commit into
mainfrom
feat/billing-paywall-e2e

Conversation

@ABB65

@ABB65 ABB65 commented Jun 11, 2026

Copy link
Copy Markdown
Member

Summary

End-to-end alignment of the SaaS plan/package modal, billing, and paywall surfaces with the real billing architecture. Plan-features data.json is treated as the single source of truth; all UI and copy derive from it. Trial-start stays card-based (hosted checkout); the existing webhook + post-payment flows were verified complete and left unchanged.

Pricing model decision: hybrid — shared core shown once, then a usage/limit + seats + AI-model comparison, with Pro-only premium features highlighted.

What changed

Plan modal (PlanSelectionModal.vue) — hybrid redesign

  • Header: name + price + seats + AI model tier (previously never surfaced) + trial badge.
  • Usage limits: the 6 metered limits, properly formatted (thousands separators, GB suffix, no singular/plural breakage — spec-row layout).
  • Included: features grouped/sorted by category (fixes the old global-sort_order interleaving); Pro shows the "Everything in Starter, plus…" delta.
  • Coming soon: roadmap features moved to a separate muted list instead of being shown with a green check.
  • Responsive grid (grid-cols-1 sm:grid-cols-2), balanced card heights, simplified CTA logic.

Proactive paywall (new PaywallOverlay.vue)

  • Replaces workspace content in locked billing states (trial_expired / grace_expired / canceled_expired); owner/admin get "Choose a plan" / "Update payment method", members get an explanatory message. isLocked / requiresPayment are now actually used.
  • Wired into the live default layout, gated to workspace routes; /settings stays reachable.

TrialBanner — was dead, now live

  • Its only mount point (workspace layout) is unused by any page, so the banner never rendered. Moved into default layout; shows the resolved plan name instead of the raw slug.

Content / dictionary alignment

  • Removed the contradictory "all features available on all plans" positioning copy; added AI-model / limits / included / coming-soon / paywall keys.
  • Aligned api.byoa_upgrade / api.conversation_upgrade error messages to the data (Pro-only).
  • Fixed client generic.server_errorcommon.server_error (key was missing from ui-strings).

Verification

  • pnpm lint:fix → 0 errors
  • pnpm typecheck → clean
  • pnpm test633/633 passing (incl. license-content-parity; no plan price/limit values changed)

Follow-ups

  • Polar dashboard: trial length is product-config-driven (not enforced in code) — confirm Starter & Pro products have the 14-day trial enabled.
  • Assumption: BYOA + Conversation API kept Pro-only per data.json. Opening them to all plans is a 2-line data change if desired.
  • workspace.vue layout is unused (dead) — cleanup candidate, left untouched here.

- Redesign PlanSelectionModal as a hybrid layout (AI model + seats →
  metered usage limits → grouped included features → Pro premium delta),
  fixing feature ordering, limit label formatting, and the inverted
  card weight; surface roadmap items as a separate "Coming soon" list
  instead of green checks.
- Add proactive PaywallOverlay for locked billing states and wire it
  into the live `default` layout (workspace routes only, settings exempt)
  so isLocked/requiresPayment are actually used.
- Move TrialBanner into the `default` layout — its only previous mount
  point (`workspace` layout) is unused, so it never rendered; show the
  resolved plan name instead of the raw slug.
- Align contradictory copy to plan-features data (single source of
  truth): neutral plan positioning and BYOA/Conversation API upgrade
  messages.
- Add ai-model / limits / included / coming-soon / paywall dictionary
  keys; fix client generic.server_error -> common.server_error.
@ABB65 ABB65 merged commit 3be84d5 into main Jun 11, 2026
1 check passed
@ABB65 ABB65 deleted the feat/billing-paywall-e2e branch June 11, 2026 08:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant