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>
This commit is contained in:
2026-05-06 20:44:20 -04:00
parent 80baf89b00
commit 7a9cb4b03b
9 changed files with 330 additions and 0 deletions

View File

@@ -4,6 +4,7 @@ import { Menu, X, LayoutGrid, Clock, AlertTriangle, GitBranch, Wand2, BarChart3,
import { useAuthStore } from '@/store/authStore'
import { usePermissions } from '@/hooks/usePermissions'
import { useUserPreferencesStore } from '@/store/userPreferencesStore'
import { useBillingPoll } from '@/hooks/useBillingPoll'
import { BrandLogo } from '@/components/common/BrandLogo'
import { TopBar } from './TopBar'
import { Sidebar } from './Sidebar'
@@ -13,6 +14,9 @@ import { FeedbackWidget } from '@/components/common/FeedbackWidget'
import { cn } from '@/lib/utils'
export function AppLayout() {
// Poll /billing/state every 60s while authenticated. Hook no-ops when logged out.
useBillingPoll()
const location = useLocation()
const navigate = useNavigate()
const { user, logout } = useAuthStore()