Files
mkd/components/ConnectionIndicator.tsx
2026-02-04 00:17:04 +05:00

95 lines
3.1 KiB
TypeScript
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React, { useState, useEffect } from 'react';
import { Wifi, WifiOff } from 'lucide-react';
import { connectionService, type ConnectionStatus } from '../services/connectionService';
export const ConnectionIndicator: React.FC = () => {
const [status, setStatus] = useState<ConnectionStatus>(connectionService.getStatus());
const [apiBaseUrl] = useState<string>(import.meta.env.VITE_API_BASE_URL || '');
const [showIndicator, setShowIndicator] = useState(false);
useEffect(() => {
const unsubscribe = connectionService.subscribe((newStatus) => {
setStatus(newStatus);
});
// Не показываем индикатор сразу при загрузке, даём время на проверку подключения
const timer = setTimeout(() => {
setShowIndicator(true);
}, 2000); // 2 секунды задержка
return () => {
unsubscribe();
clearTimeout(timer);
};
}, []);
// Если API не настроен, не показываем индикатор (используется только localStorage)
if (!apiBaseUrl) {
return null;
}
// Не показываем индикатор сразу при загрузке
if (!showIndicator) {
return null;
}
// На ПК показываем индикатор только если есть проблема с подключением
// На мобильных показываем всегда для информативности
const isDesktop = typeof window !== 'undefined' && window.innerWidth >= 768;
if (isDesktop && status === 'connected') {
return null;
}
const getStatusColor = () => {
switch (status) {
case 'connected':
return 'text-emerald-500';
case 'connecting':
return 'text-amber-500';
case 'disconnected':
return 'text-red-500';
default:
return 'text-slate-400';
}
};
const getStatusBg = () => {
switch (status) {
case 'connected':
return 'bg-emerald-50';
case 'connecting':
return 'bg-amber-50';
case 'disconnected':
return 'bg-red-50';
default:
return 'bg-slate-50';
}
};
const getStatusText = () => {
switch (status) {
case 'connected':
return 'Подключено';
case 'connecting':
return 'Подключение...';
case 'disconnected':
return 'Нет подключения';
default:
return 'Неизвестно';
}
};
return (
<div className={`flex items-center gap-2 px-3 py-1.5 rounded-lg border ${getStatusBg()} ${status === 'disconnected' ? 'border-red-200' : status === 'connecting' ? 'border-amber-200' : 'border-emerald-200'} transition-all ${status === 'disconnected' ? 'shadow-sm shadow-red-500/10' : ''}`}>
{status === 'disconnected' ? (
<WifiOff className={`w-4 h-4 ${getStatusColor()}`} />
) : (
<Wifi className={`w-4 h-4 ${getStatusColor()} ${status === 'connecting' ? 'animate-pulse' : ''}`} />
)}
<span className={`text-xs font-bold ${getStatusColor()} hidden sm:inline`}>
{getStatusText()}
</span>
</div>
);
};