Skip to content

feat: add out-of-credits warning to sidebar plan badge#637

Open
prakhar1605 wants to merge 1 commit into
rowboatlabs:devfrom
prakhar1605:feat/out-of-credits-warning
Open

feat: add out-of-credits warning to sidebar plan badge#637
prakhar1605 wants to merge 1 commit into
rowboatlabs:devfrom
prakhar1605:feat/out-of-credits-warning

Conversation

@prakhar1605

Copy link
Copy Markdown
Collaborator

What

Sidebar plan badge (Free / Starter / Pro) now shows an out-of-credits warning — a red badge state ("Out of credits" + ⚠️) with an upgrade popover ("You've run out of credits → Upgrade now"), matching the POC. It clears automatically when credits are available again.

Detection (both signals you mentioned)

  • /v1/me billing payload — warning turns on when the daily or monthly bucket is exhausted (availableCredits <= 0). Same data the Settings usage bars use; no new API work.
  • Usage API error — the existing matchBillingError "not enough credits" path also flips it on, covering the case where cached billing is stale.

Both feed a single warning state, so there's one source of truth.

Clearing (no polling)

  • A successful cost-incurring call clears it: LLM finish-step (with usage) or a successful voice synth.
  • On clear, we re-fetch /me once, and only if the warning was actually showing — so normal runs don't trigger any extra /me calls.

How it's wired

  • New lib/credit-status.tsisOutOfCredits(billing) helper + two window events (credit:exhausted / credit:replenished) with dispatch helpers (single source for the condition + event names).
  • App.tsx dispatches exhausted on a not_enough_credits billing error, and replenished on a successful LLM finish-step.
  • useVoiceTTS.ts dispatches replenished on a successful synth.
  • sidebar-content.tsx owns the warning UI + listens to both events (billing stays authoritative; events flip it in between).
  • billing-error.ts — added a kind discriminator so we only react to the credits error, not other billing errors.
  • ui/popover.tsx — added PopoverArrow (for the popover pointer).

Files

  • lib/credit-status.ts (new)
  • App.tsx, components/sidebar-content.tsx, hooks/useVoiceTTS.ts, lib/billing-error.ts, components/ui/popover.tsx

Testing

  • Forced isOutOfCredits → true: badge + popover render correctly; X dismisses popover while the indicator stays; "Upgrade now" / "Upgrade" open ?intent=upgrade.
  • Dispatched credit:exhausted / credit:replenished from devtools: warning toggles; /me re-fetch fires only on clear-after-warning, and a normal run after that fires no extra /me.
  • tsc --noEmit clean across renderer.

Note

The existing billing-error modal still shows alongside the new sidebar warning — per your call that they're two separate things. No change to the modal.

Show a warning state + popover on the sidebar plan badge when the user is
out of credits, prompting them to upgrade. Detection comes from two existing
signals: the /v1/me billing payload (daily or monthly bucket exhausted, the
same data the Settings usage bars use) and the existing 'not enough credits'
API-error path. The warning clears on a successful cost-incurring call (LLM
finish-step or a successful voice synth) and re-fetches /me once, only when
the warning was actually showing -- no polling. Popover auto-opens on first
detection and can be dismissed while the indicator persists.
@prakhar1605 prakhar1605 requested a review from ramnique June 23, 2026 14:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant