/** * Connection Status Indicator Component * * Shows the current WebSocket connection status with visual feedback. */ import React from 'react'; import classNames from 'classnames'; import { useConnectionStatus } from '../../lib/realtime/useSocket'; import type { ConnectionStatus as ConnectionStatusType } from '../../lib/realtime/types'; interface ConnectionStatusProps { showLabel?: boolean; showLatency?: boolean; size?: 'sm' | 'md' | 'lg'; className?: string; } /** * Get status color classes */ function getStatusColor(status: ConnectionStatusType): string { switch (status) { case 'connected': return 'bg-green-500'; case 'connecting': case 'reconnecting': return 'bg-yellow-500 animate-pulse'; case 'disconnected': return 'bg-gray-400'; case 'error': return 'bg-red-500'; default: return 'bg-gray-400'; } } /** * Get status label */ function getStatusLabel(status: ConnectionStatusType): string { switch (status) { case 'connected': return 'Connected'; case 'connecting': return 'Connecting...'; case 'reconnecting': return 'Reconnecting...'; case 'disconnected': return 'Disconnected'; case 'error': return 'Connection Error'; default: return 'Unknown'; } } /** * Get size classes */ function getSizeClasses(size: 'sm' | 'md' | 'lg'): { dot: string; text: string } { switch (size) { case 'sm': return { dot: 'w-2 h-2', text: 'text-xs' }; case 'md': return { dot: 'w-3 h-3', text: 'text-sm' }; case 'lg': return { dot: 'w-4 h-4', text: 'text-base' }; default: return { dot: 'w-3 h-3', text: 'text-sm' }; } } /** * Connection Status component */ export function ConnectionStatus({ showLabel = true, showLatency = false, size = 'md', className, }: ConnectionStatusProps) { const { status, latency } = useConnectionStatus(); const sizeClasses = getSizeClasses(size); return (
{/* Status dot */} {/* Label */} {showLabel && ( {getStatusLabel(status)} )} {/* Latency */} {showLatency && status === 'connected' && latency !== undefined && ( ({latency}ms) )}
); } /** * Compact connection indicator (dot only) */ export function ConnectionDot({ className }: { className?: string }) { const { status } = useConnectionStatus(); return ( ); } /** * Connection banner for showing reconnection status */ export function ConnectionBanner() { const { status } = useConnectionStatus(); if (status === 'connected') { return null; } const bannerClasses = classNames( 'fixed top-0 left-0 right-0 py-2 px-4 text-center text-sm font-medium z-50', { 'bg-yellow-100 text-yellow-800': status === 'connecting' || status === 'reconnecting', 'bg-red-100 text-red-800': status === 'error', 'bg-gray-100 text-gray-800': status === 'disconnected', } ); return (
{status === 'connecting' && 'Connecting to real-time updates...'} {status === 'reconnecting' && 'Connection lost. Reconnecting...'} {status === 'error' && 'Connection error. Please check your network.'} {status === 'disconnected' && 'Disconnected from real-time updates.'}
); } export default ConnectionStatus;