From 9cdcd054e7b50ece1e3aafd31b69ab95b77e7c21 Mon Sep 17 00:00:00 2001 From: shats Date: Sun, 7 Dec 2025 21:36:40 +0700 Subject: [PATCH] feat: Add toggle for grouping communities by tags in EasySwitchManager, enhancing user control over community display and improving organization. --- frontend/src/EasySwitchManager.jsx | 142 ++++++++++++++++++++++++++++- 1 file changed, 139 insertions(+), 3 deletions(-) diff --git a/frontend/src/EasySwitchManager.jsx b/frontend/src/EasySwitchManager.jsx index 6f4e3a1..42208d7 100644 --- a/frontend/src/EasySwitchManager.jsx +++ b/frontend/src/EasySwitchManager.jsx @@ -46,6 +46,7 @@ function EasySwitchManager() { const [initialGateways, setInitialGateways] = useState({}); // Исходное состояние для отслеживания изменений const [hasChanges, setHasChanges] = useState(false); const [expandedServers, setExpandedServers] = useState(new Set()); // Развернутые серверы + const [groupByTags, setGroupByTags] = useState(true); // Группировка по тегам useEffect(() => { const initData = async () => { @@ -492,6 +493,19 @@ function EasySwitchManager() { + {/* Переключатель "Группировка по тегам" */} +
+ +
+ {/* Поиск */}
@@ -622,8 +636,10 @@ function EasySwitchManager() { {/* Контент (сворачиваемый) */} {isExpanded && (
- {/* Группируем communities по тегам */} - {(() => { + {/* Условный рендеринг: группировка по тегам или обычный вид */} + {groupByTags ? ( + /* Группируем communities по тегам */ + (() => { // Группируем по тегам const groupedByTags = new Map(); const noTagCommunities = []; @@ -921,7 +937,127 @@ function EasySwitchManager() { )} ); - })()} + })() + ) : ( + /* Обычный вид без группировки */ +
+ {filteredCommunitiesForServer.map((comm) => { + const activeKey = `${server.id}:${comm.value}`; + const activeGw = activeGateways[activeKey]; + const hasFilterForComm = server.filtersMap.has(comm.value); + + return ( +
+
+ {/* Заголовок community */} +
+ + {comm.value} + + {comm.name || comm.description || ''} + {hasFilterForComm && ( + + настроен + + )} + + ({server.gateways.length}) + +
+ + {/* Сетка карточек шлюзов для этого community */} +
+ {server.gateways.map((gw, idx) => { + const isActive = activeGw === gw.name; + const isFastest = idx === 0; + const ping = 20 + idx * 10 + Math.floor(Math.random() * 15); + + return ( +
+
handleGatewaySelect(server.id, comm.value, gw.name)} + onMouseEnter={(e) => { + if (!isActive) { + e.currentTarget.style.boxShadow = '0 2px 6px rgba(0,0,0,0.1)'; + e.currentTarget.style.transform = 'translateY(-1px)'; + } + }} + onMouseLeave={(e) => { + if (!isActive) { + e.currentTarget.style.boxShadow = 'none'; + e.currentTarget.style.transform = 'translateY(0)'; + } + }} + > +
+ {/* Галочка (абсолютное позиционирование) */} + {isActive && ( +
+ +
+ )} + + {/* Метка Fastest */} +
+ {isFastest && !isActive && ( + + + Fast + + )} +
+ + {/* Название шлюза */} +
+ {gw.name} +
+ + {/* Описание шлюза */} + {gw.comment && ( +
+ {gw.comment} +
+ )} + + {/* Протокол */} +
+ {serverMeta?.provider || 'vless'} +
+ + {/* Метрика (пинг) */} +
+ {ping} +
+
+
+
+ ); + })} +
+
+
+ ); + })} +
+ )}
)}