From 0bd54eb26b1d241e0f0872f47c05b8ed5df06225 Mon Sep 17 00:00:00 2001 From: kaitranntt Date: Sat, 13 Dec 2025 02:42:48 -0500 Subject: [PATCH] refactor(ui/home-page): simplify and refactor home page layout Remove deprecated components and logic from the home page, including the progress bar, live clock, and old quick launch sections. Introduce new components (HeroSection, QuickCommands, StatCard) to streamline the layout. Delete unused component. --- ui/src/components/ui/progress.tsx | 25 -- ui/src/pages/home.tsx | 684 ++++++++---------------------- 2 files changed, 172 insertions(+), 537 deletions(-) delete mode 100644 ui/src/components/ui/progress.tsx diff --git a/ui/src/components/ui/progress.tsx b/ui/src/components/ui/progress.tsx deleted file mode 100644 index ed0fffe3..00000000 --- a/ui/src/components/ui/progress.tsx +++ /dev/null @@ -1,25 +0,0 @@ -'use client'; - -import * as React from 'react'; -import * as ProgressPrimitive from '@radix-ui/react-progress'; - -import { cn } from '@/lib/utils'; - -const Progress = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, value, ...props }, ref) => ( - - - -)); -Progress.displayName = ProgressPrimitive.Root.displayName; - -export { Progress }; diff --git a/ui/src/pages/home.tsx b/ui/src/pages/home.tsx index 2d6584a4..31b2bcb7 100644 --- a/ui/src/pages/home.tsx +++ b/ui/src/pages/home.tsx @@ -1,544 +1,204 @@ -import { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; -import { Card, CardContent } from '@/components/ui/card'; +import { Button } from '@/components/ui/button'; +import { Card, CardContent, CardHeader, CardTitle } 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 { Progress } from '@/components/ui/progress'; import { Key, Zap, Users, + Activity, + Plus, Stethoscope, + BookOpen, + FolderOpen, AlertTriangle, ArrowRight, - Activity, - Clock, - CheckCircle2, - XCircle, - AlertCircle, - Cpu, - Database, - Settings, - Terminal, - Sparkles, - Circle, } from 'lucide-react'; -import { CcsLogo } from '@/components/ccs-logo'; import { useOverview } from '@/hooks/use-overview'; import { useSharedSummary } from '@/hooks/use-shared'; -import { useHealth } from '@/hooks/use-health'; -import { useCliproxyAuth } from '@/hooks/use-cliproxy'; -import { cn } from '@/lib/utils'; -// Live clock component -function LiveClock() { - const [time, setTime] = useState(new Date()); - - useEffect(() => { - const timer = setInterval(() => setTime(new Date()), 1000); - return () => clearInterval(timer); - }, []); - - return ( -
- {time.toLocaleTimeString('en-US', { hour12: false })} -
- ); -} - -// Provider status configuration -const PROVIDERS = [ - { id: 'gemini', name: 'Gemini', icon: '◆', color: 'bg-blue-500' }, - { id: 'codex', name: 'Codex', icon: '⬡', color: 'bg-green-500' }, - { id: 'agy', name: 'Antigravity', icon: '◇', color: 'bg-purple-500' }, -] as const; - -// Quick launch shortcuts - icon based -const QUICK_LAUNCH = [ - { - key: 'G', - label: 'Gemini', - command: 'ccs gemini', - color: 'hover:bg-blue-500/20 hover:border-blue-500/50', - }, - { - key: 'C', - label: 'Codex', - command: 'ccs codex', - color: 'hover:bg-green-500/20 hover:border-green-500/50', - }, - { - key: 'A', - label: 'Agy', - command: 'ccs agy', - color: 'hover:bg-purple-500/20 hover:border-purple-500/50', - }, - { - key: 'K', - label: 'Kimi', - command: 'ccs kimi', - color: 'hover:bg-amber-500/20 hover:border-amber-500/50', - }, - { - key: 'L', - label: 'GLM', - command: 'ccs glm', - color: 'hover:bg-orange-500/20 hover:border-orange-500/50', - }, - { - key: 'D', - label: 'Default', - command: 'ccs', - color: 'hover:bg-primary/20 hover:border-primary/50', - }, -]; - -// System status items -const SYSTEM_ITEMS = [ - { id: 'api', label: 'API Keys', icon: Key, path: '/api' }, - { id: 'oauth', label: 'OAuth', icon: Zap, path: '/cliproxy' }, - { id: 'accounts', label: 'Accounts', icon: Users, path: '/accounts' }, - { id: 'health', label: 'Doctor', icon: Stethoscope, path: '/health' }, - { id: 'settings', label: 'Settings', icon: Settings, path: '/settings' }, - { id: 'shared', label: 'Shared', icon: Database, path: '/shared' }, -]; +const HEALTH_VARIANTS = { + ok: 'success', + warning: 'warning', + error: 'error', +} as const; export function HomePage() { const navigate = useNavigate(); const { data: overview, isLoading: isOverviewLoading } = useOverview(); const { data: shared, isLoading: isSharedLoading } = useSharedSummary(); - const { data: health, isLoading: isHealthLoading } = useHealth(); - const { data: cliproxyAuth } = useCliproxyAuth(); - if (isOverviewLoading || isSharedLoading || isHealthLoading) { - return ; + 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) => ( + + ))} +
+
+
+ ); } - const healthPercent = health?.summary - ? Math.round((health.summary.passed / health.summary.total) * 100) - : 0; - const healthStatus = overview?.health?.status ?? 'ok'; - - // Build provider status from auth data - const providerStatus = PROVIDERS.map((provider) => { - const authInfo = cliproxyAuth?.authStatus?.find((a) => a.provider === provider.id); - return { - ...provider, - authenticated: authInfo?.authenticated ?? false, - accounts: authInfo?.accounts?.length ?? 0, - }; - }); + const healthVariant = overview?.health + ? HEALTH_VARIANTS[overview.health.status as keyof typeof HEALTH_VARIANTS] + : undefined; return ( -
- {/* Subtle grid background */} -
-
+ {/* Hero Section */} + + + {/* Configuration Warning */} + {shared?.symlinkStatus && !shared.symlinkStatus.valid && ( + + + Configuration Required + {shared.symlinkStatus.message} + + )} + + {/* Stats Grid */} +
+ navigate('/api')} + /> + navigate('/cliproxy')} + /> + navigate('/accounts')} + /> + navigate('/health')} />
-
- {/* Configuration Warning - Full Width */} - {shared?.symlinkStatus && !shared.symlinkStatus.valid && ( - + + Quick Actions + + + + + + + + + {/* Quick Commands */} + + + {/* Shared Data Summary */} + + + + + Shared Data + + + + +
+
+ {shared?.commands ?? 0} + Commands +
+
+ {shared?.skills ?? 0} + Skills +
+
+ {shared?.agents ?? 0} + Agents +
- - {/* Center Column: Provider Status + Quick Launch */} -
- {/* Provider Status Board */} - - -
-

- - Provider Status -

- -
- -
- {providerStatus.map((provider) => ( -
- {/* Status Indicator */} -
- - {provider.authenticated && ( - - - - )} -
- - {/* Provider Info */} -
-
- {provider.name} - {provider.authenticated && ( - - {provider.accounts} {provider.accounts === 1 ? 'account' : 'accounts'} - - )} -
-

- {provider.authenticated ? 'Connected' : 'Not authenticated'} -

-
- - {/* Status Bar */} -
- [role=progressbar]]:bg-emerald-500' - )} - /> -
-
- ))} -
-
-
- - {/* Quick Launch Grid */} - - -
-

- - Quick Launch -

- Click to copy -
- -
- {QUICK_LAUNCH.map((item) => ( - - ))} -
-
-
-
- - {/* Right Column: Navigation + Resources */} -
- {/* System Navigation */} - - -

- - Navigation -

- -
- {SYSTEM_ITEMS.map((item) => { - const Icon = item.icon; - return ( - - ); - })} -
-
-
- - {/* Shared Resources */} - navigate('/shared')} - > - -
-

- - Shared Resources -

- -
- -
-
-

- {shared?.commands ?? 0} -

-

- Commands -

-
-
-

- {shared?.skills ?? 0} -

-

- Skills -

-
-
-

- {shared?.agents ?? 0} -

-

- Agents -

-
-
-
-
- - {/* Uptime Indicator */} - - -
-
-
-
-
-
-

System Online

-

- - Config server running -

-
-
- - -
-
-
-
- ); -} - -// Skeleton loader component - Full Width -function HomePageSkeleton() { - return ( -
-
- {/* Left Column */} -
-
-
- -
- - -
-
- -
- {[1, 2, 3].map((i) => ( - - ))} -
-
-
- - - -
-
- - {/* Center Column */} -
-
- - {[1, 2, 3].map((i) => ( - - ))} -
-
- -
- {[1, 2, 3, 4, 5, 6].map((i) => ( - - ))} -
-
-
- - {/* Right Column */} -
-
- - {[1, 2, 3, 4, 5, 6].map((i) => ( - - ))} -
-
- -
- {[1, 2, 3].map((i) => ( - - ))} -
-
-
-
+ +
); }