195 lines
5.9 KiB
TypeScript
Executable File
195 lines
5.9 KiB
TypeScript
Executable File
import { useEffect, useState } from 'react';
|
|
import { useLocation } from 'react-router-dom';
|
|
// @mui
|
|
import { styled, useTheme } from '@mui/material/styles';
|
|
import { Box, Stack, Drawer, Typography } from '@mui/material';
|
|
// hooks
|
|
import useResponsive from '../../../hooks/useResponsive';
|
|
import useCollapseDrawer from '../../../hooks/useCollapseDrawer';
|
|
// utils
|
|
import cssStyles from '../../../utils/cssStyles';
|
|
// config
|
|
import { NAVBAR } from '../../../config';
|
|
// components
|
|
import Logo from '../../../components/Logo';
|
|
import Scrollbar from '../../../components/Scrollbar';
|
|
import { NavSectionVertical } from '../../../components/nav-section';
|
|
//
|
|
// import navConfig from './NavConfig';
|
|
import NavbarAccount from './NavbarAccount';
|
|
import CollapseButton from './CollapseButton';
|
|
import useAuth from '@/hooks/useAuth';
|
|
import axios from '@/utils/axios';
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
const RootStyle = styled('div')(({ theme }) => ({
|
|
[theme.breakpoints.up('lg')]: {
|
|
flexShrink: 0,
|
|
transition: theme.transitions.create('width', {
|
|
duration: theme.transitions.duration.shorter,
|
|
}),
|
|
},
|
|
}));
|
|
|
|
// ----------------------------------------------------------------------
|
|
|
|
type Props = {
|
|
isOpenSidebar: boolean;
|
|
onCloseSidebar: VoidFunction;
|
|
};
|
|
|
|
export default function NavbarVertical({ isOpenSidebar, onCloseSidebar }: Props) {
|
|
const theme = useTheme();
|
|
|
|
const { pathname } = useLocation();
|
|
|
|
const {user} = useAuth()
|
|
|
|
const isDesktop = useResponsive('up', 'lg');
|
|
|
|
const { isCollapse, collapseClick, collapseHover, onToggleCollapse, onHoverEnter, onHoverLeave } =
|
|
useCollapseDrawer();
|
|
const [navConfig, setNavConfig] = useState([]);
|
|
useEffect(() => {
|
|
const fetchNavConfig = async () => {
|
|
try {
|
|
const response = await axios.get('/navigations');
|
|
const data = response.data.items;
|
|
|
|
// Pastikan user dan user.permissions terdefinisi dan merupakan array
|
|
const userPermissions = user.user?.permissions?.map(permission => permission.name) || [];
|
|
|
|
// Fungsi untuk memeriksa apakah pengguna memiliki izin untuk item tertentu
|
|
const hasPermission = (permission) => {
|
|
return userPermissions.includes(permission);
|
|
};
|
|
|
|
// Filter data berdasarkan izin pengguna
|
|
const filteredNavConfig = data.map(section => {
|
|
if (section.children && section.children.length > 0) {
|
|
// Cek apakah ada satu atau lebih children yang memiliki izin
|
|
const filteredChildren = section.children.filter(child => hasPermission(child.permission));
|
|
|
|
if (filteredChildren.length > 0) {
|
|
return {
|
|
...section,
|
|
children: filteredChildren
|
|
};
|
|
} else {
|
|
return null; // Lewati bagian yang tidak memiliki children dengan izin
|
|
}
|
|
}
|
|
// Jika tidak ada children, cek izin untuk section itu sendiri
|
|
return hasPermission(section.permission) ? section : null;
|
|
}).filter(section => section !== null);
|
|
|
|
setNavConfig([{ items: filteredNavConfig }]);
|
|
} catch (error) {
|
|
console.error('Gagal mengambil konfigurasi navigasi:', error);
|
|
}
|
|
};
|
|
|
|
fetchNavConfig();
|
|
}, [user]);
|
|
|
|
useEffect(() => {
|
|
if (isOpenSidebar) {
|
|
onCloseSidebar();
|
|
}
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [pathname]);
|
|
|
|
const renderContent = (
|
|
<Scrollbar
|
|
sx={{
|
|
height: 1,
|
|
'& .simplebar-content': { height: 1, display: 'flex', flexDirection: 'column' },
|
|
}}
|
|
>
|
|
<Stack
|
|
spacing={3}
|
|
sx={{
|
|
pt: 3,
|
|
pb: 2,
|
|
px: 2.5,
|
|
flexShrink: 0,
|
|
...(isCollapse && { alignItems: 'center' }),
|
|
}}
|
|
>
|
|
{isDesktop && !isCollapse ? (
|
|
<Stack direction="row" alignItems="center" justifyContent="space-between">
|
|
<Stack direction="row" alignItems="center">
|
|
<Logo />
|
|
<Typography ml={3}>Client Portal</Typography>
|
|
</Stack>
|
|
<CollapseButton onToggleCollapse={onToggleCollapse} collapseClick={collapseClick} />
|
|
</Stack>
|
|
) : (
|
|
<Stack direction="row" alignItems="center" justifyContent="space-between">
|
|
<Logo />
|
|
</Stack>
|
|
)}
|
|
|
|
<NavbarAccount isCollapse={isCollapse} />
|
|
</Stack>
|
|
|
|
<NavSectionVertical navConfig={navConfig} isCollapse={isCollapse} />
|
|
|
|
<Box sx={{ flexGrow: 1 }} />
|
|
</Scrollbar>
|
|
);
|
|
|
|
return (
|
|
<RootStyle
|
|
sx={{
|
|
width: {
|
|
lg: isCollapse ? NAVBAR.DASHBOARD_COLLAPSE_WIDTH : NAVBAR.DASHBOARD_WIDTH,
|
|
},
|
|
...(collapseClick && {
|
|
position: 'absolute',
|
|
}),
|
|
}}
|
|
>
|
|
{!isDesktop && (
|
|
<Drawer
|
|
open={isOpenSidebar}
|
|
onClose={onCloseSidebar}
|
|
PaperProps={{ sx: { width: NAVBAR.DASHBOARD_WIDTH } }}
|
|
>
|
|
{renderContent}
|
|
</Drawer>
|
|
)}
|
|
|
|
{isDesktop && (
|
|
<Drawer
|
|
open
|
|
variant="persistent"
|
|
onMouseEnter={onHoverEnter}
|
|
onMouseLeave={onHoverLeave}
|
|
PaperProps={{
|
|
sx: {
|
|
width: NAVBAR.DASHBOARD_WIDTH,
|
|
borderRightStyle: 'dashed',
|
|
bgcolor: 'background.default',
|
|
transition: (theme) =>
|
|
theme.transitions.create('width', {
|
|
duration: theme.transitions.duration.standard,
|
|
}),
|
|
...(isCollapse && {
|
|
width: NAVBAR.DASHBOARD_COLLAPSE_WIDTH,
|
|
}),
|
|
...(collapseHover && {
|
|
...cssStyles(theme).bgBlur(),
|
|
boxShadow: (theme) => theme.customShadows.z24,
|
|
}),
|
|
},
|
|
}}
|
|
>
|
|
{renderContent}
|
|
</Drawer>
|
|
)}
|
|
</RootStyle>
|
|
);
|
|
}
|