diff --git a/ui/src/pages/home.tsx b/ui/src/pages/home.tsx index ca463e7f..ae05f753 100644 --- a/ui/src/pages/home.tsx +++ b/ui/src/pages/home.tsx @@ -1,258 +1,382 @@ import { useNavigate } from 'react-router-dom'; import { Card, CardContent } from '@/components/ui/card'; -import { StatCard } from '@/components/stat-card'; -import { HeroSection } from '@/components/hero-section'; -import { QuickCommands } from '@/components/quick-commands'; import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'; import { Skeleton } from '@/components/ui/skeleton'; +import { Badge } from '@/components/ui/badge'; import { Key, Zap, Users, - Activity, - Plus, + Search, Stethoscope, - BookOpen, - FolderOpen, AlertTriangle, + Terminal, + ArrowRight, + Command, + Sparkles, } from 'lucide-react'; import { useOverview } from '@/hooks/use-overview'; import { useSharedSummary } from '@/hooks/use-shared'; +import { cn } from '@/lib/utils'; -const HEALTH_VARIANTS = { - ok: 'success', - warning: 'warning', - error: 'error', +const HEALTH_STATUS = { + ok: { label: 'Operational', class: 'bg-emerald-500/20 text-emerald-500 border-emerald-500/30' }, + warning: { label: 'Degraded', class: 'bg-amber-500/20 text-amber-500 border-amber-500/30' }, + error: { label: 'Issues', class: 'bg-red-500/20 text-red-500 border-red-500/30' }, } as const; +// Three Pillars configuration - matches README branding +const THREE_PILLARS = [ + { + id: 'api', + title: 'API Keys', + description: 'Configure GLM, Kimi with your own API keys', + icon: Key, + path: '/api', + gradient: 'from-orange-500/20 to-amber-500/10', + iconBg: 'bg-orange-500/20 text-orange-500', + }, + { + id: 'oauth', + title: 'OAuth Providers', + description: 'Gemini, Codex, Antigravity - zero config', + icon: Zap, + path: '/cliproxy', + gradient: 'from-blue-500/20 to-cyan-500/10', + iconBg: 'bg-blue-500/20 text-blue-500', + }, + { + id: 'accounts', + title: 'Multiple Accounts', + description: 'Isolated Claude instances for work & personal', + icon: Users, + path: '/accounts', + gradient: 'from-violet-500/20 to-purple-500/10', + iconBg: 'bg-violet-500/20 text-violet-500', + }, +]; + +// Quick launch shortcuts +const QUICK_LAUNCH = [ + { key: 'G', label: 'Gemini', command: 'ccs gemini' }, + { key: 'C', label: 'Codex', command: 'ccs codex' }, + { key: 'A', label: 'Agy', command: 'ccs agy' }, +]; + export function HomePage() { const navigate = useNavigate(); const { data: overview, isLoading: isOverviewLoading } = useOverview(); const { data: shared, isLoading: isSharedLoading } = useSharedSummary(); if (isOverviewLoading || isSharedLoading) { - return ( -
- {/* Hero Skeleton */} -
-
- -
- - -
-
-
- - {/* Stats Skeleton */} -
- {[1, 2, 3, 4].map((i) => ( -
-
- -
- - -
-
-
- ))} -
- - {/* Quick Actions Skeleton */} -
- -
- - - -
-
- - {/* Quick Commands Skeleton */} -
- -
- {[1, 2, 3, 4].map((i) => ( - - ))} -
-
-
- ); + return ; } - const healthVariant = overview?.health - ? HEALTH_VARIANTS[overview.health.status as keyof typeof HEALTH_VARIANTS] - : undefined; + const healthInfo = overview?.health?.status + ? HEALTH_STATUS[overview.health.status as keyof typeof HEALTH_STATUS] + : HEALTH_STATUS.ok; + + const pillarCounts = { + api: overview?.profiles ?? 0, + oauth: overview?.cliproxy ?? 0, + accounts: overview?.accounts ?? 0, + }; return ( -
- {/* Hero Section */} - +
+ {/* Gradient Mesh Background */} +
+
+
+
- {/* Configuration Warning */} - {shared?.symlinkStatus && !shared.symlinkStatus.valid && ( - - - Configuration Required - {shared.symlinkStatus.message} - - )} - - {/* Stats Grid */} -
-
-

System Status

-
-
- navigate('/api')} - /> - navigate('/cliproxy')} - /> - navigate('/accounts')} - /> - navigate('/health')} - /> -
-
- -
- {/* Left Column: Quick Actions & Shared Data */} -
- {/* Quick Actions */} -
-
-

