Files
supervisor-ui/components/ui/ConnectionStatus.tsx

82 lines
2.2 KiB
TypeScript
Raw Normal View History

'use client';
import { Wifi, WifiOff, Loader2, AlertCircle } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { ConnectionStatus as Status } from '@/lib/hooks/useEventSource';
import { cn } from '@/lib/utils/cn';
interface ConnectionStatusProps {
status: Status;
reconnectAttempts?: number;
onReconnect?: () => void;
}
export function ConnectionStatus({ status, reconnectAttempts = 0, onReconnect }: ConnectionStatusProps) {
const getStatusConfig = () => {
switch (status) {
case 'connected':
return {
icon: Wifi,
text: 'Live',
color: 'text-success',
bgColor: 'bg-success/10',
borderColor: 'border-success/20',
};
case 'connecting':
return {
icon: Loader2,
text: 'Connecting...',
color: 'text-warning',
bgColor: 'bg-warning/10',
borderColor: 'border-warning/20',
animate: true,
};
case 'error':
return {
icon: AlertCircle,
text: reconnectAttempts > 0 ? `Retrying (${reconnectAttempts})` : 'Error',
color: 'text-destructive',
bgColor: 'bg-destructive/10',
borderColor: 'border-destructive/20',
};
case 'disconnected':
default:
return {
icon: WifiOff,
text: 'Offline',
color: 'text-muted-foreground',
bgColor: 'bg-muted',
borderColor: 'border-muted',
};
}
};
const config = getStatusConfig();
const Icon = config.icon;
return (
<div
className={cn(
'flex items-center gap-2 px-3 py-1.5 rounded-md border text-sm',
config.bgColor,
config.borderColor
)}
>
<Icon
className={cn('h-4 w-4', config.color, config.animate && 'animate-spin')}
/>
<span className={cn('font-medium', config.color)}>{config.text}</span>
{(status === 'error' || status === 'disconnected') && onReconnect && (
<Button
variant="ghost"
size="sm"
onClick={onReconnect}
className="h-6 px-2 ml-1"
>
Reconnect
</Button>
)}
</div>
);
}