Portal/rsconcept/frontend/src/app/application-layout.tsx
2025-11-03 19:52:34 +03:00

64 lines
2.3 KiB
TypeScript

'use client';
import { Suspense } from 'react';
import { Outlet } from 'react-router';
import clsx from 'clsx';
import { ModalLoader } from '@/components/modal';
import { useBrowserNavigation } from '@/hooks/use-browser-navigation';
import { useAppLayoutStore, useMainHeight, useViewportHeight } from '@/stores/app-layout';
import { useDialogsStore } from '@/stores/dialogs';
import { NavigationState } from './navigation/navigation-context';
import { Footer } from './footer';
import { GlobalDialogs } from './global-dialogs';
import { GlobalLoader } from './global-loader';
import { ToasterThemed } from './global-toaster';
import { GlobalTooltips } from './global-tooltips';
import { MutationErrors } from './mutation-errors';
import { Navigation } from './navigation';
export function ApplicationLayout() {
useBrowserNavigation();
const mainHeight = useMainHeight();
const viewportHeight = useViewportHeight();
const noNavigationAnimation = useAppLayoutStore(state => state.noNavigationAnimation);
const noNavigation = useAppLayoutStore(state => state.noNavigation);
const toastBottom = useAppLayoutStore(state => state.toastBottom);
const noFooter = useAppLayoutStore(state => state.noFooter);
const activeDialog = useDialogsStore(state => state.active);
return (
<NavigationState>
<div className='min-w-80 antialiased h-full max-w-480 mx-auto'>
<ToasterThemed
className={clsx('sm:text-[14px]/[20px] text-[12px]/[16px]', noNavigationAnimation ? 'mt-9' : 'mt-17')}
aria-label='Оповещения'
autoClose={3000}
draggable={false}
pauseOnFocusLoss={false}
position={toastBottom ? 'bottom-right' : 'top-right'}
newestOnTop={toastBottom}
/>
<Suspense fallback={<ModalLoader />}>
<GlobalDialogs />
</Suspense>
<GlobalTooltips />
<Navigation />
<div className='overflow-x-auto max-w-dvw' style={{ maxHeight: viewportHeight }} inert={activeDialog !== null}>
<main className='cc-scroll-y overflow-y-auto' style={{ minHeight: mainHeight }}>
<GlobalLoader />
<MutationErrors />
<Outlet />
</main>
{!noNavigation && !noFooter ? <Footer /> : null}
</div>
</div>
</NavigationState>
);
}