sozsoft-platform/ui/src/components/template/MobileNav.tsx
2026-06-15 23:05:44 +03:00

102 lines
3.4 KiB
TypeScript

import { useState, Suspense, lazy } from 'react'
import classNames from 'classnames'
import Drawer from '@/components/ui/Drawer'
import { DIR_RTL, MODE_DARK, NAV_MODE_DARK, NAV_MODE_THEMED } from '@/constants/theme.constant'
import withHeaderItem, { WithHeaderItemProps } from '@/utils/hoc/withHeaderItem'
import NavToggle from '@/components/shared/NavToggle'
import useResponsive from '@/utils/hooks/useResponsive'
import { useStoreState } from '@/store'
import { ROUTES_ENUM } from '@/routes/route.constant'
import type { NavigationTree } from '@/proxy/menus/navigation'
const VerticalMenuContent = lazy(() => import('@/components/template/VerticalMenuContent'))
type MobileNavToggleProps = {
toggled?: boolean
}
const MobileNavToggle = withHeaderItem<MobileNavToggleProps & WithHeaderItemProps>(NavToggle)
const intranetDashboardNavItem: NavigationTree = {
key: ROUTES_ENUM.protected.dashboard,
path: ROUTES_ENUM.protected.dashboard,
title: 'Intranet',
translateKey: 'App.Intranet',
icon: 'FaHome',
type: 'item',
authority: [],
subMenu: [],
}
const MobileNav = () => {
const [isOpen, setIsOpen] = useState(false)
const openDrawer = () => {
setIsOpen(true)
}
const onDrawerClose = () => {
setIsOpen(false)
}
const themeColor = useStoreState((state) => state.theme.themeColor)
const primaryColorLevel = useStoreState((state) => state.theme.primaryColorLevel)
const navMode = useStoreState((state) => state.theme.navMode)
const mode = useStoreState((state) => state.theme.mode)
const direction = useStoreState((state) => state.theme.direction)
const currentRouteKey = useStoreState((state) => state.base.common.currentRouteKey)
const userAuthority = useStoreState((state) => state.auth.user.authority)
const { smaller } = useResponsive()
const mobileNavMode = mode === MODE_DARK && navMode !== NAV_MODE_THEMED ? NAV_MODE_DARK : navMode
const navColor = () => {
if (mobileNavMode === NAV_MODE_THEMED) {
return `bg-${themeColor}-${primaryColorLevel} side-nav-${navMode}`
}
return `side-nav-${mobileNavMode}`
}
const { mainMenu: navigationConfig } = useStoreState((state) => state.abpConfig.menu)
const mobileNavigationConfig = [intranetDashboardNavItem, ...navigationConfig]
return (
<>
{smaller.md && (
<>
<div className="text-2xl" onClick={openDrawer}>
<MobileNavToggle toggled={isOpen} />
</div>
<Drawer
title="Navigation"
isOpen={isOpen}
className={classNames(mode === MODE_DARK && 'bg-gray-800 text-gray-100')}
headerClass={classNames(mode === MODE_DARK && 'border-gray-700')}
bodyClass={classNames(navColor(), 'p-0')}
width={320}
placement={direction === DIR_RTL ? 'right' : 'left'}
onClose={onDrawerClose}
onRequestClose={onDrawerClose}
>
<Suspense fallback={<></>}>
{isOpen && (
<VerticalMenuContent
navMode={mobileNavMode}
collapsed={false}
navigationTree={mobileNavigationConfig}
routeKey={currentRouteKey}
userAuthority={userAuthority as string[]}
direction={direction}
onMenuItemClick={onDrawerClose}
/>
)}
</Suspense>
</Drawer>
</>
)}
</>
)
}
export default MobileNav