fix(accounts-ui): move action center content into left column

This commit is contained in:
Tam Nhu Tran
2026-02-26 21:11:35 +07:00
parent 1708128a62
commit cfdad81bee
+162 -228
View File
@@ -5,15 +5,7 @@
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import {
AlertTriangle,
ArrowRight,
ChevronDown,
ChevronLeft,
Plus,
Users,
Zap,
} from 'lucide-react';
import { AlertTriangle, ArrowRight, ChevronDown, Plus, Users, Zap } from 'lucide-react';
import { AccountsTable } from '@/components/account/accounts-table';
import { CreateAuthProfileDialog } from '@/components/account/create-auth-profile-dialog';
import { HistorySyncLearningMap } from '@/components/account/history-sync-learning-map';
@@ -31,7 +23,6 @@ export function AccountsPage() {
const { data, isLoading } = useAccounts();
const confirmLegacyMutation = useConfirmLegacyAccountPolicies();
const [createDialogOpen, setCreateDialogOpen] = useState(false);
const [showGuideRail, setShowGuideRail] = useState(true);
const [guideOpen, setGuideOpen] = useState(false);
const authAccounts = data?.accounts || [];
@@ -63,34 +54,69 @@ export function AccountsPage() {
return (
<>
<div className="h-[calc(100vh-100px)] hidden lg:flex">
{/* Left rail */}
<div className="w-80 border-r flex flex-col bg-muted/30 shrink-0">
<div className="p-4 border-b bg-background space-y-3">
<div>
<div className="flex items-center gap-2">
<Users className="h-5 w-5 text-primary" />
<h1 className="font-semibold">Accounts</h1>
</div>
<p className="mt-1 text-xs text-muted-foreground">
Dedicated
<code className="mx-1 rounded bg-muted px-1 py-0.5">ccs auth</code>
continuity controls.
</p>
{/* Left action column */}
<div className="w-80 border-r flex flex-col bg-muted/20 shrink-0">
<div className="p-4 border-b bg-background space-y-2">
<div className="flex items-center gap-2">
<Users className="h-5 w-5 text-primary" />
<h1 className="font-semibold">Accounts</h1>
<Badge variant="outline" className="ml-auto">
Action Center
</Badge>
</div>
<div className="grid grid-cols-1 gap-2">
<Button onClick={() => setCreateDialogOpen(true)} size="sm" className="justify-start">
<Plus className="w-4 h-4 mr-2" />
Create Account
</Button>
</div>
<p className="text-[11px] text-muted-foreground">
Pool auth actions live in Action Center to avoid duplicate controls.
<p className="text-xs text-muted-foreground">
Manage
<code className="mx-1 rounded bg-muted px-1 py-0.5">ccs auth</code>
accounts and pool onboarding from one panel.
</p>
</div>
<ScrollArea className="flex-1">
<div className="p-3 space-y-3">
<div className="p-4 space-y-3">
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-sm">Immediate Actions</CardTitle>
</CardHeader>
<CardContent className="space-y-2">
<Button
size="sm"
className="w-full justify-start"
onClick={() => setCreateDialogOpen(true)}
>
<Plus className="w-4 h-4 mr-2" />
Create Account
</Button>
<Button
size="sm"
className="w-full justify-start"
onClick={handleOpenClaudePoolAuth}
>
<Zap className="w-4 h-4 mr-2" />
Authenticate Claude in Pool
</Button>
<Button
variant="outline"
size="sm"
className="w-full justify-start"
onClick={handleOpenClaudePool}
>
Open Claude Pool Settings
<ArrowRight className="w-4 h-4 ml-auto" />
</Button>
<Button
variant="outline"
size="sm"
className="w-full justify-start"
onClick={handleConfirmLegacy}
disabled={confirmLegacyMutation.isPending || legacyTargetCount === 0}
>
{confirmLegacyMutation.isPending
? 'Confirming Legacy Policies...'
: `Confirm Legacy Policies (${legacyTargetCount})`}
</Button>
</CardContent>
</Card>
{hasLegacyFollowUp && (
<section className="space-y-2">
<p className="text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
@@ -116,218 +142,126 @@ export function AccountsPage() {
)}
</div>
</div>
<Button
variant="secondary"
size="sm"
className="w-full justify-start"
onClick={handleConfirmLegacy}
disabled={confirmLegacyMutation.isPending || legacyTargetCount === 0}
>
{confirmLegacyMutation.isPending
? 'Confirming Legacy Accounts...'
: `Confirm Current Policy for ${legacyTargetCount} Legacy Account${legacyTargetCount > 1 ? 's' : ''}`}
</Button>
</div>
</section>
)}
{!hasLegacyFollowUp && (
<div className="rounded-md border bg-background px-3 py-2 text-xs text-muted-foreground">
No legacy follow-up pending. Manage pool auth from Action Center.
No legacy follow-up pending.
</div>
)}
<Collapsible open={guideOpen} onOpenChange={setGuideOpen}>
<Card>
<CardHeader className="pb-2">
<CollapsibleTrigger asChild>
<Button variant="ghost" className="h-auto w-full justify-between px-0 py-0">
<div className="text-left">
<CardTitle className="text-sm">Continuity Guide</CardTitle>
<CardDescription className="mt-1">
Expand only when needed.
</CardDescription>
</div>
<ChevronDown
className={cn('h-4 w-4 transition-transform', guideOpen && 'rotate-180')}
/>
</Button>
</CollapsibleTrigger>
</CardHeader>
<CollapsibleContent>
<CardContent className="space-y-3 text-xs text-muted-foreground">
<div className="rounded-md border p-2.5">
<p className="font-semibold text-foreground">Shared Standard</p>
<p className="mt-1">
Project workspace sync only. Best default for most teams.
</p>
</div>
<div className="rounded-md border p-2.5">
<p className="font-semibold text-foreground">Shared Deeper</p>
<p className="mt-1">
Adds <code>session-env</code>, <code>file-history</code>,{' '}
<code>shell-snapshots</code>, <code>todos</code>.
</p>
</div>
<div className="rounded-md border p-2.5">
<p className="font-semibold text-foreground">Isolated</p>
<p className="mt-1">No link. Best for strict separation.</p>
</div>
</CardContent>
</CollapsibleContent>
</Card>
</Collapsible>
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-sm">Quick Commands</CardTitle>
<CardDescription>Copy and run in terminal.</CardDescription>
</CardHeader>
<CardContent className="space-y-2">
<div className="rounded-md border bg-background px-2 py-2 font-mono text-[11px] flex items-start gap-2">
<span className="flex-1 break-all">
ccs auth create work --context-group sprint-a --deeper-continuity
</span>
<CopyButton
value="ccs auth create work --context-group sprint-a --deeper-continuity"
size="icon"
/>
</div>
<div className="rounded-md border bg-background px-2 py-2 font-mono text-[11px] flex items-start gap-2">
<span className="flex-1 break-all">ccs cliproxy auth claude</span>
<CopyButton value="ccs cliproxy auth claude" size="icon" />
</div>
</CardContent>
</Card>
</div>
</ScrollArea>
</div>
{/* Main workspace */}
<div className="flex-1 min-w-0 flex">
{/* Table column */}
<div className="flex-1 min-w-0 flex flex-col border-r bg-background">
<div className="px-5 py-4 border-b bg-background">
<div className="flex items-center gap-2">
<Badge variant="outline">ccs auth Workspace</Badge>
<Badge variant="secondary">History Sync Controls</Badge>
<Button
variant="outline"
size="sm"
className="ml-auto"
onClick={() => setShowGuideRail((prev) => !prev)}
>
{showGuideRail ? 'Hide Action Center' : 'Show Action Center'}
</Button>
</div>
<h2 className="mt-2 text-xl font-semibold tracking-tight">Auth Accounts</h2>
<p className="mt-1 text-sm text-muted-foreground">
This table is intentionally scoped to
<code className="mx-1 rounded bg-muted px-1 py-0.5">ccs auth</code>
accounts. Use
<code className="mx-1 rounded bg-muted px-1 py-0.5">Sync</code>
for mode/group/depth changes.
</p>
</div>
<div className="flex-1 min-h-0 p-5 space-y-4 overflow-y-auto">
<HistorySyncLearningMap
isolatedCount={isolatedCount}
sharedStandardCount={sharedStandardCount}
deeperSharedCount={deeperSharedCount}
sharedGroups={sharedGroups}
legacyTargetCount={legacyTargetCount}
cliproxyCount={cliproxyCount}
/>
<Card className="flex flex-col">
<CardHeader className="pb-3">
<CardTitle className="text-lg">Account Matrix</CardTitle>
<CardDescription>
Shared total: {sharedCount}. Actions include Sync settings and legacy
confirmation.
</CardDescription>
</CardHeader>
<CardContent>
{isLoading ? (
<div className="text-muted-foreground">Loading accounts...</div>
) : (
<AccountsTable data={authAccounts} defaultAccount={data?.default ?? null} />
)}
</CardContent>
</Card>
<div className="flex-1 min-w-0 flex flex-col bg-background">
<div className="px-5 py-4 border-b bg-background">
<div className="flex items-center gap-2">
<Badge variant="outline">ccs auth Workspace</Badge>
<Badge variant="secondary">History Sync Controls</Badge>
</div>
<h2 className="mt-2 text-xl font-semibold tracking-tight">Auth Accounts</h2>
<p className="mt-1 text-sm text-muted-foreground">
This table is intentionally scoped to
<code className="mx-1 rounded bg-muted px-1 py-0.5">ccs auth</code>
accounts. Use
<code className="mx-1 rounded bg-muted px-1 py-0.5">Sync</code>
for mode/group/depth changes.
</p>
</div>
{/* Right action center */}
{showGuideRail ? (
<div className="w-80 shrink-0 flex flex-col bg-muted/20">
<div className="p-4 border-b bg-background flex items-start justify-between gap-3">
<div>
<h3 className="font-semibold">Action Center</h3>
<p className="mt-1 text-xs text-muted-foreground">
High-value actions for pool auth and legacy cleanup.
</p>
</div>
<Button variant="ghost" size="icon" onClick={() => setShowGuideRail(false)}>
<ChevronLeft className="h-4 w-4" />
</Button>
</div>
<div className="flex-1 min-h-0 p-5 space-y-4 overflow-y-auto">
<HistorySyncLearningMap
isolatedCount={isolatedCount}
sharedStandardCount={sharedStandardCount}
deeperSharedCount={deeperSharedCount}
sharedGroups={sharedGroups}
legacyTargetCount={legacyTargetCount}
cliproxyCount={cliproxyCount}
/>
<ScrollArea className="flex-1">
<div className="p-4 space-y-3">
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-sm">Immediate Actions</CardTitle>
</CardHeader>
<CardContent className="space-y-2">
<Button
size="sm"
className="w-full justify-start"
onClick={handleOpenClaudePoolAuth}
>
<Zap className="w-4 h-4 mr-2" />
Authenticate Claude in Pool
</Button>
<Button
variant="outline"
size="sm"
className="w-full justify-start"
onClick={handleOpenClaudePool}
>
Open Claude Pool Settings
<ArrowRight className="w-4 h-4 ml-auto" />
</Button>
<Button
variant="outline"
size="sm"
className="w-full justify-start"
onClick={handleConfirmLegacy}
disabled={confirmLegacyMutation.isPending || legacyTargetCount === 0}
>
{confirmLegacyMutation.isPending
? 'Confirming Legacy Policies...'
: `Confirm Legacy Policies (${legacyTargetCount})`}
</Button>
</CardContent>
</Card>
<Collapsible open={guideOpen} onOpenChange={setGuideOpen}>
<Card>
<CardHeader className="pb-2">
<CollapsibleTrigger asChild>
<Button
variant="ghost"
className="h-auto w-full justify-between px-0 py-0"
>
<div className="text-left">
<CardTitle className="text-sm">Continuity Guide</CardTitle>
<CardDescription className="mt-1">
Expand only when needed.
</CardDescription>
</div>
<ChevronDown
className={cn(
'h-4 w-4 transition-transform',
guideOpen && 'rotate-180'
)}
/>
</Button>
</CollapsibleTrigger>
</CardHeader>
<CollapsibleContent>
<CardContent className="space-y-3 text-xs text-muted-foreground">
<div className="rounded-md border p-2.5">
<p className="font-semibold text-foreground">Shared Standard</p>
<p className="mt-1">
Project workspace sync only. Best default for most teams.
</p>
</div>
<div className="rounded-md border p-2.5">
<p className="font-semibold text-foreground">Shared Deeper</p>
<p className="mt-1">
Adds <code>session-env</code>, <code>file-history</code>,{' '}
<code>shell-snapshots</code>, <code>todos</code>.
</p>
</div>
<div className="rounded-md border p-2.5">
<p className="font-semibold text-foreground">Isolated</p>
<p className="mt-1">No link. Best for strict separation.</p>
</div>
</CardContent>
</CollapsibleContent>
</Card>
</Collapsible>
<Card>
<CardHeader className="pb-2">
<CardTitle className="text-sm">Quick Commands</CardTitle>
<CardDescription>Copy and run in terminal.</CardDescription>
</CardHeader>
<CardContent className="space-y-2">
<div className="rounded-md border bg-background px-2 py-2 font-mono text-[11px] flex items-start gap-2">
<span className="flex-1 break-all">
ccs auth create work --context-group sprint-a --deeper-continuity
</span>
<CopyButton
value="ccs auth create work --context-group sprint-a --deeper-continuity"
size="icon"
/>
</div>
<div className="rounded-md border bg-background px-2 py-2 font-mono text-[11px] flex items-start gap-2">
<span className="flex-1 break-all">ccs cliproxy auth claude</span>
<CopyButton value="ccs cliproxy auth claude" size="icon" />
</div>
</CardContent>
</Card>
</div>
</ScrollArea>
</div>
) : (
<div className="w-14 shrink-0 border-l bg-muted/20 flex items-start justify-center pt-3">
<Button variant="ghost" size="icon" onClick={() => setShowGuideRail(true)}>
<ChevronLeft className="h-4 w-4 rotate-180" />
</Button>
</div>
)}
<Card className="flex flex-col">
<CardHeader className="pb-3">
<CardTitle className="text-lg">Account Matrix</CardTitle>
<CardDescription>
Shared total: {sharedCount}. Actions include Sync settings and legacy
confirmation.
</CardDescription>
</CardHeader>
<CardContent>
{isLoading ? (
<div className="text-muted-foreground">Loading accounts...</div>
) : (
<AccountsTable data={authAccounts} defaultAccount={data?.default ?? null} />
)}
</CardContent>
</Card>
</div>
</div>
</div>