diff --git a/ui/src/components/account/flow-viz/account-card.tsx b/ui/src/components/account/flow-viz/account-card.tsx
index dc10aea9..a07958fa 100644
--- a/ui/src/components/account/flow-viz/account-card.tsx
+++ b/ui/src/components/account/flow-viz/account-card.tsx
@@ -6,6 +6,7 @@ import { AccountSurfaceCard } from '@/components/account/shared/account-surface-
import { QuotaTooltipContent } from '@/components/shared/quota-tooltip-content';
import { Button } from '@/components/ui/button';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
+import { getCodexIdentityBadge, type CodexIdentityBadge } from '@/lib/account-identity';
import {
cn,
formatQuotaPercent,
@@ -88,68 +89,56 @@ function getCompactQuotaColor(percentage: number) {
return 'bg-red-500';
}
-function getCodexPlanAudience(quota: unknown): AccountAudience {
+function getCodexQuotaBadge(quota: unknown): CodexIdentityBadge {
if (!quota || typeof quota !== 'object' || !('planType' in quota)) {
- return 'unknown';
+ return { audience: 'unknown', label: null };
}
const planType = (quota as { planType?: unknown }).planType;
if (typeof planType !== 'string' || planType.trim().length === 0) {
- return 'unknown';
+ return { audience: 'unknown', label: null };
}
- if (planType === 'team') return 'business';
- if (planType === 'free') return 'free';
- if (planType === 'plus' || planType === 'pro') return 'personal';
- return 'unknown';
+ if (planType === 'team') {
+ return { audience: 'business', label: 'Business' };
+ }
+
+ if (planType === 'free') {
+ return { audience: 'free', label: 'Free' };
+ }
+
+ if (planType === 'plus') {
+ return { audience: 'personal', label: 'Plus' };
+ }
+
+ if (planType === 'pro') {
+ return { audience: 'personal', label: 'Pro' };
+ }
+
+ return { audience: 'unknown', label: null };
}
-function resolveCodexAudience(
- identityAudience: AccountAudience,
- planAudience: AccountAudience
-): AccountAudience {
- if (planAudience === 'unknown') {
- return identityAudience;
+function resolveCodexBadge(
+ identityBadge: CodexIdentityBadge,
+ quotaBadge: CodexIdentityBadge
+): CodexIdentityBadge {
+ if (!quotaBadge.label) {
+ return identityBadge;
}
- if (planAudience === 'business') {
- return 'business';
+ if (
+ quotaBadge.label === 'Business' ||
+ quotaBadge.label === 'Plus' ||
+ quotaBadge.label === 'Pro'
+ ) {
+ return quotaBadge;
}
- if (identityAudience === 'business') {
- return 'business';
+ if (quotaBadge.label === 'Free' && identityBadge.label && identityBadge.label !== 'Free') {
+ return identityBadge;
}
- if (planAudience === 'personal') {
- return 'personal';
- }
-
- if (planAudience === 'free') {
- return identityAudience === 'unknown' || identityAudience === 'free'
- ? 'free'
- : identityAudience;
- }
-
- return identityAudience;
-}
-
-function getCodexPlanDetailLabel(quota: unknown): string | null {
- if (!quota || typeof quota !== 'object' || !('planType' in quota)) {
- return null;
- }
-
- const planType = (quota as { planType?: unknown }).planType;
- if (typeof planType !== 'string' || planType.trim().length === 0) {
- return null;
- }
-
- if (planType === 'free' || planType === 'team') {
- return null;
- }
-
- return planType === 'plus' || planType === 'pro'
- ? planType[0].toUpperCase() + planType.slice(1)
- : null;
+ return quotaBadge;
}
function getVariantDetailLabel(
@@ -160,9 +149,32 @@ function getVariantDetailLabel(
},
quota?: unknown
) {
- return (
- variant.detailLabel ?? variant.compactDetailLabel ?? getCodexPlanDetailLabel(quota) ?? null
- );
+ return resolveCodexBadge(
+ getCodexIdentityBadge({
+ audience: variant.audience,
+ detailLabel: variant.detailLabel,
+ compactDetailLabel: variant.compactDetailLabel,
+ }),
+ getCodexQuotaBadge(quota)
+ ).label;
+}
+
+function getVariantBadgeAudience(
+ variant: {
+ audience: AccountAudience;
+ detailLabel?: string | null;
+ compactDetailLabel?: string | null;
+ },
+ quota?: unknown
+) {
+ return resolveCodexBadge(
+ getCodexIdentityBadge({
+ audience: variant.audience,
+ detailLabel: variant.detailLabel,
+ compactDetailLabel: variant.compactDetailLabel,
+ }),
+ getCodexQuotaBadge(quota)
+ ).audience;
}
function getVariantCompactDetailLabel(
@@ -173,9 +185,7 @@ function getVariantCompactDetailLabel(
},
quota?: unknown
) {
- return (
- variant.compactDetailLabel ?? variant.detailLabel ?? getCodexPlanDetailLabel(quota) ?? null
- );
+ return getVariantDetailLabel(variant, quota);
}
function getDetailedAudienceLabel(audience: AccountAudience): string | null {
@@ -191,7 +201,7 @@ function getVariantAudience(
},
quota?: unknown
) {
- return resolveCodexAudience(variant.audience, getCodexPlanAudience(quota));
+ return getVariantBadgeAudience(variant, quota);
}
function getVariantInlineLabel(
@@ -204,14 +214,7 @@ function getVariantInlineLabel(
},
quota?: unknown
) {
- const detailLabel = getVariantDetailLabel(variant, quota);
- const audience = getVariantAudience(variant, quota);
- const audienceLabel =
- variant.audience === audience
- ? (variant.audienceLabel ?? getDetailedAudienceLabel(audience))
- : getDetailedAudienceLabel(audience);
- const composedLabel = [audienceLabel, detailLabel].filter(Boolean).join(' · ');
- return composedLabel || variant.inlineLabel || null;
+ return getVariantDetailLabel(variant, quota) || variant.inlineLabel || null;
}
function getVariantMarkerLabel(
@@ -227,8 +230,7 @@ function getVariantMarkerLabel(
const audience = getVariantAudience(variant, quota);
const compactDetailLabel = getVariantCompactDetailLabel(variant, quota);
if (audience === 'business') {
- const businessVariantCount = audienceCounts.get('business') ?? 0;
- return businessVariantCount > 1 && compactDetailLabel ? compactDetailLabel : 'Biz';
+ return 'Biz';
}
if (audience === 'free') {
return compactDetailLabel ?? 'Free';
@@ -237,11 +239,7 @@ function getVariantMarkerLabel(
return compactDetailLabel ?? 'Pers';
}
- const normalizedFallback =
- compactDetailLabel?.trim() ||
- getDetailedAudienceLabel(audience) ||
- variant.audienceLabel?.trim() ||
- variant.detailLabel?.trim();
+ const normalizedFallback = compactDetailLabel?.trim() || getDetailedAudienceLabel(audience);
return normalizedFallback?.[0]?.toUpperCase() ?? '?';
}
diff --git a/ui/src/components/account/shared/account-surface-card.tsx b/ui/src/components/account/shared/account-surface-card.tsx
index 3de92fe5..ad61b231 100644
--- a/ui/src/components/account/shared/account-surface-card.tsx
+++ b/ui/src/components/account/shared/account-surface-card.tsx
@@ -2,7 +2,11 @@ import type { ReactNode } from 'react';
import { Badge } from '@/components/ui/badge';
import { PRIVACY_BLUR_CLASS } from '@/contexts/privacy-context';
import type { UnifiedQuotaResult } from '@/hooks/use-cliproxy-stats';
-import { formatAccountVariantPart, getAccountIdentityPresentation } from '@/lib/account-identity';
+import {
+ getAccountIdentityPresentation,
+ getCodexIdentityBadge,
+ type CodexIdentityBadge,
+} from '@/lib/account-identity';
import { cn } from '@/lib/utils';
import { Pause, Star, User } from 'lucide-react';
import { useTranslation } from 'react-i18next';
@@ -66,13 +70,6 @@ function getCompactAudienceBadgeLabel(audience: AccountAudience, t: (key: string
return '?';
}
-function getDetailedAudienceLabel(audience: AccountAudience): string | null {
- if (audience === 'business') return 'Business';
- if (audience === 'free') return 'Free';
- if (audience === 'personal') return 'Personal';
- return null;
-}
-
function getCompactDetailBadgeClass(audience: AccountAudience) {
if (audience === 'business') {
return 'border-sky-500/30 bg-sky-500/10 text-sky-700 dark:border-sky-400/30 dark:bg-sky-500/15 dark:text-sky-200';
@@ -102,56 +99,51 @@ function resolveEffectiveTier(
return tier;
}
-function getCodexPlanAudience(quota: UnifiedQuotaResult | undefined): AccountAudience {
+function getCodexQuotaBadge(quota: UnifiedQuotaResult | undefined): CodexIdentityBadge {
if (!quota || !('planType' in quota) || !quota.planType) {
- return 'unknown';
+ return { audience: 'unknown', label: null };
}
- if (quota.planType === 'team') return 'business';
- if (quota.planType === 'free') return 'free';
- if (quota.planType === 'plus' || quota.planType === 'pro') return 'personal';
- return 'unknown';
+ if (quota.planType === 'team') {
+ return { audience: 'business', label: 'Business' };
+ }
+
+ if (quota.planType === 'free') {
+ return { audience: 'free', label: 'Free' };
+ }
+
+ if (quota.planType === 'plus') {
+ return { audience: 'personal', label: 'Plus' };
+ }
+
+ if (quota.planType === 'pro') {
+ return { audience: 'personal', label: 'Pro' };
+ }
+
+ return { audience: 'unknown', label: null };
}
-function resolveCodexAudience(
- identityAudience: AccountAudience,
- planAudience: AccountAudience
-): AccountAudience {
- if (planAudience === 'unknown') {
- return identityAudience;
+function resolveCodexBadge(
+ identityBadge: CodexIdentityBadge,
+ quotaBadge: CodexIdentityBadge
+): CodexIdentityBadge {
+ if (!quotaBadge.label) {
+ return identityBadge;
}
- if (planAudience === 'business') {
- return 'business';
+ if (
+ quotaBadge.label === 'Business' ||
+ quotaBadge.label === 'Plus' ||
+ quotaBadge.label === 'Pro'
+ ) {
+ return quotaBadge;
}
- if (identityAudience === 'business') {
- return 'business';
+ if (quotaBadge.label === 'Free' && identityBadge.label && identityBadge.label !== 'Free') {
+ return identityBadge;
}
- if (planAudience === 'personal') {
- return 'personal';
- }
-
- if (planAudience === 'free') {
- return identityAudience === 'unknown' || identityAudience === 'free'
- ? 'free'
- : identityAudience;
- }
-
- return identityAudience;
-}
-
-function getCodexPlanDetailLabel(quota: UnifiedQuotaResult | undefined): string | null {
- if (!quota || !('planType' in quota) || !quota.planType) {
- return null;
- }
-
- if (quota.planType === 'free' || quota.planType === 'team') {
- return null;
- }
-
- return formatAccountVariantPart(quota.planType);
+ return quotaBadge;
}
export function AccountSurfaceCard({
@@ -182,22 +174,10 @@ export function AccountSurfaceCard({
const title = displayEmail || identity.email || accountId;
const normalizedProvider = provider.toLowerCase();
const effectiveTier = resolveEffectiveTier(tier, quota);
- const codexPlanAudience =
- normalizedProvider === 'codex' ? getCodexPlanAudience(quota) : 'unknown';
- const codexPlanDetailLabel =
- normalizedProvider === 'codex' ? getCodexPlanDetailLabel(quota) : null;
- const effectiveAudience =
+ const effectiveCodexBadge =
normalizedProvider === 'codex'
- ? resolveCodexAudience(identity.audience, codexPlanAudience)
- : identity.audience !== 'unknown'
- ? identity.audience
- : codexPlanAudience;
- const effectiveAudienceLabel =
- identity.audience === effectiveAudience
- ? (identity.audienceLabel ?? getDetailedAudienceLabel(effectiveAudience))
- : getDetailedAudienceLabel(effectiveAudience);
- const resolvedDetailLabel = identity.detailLabel ?? codexPlanDetailLabel;
- const resolvedCompactDetailLabel = identity.compactDetailLabel ?? codexPlanDetailLabel;
+ ? resolveCodexBadge(getCodexIdentityBadge(identity), getCodexQuotaBadge(quota))
+ : null;
const showTierBadge =
(normalizedProvider === 'agy' ||
normalizedProvider === 'antigravity' ||
@@ -218,26 +198,38 @@ export function AccountSurfaceCard({
{effectiveTier}
)}
- {effectiveAudienceLabel && (
-
+ {effectiveCodexBadge.label}
+
+ )
+ : identity.audienceLabel && (
+
+ {getCompactAudienceBadgeLabel(identity.audience, t)}
+
)}
- >
- {getCompactAudienceBadgeLabel(effectiveAudience, t)}
-
- )}
- {resolvedCompactDetailLabel && (
+ {normalizedProvider !== 'codex' && identity.compactDetailLabel && (
- {resolvedCompactDetailLabel}
+ {identity.compactDetailLabel}
)}
{paused && (
@@ -295,20 +287,31 @@ export function AccountSurfaceCard({
{title}
{isCompact && (compactMetaBadges ?? defaultCompactMetaBadges)}
- {!isCompact && effectiveAudienceLabel && (
+ {!isCompact && normalizedProvider === 'codex' && effectiveCodexBadge?.label && (