From 2d78c8156fbd2cc135924f8708e6d5bbbde27155 Mon Sep 17 00:00:00 2001 From: Denozordec Date: Tue, 19 May 2026 11:56:24 +0700 Subject: [PATCH] =?UTF-8?q?web(ui):=20app=20layout=20=E2=80=94=20sidebar,?= =?UTF-8?q?=20mobile=20sheet,=20topbar,=20PageHeader?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Cursor --- web/src/lib/AppShell.svelte | 207 ------------------ web/src/lib/ui/app/layout/app-layout.svelte | 33 +++ .../lib/ui/app/layout/app-mobile-nav.svelte | 45 ++++ .../lib/ui/app/layout/app-nav-links.svelte | 91 ++++++++ web/src/lib/ui/app/layout/app-sidebar.svelte | 56 +++++ web/src/lib/ui/app/layout/app-topbar.svelte | 38 ++++ web/src/lib/ui/app/layout/nav.ts | 29 +++ web/src/lib/ui/app/layout/theme-menu.svelte | 51 +++++ .../lib/ui/app/page-header/page-header.svelte | 40 ++++ web/src/routes/+layout.svelte | 4 +- web/src/routes/directories/+page.svelte | 21 +- 11 files changed, 393 insertions(+), 222 deletions(-) delete mode 100644 web/src/lib/AppShell.svelte create mode 100644 web/src/lib/ui/app/layout/app-layout.svelte create mode 100644 web/src/lib/ui/app/layout/app-mobile-nav.svelte create mode 100644 web/src/lib/ui/app/layout/app-nav-links.svelte create mode 100644 web/src/lib/ui/app/layout/app-sidebar.svelte create mode 100644 web/src/lib/ui/app/layout/app-topbar.svelte create mode 100644 web/src/lib/ui/app/layout/nav.ts create mode 100644 web/src/lib/ui/app/layout/theme-menu.svelte create mode 100644 web/src/lib/ui/app/page-header/page-header.svelte diff --git a/web/src/lib/AppShell.svelte b/web/src/lib/AppShell.svelte deleted file mode 100644 index d49f066..0000000 --- a/web/src/lib/AppShell.svelte +++ /dev/null @@ -1,207 +0,0 @@ - - - -
- - -
- {@render children?.()} -
-
-
diff --git a/web/src/lib/ui/app/layout/app-layout.svelte b/web/src/lib/ui/app/layout/app-layout.svelte new file mode 100644 index 0000000..3dfbe95 --- /dev/null +++ b/web/src/lib/ui/app/layout/app-layout.svelte @@ -0,0 +1,33 @@ + + + +
+ +
+
+ + EvoBGP +
+
+ {@render children()} +
+
+
+
diff --git a/web/src/lib/ui/app/layout/app-mobile-nav.svelte b/web/src/lib/ui/app/layout/app-mobile-nav.svelte new file mode 100644 index 0000000..84b696d --- /dev/null +++ b/web/src/lib/ui/app/layout/app-mobile-nav.svelte @@ -0,0 +1,45 @@ + + + + + + + + + + EvoBGP + +

Панель управления

