mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-11 03:13:12 +00:00
feat(ui): add tier badges to account cards
- flow-viz: inline tier badge (ULTRA/PRO) with violet/yellow colors - provider-editor: tier badge on avatar corner (U/P) - subtle design with low opacity backgrounds
This commit is contained in:
1 parent
890fd140f2
commit
31a91f609f
2 files changed
+57
-27
No files matched your search
@@ -99,6 +99,10 @@ export function AccountCard({
|
|||||||
// Show minimum quota of Claude models (primary), fallback to min of all models
|
// Show minimum quota of Claude models (primary), fallback to min of all models
|
||||||
const minQuota = quota?.success ? getMinClaudeQuota(quota.models) : null;
|
const minQuota = quota?.success ? getMinClaudeQuota(quota.models) : null;
|
||||||
|
|
||||||
|
// Tier badge (AGY only) - show P for Pro, U for Ultra
|
||||||
|
const showTierBadge =
|
||||||
|
isAgy && account.tier && account.tier !== 'unknown' && account.tier !== 'free';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
data-account-index={originalIndex}
|
data-account-index={originalIndex}
|
||||||
@@ -124,16 +128,33 @@ export function AccountCard({
|
|||||||
transform: `translate(${offset.x}px, ${offset.y}px)${isDragging ? ' scale(1.05)' : ''}`,
|
transform: `translate(${offset.x}px, ${offset.y}px)${isDragging ? ' scale(1.05)' : ''}`,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<GripVertical className="absolute top-2 right-2 w-4 h-4 text-muted-foreground/40" />
|
{/* Header row: Email + Tier | Pause button | Drag handle */}
|
||||||
<div className="flex items-center gap-1.5 mb-1 mr-4">
|
<div className="flex items-center gap-1.5 mb-1">
|
||||||
<span
|
{/* Email with tier badge inline */}
|
||||||
className={cn(
|
<div className="flex items-center gap-1.5 flex-1 min-w-0">
|
||||||
'text-xs font-semibold text-foreground tracking-tight truncate max-w-[100px]',
|
<span
|
||||||
privacyMode && PRIVACY_BLUR_CLASS
|
className={cn(
|
||||||
|
'text-xs font-semibold text-foreground tracking-tight truncate',
|
||||||
|
privacyMode && PRIVACY_BLUR_CLASS
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{cleanEmail(account.email)}
|
||||||
|
</span>
|
||||||
|
{showTierBadge && (
|
||||||
|
<span
|
||||||
|
className={cn(
|
||||||
|
'text-[7px] font-bold uppercase tracking-wide px-1 py-px rounded shrink-0',
|
||||||
|
account.tier === 'ultra'
|
||||||
|
? 'bg-violet-500/15 text-violet-600 dark:bg-violet-500/25 dark:text-violet-300'
|
||||||
|
: 'bg-yellow-500/15 text-yellow-700 dark:bg-yellow-500/20 dark:text-yellow-400'
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{account.tier}
|
||||||
|
</span>
|
||||||
)}
|
)}
|
||||||
>
|
</div>
|
||||||
{cleanEmail(account.email)}
|
|
||||||
</span>
|
{/* Pause/Resume button */}
|
||||||
{onPauseToggle && (
|
{onPauseToggle && (
|
||||||
<TooltipProvider>
|
<TooltipProvider>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
@@ -167,7 +188,11 @@ export function AccountCard({
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
{/* Drag handle */}
|
||||||
|
<GripVertical className="w-4 h-4 text-muted-foreground/40 shrink-0" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<AccountCardStats
|
<AccountCardStats
|
||||||
success={account.successCount}
|
success={account.successCount}
|
||||||
failure={account.failureCount}
|
failure={account.failureCount}
|
||||||
|
|||||||
@@ -179,13 +179,30 @@ export function AccountItem({
|
|||||||
</Tooltip>
|
</Tooltip>
|
||||||
</TooltipProvider>
|
</TooltipProvider>
|
||||||
)}
|
)}
|
||||||
<div
|
{/* Avatar with tier badge overlay */}
|
||||||
className={cn(
|
<div className="relative shrink-0">
|
||||||
'flex items-center justify-center w-8 h-8 rounded-full',
|
<div
|
||||||
account.isDefault ? 'bg-primary/10' : 'bg-muted'
|
className={cn(
|
||||||
|
'flex items-center justify-center w-8 h-8 rounded-full',
|
||||||
|
account.isDefault ? 'bg-primary/10' : 'bg-muted'
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<User className="w-4 h-4" />
|
||||||
|
</div>
|
||||||
|
{/* Tier badge - fixed position on avatar */}
|
||||||
|
{account.tier && account.tier !== 'unknown' && account.tier !== 'free' && (
|
||||||
|
<span
|
||||||
|
className={cn(
|
||||||
|
'absolute -bottom-0.5 -right-0.5 text-[7px] font-bold uppercase px-1 py-px rounded',
|
||||||
|
'ring-1 ring-background',
|
||||||
|
account.tier === 'ultra'
|
||||||
|
? 'bg-violet-500/20 text-violet-600 dark:bg-violet-500/30 dark:text-violet-300'
|
||||||
|
: 'bg-yellow-500/20 text-yellow-700 dark:bg-yellow-500/25 dark:text-yellow-400'
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{account.tier === 'ultra' ? 'U' : 'P'}
|
||||||
|
</span>
|
||||||
)}
|
)}
|
||||||
>
|
|
||||||
<User className="w-4 h-4" />
|
|
||||||
</div>
|
</div>
|
||||||
<div className="min-w-0 flex-1">
|
<div className="min-w-0 flex-1">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
@@ -200,18 +217,6 @@ export function AccountItem({
|
|||||||
Default
|
Default
|
||||||
</Badge>
|
</Badge>
|
||||||
)}
|
)}
|
||||||
{account.tier && account.tier !== 'unknown' && (
|
|
||||||
<Badge
|
|
||||||
variant="outline"
|
|
||||||
className={cn(
|
|
||||||
'text-[10px] h-4 px-1.5 uppercase',
|
|
||||||
account.tier === 'paid' && 'border-blue-500 text-blue-600',
|
|
||||||
account.tier === 'free' && 'border-gray-400 text-gray-500'
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
{account.tier}
|
|
||||||
</Badge>
|
|
||||||
)}
|
|
||||||
{account.paused && (
|
{account.paused && (
|
||||||
<Badge
|
<Badge
|
||||||
variant="outline"
|
variant="outline"
|
||||||
|
|||||||
Reference in new issue
Block a user