import {
CHATGPT_USAGE_URL,
collectLimitAccounts,
collectExternalUsageLinks,
collectLimitNotices,
collectLimitPools,
cursorUsageWindowDetails,
displayLimitWindows,
formatResetsIn,
type LimitAccount,
type LimitPool,
type LimitPoolMember,
type LimitPoolWindow,
paceRemainingPercent,
remainingPercent,
type ResetCreditChoice,
resetCreditChoices,
} from "@t3tools/shared/usageLimits";
import type { Popover as PopoverPrimitive } from "@base-ui/react/popover";
import { normalizeProviderAccentColor } from "@t3tools/client-runtime/state/provider-instance-display";
import { AlertTriangleIcon, ExternalLinkIcon, TicketIcon } from "lucide-react";
import {
createContext,
Fragment,
type ReactNode,
type RefObject,
use,
useLayoutEffect,
useRef,
useState,
} from "react";
import { ensureLocalApi } from "../../localApi";
import { usePrimarySettings } from "../../hooks/useSettings";
import { cn } from "../../lib/utils";
import { formatUpcomingTimestamp } from "../../timestampFormat";
import { ProviderInstanceIcon } from "../chat/ProviderInstanceIcon";
import { providerClients } from "../settings/providerDriverMeta";
import { RedactedSensitiveText } from "../settings/RedactedSensitiveText";
import { Button } from "../ui/button";
import { OpenAI } from "../Icons";
import { Alert, AlertTitle } from "../ui/alert";
import { Popover, PopoverCreateHandle, PopoverPopup, PopoverTrigger } from "../ui/popover";
import { PaceIcon, ResetCreditDialog, barColor, usePaceMark, useResetCredit } from "./UsageLimits";
function accountInitials(email: string): string {
const [local = "", domain = ""] = email.split("@");
return `${local[0] ?? ""}${domain[0] ?? ""}`.toUpperCase() || "?";
}
function accountHue(email: string): number {
let hash = 0;
for (let index = 0; index < email.length; index += 1) {
hash = (hash * 31 + email.charCodeAt(index)) | 0;
}
return Math.abs(hash) % 360;
}
function AccountChip({ email }: { readonly email: string }) {
const hue = accountHue(email);
return (
{accountInitials(email)}
);
}
function AccountAvatar({
account,
className,
}: {
readonly account: LimitAccount;
readonly className?: string;
}) {
if (account.redeem) {
return (
);
}
return account.email ? : null;
}
function AccountName({
account,
className,
}: {
readonly account: LimitAccount;
readonly className?: string;
}) {
if (account.displayName) return {account.displayName};
if (account.email) {
return (
);
}
return (
{providerClients.get(account.driver)?.label ?? String(account.driver)}
);
}
function Row({ label, children }: { readonly label: string; readonly children: ReactNode }) {
return (
{label}
{children}
);
}
function SegmentPopover({
account,
window,
reset,
now,
redeem,
onRedeem,
}: {
readonly account: LimitAccount;
readonly window: LimitPoolMember["window"];
readonly reset: LimitPoolWindow["resets"][number] | undefined;
readonly now: number;
readonly redeem: ReturnType | null;
readonly onRedeem: (choice: ResetCreditChoice) => void;
}) {
const timestampFormat = usePrimarySettings((settings) => settings.timestampFormat);
const remaining = remainingPercent(window);
const timeLeft = paceRemainingPercent(window, now);
const resetsIn = formatResetsIn(window, now);
const where =
account.environments.length > 0
? account.environments.map((environment) => environment.label).join(", ")
: account.sourceLabel;
const choices =
redeem && account.redeem && account.limits.resetCredits?.availableCount
? resetCreditChoices(account.limits.resetCredits, account.redeem.input, now, true)
: [];
return (
{account.displayName ?? providerClients.get(account.driver)?.label ?? account.driver}
{account.email ? (
) : null}
{account.plan ? {account.plan}
: null}
{where ? (
0 ? "Signed in" : "Via"}>{where}
) : null}
{remaining}%
{window.resetsAt ? (
{formatUpcomingTimestamp(window.resetsAt, timestampFormat, now)}
{resetsIn ? ` · ${resetsIn.replace("resets in ", "in ")}` : ""}
) : null}
{timeLeft !== null ? {timeLeft}% left by now
: null}
{reset && reset.restoresPercent > 0 ? (
+{reset.restoresPercent}% of pool
) : null}
{choices.length > 0 && redeem ? (
{choices.map((choice) => (
{choice.summary}
{choice.availableCount > 0 ? (
) : null}
))}
) : null}
);
}
/**
* Every segment on the page shares one popover, so hovering or clicking another
* segment moves it instead of opening a second one. The payload is the segment
* it currently describes.
*/
type SegmentPayload = Omit[0], "now" | "onRedeem">;
const SegmentPopoverContext = createContext
> | null>(null);
function ActiveSegmentPopover({
handle,
actions,
payload,
pools,
now,
}: {
readonly handle: ReturnType>;
readonly actions: RefObject;
readonly payload: SegmentPayload;
readonly pools: readonly LimitPool[];
readonly now: number;
}) {
const available = pools.some((pool) =>
displayLimitWindows(pool).some((window) =>
window.members.some(
(member) =>
member.account.key === payload.account.key &&
member.window.id === payload.window.id &&
member.window.kind === payload.window.kind &&
Boolean(member.account.redeem) === Boolean(payload.redeem),
),
),
);
// The trigger is gone, so the popup has nothing to anchor to: an exit transition would
// slide it to the viewport origin. Unmount it outright, which also clears Base UI's
// active-trigger bookkeeping so the segment can open again when it comes back.
// oxlint-disable-next-line t3code/no-unreasoned-state-sync -- closes the popover handle and unmounts the Base UI popup before paint when its trigger is gone
useLayoutEffect(() => {
if (available) return;
handle.close();
actions.current?.unmount();
}, [available, handle, actions]);
return (
{
handle.close();
payload.redeem?.confirm(choice);
}}
/>
);
}
/**
* The confirm is a sibling of the popover, not a child: dialogs stack under
* popovers, and the popover closes as the confirm opens.
*/
function PoolSegment({
account,
...props
}: {
readonly account: LimitAccount;
readonly window: LimitPoolMember["window"];
readonly reset: LimitPoolWindow["resets"][number] | undefined;
readonly refillPercent: number;
readonly color: string;
readonly now: number;
readonly index: number;
readonly showAccountName: boolean;
}) {
return account.redeem ? (
) : (
);
}
function RedeemableSegment({
redeemAt,
...props
}: Omit[0], "redeem"> & {
readonly redeemAt: NonNullable;
}) {
const redeem = useResetCredit(redeemAt.environmentId);
return (
<>
void redeem.redeem()}
disabled={!redeem.canManageProviders}
/>
{/* The popover closed before the confirm, so progress and the outcome need a home outside it. */}
{redeem.busy || redeem.status ? (
{" "}
{redeem.busy ? "Using reset credit…" : redeem.status}
) : null}
>
);
}
function SegmentTriggers({
account,
window,
reset,
redeem,
refillPercent,
color,
now,
index,
showAccountName,
}: SegmentPayload & {
readonly refillPercent: number;
readonly color: string;
readonly now: number;
readonly index: number;
readonly showAccountName: boolean;
}) {
const popover = use(SegmentPopoverContext) ?? undefined;
const payload: SegmentPayload = { account, window, reset, redeem };
const remaining = remainingPercent(window);
const timeLeft = paceRemainingPercent(window, now);
const [segmentRef, paceMark] = usePaceMark(timeLeft);
const resetsIn = formatResetsIn(window, now);
const credits = account.limits.resetCredits?.availableCount ?? 0;
return (
<>
}
>
{/* Clipped inside the rounded clip so the bar's own corners keep their antialiasing. */}
{remaining < 100 && reset && refillPercent > 0 ? (
) : null}
{paceMark ? (
) : null}
{index}
{showAccountName ? (
) : null}
{/* A single-account bar repeats the headline percentage. */}
{showAccountName ? (
{remaining}%
) : null}
{resetsIn || credits ? (
{resetsIn?.replace("resets in ", "↻ ") ?? ""}
{credits ? (
<>
{resetsIn ? (
·
) : null}
{credits}
>
) : null}
) : null}
>
);
}
function LegendRow({
payload,
color,
now,
index,
}: {
readonly payload: SegmentPayload;
readonly color: string;
readonly now: number;
readonly index: number;
}) {
const popover = use(SegmentPopoverContext) ?? undefined;
const { account, window } = payload;
const remaining = remainingPercent(window);
const resetsIn = formatResetsIn(window, now);
const credits = account.limits.resetCredits?.availableCount ?? 0;
return (
}
className="min-w-0 @2xl/pool:hidden"
>
Segment
{index}
{remaining}%
{resetsIn?.replace("resets in ", "↻ ") ?? ""}
{credits ? (
<>
{resetsIn ? · : null}
{credits}
{credits} reset {credits === 1 ? "credit" : "credits"} banked
>
) : null}
);
}
function PoolBar({
pool,
color,
now,
}: {
readonly pool: LimitPoolWindow;
readonly color: string;
readonly now: number;
}) {
const restores = new Map(pool.resets.map((reset) => [reset.member.account.key, reset]));
return (
{pool.columns.map((member, position) =>
member.window ? (
1}
/>
) : null,
)}
);
}
function PoolWindowCard({
pool,
color,
now,
label,
description,
}: {
readonly pool: LimitPoolWindow;
readonly color: string;
readonly now: number;
readonly label?: string | undefined;
readonly description?: string | undefined;
}) {
const nextRefill = pool.resets.find((reset) => reset.restoresPercent > 0);
return (
{label ?? pool.label}
{pool.remainingPercent}%
left
{pool.pace ? : null}
{nextRefill && pool.columns.length > 1 ? (
↻ +{nextRefill.restoresPercent}%
) : null}
{description ? (
{description}
) : null}
);
}
function PoolSection({ pool, now }: { readonly pool: LimitPool; readonly now: number }) {
const color = barColor(pool.driver);
const label = providerClients.get(pool.driver)?.label ?? String(pool.driver);
const windows = displayLimitWindows(pool);
return (
{label}
{windows.map((window) => {
const details = pool.driver === "cursor" ? cursorUsageWindowDetails(window.id) : undefined;
return (
);
})}
);
}
export function UsageLimitsPooled({
presentations,
now,
}: {
readonly presentations: Parameters[0];
readonly now: number;
}) {
const [segmentPopover] = useState(() => PopoverCreateHandle());
const segmentPopoverActions = useRef(null);
const pools = collectLimitPools(collectLimitAccounts(presentations), now);
const notices = collectLimitNotices(presentations);
const externalLinks = collectExternalUsageLinks(presentations);
return (
{pools.length === 0 && notices.length === 0 && externalLinks.length === 0 ? (
No provider on the selected environments reports subscription limits.
) : null}
{pools.map((pool) => (
))}
{({ payload }) =>
payload ? (
) : null
}
{externalLinks.map((link) => (
{link.url === CHATGPT_USAGE_URL ? (
) : null}
{link.label}
{link.accounts.join(", ")}
{link.url === CHATGPT_USAGE_URL ? (
View usage in ChatGPT with your connected account.
) : link.message ? (
{link.message}
) : null}
))}
);
}
function LimitNotices({ notices }: { readonly notices: readonly string[] }) {
if (notices.length === 0) return null;
return (
{notices.map((notice) => (
{notice}
))}
);
}