Quick Actions

-
-
- navigate('/api')} - > - -
- -
-
-

New Profile

-

Create a new API profile

-
-
-
- - navigate('/health')} - > - -
- -
-
-

Run Doctor

-

Check system health

-
-
-
- - window.open('https://github.com/kaitranntt/ccs', '_blank')} - > - -
- -
-
-

Documentation

-

View guides & reference

-
-
-
- - navigate('/shared')} - > - -
- -
-
-

Shared Data

-

Manage resources

-
-
-
-
-
- - {/* Shared Data Stats */} -
-
-

Resource Summary

-
- - -
-
- - {shared?.commands ?? 0} - - Commands -
-
- - {shared?.skills ?? 0} - - Skills -
-
- - {shared?.agents ?? 0} - - Agents +
+ {/* Hero Header */} +
+ + +
+
+
+
+ +
+
+

CCS

+

Multi-Account AI Management

+
- - -
-
+
+ + v{overview?.version ?? '0.0.0'} + + + + {healthInfo.label} + +
+
- {/* Right Column: Quick Commands */} -
-

Command Palette

- + {/* Command Palette Search Bar */} +
navigate('/health')}> +
+ + + Search commands, profiles, or run diagnostics... + + + K + +
+
+ + + + + {/* Configuration Warning */} + {shared?.symlinkStatus && !shared.symlinkStatus.valid && ( + + + Configuration Required + {shared.symlinkStatus.message} + + )} + + {/* Three Pillars Section */} +
+
+

The Three Pillars

+ — What do you want to do? +
+
+ {THREE_PILLARS.map((pillar) => { + const Icon = pillar.icon; + const count = pillarCounts[pillar.id as keyof typeof pillarCounts]; + return ( + navigate(pillar.path)} + > + +
+
+ +
+ {count} +
+
+

+ {pillar.title} +

+

+ {pillar.description} +

+
+
+ Configure + +
+
+
+ ); + })} +
+
+ + {/* Quick Launch & Health Grid */} +
+ {/* Quick Launch */} + + +
+

+ + Quick Launch +

+ Click to copy command +
+
+ {QUICK_LAUNCH.map((item) => ( + + ))} + {/* Account shortcuts */} + {overview?.accounts && overview.accounts > 0 && ( + <> + + + )} + {/* Doctor shortcut */} + +
+
+
+ + {/* Health & Resources */} + + + {/* Health Summary */} +
+

+ System Health +

+
navigate('/health')} + > +
+
+ + {overview?.health?.passed ?? 0}/{overview?.health?.total ?? 0} + +
+ checks passed +
+
+ + {/* Resources Summary */} +
+

+ Shared Resources +

+
navigate('/shared')} + > +
+ + {shared?.commands ?? 0} + + cmds +
+
+ + {shared?.skills ?? 0} + + skills +
+
+ + {shared?.agents ?? 0} + + agents +
+
+
+ + +
+
+
+ ); +} + +// Skeleton loader component +function HomePageSkeleton() { + return ( +
+ {/* Hero Skeleton */} +
+
+ +
+ + +
+
+ +
+ + {/* Pillars Skeleton */} +
+ {[1, 2, 3].map((i) => ( +
+
+ + +
+ + +
+ ))} +
+ + {/* Quick Launch Skeleton */} +
+
+ +
+ {[1, 2, 3, 4, 5, 6].map((i) => ( + + ))} +
+
+
+ + + +
+ {[1, 2, 3].map((i) => ( + + ))} +