-
-
Configuration
-
Manage node settings and peers
-
Coming soon...
+
+
+
+
Состояние узла
+
+
+ Активен
+
+
WebUI запущен и доступен
+
+
+
+
+
Сетевая информация
+
Адрес: 200:1234:5678:9abc::1
+
Подсеть: 300:1234:5678:9abc::/64
+
+
+
+
Статистика
+
Время работы: 2д 15ч 42м
+
Активных соединений: 3
+
+
-
-
Peers
-
View and manage peer connections
-
Coming soon...
+
+
+
Управление пирами
+
Просмотр и управление соединениями с пирами
+
+
+
+
+
Активные пиры
+
Количество активных соединений
+
Функция в разработке...
+
+
+
+
Добавить пир
+
Подключение к новому узлу
+
Функция в разработке...
+
+
-
-
Network
-
Network topology and routing
-
Coming soon...
+
+
+
Конфигурация
+
Настройки узла и параметры сети
+
+
+
+
+
Основные настройки
+
Базовая конфигурация узла
+
Функция в разработке...
+
+
+
+
Сетевые настройки
+
Параметры сетевого взаимодействия
+
Функция в разработке...
+
+
-
-
+
+
diff --git a/src/webui/static/lang/en.js b/src/webui/static/lang/en.js
new file mode 100644
index 00000000..7001e9c2
--- /dev/null
+++ b/src/webui/static/lang/en.js
@@ -0,0 +1,33 @@
+window.translations = window.translations || {};
+window.translations.en = {
+ 'title': '🌳 Yggdrasil Web Interface',
+ 'subtitle': 'Network mesh management dashboard',
+ 'logout': 'Logout',
+ 'nav_status': 'Status',
+ 'nav_peers': 'Peers',
+ 'nav_config': 'Configuration',
+ 'status_title': 'Node Status',
+ 'status_active': 'Active',
+ 'status_description': 'WebUI is running and accessible',
+ 'network_info': 'Network Information',
+ 'address': 'Address',
+ 'subnet': 'Subnet',
+ 'statistics': 'Statistics',
+ 'uptime': 'Uptime',
+ 'connections': 'Active connections',
+ 'peers_title': 'Peer Management',
+ 'peers_description': 'View and manage peer connections',
+ 'active_peers': 'Active Peers',
+ 'active_connections': 'Number of active connections',
+ 'add_peer': 'Add Peer',
+ 'add_peer_description': 'Connect to a new node',
+ 'config_title': 'Configuration',
+ 'config_description': 'Node settings and network parameters',
+ 'basic_settings': 'Basic Settings',
+ 'basic_settings_description': 'Basic node configuration',
+ 'network_settings': 'Network Settings',
+ 'network_settings_description': 'Network interaction parameters',
+ 'coming_soon': 'Coming soon...',
+ 'footer_text': 'Yggdrasil Network • Minimal WebUI v1.0',
+ 'logout_confirm': 'Are you sure you want to logout?'
+};
\ No newline at end of file
diff --git a/src/webui/static/lang/ru.js b/src/webui/static/lang/ru.js
new file mode 100644
index 00000000..09586a6f
--- /dev/null
+++ b/src/webui/static/lang/ru.js
@@ -0,0 +1,33 @@
+window.translations = window.translations || {};
+window.translations.ru = {
+ 'title': '🌳 Yggdrasil Web Interface',
+ 'subtitle': 'Панель управления mesh-сетью',
+ 'logout': 'Выход',
+ 'nav_status': 'Состояние',
+ 'nav_peers': 'Пиры',
+ 'nav_config': 'Конфигурация',
+ 'status_title': 'Состояние узла',
+ 'status_active': 'Активен',
+ 'status_description': 'WebUI запущен и доступен',
+ 'network_info': 'Сетевая информация',
+ 'address': 'Адрес',
+ 'subnet': 'Подсеть',
+ 'statistics': 'Статистика',
+ 'uptime': 'Время работы',
+ 'connections': 'Активных соединений',
+ 'peers_title': 'Управление пирами',
+ 'peers_description': 'Просмотр и управление соединениями с пирами',
+ 'active_peers': 'Активные пиры',
+ 'active_connections': 'Количество активных соединений',
+ 'add_peer': 'Добавить пир',
+ 'add_peer_description': 'Подключение к новому узлу',
+ 'config_title': 'Конфигурация',
+ 'config_description': 'Настройки узла и параметры сети',
+ 'basic_settings': 'Основные настройки',
+ 'basic_settings_description': 'Базовая конфигурация узла',
+ 'network_settings': 'Сетевые настройки',
+ 'network_settings_description': 'Параметры сетевого взаимодействия',
+ 'coming_soon': 'Функция в разработке...',
+ 'footer_text': 'Yggdrasil Network • Minimal WebUI v1.0',
+ 'logout_confirm': 'Вы уверены, что хотите выйти?'
+};
\ No newline at end of file
diff --git a/src/webui/static/style.css b/src/webui/static/style.css
index 81f27757..c03300a1 100644
--- a/src/webui/static/style.css
+++ b/src/webui/static/style.css
@@ -29,6 +29,41 @@ header {
text-align: left;
}
+.header-actions {
+ display: flex;
+ align-items: center;
+ gap: 15px;
+}
+
+.language-switcher {
+ display: flex;
+ background: rgba(255, 255, 255, 0.15);
+ border-radius: 8px;
+ padding: 4px;
+ border: 1px solid rgba(255, 255, 255, 0.2);
+}
+
+.lang-btn {
+ background: transparent;
+ color: white;
+ border: none;
+ padding: 6px 12px;
+ border-radius: 6px;
+ cursor: pointer;
+ font-size: 12px;
+ font-weight: 500;
+ transition: all 0.2s ease;
+}
+
+.lang-btn:hover {
+ background: rgba(255, 255, 255, 0.2);
+}
+
+.lang-btn.active {
+ background: rgba(255, 255, 255, 0.3);
+ box-shadow: 0 2px 4px rgba(0,0,0,0.2);
+}
+
.header-content > div:first-child {
text-align: center;
flex: 1;
@@ -60,20 +95,88 @@ header p {
background: rgba(255, 255, 255, 0.3);
}
-main {
- background: white;
- border-radius: 12px;
- padding: 30px;
- box-shadow: 0 8px 32px rgba(0,0,0,0.1);
+.layout {
+ display: flex;
+ gap: 20px;
margin-bottom: 20px;
}
-.status-card {
- background: #f8f9fa;
- border-radius: 8px;
+.sidebar {
+ min-width: 250px;
+ background: rgba(255, 255, 255, 0.15);
+ backdrop-filter: blur(10px);
+ border-radius: 12px;
padding: 20px;
+ box-shadow: 0 8px 32px rgba(0,0,0,0.1);
+ border: 1px solid rgba(255, 255, 255, 0.18);
+}
+
+.nav-menu {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+}
+
+.nav-item {
+ display: flex;
+ align-items: center;
+ gap: 12px;
+ padding: 15px 18px;
+ background: rgba(255, 255, 255, 0.1);
+ border-radius: 10px;
+ cursor: pointer;
+ transition: all 0.3s ease;
+ color: white;
+ border: 1px solid rgba(255, 255, 255, 0.2);
+}
+
+.nav-item:hover {
+ background: rgba(255, 255, 255, 0.2);
+ transform: translateY(-2px);
+ box-shadow: 0 4px 15px rgba(0,0,0,0.2);
+}
+
+.nav-item.active {
+ background: rgba(255, 255, 255, 0.25);
+ border-color: rgba(255, 255, 255, 0.4);
+ box-shadow: 0 4px 15px rgba(0,0,0,0.2);
+}
+
+.nav-icon {
+ font-size: 20px;
+}
+
+.nav-text {
+ font-weight: 500;
+ font-size: 16px;
+}
+
+.main-content {
+ flex: 1;
+ background: rgba(255, 255, 255, 0.95);
+ border-radius: 12px;
+ padding: 30px;
+ box-shadow: 0 8px 32px rgba(0,0,0,0.1);
+ backdrop-filter: blur(10px);
+ border: 1px solid rgba(255, 255, 255, 0.18);
+}
+
+.content-section {
+ display: none;
+}
+
+.content-section.active {
+ display: block;
+}
+
+.status-card {
+ background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
+ border-radius: 15px;
+ padding: 25px;
margin-bottom: 30px;
text-align: center;
+ box-shadow: 0 4px 20px rgba(0,0,0,0.08);
+ border: 1px solid rgba(255, 255, 255, 0.5);
}
.status-indicator {
@@ -109,17 +212,19 @@ main {
}
.info-card {
- background: #ffffff;
- border: 1px solid #e9ecef;
- border-radius: 8px;
- padding: 20px;
+ background: linear-gradient(135deg, #ffffff 0%, #f8f9fa 100%);
+ border: 1px solid rgba(233, 236, 239, 0.6);
+ border-radius: 15px;
+ padding: 25px;
text-align: center;
- transition: transform 0.2s ease, box-shadow 0.2s ease;
+ transition: all 0.3s ease;
+ box-shadow: 0 2px 10px rgba(0,0,0,0.05);
}
.info-card:hover {
- transform: translateY(-2px);
- box-shadow: 0 4px 12px rgba(0,0,0,0.1);
+ transform: translateY(-5px);
+ box-shadow: 0 8px 25px rgba(0,0,0,0.15);
+ border-color: rgba(102, 126, 234, 0.3);
}
.info-card h3 {
@@ -153,6 +258,11 @@ footer {
gap: 20px;
}
+ .header-actions {
+ flex-direction: column;
+ gap: 10px;
+ }
+
.header-content > div:first-child {
text-align: center;
}
@@ -161,8 +271,35 @@ footer {
font-size: 2rem;
}
- main {
+ .layout {
+ flex-direction: column;
+ gap: 15px;
+ }
+
+ .sidebar {
+ min-width: auto;
+ order: 2;
+ }
+
+ .nav-menu {
+ flex-direction: row;
+ overflow-x: auto;
+ gap: 8px;
+ }
+
+ .nav-item {
+ min-width: 120px;
+ justify-content: center;
+ padding: 12px 15px;
+ }
+
+ .nav-text {
+ font-size: 14px;
+ }
+
+ .main-content {
padding: 20px;
+ order: 1;
}
.info-grid {