Files
auth-portal/apps/web/src/design-preview/preview-shell.tsx
T
DenozordecandClaude Sonnet 5.5 5de88e18c8 feat(design-preview): упростить страницы — без технической строки источника, дублей и лишних KPI
Убрана строка «Получено… GET /api/…» из шапок страниц (свежесть в кнопке i), дублирующий
баннер на «Пользователях», KPI на «Приложениях». Контент ограничен шириной 1480px.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-18 01:35:17 +07:00

54 lines
2.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 { TooltipProvider } from '@authportal/ui/components/tooltip'
import { CommandPalette, PreviewHeader, PreviewSidebar } from './preview-chrome'
import { UnsavedBar } from './unsaved-bar'
import './design-preview.css'
/** Оболочка макета: сайдбар, шапка, палитра и панель «Не сохранено». Монтируется после гидрации. */
export function PreviewShell({ children }: { children: ReactNode }) {
const [mounted, setMounted] = useState(false)
const [open, setOpen] = useState(true)
useEffect(() => {
// До 1100px меню сворачивается в колонку иконок (на мобильных его заменяет Sheet).
const mq = window.matchMedia('(min-width: 1100px)')
const sync = () => setOpen(mq.matches)
sync()
mq.addEventListener('change', sync)
setMounted(true)
return () => mq.removeEventListener('change', sync)
}, [])
if (!mounted) {
return (
<div className="flex min-h-svh flex-col gap-4 p-6" aria-busy>
<Skeleton className="h-12 w-full" />
<Skeleton className="h-64 w-full" />
</div>
)
}
return (
<TooltipProvider delay={0}>
<SidebarProvider open={open} onOpenChange={setOpen} style={{ '--sidebar-width': '240px' } as CSSProperties}>
<a
href="#main-content"
className="bg-background text-foreground ring-ring sr-only focus:not-sr-only focus:absolute focus:top-2 focus:left-2 focus:z-50 focus:rounded-md focus:px-3 focus:py-2 focus:text-sm focus:font-medium focus:ring-2"
>
К содержимому
</a>
<PreviewSidebar />
<SidebarInset id="main-content" className="min-w-0">
<PreviewHeader />
<div className="mx-auto flex w-full min-w-0 max-w-[1480px] flex-1 flex-col gap-4 px-4 py-4 pb-24 md:gap-6 md:px-6 md:py-5 md:pb-24">
{children}
</div>
</SidebarInset>
<CommandPalette />
<UnsavedBar />
</SidebarProvider>
</TooltipProvider>
)
}