mirror of
https://github.com/tiennm99/ccs.git
synced 2026-09-02 18:18:43 +00:00
feat(ui): add visible pause toggle button to account item cards
- add pause/play button left of user avatar - paused accounts show play icon (green) and dimmed card - active accounts show pause icon - includes loading spinner and tooltip
This commit is contained in:
@@ -6,8 +6,6 @@
|
|||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Badge } from '@/components/ui/badge';
|
import { Badge } from '@/components/ui/badge';
|
||||||
import { Progress } from '@/components/ui/progress';
|
import { Progress } from '@/components/ui/progress';
|
||||||
import { Switch } from '@/components/ui/switch';
|
|
||||||
import { Checkbox } from '@/components/ui/checkbox';
|
|
||||||
import {
|
import {
|
||||||
DropdownMenu,
|
DropdownMenu,
|
||||||
DropdownMenuContent,
|
DropdownMenuContent,
|
||||||
@@ -25,10 +23,10 @@ import {
|
|||||||
CheckCircle2,
|
CheckCircle2,
|
||||||
HelpCircle,
|
HelpCircle,
|
||||||
Pause,
|
Pause,
|
||||||
|
Play,
|
||||||
AlertCircle,
|
AlertCircle,
|
||||||
AlertTriangle,
|
AlertTriangle,
|
||||||
FolderCode,
|
FolderCode,
|
||||||
Radio,
|
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import {
|
import {
|
||||||
cn,
|
cn,
|
||||||
@@ -95,15 +93,10 @@ export function AccountItem({
|
|||||||
onSetDefault,
|
onSetDefault,
|
||||||
onRemove,
|
onRemove,
|
||||||
onPauseToggle,
|
onPauseToggle,
|
||||||
onSoloMode,
|
|
||||||
isRemoving,
|
isRemoving,
|
||||||
isPausingAccount,
|
isPausingAccount,
|
||||||
isSoloingAccount,
|
|
||||||
privacyMode,
|
privacyMode,
|
||||||
showQuota,
|
showQuota,
|
||||||
selectable,
|
|
||||||
selected,
|
|
||||||
onSelectChange,
|
|
||||||
}: AccountItemProps) {
|
}: AccountItemProps) {
|
||||||
// Fetch runtime stats to get actual lastUsedAt (more accurate than file state)
|
// Fetch runtime stats to get actual lastUsedAt (more accurate than file state)
|
||||||
const { data: stats } = useCliproxyStats(showQuota);
|
const { data: stats } = useCliproxyStats(showQuota);
|
||||||
@@ -131,18 +124,37 @@ export function AccountItem({
|
|||||||
className={cn(
|
className={cn(
|
||||||
'flex flex-col gap-2 p-3 rounded-lg border transition-colors',
|
'flex flex-col gap-2 p-3 rounded-lg border transition-colors',
|
||||||
account.isDefault ? 'border-primary/30 bg-primary/5' : 'border-border hover:bg-muted/30',
|
account.isDefault ? 'border-primary/30 bg-primary/5' : 'border-border hover:bg-muted/30',
|
||||||
account.paused && 'opacity-50 border-muted'
|
account.paused && 'opacity-75'
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
{/* Multi-select checkbox */}
|
{/* Pause/Resume toggle button - visible left of avatar */}
|
||||||
{selectable && (
|
{onPauseToggle && (
|
||||||
<Checkbox
|
<TooltipProvider>
|
||||||
checked={selected}
|
<Tooltip>
|
||||||
onCheckedChange={(checked) => onSelectChange?.(!!checked)}
|
<TooltipTrigger asChild>
|
||||||
aria-label={`Select ${account.email || account.id}`}
|
<Button
|
||||||
/>
|
variant="ghost"
|
||||||
|
size="icon"
|
||||||
|
className="h-7 w-7 shrink-0"
|
||||||
|
onClick={() => onPauseToggle(!account.paused)}
|
||||||
|
disabled={isPausingAccount}
|
||||||
|
>
|
||||||
|
{isPausingAccount ? (
|
||||||
|
<Loader2 className="w-4 h-4 animate-spin" />
|
||||||
|
) : account.paused ? (
|
||||||
|
<Play className="w-4 h-4 text-emerald-500" />
|
||||||
|
) : (
|
||||||
|
<Pause className="w-4 h-4 text-muted-foreground hover:text-foreground" />
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent side="top">
|
||||||
|
{account.paused ? 'Resume account' : 'Pause account'}
|
||||||
|
</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
|
</TooltipProvider>
|
||||||
)}
|
)}
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
@@ -242,80 +254,47 @@ export function AccountItem({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Inline controls: Solo button + Toggle switch */}
|
<DropdownMenu>
|
||||||
<div className="flex items-center gap-1.5">
|
<DropdownMenuTrigger asChild>
|
||||||
{/* Solo mode button */}
|
<Button variant="ghost" size="icon" className="h-7 w-7">
|
||||||
{onSoloMode && (
|
<MoreHorizontal className="w-4 h-4" />
|
||||||
<TooltipProvider>
|
</Button>
|
||||||
<Tooltip>
|
</DropdownMenuTrigger>
|
||||||
<TooltipTrigger asChild>
|
<DropdownMenuContent align="end">
|
||||||
<Button
|
{!account.isDefault && (
|
||||||
variant="ghost"
|
<DropdownMenuItem onClick={onSetDefault}>
|
||||||
size="icon"
|
<Star className="w-4 h-4 mr-2" />
|
||||||
className="h-6 w-6"
|
Set as default
|
||||||
onClick={onSoloMode}
|
|
||||||
disabled={isSoloingAccount || account.paused}
|
|
||||||
aria-label="Activate only this account"
|
|
||||||
>
|
|
||||||
{isSoloingAccount ? (
|
|
||||||
<Loader2 className="h-3.5 w-3.5 animate-spin" />
|
|
||||||
) : (
|
|
||||||
<Radio className="h-3.5 w-3.5" />
|
|
||||||
)}
|
|
||||||
</Button>
|
|
||||||
</TooltipTrigger>
|
|
||||||
<TooltipContent>Activate only this account</TooltipContent>
|
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Pause/Resume toggle switch */}
|
|
||||||
{onPauseToggle && (
|
|
||||||
<TooltipProvider>
|
|
||||||
<Tooltip>
|
|
||||||
<TooltipTrigger asChild>
|
|
||||||
<div>
|
|
||||||
<Switch
|
|
||||||
checked={!account.paused}
|
|
||||||
onCheckedChange={(checked) => onPauseToggle(!checked)}
|
|
||||||
disabled={isPausingAccount}
|
|
||||||
aria-label={account.paused ? 'Resume account' : 'Pause account'}
|
|
||||||
className="scale-90"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</TooltipTrigger>
|
|
||||||
<TooltipContent>
|
|
||||||
{account.paused ? 'Resume account' : 'Pause account'}
|
|
||||||
</TooltipContent>
|
|
||||||
</Tooltip>
|
|
||||||
</TooltipProvider>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Dropdown menu for other actions */}
|
|
||||||
<DropdownMenu>
|
|
||||||
<DropdownMenuTrigger asChild>
|
|
||||||
<Button variant="ghost" size="icon" className="h-7 w-7">
|
|
||||||
<MoreHorizontal className="w-4 h-4" />
|
|
||||||
</Button>
|
|
||||||
</DropdownMenuTrigger>
|
|
||||||
<DropdownMenuContent align="end">
|
|
||||||
{!account.isDefault && (
|
|
||||||
<DropdownMenuItem onClick={onSetDefault}>
|
|
||||||
<Star className="w-4 h-4 mr-2" />
|
|
||||||
Set as default
|
|
||||||
</DropdownMenuItem>
|
|
||||||
)}
|
|
||||||
<DropdownMenuItem
|
|
||||||
className="text-destructive focus:text-destructive"
|
|
||||||
onClick={onRemove}
|
|
||||||
disabled={isRemoving}
|
|
||||||
>
|
|
||||||
<Trash2 className="w-4 h-4 mr-2" />
|
|
||||||
{isRemoving ? 'Removing...' : 'Remove account'}
|
|
||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
</DropdownMenuContent>
|
)}
|
||||||
</DropdownMenu>
|
{onPauseToggle && (
|
||||||
</div>
|
<DropdownMenuItem
|
||||||
|
onClick={() => onPauseToggle(!account.paused)}
|
||||||
|
disabled={isPausingAccount}
|
||||||
|
>
|
||||||
|
{account.paused ? (
|
||||||
|
<>
|
||||||
|
<Play className="w-4 h-4 mr-2" />
|
||||||
|
{isPausingAccount ? 'Resuming...' : 'Resume account'}
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<Pause className="w-4 h-4 mr-2" />
|
||||||
|
{isPausingAccount ? 'Pausing...' : 'Pause account'}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</DropdownMenuItem>
|
||||||
|
)}
|
||||||
|
<DropdownMenuItem
|
||||||
|
className="text-destructive focus:text-destructive"
|
||||||
|
onClick={onRemove}
|
||||||
|
disabled={isRemoving}
|
||||||
|
>
|
||||||
|
<Trash2 className="w-4 h-4 mr-2" />
|
||||||
|
{isRemoving ? 'Removing...' : 'Remove account'}
|
||||||
|
</DropdownMenuItem>
|
||||||
|
</DropdownMenuContent>
|
||||||
|
</DropdownMenu>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Quota bar - supports all providers with quota API */}
|
{/* Quota bar - supports all providers with quota API */}
|
||||||
|
|||||||
Reference in New Issue
Block a user