diff --git a/apps/web/src/design-preview/preview-chrome.tsx b/apps/web/src/design-preview/preview-chrome.tsx index c3a9c65..6ff9bc0 100644 --- a/apps/web/src/design-preview/preview-chrome.tsx +++ b/apps/web/src/design-preview/preview-chrome.tsx @@ -3,9 +3,8 @@ import { Link, useNavigate, useRouterState } from '@tanstack/react-router' import { ActivityIcon, ArrowRightIcon, - CheckIcon, ChevronDownIcon, - ChevronsUpDownIcon, + LayoutGridIcon, CloudIcon, FingerprintIcon, GlobeIcon, @@ -29,8 +28,10 @@ import { Badge } from '@/components/reui/badge' import { Breadcrumb, BreadcrumbItem, + BreadcrumbLink, BreadcrumbList, BreadcrumbPage, + BreadcrumbSeparator, } from '@authportal/ui/components/breadcrumb' import { Button } from '@authportal/ui/components/button' import { @@ -69,7 +70,7 @@ import { } from '@authportal/ui/components/sidebar' import { cn } from '@authportal/ui/lib/utils' import { Segmented } from './bits' -import { FRESH_BY_PAGE, MONITOR_ITEMS, NAV_GROUPS, NAV_ITEMS, type NavItem } from './mock' +import { APP_SHORT, FRESH_BY_PAGE, MONITOR_ITEMS, NAV_GROUPS, NAV_ITEMS, type NavItem } from './mock' import { usePreviewStore } from './preview-store' const APP_ICON: Record = { @@ -82,90 +83,76 @@ const APP_ICON: Record = { mm: LayoutDashboardIcon, } -function PreviewAppSwitcher() { - const { isMobile } = useSidebar() +/** Бренд как в app-shell-12: логотип, название и подпись; переключатель приложений семейства — в шапке. */ +function PreviewBrand() { return ( - - } - > -
- -
-
- Auth Portal - Единый вход · SSO -
- -
- - - Приложения - - - Auth Portal - - - {APPS.map((app) => { - const Icon = APP_ICON[app.id] - return ( - toast(`Открыть ${app.title}`, { description: `${app.url} · SSO handoff (макет)` })} - > - - {app.title} - {app.id} - - ) - })} - - -
+ }> + + + + + Auth Portal + Единый вход · SSO + +
) } +/** Сетка приложений семейства в шапке (app-shell-12: Apps menu). */ +function AppsMenu() { + return ( + + }> + + + + + Приложения +
+ + + Auth Portal + + {APPS.map((app) => { + const Icon = APP_ICON[app.id] + return ( + toast(`Открыть ${app.title}`, { description: `${app.url} · SSO handoff (макет)` })} + className="h-auto flex-col gap-1.5 py-3 text-center [&_svg]:size-5" + > + + {APP_SHORT[app.id]} + + ) + })} +
+
+
+
+ ) +} + const LABEL_CLASS = 'text-muted-foreground text-[11px] font-medium uppercase' -function PreviewNavUser() { - const { isMobile } = useSidebar() +function PreviewUserMenu() { const { theme, setTheme, resolvedTheme } = useTheme() const { density, setDensity, contrast, setContrast } = usePreviewStore() const navigate = useNavigate() const current = theme === 'light' || theme === 'dark' ? theme : resolvedTheme === 'light' ? 'light' : 'dark' return ( - - - + - } - > -
- AD -
-
- Admin - admin@shnt.top -
- -
- + render={ -
-
-
+ ) } @@ -261,6 +246,64 @@ function NavEntry({ item, pathname, pinned, onTogglePin }: { item: NavItem; path ) } +function PreviewSecondaryNav() { + const { setPaletteOpen } = usePreviewStore() + return ( + + + + setPaletteOpen(true)} className="h-8! [&_svg]:size-3.5"> + + Поиск и команды + ⌘K + + + + } className="h-8! [&_svg]:size-3.5"> + + Журнал входов + + + + + ) +} + +/** Кнопка на кромке меню (app-shell-12): свернуть или развернуть. */ +function SidebarRailToggle() { + const { state, toggleSidebar } = useSidebar() + const expanded = state === 'expanded' + return ( + + ) +} + export function PreviewSidebar() { const pathname = useRouterState({ select: (s) => s.location.pathname }) const { pins, togglePin } = usePreviewStore() @@ -268,8 +311,8 @@ export function PreviewSidebar() { const pinned = NAV_ITEMS.filter((i) => pins.includes(i.id)) return ( - - + + {pinned.length > 0 ? ( @@ -318,9 +361,13 @@ export function PreviewSidebar() { ))} - - + +
+ +
+
+
) } @@ -462,35 +509,51 @@ export function PreviewHeader() { const current = NAV_ITEMS.find((i) => pathname === i.to || pathname.startsWith(`${i.to}/`)) return ( -
- - - - - - {current?.label ?? 'Макет'} - - - -
+
+
+ + + + + }>{current?.group ?? 'Портал'} + + + + {current?.label ?? 'Макет'} + + + +
+
- - + + + +
) } +/** Подвал страницы как в app-shell-12. */ +export function PreviewFooter() { + return ( +
+
+ 2026 © Auth Portal · shnt.top + +
+
+ ) +} + type PaletteEntry = { id: string group: string diff --git a/apps/web/src/design-preview/preview-shell.tsx b/apps/web/src/design-preview/preview-shell.tsx index 3874e8e..44a35bc 100644 --- a/apps/web/src/design-preview/preview-shell.tsx +++ b/apps/web/src/design-preview/preview-shell.tsx @@ -1,8 +1,9 @@ import { useEffect, useState, type CSSProperties, type ReactNode } from 'react' import { Skeleton } from '@authportal/ui/components/skeleton' import { SidebarInset, SidebarProvider } from '@authportal/ui/components/sidebar' +import { cn } from '@authportal/ui/lib/utils' import { TooltipProvider } from '@authportal/ui/components/tooltip' -import { CommandPalette, PreviewHeader, PreviewSidebar } from './preview-chrome' +import { CommandPalette, PreviewFooter, PreviewHeader, PreviewSidebar } from './preview-chrome' import { UnsavedBar } from './unsaved-bar' import './design-preview.css' @@ -31,7 +32,17 @@ export function PreviewShell({ children }: { children: ReactNode }) { return ( - + {children}
+