From 9ab53034df951ca098f8698f5bef5b73ce9270b6 Mon Sep 17 00:00:00 2001 From: PEDZEO Date: Sat, 17 Jan 2026 07:24:14 +0300 Subject: [PATCH] Enhance localization and AdminBanSystem component - Added new localization keys for settings related to punishment, traffic monitoring, and network detection in both English and Russian. - Implemented formatting functions in AdminBanSystem to improve the display of setting keys and categories, enhancing readability and user experience. --- src/locales/en.json | 41 +++++++++++++++++++++++++++++++++++- src/locales/ru.json | 41 +++++++++++++++++++++++++++++++++++- src/pages/AdminBanSystem.tsx | 28 +++++++++++++++++++++--- 3 files changed, 105 insertions(+), 5 deletions(-) diff --git a/src/locales/en.json b/src/locales/en.json index 1152287..6436c47 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -973,7 +973,46 @@ "notifications": "Notifications", "whitelist": "Whitelist", "saved": "Setting saved", - "error": "Error saving" + "error": "Error saving", + "categories": { + "general": "General Settings", + "punishment": "Punishments", + "progressive_bans": "Progressive Bans", + "traffic": "Traffic Monitoring", + "network": "Network Detection", + "notifications": "Notifications", + "rate_limit": "Rate Limits" + }, + "punishment_enabled": "Enable auto-ban", + "punishment_minutes": "Ban duration (minutes)", + "ip_window_seconds": "IP counting window (seconds)", + "notify_on_punishment": "Notify on bans", + "notify_on_node_status": "Notify on node status", + "daily_report_enabled": "Daily report", + "daily_report_hour": "Report hour", + "rate_limit_max": "Max requests", + "rate_limit_window": "Rate limit window (sec)", + "heartbeat_timeout": "Heartbeat timeout (sec)", + "progressive_bans_enabled": "Progressive bans", + "progressive_ban_1": "1st ban (minutes)", + "progressive_ban_2": "2nd ban (minutes)", + "progressive_ban_3": "3rd ban (minutes)", + "progressive_ban_window_hours": "Reset window (hours)", + "traffic_monitor_enabled": "Traffic monitoring", + "traffic_limit_gb": "Traffic limit (GB)", + "traffic_window_minutes": "Check window (min)", + "traffic_check_interval": "Check interval (min)", + "traffic_ban_minutes": "Traffic ban (min)", + "network_detection_enabled": "Network type detection", + "network_detection_nodes": "Detection nodes", + "network_detection_monitor_all": "Monitor all nodes", + "network_detection_collect_all": "Collect from all nodes", + "network_notify_mobile": "Notify on mobile", + "network_block_mobile": "Block mobile", + "network_block_mobile_minutes": "Block mobile (min)", + "network_notify_wifi": "Notify on WiFi", + "network_block_wifi": "Block WiFi", + "network_block_wifi_minutes": "Block WiFi (min)" }, "health": { "title": "System Health", diff --git a/src/locales/ru.json b/src/locales/ru.json index ac4ce57..2fc81af 100644 --- a/src/locales/ru.json +++ b/src/locales/ru.json @@ -973,7 +973,46 @@ "notifications": "Уведомления", "whitelist": "Белый список", "saved": "Настройка сохранена", - "error": "Ошибка сохранения" + "error": "Ошибка сохранения", + "categories": { + "general": "Общие настройки", + "punishment": "Наказания", + "progressive_bans": "Прогрессивные баны", + "traffic": "Мониторинг трафика", + "network": "Детекция сети", + "notifications": "Уведомления", + "rate_limit": "Лимиты запросов" + }, + "punishment_enabled": "Включить автобан", + "punishment_minutes": "Длительность бана (минуты)", + "ip_window_seconds": "Окно подсчёта IP (секунды)", + "notify_on_punishment": "Уведомлять о банах", + "notify_on_node_status": "Уведомлять о статусе нод", + "daily_report_enabled": "Ежедневный отчёт", + "daily_report_hour": "Час отправки отчёта", + "rate_limit_max": "Макс. запросов", + "rate_limit_window": "Окно лимита (сек)", + "heartbeat_timeout": "Таймаут heartbeat (сек)", + "progressive_bans_enabled": "Прогрессивные баны", + "progressive_ban_1": "1-й бан (минуты)", + "progressive_ban_2": "2-й бан (минуты)", + "progressive_ban_3": "3-й бан (минуты)", + "progressive_ban_window_hours": "Окно сброса (часы)", + "traffic_monitor_enabled": "Мониторинг трафика", + "traffic_limit_gb": "Лимит трафика (ГБ)", + "traffic_window_minutes": "Окно проверки (мин)", + "traffic_check_interval": "Интервал проверки (мин)", + "traffic_ban_minutes": "Бан за трафик (мин)", + "network_detection_enabled": "Детекция типа сети", + "network_detection_nodes": "Ноды для детекции", + "network_detection_monitor_all": "Мониторить все ноды", + "network_detection_collect_all": "Собирать со всех нод", + "network_notify_mobile": "Уведомлять о мобильных", + "network_block_mobile": "Блокировать мобильные", + "network_block_mobile_minutes": "Блок мобильных (мин)", + "network_notify_wifi": "Уведомлять о WiFi", + "network_block_wifi": "Блокировать WiFi", + "network_block_wifi_minutes": "Блок WiFi (мин)" }, "health": { "title": "Состояние системы", diff --git a/src/pages/AdminBanSystem.tsx b/src/pages/AdminBanSystem.tsx index ec1c3d1..a135121 100644 --- a/src/pages/AdminBanSystem.tsx +++ b/src/pages/AdminBanSystem.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect } from 'react' +import { useState, useEffect, useCallback } from 'react' import { useTranslation } from 'react-i18next' import { banSystemApi, @@ -148,6 +148,28 @@ export default function AdminBanSystem() { const [reportHours, setReportHours] = useState(24) const [settingLoading, setSettingLoading] = useState(null) const [loading, setLoading] = useState(true) + + // Format snake_case to readable label + const formatSettingKey = useCallback((key: string): string => { + // Try translation first + const translated = t(`banSystem.settings.${key}`, { defaultValue: '' }) + if (translated && translated !== `banSystem.settings.${key}`) { + return translated + } + // Fallback: convert snake_case to Title Case + return key + .split('_') + .map(word => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase()) + .join(' ') + }, [t]) + + const formatCategory = useCallback((category: string): string => { + const translated = t(`banSystem.settings.categories.${category}`, { defaultValue: '' }) + if (translated && translated !== `banSystem.settings.categories.${category}`) { + return translated + } + return category.charAt(0).toUpperCase() + category.slice(1).replace(/_/g, ' ') + }, [t]) const [error, setError] = useState(null) const [searchQuery, setSearchQuery] = useState('') const [actionLoading, setActionLoading] = useState(null) @@ -925,13 +947,13 @@ export default function AdminBanSystem() { return Object.entries(grouped).map(([category, items]) => (
-

{category}

+

{formatCategory(category)}

{items.map((setting) => (
-
{setting.key}
+
{formatSettingKey(setting.key)}
{setting.description && (
{setting.description}
)}