From cf6d8b61a35be437573c49840b00d221967f9e97 Mon Sep 17 00:00:00 2001 From: shats Date: Mon, 16 Feb 2026 19:26:56 +0700 Subject: [PATCH] refactor(PageHeader): standardize header component across various managers by adding icons for improved visual consistency and user experience --- frontend/src/ASNsNewManager.jsx | 1 + frontend/src/AutoUrlManager.jsx | 1 + frontend/src/BillingManager.jsx | 1 + frontend/src/CommunitiesManager.jsx | 40 ++-- frontend/src/Dashboard.jsx | 1 + frontend/src/DomainsNewManager.jsx | 1 + frontend/src/EasySwitchManager.jsx | 74 +++----- frontend/src/FilterManager.jsx | 234 ++++++++++++------------ frontend/src/IPRangesManager.jsx | 1 + frontend/src/MikrotikBackupsManager.jsx | 1 + frontend/src/MikrotikTools.jsx | 1 + frontend/src/NetworkConfigManager.jsx | 164 ++++++++--------- frontend/src/ServerManager.jsx | 69 +++---- frontend/src/components/PageHeader.jsx | 17 +- 14 files changed, 290 insertions(+), 316 deletions(-) diff --git a/frontend/src/ASNsNewManager.jsx b/frontend/src/ASNsNewManager.jsx index fba44c3..6e43dcb 100644 --- a/frontend/src/ASNsNewManager.jsx +++ b/frontend/src/ASNsNewManager.jsx @@ -529,6 +529,7 @@ function ASNsNewManager() { } meta={} actions={ } actions={(
diff --git a/frontend/src/BillingManager.jsx b/frontend/src/BillingManager.jsx index feccbf1..f386f82 100644 --- a/frontend/src/BillingManager.jsx +++ b/frontend/src/BillingManager.jsx @@ -576,6 +576,7 @@ function BillingManager() { {/* Заголовок */} } actions={ -
-
-
-
-

- - Справочник Community -

-
-
- -
-
-
-
+ } + actions={ + + } + />
diff --git a/frontend/src/Dashboard.jsx b/frontend/src/Dashboard.jsx index 374779c..7d9cf68 100644 --- a/frontend/src/Dashboard.jsx +++ b/frontend/src/Dashboard.jsx @@ -205,6 +205,7 @@ function Dashboard() { {/* Заголовок страницы */} } actions={(
{lastFetchTime && ( diff --git a/frontend/src/DomainsNewManager.jsx b/frontend/src/DomainsNewManager.jsx index d3df82e..f50c181 100644 --- a/frontend/src/DomainsNewManager.jsx +++ b/frontend/src/DomainsNewManager.jsx @@ -518,6 +518,7 @@ function DomainsNewManager() { } meta={} actions={( { @@ -495,18 +496,12 @@ function EasySwitchManager() { if (loading && servers.length === 0) { return (
-
-
-
-

- - Easy Switch -

-
Быстрое переключение шлюзов
-
-
-
- + } + meta="Быстрое переключение шлюзов" + /> +
@@ -521,41 +516,32 @@ function EasySwitchManager() { return (
- {/* Заголовок */} -
-
-
-

- - Easy Switch -

-
- Быстрое переключение шлюзов • {servers.length} {servers.length === 1 ? 'сервер' : 'серверов'} • {communitiesDirectory.length} communities -
-
-
-
- {hasChanges && ( - - )} - -
+ )} +
-
-
+ } + /> {/* Вкладки */}
diff --git a/frontend/src/FilterManager.jsx b/frontend/src/FilterManager.jsx index ad54b5e..b28c943 100644 --- a/frontend/src/FilterManager.jsx +++ b/frontend/src/FilterManager.jsx @@ -6,6 +6,7 @@ import FormModal from './components/FormModal.jsx'; import ConfirmModal from './components/ConfirmModal.jsx'; import FormField from './components/FormField.jsx'; import Modal from './components/Modal.jsx'; +import PageHeader from './components/PageHeader.jsx'; import { IconPlus, IconSearch, @@ -1755,133 +1756,126 @@ function FilterManager() { return (
-
-
-
-
-

Управление фильтрами frouting

-
-
-
- {/* Dropdown выбора сервера */} -
- -
-
- setServerSearch(e.target.value)} - onClick={(e) => e.stopPropagation()} - /> -
-
- {activeServers.length > 0 && ( - <> -
Активные серверы
- {activeServers.map(server => ( - { - e.preventDefault(); - setSelectedServer(server); - }} - > -
- - {server.name} -
-
- ))} - - )} - {inactiveServers.length > 0 && ( - <> -
-
Неактивные серверы
- {inactiveServers.map(server => ( - { - e.preventDefault(); - setSelectedServer(server); - }} - > -
- - {server.name} -
-
- ))} - - )} -
- -
+ } + actions={ +
+
+ +
+
+ setServerSearch(e.target.value)} + onClick={(e) => e.stopPropagation()} + />
- - {selectedServer && ( +
+ {activeServers.length > 0 && ( <> - - - - +
Активные серверы
+ {activeServers.map(server => ( + { + e.preventDefault(); + setSelectedServer(server); + }} + > +
+ + {server.name} +
+
+ ))} )} + {inactiveServers.length > 0 && ( + <> +
+
Неактивные серверы
+ {inactiveServers.map(server => ( + { + e.preventDefault(); + setSelectedServer(server); + }} + > +
+ + {server.name} +
+
+ ))} + + )} +
+
+ {selectedServer && ( + <> + + + + + + )}
-
-
+ } + />
diff --git a/frontend/src/IPRangesManager.jsx b/frontend/src/IPRangesManager.jsx index 8cec35c..b6f160d 100644 --- a/frontend/src/IPRangesManager.jsx +++ b/frontend/src/IPRangesManager.jsx @@ -790,6 +790,7 @@ function IPRangesManager() { } meta={} actions={ } meta={`Текущий сервер: ${currentServerLabel}`} actions={actions} /> diff --git a/frontend/src/MikrotikTools.jsx b/frontend/src/MikrotikTools.jsx index d3e6686..f615903 100644 --- a/frontend/src/MikrotikTools.jsx +++ b/frontend/src/MikrotikTools.jsx @@ -227,6 +227,7 @@ function MikrotikTools() {
} meta={`Текущий сервер: ${currentServerLabel}`} /> diff --git a/frontend/src/NetworkConfigManager.jsx b/frontend/src/NetworkConfigManager.jsx index 38b7f2b..7bb86e1 100644 --- a/frontend/src/NetworkConfigManager.jsx +++ b/frontend/src/NetworkConfigManager.jsx @@ -4,6 +4,7 @@ import { useNotify } from './components/NotifyProvider.jsx'; import FormModal from './components/FormModal.jsx'; import FormField from './components/FormField.jsx'; import ConfirmModal from './components/ConfirmModal.jsx'; +import PageHeader from './components/PageHeader.jsx'; import ServerAutocompleteInput from './components/ServerAutocompleteInput.jsx'; import GatewayAutocompleteInput from './components/GatewayAutocompleteInput.jsx'; import Tooltip from './components/Tooltip.jsx'; @@ -3231,100 +3232,91 @@ function NetworkConfigManager() { return (
- {/* Page Header */} -
-
-
-

- - Сетевые настройки -

-
-
-
- {/* Tabs as button group */} -
- - - - -
- + } + actions={ +
+
+ + -
+ + +
-
-
+ } + /> {/* Toolbar */}
diff --git a/frontend/src/ServerManager.jsx b/frontend/src/ServerManager.jsx index 604bf1e..292074e 100644 --- a/frontend/src/ServerManager.jsx +++ b/frontend/src/ServerManager.jsx @@ -33,6 +33,7 @@ import { ServerCard, ServerBulkActions } from './components/server/index.js'; +import PageHeader from './components/PageHeader.jsx'; const API_URL = '/api'; @@ -585,49 +586,39 @@ function ServerManager() { return (
- {/* Header */} -
-
-
-

- - Управление серверами -

-
-
-
- {/* Tabs */} -
- - -
- - {/* Actions */} - - -
+ + +
-
-
+ } + /> {/* Offcanvas: фильтры (только для вкладки «Серверы») */} {activeTab === 'servers' && ( diff --git a/frontend/src/components/PageHeader.jsx b/frontend/src/components/PageHeader.jsx index 37ff3b2..f8d1a32 100644 --- a/frontend/src/components/PageHeader.jsx +++ b/frontend/src/components/PageHeader.jsx @@ -1,7 +1,15 @@ import React from 'react' -/** Заголовок страницы в стиле Tabler (page-header + page-title + опционально actions справа) */ -function PageHeader({ title, pretitle, actions, meta }) { +/** + * Единый заголовок страницы в стиле Tabler UI. + * Используется на всех страницах для одинакового UX. + * @param {string} title - Заголовок страницы + * @param {React.ReactNode} [icon] - Иконка слева от заголовка (например, ) + * @param {string} [pretitle] - Небольшая надпись над заголовком (page-pretitle) + * @param {React.ReactNode} [meta] - Подзаголовок или мета-информация под заголовком + * @param {React.ReactNode} [actions] - Кнопки/действия справа (btn-list, btn-group) + */ +function PageHeader({ title, icon, pretitle, actions, meta }) { return (
@@ -9,7 +17,10 @@ function PageHeader({ title, pretitle, actions, meta }) { {pretitle && (
{pretitle}
)} -

{title}

+

+ {icon && {icon}} + {title} +

{meta && (
{meta}
)}