diff --git a/surfsense_web/components/settings/buy-tokens-content.tsx b/surfsense_web/components/settings/buy-tokens-content.tsx index 649a50639..e7fac4255 100644 --- a/surfsense_web/components/settings/buy-tokens-content.tsx +++ b/surfsense_web/components/settings/buy-tokens-content.tsx @@ -1,5 +1,6 @@ "use client"; +import { useQuery as useZeroQuery } from "@rocicorp/zero/react"; import { useMutation, useQuery } from "@tanstack/react-query"; import { Minus, Plus } from "lucide-react"; import { useParams } from "next/navigation"; @@ -11,6 +12,7 @@ import { Spinner } from "@/components/ui/spinner"; import { stripeApiService } from "@/lib/apis/stripe-api.service"; import { AppError } from "@/lib/error"; import { cn } from "@/lib/utils"; +import { queries } from "@/zero/queries"; const TOKEN_PACK_SIZE = 1_000_000; const PRICE_PER_PACK_USD = 1; @@ -21,11 +23,15 @@ export function BuyTokensContent() { const searchSpaceId = Number(params?.search_space_id); const [quantity, setQuantity] = useState(1); + // Server config flag: stays on REST, not per-user. const { data: tokenStatus } = useQuery({ queryKey: ["token-status"], queryFn: () => stripeApiService.getTokenStatus(), }); + // Live per-user usage via Zero. + const [me] = useZeroQuery(queries.user.me({})); + const purchaseMutation = useMutation({ mutationFn: stripeApiService.createTokenCheckoutSession, onSuccess: (response) => { @@ -54,12 +60,11 @@ export function BuyTokensContent() { ); } - const usagePercentage = tokenStatus - ? Math.min( - (tokenStatus.premium_tokens_used / Math.max(tokenStatus.premium_tokens_limit, 1)) * 100, - 100 - ) - : 0; + const used = me?.premiumTokensUsed ?? 0; + const limit = me?.premiumTokensLimit ?? 0; + // Mirrors the backend formula in stripe_routes.py:608 (max(0, limit - used)). + const remaining = Math.max(0, limit - used); + const usagePercentage = me ? Math.min((used / Math.max(limit, 1)) * 100, 100) : 0; return (
$1 per 1M tokens, pay as you go
- {tokenStatus.premium_tokens_remaining.toLocaleString()} tokens remaining + {remaining.toLocaleString()} tokens remaining