MCPcopy Create free account
hub / github.com/CodebuffAI/codebuff / OutOfCreditsBanner

Function OutOfCreditsBanner

cli/src/components/out-of-credits-banner.tsx:18–157  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

16export const areCreditsRestored = () => creditsRestoredGlobal
17
18export const OutOfCreditsBanner = () => {
19 if (IS_FREEBUFF) return null
20
21 const sessionCreditsUsed = useChatStore((state) => state.sessionCreditsUsed)
22 const [creditsRestored, setCreditsRestored] = useState(false)
23
24 const { data: apiData } = useUsageQuery({
25 enabled: true,
26 refetchInterval: CREDIT_POLL_INTERVAL,
27 })
28
29 // Get cached data for immediate display
30 const cachedUsageData = getActivityQueryData<{
31 type: 'usage-response'
32 usage: number
33 remainingBalance: number | null
34 balanceBreakdown?: { free: number; paid: number; ad?: number }
35 next_quota_reset: string | null
36 }>(usageQueryKeys.current())
37
38 const theme = useTheme()
39 const activeData = apiData || cachedUsageData
40 const remainingBalance = activeData?.remainingBalance ?? 0
41
42 // Track if we've confirmed the zero-balance state to avoid false positives from stale cache
43 const [confirmedZeroBalance, setConfirmedZeroBalance] = useState(false)
44
45 // Reset global flag when component mounts (handles re-entry to out-of-credits mode)
46 useEffect(() => {
47 creditsRestoredGlobal = false
48 }, [])
49
50 // Confirm zero balance on first fetch to avoid race condition with cached data
51 useEffect(() => {
52 if (apiData && !confirmedZeroBalance) {
53 if ((apiData.remainingBalance ?? 0) <= 0) {
54 setConfirmedZeroBalance(true)
55 }
56 }
57 }, [apiData, confirmedZeroBalance])
58
59 // Check if credits have been restored - show celebratory message
60 useEffect(() => {
61 // Only check for restoration after we've confirmed zero balance
62 if (!confirmedZeroBalance || remainingBalance <= 0 || creditsRestored) {
63 return
64 }
65
66 // Credits restored! Show the success state
67 setCreditsRestored(true)
68 creditsRestoredGlobal = true
69 }, [remainingBalance, creditsRestored, confirmedZeroBalance])
70
71 // Build stats text
72 const statsText = activeData
73 ? `Session: ${sessionCreditsUsed.toLocaleString()} credits used · Balance: ${remainingBalance.toLocaleString()} credits`
74 : `Session: ${sessionCreditsUsed.toLocaleString()} credits used`
75

Callers

nothing calls this directly

Calls 3

useUsageQueryFunction · 0.90
getActivityQueryDataFunction · 0.90
useThemeFunction · 0.90

Tested by

no test coverage detected