+
+
+ +
+
+ (open = false)} /> +
+
+
diff --git a/web/src/lib/ui/app/layout/app-nav-links.svelte b/web/src/lib/ui/app/layout/app-nav-links.svelte new file mode 100644 index 0000000..712545f --- /dev/null +++ b/web/src/lib/ui/app/layout/app-nav-links.svelte @@ -0,0 +1,91 @@ + + + + +
+ + {#each bottomNav as item (item.href)} + {@const Icon = item.icon} + {@const active = isActive(item.href)} + {#if collapsed} + + + + + + + {item.label} + + {:else} + + + {item.label} + + {/if} + {/each} +
diff --git a/web/src/lib/ui/app/layout/app-sidebar.svelte b/web/src/lib/ui/app/layout/app-sidebar.svelte new file mode 100644 index 0000000..fd588be --- /dev/null +++ b/web/src/lib/ui/app/layout/app-sidebar.svelte @@ -0,0 +1,56 @@ + + + diff --git a/web/src/lib/ui/app/layout/app-topbar.svelte b/web/src/lib/ui/app/layout/app-topbar.svelte new file mode 100644 index 0000000..da8e5b2 --- /dev/null +++ b/web/src/lib/ui/app/layout/app-topbar.svelte @@ -0,0 +1,38 @@ + + +
+
+ {#if mobileNav} +
{@render mobileNav()}
+ {/if} +
+ {#if title} +

{title}

+ {/if} + {#if description} +

{description}

+ {/if} +
+ {#if actions} +
{@render actions()}
+ {/if} +
+
diff --git a/web/src/lib/ui/app/layout/nav.ts b/web/src/lib/ui/app/layout/nav.ts new file mode 100644 index 0000000..35e4d90 --- /dev/null +++ b/web/src/lib/ui/app/layout/nav.ts @@ -0,0 +1,29 @@ +import type { Component } from 'svelte'; +import Activity from '@lucide/svelte/icons/activity'; +import Boxes from '@lucide/svelte/icons/boxes'; +import BookOpen from '@lucide/svelte/icons/book-open'; +import CalendarClock from '@lucide/svelte/icons/calendar-clock'; +import Gauge from '@lucide/svelte/icons/gauge'; +import LayoutDashboard from '@lucide/svelte/icons/layout-dashboard'; +import Network from '@lucide/svelte/icons/network'; +import Settings from '@lucide/svelte/icons/settings'; +import Zap from '@lucide/svelte/icons/zap'; + +export type NavItem = { + href: string; + label: string; + icon: Component; +}; + +export const mainNav: NavItem[] = [ + { href: '/', label: 'Обзор', icon: LayoutDashboard }, + { href: '/modules', label: 'Модули', icon: Boxes }, + { href: '/directories', label: 'Справочники', icon: BookOpen }, + { href: '/network', label: 'Сеть', icon: Network }, + { href: '/revisions', label: 'Ревизии', icon: Activity }, + { href: '/operations', label: 'Операции', icon: Zap }, + { href: '/schedule', label: 'Расписание', icon: CalendarClock }, + { href: '/monitoring', label: 'Мониторинг', icon: Gauge } +]; + +export const bottomNav: NavItem[] = [{ href: '/settings', label: 'Настройки', icon: Settings }]; diff --git a/web/src/lib/ui/app/layout/theme-menu.svelte b/web/src/lib/ui/app/layout/theme-menu.svelte new file mode 100644 index 0000000..3fcc0ed --- /dev/null +++ b/web/src/lib/ui/app/layout/theme-menu.svelte @@ -0,0 +1,51 @@ + + + + + + + + + + Тема + + + + Светлая + + + + Тёмная + + + + Как в системе + + + + diff --git a/web/src/lib/ui/app/page-header/page-header.svelte b/web/src/lib/ui/app/page-header/page-header.svelte new file mode 100644 index 0000000..eaaeafb --- /dev/null +++ b/web/src/lib/ui/app/page-header/page-header.svelte @@ -0,0 +1,40 @@ + + +
+
+ {#if Icon} + + {/if} +
+

{title}

+ {#if description} +

{description}

+ {/if} +
+
+ {#if actions} +
{@render actions()}
+ {/if} +
diff --git a/web/src/routes/+layout.svelte b/web/src/routes/+layout.svelte index 5362d4d..48f9660 100644 --- a/web/src/routes/+layout.svelte +++ b/web/src/routes/+layout.svelte @@ -3,7 +3,7 @@ import { onMount } from 'svelte'; import './layout.css'; import favicon from '$lib/assets/favicon.svg'; - import AppShell from '$lib/AppShell.svelte'; + import AppLayout from '$lib/ui/app/layout/app-layout.svelte'; import { applyTheme, readTheme, THEME_STORAGE_KEY, type ThemePreference } from '$lib/theme.js'; import { Toaster } from 'svelte-sonner'; @@ -42,4 +42,4 @@ EvoBGP -{@render children()} +{@render children()} diff --git a/web/src/routes/directories/+page.svelte b/web/src/routes/directories/+page.svelte index 14febd1..fa568d1 100644 --- a/web/src/routes/directories/+page.svelte +++ b/web/src/routes/directories/+page.svelte @@ -46,6 +46,7 @@ import Trash2 from '@lucide/svelte/icons/trash-2'; import RefreshCw from '@lucide/svelte/icons/refresh-cw'; import BookOpen from '@lucide/svelte/icons/book-open'; + import PageHeader from '$lib/ui/app/page-header/page-header.svelte'; // --- Communities --- let communities = $state([]); @@ -183,19 +184,13 @@ } -
-
- -
-

Справочники

-

Сообщества BGP и DoH-профили для резолвинга доменов.

-
-
+
+