State Management#

Uses Zustand. Stores are in web/src/lib/stores/.

useUserStore#

typescriptimport { useUserStore } from "@/lib/stores/user"

const { user, fetchUser, clearUser, isOwner } = useUserStore()
Field/MethodDescription
userUser info { id, email, role, ... }
fetchUser()Fetches /v1/users/info, returns success boolean
clearUser()Clears user state
isOwner()Whether user is owner (user.role === 'owner')

useBillingStore#

typescriptimport { useBillingStore } from "@/lib/stores/billing"

const { subscription, lifetime, credits, fetchAll, clear, getTotalCredits, hasSubscription, hasLifetime } = useBillingStore()
Field/MethodDescription
subscriptionActive subscriptions
lifetimeLifetime purchases
creditsCredits { all: [], total: number }
fetchAll()Load subscriptions, lifetime, credits in parallel
clear()Clear all billing data
getTotalCredits()Get total available credits
hasSubscription()Has active subscription
hasLifetime()Has lifetime purchase

useWebsiteStore#

typescriptimport { useWebsiteStore } from "@/lib/stores/website"

const { config, fetchConfig } = useWebsiteStore()
FieldDescription
config.subscriptionSubscription config (enabled, packages, has_lifetime, has_free)
config.creditCredit config (enabled, min_credits, packages)
config.app_modeApp mode

Example#

tsx"use client"

import { useUserStore } from "@/lib/stores/user"
import { useBillingStore } from "@/lib/stores/billing"

export default function MyComponent() {
  const { user } = useUserStore()
  const { credits } = useBillingStore()

  return (
    <div>
      <p>User: {user?.email}</p>
      <p>Credits: {credits?.total}</p>
    </div>
  )
}