'use client'; import React, { useCallback, useEffect, useRef, useContext } from 'react'; import { classNames, DomHandler } from 'primereact/utils'; import { usePathname, useSearchParams } from 'next/navigation'; import { LayoutContext } from './context/layoutcontext'; import { useEventListener, useMountEffect, useResizeListener, useUnmountEffect } from 'primereact/hooks'; import AppTopbar from './AppTopbar'; import AppConfig from './AppConfig'; import AppBreadCrumb from './AppBreadCrumb'; import { PrimeReactContext } from 'primereact/api'; import { Tooltip } from 'primereact/tooltip'; import { ChildContainerProps } from '@/types'; import { Toast } from 'primereact/toast'; import AppProfileMenu from './AppProfileMenu'; import AppSidebar from './AppSidebar'; import GlobalErrorHandler from '../components/GlobalErrorHandler'; const Layout = (props: ChildContainerProps) => { const { layoutConfig, layoutState, setLayoutState, isSlim, isSlimPlus, isHorizontal, isDesktop } = useContext(LayoutContext); const { setRipple } = useContext(PrimeReactContext); const topbarRef = useRef(null); const sidebarRef = useRef(null); const copyTooltipRef = useRef(null); const pathname = usePathname(); const searchParams = useSearchParams(); const [bindMenuOutsideClickListener, unbindMenuOutsideClickListener] = useEventListener({ type: 'click', listener: (event) => { const isOutsideClicked = !(sidebarRef.current.isSameNode(event.target) || sidebarRef.current.contains(event.target) || topbarRef.current.menubutton.isSameNode(event.target) || topbarRef.current.menubutton.contains(event.target)); if (isOutsideClicked) { hideMenu(); } } }); const [bindDocumentResizeListener, unbindDocumentResizeListener] = useResizeListener({ listener: () => { if (isDesktop() && !DomHandler.isTouchDevice()) { hideMenu(); } } }); const hideMenu = useCallback(() => { setLayoutState((prevLayoutState) => ({ ...prevLayoutState, overlayMenuActive: false, overlaySubmenuActive: false, staticMenuMobileActive: false, menuHoverActive: false, menuClick: false, resetMenu: (isSlim() || isSlimPlus() || isHorizontal()) && isDesktop() })); }, [isSlim, isHorizontal, isDesktop, setLayoutState]); const blockBodyScroll = () => { if (document.body.classList) { document.body.classList.add('blocked-scroll'); } else { document.body.className += ' blocked-scroll'; } }; const unblockBodyScroll = () => { if (document.body.classList) { document.body.classList.remove('blocked-scroll'); } else { document.body.className = document.body.className.replace(new RegExp('(^|\\b)' + 'blocked-scroll'.split(' ').join('|') + '(\\b|$)', 'gi'), ' '); } }; useMountEffect(() => { setRipple(layoutConfig.ripple); }); useEffect(() => { if (layoutState.overlayMenuActive || layoutState.staticMenuMobileActive || layoutState.overlaySubmenuActive) { bindMenuOutsideClickListener(); } if (layoutState.staticMenuMobileActive) { blockBodyScroll(); (isSlim() || isSlimPlus() || isHorizontal()) && bindDocumentResizeListener(); } return () => { unbindMenuOutsideClickListener(); unbindDocumentResizeListener(); unblockBodyScroll(); }; }, [layoutState.overlayMenuActive, layoutState.staticMenuMobileActive, layoutState.overlaySubmenuActive]); useEffect(() => { const onRouteChange = () => { hideMenu(); }; onRouteChange(); }, [pathname, searchParams]); useUnmountEffect(() => { unbindMenuOutsideClickListener(); }); const containerClassName = classNames('layout-wrapper', { 'layout-light': layoutConfig.colorScheme === 'light', 'layout-dark': layoutConfig.colorScheme === 'dark', 'layout-overlay': layoutConfig.menuMode === 'overlay', 'layout-static': layoutConfig.menuMode === 'static', 'layout-slim': layoutConfig.menuMode === 'slim', 'layout-slim-plus': layoutConfig.menuMode === 'slim-plus', 'layout-horizontal': layoutConfig.menuMode === 'horizontal', 'layout-reveal': layoutConfig.menuMode === 'reveal', 'layout-drawer': layoutConfig.menuMode === 'drawer', 'layout-static-inactive': layoutState.staticMenuDesktopInactive && layoutConfig.menuMode === 'static', 'layout-overlay-active': layoutState.overlayMenuActive, 'layout-mobile-active': layoutState.staticMenuMobileActive, 'p-ripple-disabled': !layoutConfig.ripple, 'layout-sidebar-active': layoutState.sidebarActive, 'layout-sidebar-anchored': layoutState.anchored }); return (
{props.children}
); }; export default Layout;