import { useState, useMemo } from 'react';
import {
IconServer,
IconWorld,
IconBuildingSkyscraper,
IconNetwork,
IconChevronDown,
IconChevronRight,
IconX,
IconSearch,
IconFilter,
IconDatabase
} from '@tabler/icons-react';
// Преобразование кода страны в emoji-флаг
function countryToFlag(isoCode) {
if (!isoCode) return '';
const codeMap = {
'SWE': 'SE',
'RUS': 'RU',
'USA': 'US',
'GER': 'DE',
'FIN': 'FI',
'NLD': 'NL'
};
const code = codeMap[isoCode?.toUpperCase()] || isoCode?.toUpperCase();
if (!code || code.length !== 2) return isoCode;
return code
.replace(/./g, char =>
String.fromCodePoint(127397 + char.charCodeAt())
);
}
export default function ServerSidebar({
servers = [],
filters = {},
onFiltersChange,
onSearch,
searchTerm = '',
onReset
}) {
const [expandedSections, setExpandedSections] = useState({
country: true,
provider: true,
type: true,
tunnel: false
});
// Подсчёт серверов по категориям
const stats = useMemo(() => {
const byCountry = {};
const byProvider = {};
const byType = {};
const byTunnel = {};
servers.forEach(srv => {
byCountry[srv.country] = (byCountry[srv.country] || 0) + 1;
byProvider[srv.provider] = (byProvider[srv.provider] || 0) + 1;
byType[srv.type] = (byType[srv.type] || 0) + 1;
byTunnel[srv.tunnel] = (byTunnel[srv.tunnel] || 0) + 1;
});
return { byCountry, byProvider, byType, byTunnel };
}, [servers]);
const toggleSection = (section) => {
setExpandedSections(prev => ({
...prev,
[section]: !prev[section]
}));
};
const handleFilterClick = (category, value) => {
const currentValue = filters[category];
const newValue = currentValue === value ? '' : value;
onFiltersChange({ ...filters, [category]: newValue });
};
const activeFiltersCount = Object.values(filters).filter(Boolean).length + (searchTerm ? 1 : 0);
const typeLabels = {
'jumphost': 'Jumphost',
'exit': 'Выходная нода'
};
return (
{/* Заголовок */}
Фильтры
{activeFiltersCount > 0 && (
{activeFiltersCount}
)}
{activeFiltersCount > 0 && (
)}
{/* Поиск */}
{/* Скроллируемый контент */}
{/* Секция: Страны */}
toggleSection('country')}
style={{
background: 'rgba(0,0,0,0.02)',
borderBottom: '1px solid rgba(0,0,0,0.04)'
}}
>
Страны
{expandedSections.country ?
:
}
{expandedSections.country && (
{Object.entries(stats.byCountry)
.sort((a, b) => b[1] - a[1])
.map(([country, count]) => (
))}
)}
{/* Секция: Провайдеры */}
toggleSection('provider')}
style={{
background: 'rgba(0,0,0,0.02)',
borderBottom: '1px solid rgba(0,0,0,0.04)'
}}
>
Провайдеры
{expandedSections.provider ?
:
}
{expandedSections.provider && (
{Object.entries(stats.byProvider)
.sort((a, b) => b[1] - a[1])
.map(([provider, count]) => (
))}
)}
{/* Секция: Типы */}
toggleSection('type')}
style={{
background: 'rgba(0,0,0,0.02)',
borderBottom: '1px solid rgba(0,0,0,0.04)'
}}
>
Тип сервера
{expandedSections.type ?
:
}
{expandedSections.type && (
{Object.entries(stats.byType)
.sort((a, b) => b[1] - a[1])
.map(([type, count]) => (
))}
)}
{/* Секция: Туннели */}
toggleSection('tunnel')}
style={{
background: 'rgba(0,0,0,0.02)',
borderBottom: '1px solid rgba(0,0,0,0.04)'
}}
>
Туннель
{expandedSections.tunnel ?
:
}
{expandedSections.tunnel && (
{Object.entries(stats.byTunnel)
.sort((a, b) => b[1] - a[1])
.map(([tunnel, count]) => (
))}
)}
{/* Статистика внизу */}
Статистика
Всего серверов
{servers.length}
Выходных нод
{stats.byType['exit'] || 0}
Jumphosts
{stats.byType['jumphost'] || 0}
);
}