82 lines
2.2 KiB
TypeScript
82 lines
2.2 KiB
TypeScript
|
|
'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>
|
||
|
|
);
|
||
|
|
}
|