refactor(SettingsPage): streamline loading and success/error message display for improved clarity and user experience
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m56s
Publish Fast Tabler Docker image / build-and-push-fast (push) Successful in 1m56s
This commit is contained in:
@@ -246,33 +246,35 @@ export default function SettingsPage() {
|
|||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return (
|
return (
|
||||||
<div className="page-wrapper">
|
<>
|
||||||
<div className="page-body">
|
<PageHeader title="Настройки интерфейса" icon={<IconSettings size={24} />} pretitle="Интерфейс" />
|
||||||
<div className="container-xl">
|
|
||||||
<PageHeader
|
|
||||||
title="Настройки интерфейса"
|
|
||||||
icon={<IconSettings size={28} />}
|
|
||||||
pretitle="Интерфейс"
|
|
||||||
/>
|
|
||||||
<div className="card">
|
<div className="card">
|
||||||
<div className="card-body text-center py-5">
|
<div className="card-body text-center py-5">
|
||||||
<div className="spinner-border text-primary" role="status" />
|
<div className="spinner-border text-primary" role="status" />
|
||||||
<p className="mt-2 mb-0 text-muted">Загрузка настроек…</p>
|
<p className="mt-2 mb-0 text-muted">Загрузка настроек…</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="page-wrapper">
|
<>
|
||||||
<div className="page-body">
|
{error && (
|
||||||
<div className="container-xl">
|
<ErrorAlert message={error} onClose={() => setError('')} />
|
||||||
|
)}
|
||||||
|
{success && (
|
||||||
|
<div className="alert alert-success alert-dismissible mb-3" role="alert">
|
||||||
|
<div className="d-flex">
|
||||||
|
<div className="flex-grow-1">{success}</div>
|
||||||
|
</div>
|
||||||
|
<button type="button" className="btn-close" onClick={() => setSuccess('')} aria-label="Закрыть" />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<PageHeader
|
<PageHeader
|
||||||
title="Настройки интерфейса"
|
title="Настройки интерфейса"
|
||||||
icon={<IconSettings size={28} />}
|
icon={<IconSettings size={24} />}
|
||||||
pretitle="Интерфейс"
|
pretitle="Интерфейс"
|
||||||
meta="WebSocket, DoH, пинг, PTR зона"
|
meta="WebSocket, DoH, пинг, PTR зона"
|
||||||
actions={
|
actions={
|
||||||
@@ -283,9 +285,7 @@ export default function SettingsPage() {
|
|||||||
onClick={onSave}
|
onClick={onSave}
|
||||||
disabled={saving}
|
disabled={saving}
|
||||||
>
|
>
|
||||||
{saving && (
|
{saving && <span className="spinner-border spinner-border-sm me-2" />}
|
||||||
<span className="spinner-border spinner-border-sm me-2" />
|
|
||||||
)}
|
|
||||||
<IconDeviceFloppy size={18} className="me-1" />
|
<IconDeviceFloppy size={18} className="me-1" />
|
||||||
Сохранить
|
Сохранить
|
||||||
</button>
|
</button>
|
||||||
@@ -293,34 +293,10 @@ export default function SettingsPage() {
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{error && (
|
<div className="row">
|
||||||
<div className="mb-3">
|
{/* Сайдбар навигации — как блок в общем стиле страниц */}
|
||||||
<ErrorAlert message={error} onClose={() => setError('')} />
|
<div className="col-12 col-md-3 mb-4 mb-md-0">
|
||||||
</div>
|
<div className="card card-flat">
|
||||||
)}
|
|
||||||
|
|
||||||
{success && (
|
|
||||||
<div
|
|
||||||
className="alert alert-success alert-dismissible mb-3"
|
|
||||||
role="alert"
|
|
||||||
>
|
|
||||||
<div className="d-flex">
|
|
||||||
<div className="flex-grow-1">{success}</div>
|
|
||||||
</div>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="btn-close"
|
|
||||||
onClick={() => setSuccess('')}
|
|
||||||
aria-label="Закрыть"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Как в Tabler Settings: одна card, row g-0, col-md-3 border-end + col-md-9 */}
|
|
||||||
<div className="card">
|
|
||||||
<div className="row g-0">
|
|
||||||
{/* Левая колонка — навигация (list-group list-group-transparent) */}
|
|
||||||
<div className="col-12 col-md-3 border-end">
|
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
<div className="input-icon mb-3">
|
<div className="input-icon mb-3">
|
||||||
<span className="input-icon-addon">
|
<span className="input-icon-addon">
|
||||||
@@ -364,9 +340,11 @@ export default function SettingsPage() {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* Правая колонка — контент раздела */}
|
{/* Контент раздела — карточка как на других страницах */}
|
||||||
<div className="col-12 col-md-9 d-flex flex-column">
|
<div className="col-12 col-md-9">
|
||||||
|
<div className="card card-flat">
|
||||||
<div className="card-body">
|
<div className="card-body">
|
||||||
{activeSection === 'live-doh' && (
|
{activeSection === 'live-doh' && (
|
||||||
<>
|
<>
|
||||||
@@ -562,8 +540,6 @@ export default function SettingsPage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user