feat(ui): add shared skeleton component and update CLI status

- Add reusable SkeletonPulse component to replace 4 duplicate definitions
- Update CLI status components to use shared skeleton
- Simplify CLI status components by using React Query hooks

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Shirone
2026-01-15 16:21:08 +01:00
parent d81997d24b
commit d08ef472a3
5 changed files with 22 additions and 16 deletions

View File

@@ -0,0 +1,18 @@
/**
* Skeleton Components
*
* Loading placeholder components for content that's being fetched.
*/
import { cn } from '@/lib/utils';
interface SkeletonPulseProps {
className?: string;
}
/**
* Pulsing skeleton placeholder for loading states
*/
export function SkeletonPulse({ className }: SkeletonPulseProps) {
return <div className={cn('animate-pulse bg-muted/50 rounded', className)} />;
}

View File

@@ -1,5 +1,6 @@
import { useState, useCallback } from 'react';
import { Button } from '@/components/ui/button';
import { SkeletonPulse } from '@/components/ui/skeleton';
import { CheckCircle2, AlertCircle, RefreshCw, XCircle } from 'lucide-react';
import { cn } from '@/lib/utils';
import type { CliStatus } from '../shared/types';
@@ -34,10 +35,6 @@ function getAuthMethodLabel(method: string): string {
}
}
function SkeletonPulse({ className }: { className?: string }) {
return <div className={cn('animate-pulse bg-muted/50 rounded', className)} />;
}
function ClaudeCliStatusSkeleton() {
return (
<div

View File

@@ -1,5 +1,6 @@
import { useState, useCallback } from 'react';
import { Button } from '@/components/ui/button';
import { SkeletonPulse } from '@/components/ui/skeleton';
import { CheckCircle2, AlertCircle, RefreshCw, XCircle } from 'lucide-react';
import { cn } from '@/lib/utils';
import type { CliStatus } from '../shared/types';
@@ -29,10 +30,6 @@ function getAuthMethodLabel(method: string): string {
}
}
function SkeletonPulse({ className }: { className?: string }) {
return <div className={cn('animate-pulse bg-muted/50 rounded', className)} />;
}
function CodexCliStatusSkeleton() {
return (
<div

View File

@@ -1,5 +1,6 @@
import { useState, useCallback } from 'react';
import { Button } from '@/components/ui/button';
import { SkeletonPulse } from '@/components/ui/skeleton';
import { CheckCircle2, AlertCircle, RefreshCw, XCircle } from 'lucide-react';
import { cn } from '@/lib/utils';
import { CursorIcon } from '@/components/ui/provider-icon';
@@ -19,10 +20,6 @@ interface CursorCliStatusProps {
onRefresh: () => void;
}
function SkeletonPulse({ className }: { className?: string }) {
return <div className={cn('animate-pulse bg-muted/50 rounded', className)} />;
}
export function CursorCliStatusSkeleton() {
return (
<div

View File

@@ -1,5 +1,6 @@
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import { SkeletonPulse } from '@/components/ui/skeleton';
import { CheckCircle2, AlertCircle, RefreshCw, Bot, Cloud } from 'lucide-react';
import { cn } from '@/lib/utils';
import type { CliStatus } from '../shared/types';
@@ -74,10 +75,6 @@ interface OpencodeCliStatusProps {
onRefresh: () => void;
}
function SkeletonPulse({ className }: { className?: string }) {
return <div className={cn('animate-pulse bg-muted/50 rounded', className)} />;
}
export function OpencodeCliStatusSkeleton() {
return (
<div