Blocks
Usage quota banner
A dismissible banner that warns when a metered quota nears its plan limit, using the usage and flags surfaces.
A dismissible banner that appears when one of the org's metered quotas is at or near its plan limit — a nudge to upgrade before work is blocked. It renders nothing while loading, when no quota is near its cap, or after dismissal. The threshold defaults to 80% of a finite limit; uncapped metrics never trigger it.
Requires: usage, flags
Preview
You're close to a plan limit
- API calls: 9200 / 10000
"use client";import { useState } from "react";import { Button } from "@/components/ui/button";import { cn } from "@/lib/utils";import { useQuotaStatus } from "./use-quota-status";/** * A dismissible banner that appears when one of the org's metered quotas is at or * near its plan limit — a nudge to upgrade before work is blocked. Renders nothing * while loading, when no quota is near its cap, or after dismissal. The threshold * defaults to 80% of a finite limit; uncapped metrics never trigger it. */export function QuotaBanner({ className }: { className?: string }) { const [dismissed, setDismissed] = useState(false); const { isPending, breaches } = useQuotaStatus(); if (isPending || dismissed || breaches.length === 0) return null; const critical = breaches.some((breach) => breach.severity === "critical"); return ( <div role="status" className={cn( "flex items-start justify-between gap-4 rounded-md border px-4 py-3 text-sm", critical ? "border-destructive/50 text-destructive" : "border-border text-foreground", className, )} > <div className="flex flex-col gap-1"> <p className="font-medium"> {critical ? "You've hit a plan limit" : "You're close to a plan limit"} </p> <ul className="text-muted-foreground"> {breaches.map((breach) => ( <li key={breach.key}> {breach.description}: {breach.used} / {breach.limit} </li> ))} </ul> </div> <Button variant="secondary" size="sm" onClick={() => setDismissed(true)} aria-label="Dismiss" > Dismiss </Button> </div> );}Offline preview
The docs site has no backend, so the preview seeds one representative metric at
92% of its cap — that's what surfaces the warning state. In an app the data
comes from the usage router.
Install
npx create-saas-starter add quota-bannerRun it from your app's root. add only writes new files — wiring is up to you:
import { QuotaBanner } from "@/components/blocks/quota-banner/quota-banner";