Commit Graph

2 Commits

Author SHA1 Message Date
502c0a44e8 feat(billing): add /account/billing and /account/billing/select-plan pages
Wires up the missing frontend billing surfaces that TrialPill, UpgradePrompt,
NextStepCard, and SetupChecklist all link to. Trial-expired, canceled,
past-due, and "Pick a plan" CTAs no longer 404.

- BillingPage: subscription summary, status-specific messaging
  (trialing / past_due / canceled / complimentary), Manage billing button
  routed through the Stripe Customer Portal, and a Pick/Change-plan link.
- SelectPlanPage: plan picker with monthly/annual toggle + seat count.
  Starter/Pro hit /billing/checkout-session; Enterprise links to
  /contact-sales. Active current plan is tagged "Current plan" with a
  disabled CTA.
- billingApi.getPortalSession + createCheckoutSession; getPortalSession
  surfaces a typed BillingPortalError (no_stripe_customer / stripe_not_
  configured) so the UI can show the right toast.
- AccountSettingsPage gets a Billing link card so the page is discoverable
  from the account hub.
- 10 new vitest cases covering subscription summary, trial/past-due/
  canceled/complimentary states, portal-session error fallback, plan-card
  rendering, checkout payload, and current-plan badge.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 01:43:48 -04:00
7a9cb4b03b feat(billing): add useBillingStore and /billing/state integration
T32: Single frontend source of truth for subscription / plan / feature
state. New Zustand `useBillingStore` fetches `/billing/state` (auto-fetch
on login via authStore, reset on logout), exposes `refetch` for
post-Checkout refresh, and is supported by a `useBillingPoll` hook
that re-fetches every 60s while authenticated. The new `billingApi`
client transforms the snake_case backend payload to camelCase at a
single boundary so the rest of the frontend never sees `plan_billing`
or `enabled_features`.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-06 20:47:50 -04:00