initial commit

This commit is contained in:
2026-05-13 17:48:36 +05:30
commit 5a80256856
305 changed files with 80994 additions and 0 deletions

View File

@@ -0,0 +1,32 @@
// material-ui
import { Button, Link, CardMedia, Stack, Typography } from '@mui/material';
// project import
import MainCard from 'components/MainCard';
// assets
import avatar from 'assets/images/users/avatar-group.png';
import AnimateButton from 'components/@extended/AnimateButton';
// ==============================|| DRAWER CONTENT - NAVIGATION CARD ||============================== //
const NavCard = () => (
<MainCard sx={{ bgcolor: 'grey.50', m: 3 }}>
<Stack alignItems="center" spacing={2.5}>
<CardMedia component="img" image={avatar} />
<Stack alignItems="center">
<Typography variant="h5">Help?</Typography>
<Typography variant="h6" color="secondary">
Get to resolve query
</Typography>
</Stack>
<AnimateButton>
<Button variant="shadow" size="small" component={Link} href="https://codedthemes.support-hub.io/" target="_blank">
Support
</Button>
</AnimateButton>
</Stack>
</MainCard>
);
export default NavCard;

View File

@@ -0,0 +1,503 @@
import PropTypes from 'prop-types';
import React, { useEffect, useState, useMemo } from 'react';
import { useLocation, useNavigate } from 'react-router-dom';
// material-ui
import { styled, useTheme } from '@mui/material/styles';
import {
Box,
Collapse,
ClickAwayListener,
List,
ListItemButton,
ListItemIcon,
ListItemText,
Paper,
Popper,
Typography,
useMediaQuery
} from '@mui/material';
// project import
import NavItem from './NavItem';
import Dot from 'components/@extended/Dot';
import SimpleBar from 'components/third-party/SimpleBar';
import Transitions from 'components/@extended/Transitions';
import useConfig from 'hooks/useConfig';
import { dispatch, useSelector } from 'store';
import { activeItem } from 'store/reducers/menu';
import { MenuOrientation, ThemeMode } from 'config';
// assets
import { BorderOutlined, DownOutlined, UpOutlined, RightOutlined } from '@ant-design/icons';
// mini-menu - wrapper
const PopperStyled = styled(Popper)(({ theme }) => ({
overflow: 'visible',
zIndex: 1202,
minWidth: 180,
'&:before': {
content: '""',
display: 'block',
position: 'absolute',
top: 38,
left: -5,
width: 10,
height: 10,
backgroundColor: theme.palette.background.paper,
transform: 'translateY(-50%) rotate(45deg)',
zIndex: 120,
borderLeft: `1px solid ${theme.palette.grey.A800}`,
borderBottom: `1px solid ${theme.palette.grey.A800}`
}
}));
// ==============================|| NAVIGATION - LIST COLLAPSE ||============================== //
const NavCollapse = ({ menu, level, parentId, setSelectedItems, selectedItems, setSelectedLevel, selectedLevel }) => {
const theme = useTheme();
const downLG = useMediaQuery(theme.breakpoints.down('lg'));
const menuState = useSelector((state) => state.menu);
const { drawerOpen } = menuState;
const { menuOrientation } = useConfig();
const navigation = useNavigate();
const [open, setOpen] = useState(false);
const [selected, setSelected] = useState(null);
const [anchorEl, setAnchorEl] = useState(null);
const handleClick = (event) => {
setAnchorEl(null);
setSelectedLevel(level);
if (drawerOpen) {
setOpen(!open);
setSelected(!selected ? menu.id : null);
setSelectedItems(!selected ? menu.id : '');
if (menu.url) navigation(`${menu.url}`);
} else {
setAnchorEl(event?.currentTarget);
}
};
const handlerIconLink = () => {
if (!drawerOpen) {
if (menu.url) navigation(`${menu.url}`);
setSelected(menu.id);
}
};
const handleHover = (event) => {
setAnchorEl(event?.currentTarget);
if (!drawerOpen) {
setSelected(menu.id);
}
};
const miniMenuOpened = Boolean(anchorEl);
const handleClose = () => {
setOpen(false);
if (!miniMenuOpened) {
if (!menu.url) {
setSelected(null);
}
}
setAnchorEl(null);
};
useMemo(() => {
if (selected === selectedItems) {
if (level === 1) {
setOpen(true);
}
} else {
if (level === selectedLevel) {
setOpen(false);
if (!miniMenuOpened && !drawerOpen && !selected) {
setSelected(null);
}
if (drawerOpen) {
setSelected(null);
}
}
}
}, [selectedItems, level, selected, miniMenuOpened, drawerOpen, selectedLevel]);
const { pathname } = useLocation();
useEffect(() => {
if (pathname === menu.url) {
setSelected(menu.id);
}
// eslint-disable-next-line
}, [pathname]);
const checkOpenForParent = (child, id) => {
child.forEach((item) => {
if (item.url === pathname) {
setOpen(true);
setSelected(id);
}
});
};
useEffect(() => {
setOpen(false);
if (!miniMenuOpened) {
setSelected(null);
}
if (miniMenuOpened) setAnchorEl(null);
if (menu.children) {
menu.children.forEach((item) => {
if (item.children?.length) {
checkOpenForParent(item.children, menu.id);
}
if (pathname && pathname.includes('product-details')) {
if (item.url && item.url.includes('product-details')) {
setSelected(menu.id);
setOpen(true);
}
}
if (item.url === pathname) {
setSelected(menu.id);
setOpen(true);
}
});
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [pathname, menu.children]);
useEffect(() => {
if (menu.url === pathname) {
dispatch(activeItem({ openItem: [menu.id] }));
setSelected(menu.id);
setAnchorEl(null);
setOpen(true);
}
}, [pathname, menu]);
const navCollapse = menu.children?.map((item) => {
switch (item.type) {
case 'collapse':
return (
<NavCollapse
key={item.id}
setSelectedItems={setSelectedItems}
setSelectedLevel={setSelectedLevel}
selectedLevel={selectedLevel}
selectedItems={selectedItems}
menu={item}
level={level + 1}
parentId={parentId}
/>
);
case 'item':
return <NavItem key={item.id} item={item} level={level + 1} />;
default:
return (
<Typography key={item.id} variant="h6" color="error" align="center">
Fix - Collapse or Item
</Typography>
);
}
});
const isSelected = selected === menu.id;
const borderIcon = level === 1 ? <BorderOutlined style={{ fontSize: '1rem' }} /> : false;
const Icon = menu.icon;
const menuIcon = menu.icon ? <Icon style={{ fontSize: drawerOpen ? '1rem' : '1.25rem', color: 'white' }} /> : borderIcon;
// const textColor = theme.palette.mode === ThemeMode.DARK ? 'grey.400' : 'text.primary';
// const iconSelectedColor = theme.palette.mode === ThemeMode.DARK && drawerOpen ? theme.palette.text.primary : theme.palette.primary.main;
const popperId = miniMenuOpened ? `collapse-pop-${menu.id}` : undefined;
const FlexBox = { display: 'flex', justifyContent: 'space-between', alignItems: 'center', width: '100%' };
const textColor = 'white';
const iconSelectedColor = 'white';
// const isSelected = true;
return (
<>
{menuOrientation === MenuOrientation.VERTICAL || downLG ? (
<>
<ListItemButton
disableRipple
selected={selected === menu.id}
{...(!drawerOpen && { onMouseEnter: handleClick, onMouseLeave: handleClose })}
onClick={handleClick}
sx={{
pl: drawerOpen ? `${level * 28}px` : 1.5,
py: !drawerOpen && level === 1 ? 1.25 : 1,
...(drawerOpen && {
'&:hover': {
// bgcolor: theme.palette.mode === ThemeMode.DARK ? 'divider' : 'primary.lighter'
bgcolor: '#7b1fa2'
},
'&.Mui-selected': {
bgcolor: 'transparent',
color: iconSelectedColor,
'&:hover': { color: iconSelectedColor, bgcolor: theme.palette.mode === ThemeMode.DARK ? 'divider' : 'transparent' }
}
}),
...(!drawerOpen && {
'&:hover': {
bgcolor: 'transparent'
// bgcolor:'#7b1fa2'
},
'&.Mui-selected': {
'&:hover': {
bgcolor: 'transparent'
},
bgcolor: 'transparent'
}
})
}}
>
{menuIcon && (
<ListItemIcon
onClick={handlerIconLink}
sx={{
minWidth: 28,
// color: selected === menu.id ? 'primary.main' : textColor,
// color: selected === menu.id ? textColor : textColor,
// bgcolor:'white',
// color:'white',
...(!drawerOpen && {
borderRadius: 1.5,
width: 36,
height: 36,
alignItems: 'center',
justifyContent: 'center',
'&:hover': {
// bgcolor: theme.palette.mode === ThemeMode.DARK ? 'secondary.light' : 'secondary.lighter'
bgcolor: '#7b1fa2',
color: 'white'
}
}),
...(!drawerOpen &&
selected === menu.id && {
bgcolor: 'primary.light',
color: 'primary.main',
'&:hover': {
bgcolor: '#7b1fa2',
color: 'primary.main'
}
})
}}
>
{menuIcon}
</ListItemIcon>
)}
{(drawerOpen || (!drawerOpen && level !== 1)) && (
<ListItemText
primary={
<Typography
variant="h6"
// color={selected === menu.id ? 'primary' : textColor}
// color={'white'}
color={selected === menu.id ? textColor : textColor}
>
{menu.title}
</Typography>
}
secondary={
menu.caption && (
<Typography variant="caption" color="secondary">
{menu.caption}
</Typography>
)
}
/>
)}
{(drawerOpen || (!drawerOpen && level !== 1)) &&
(miniMenuOpened || open ? (
<UpOutlined
style={{
fontSize: '0.625rem',
marginLeft: 1,
// color: theme.palette.primary.main
color: 'white'
}}
/>
) : (
<DownOutlined
style={{
fontSize: '0.625rem',
marginLeft: 1,
color: 'white'
}}
/>
))}
{!drawerOpen && (
<PopperStyled
open={miniMenuOpened}
anchorEl={anchorEl}
placement="right-start"
style={{
zIndex: 2001
}}
popperOptions={{
modifiers: [
{
name: 'offset',
options: {
offset: [-12, 1]
}
}
]
}}
>
{({ TransitionProps }) => (
<Transitions in={miniMenuOpened} {...TransitionProps}>
<Paper
sx={{
overflow: 'hidden',
mt: 1.5,
boxShadow: theme.customShadows.z1,
backgroundImage: 'none',
border: `2px solid ${theme.palette.primary.main}`,
width: 'auto'
}}
>
<ClickAwayListener onClickAway={handleClose}>
<SimpleBar
sx={{
overflowX: 'hidden',
overflowY: 'auto',
maxHeight: 'calc(100vh - 170px)'
}}
>
{navCollapse}
</SimpleBar>
</ClickAwayListener>
</Paper>
</Transitions>
)}
</PopperStyled>
)}
</ListItemButton>
{drawerOpen && (
<Collapse in={open} timeout="auto" unmountOnExit>
<List sx={{ p: 0 }}>{navCollapse}</List>
</Collapse>
)}
</>
) : (
<>
<ListItemButton
id={`boundary-${popperId}`}
disableRipple
selected={isSelected}
onMouseEnter={handleHover}
onMouseLeave={handleClose}
onClick={handleHover}
aria-describedby={popperId}
sx={{
'&.Mui-selected': {
bgcolor: 'transparent'
}
}}
>
<Box onClick={handlerIconLink} sx={FlexBox}>
{menuIcon && (
<ListItemIcon
sx={{
my: 'auto',
minWidth: !menu.icon ? 18 : 36
// color: theme.palette.secondary.dark
// color:'white'
}}
>
{menuIcon}
</ListItemIcon>
)}
{!menuIcon && level !== 1 && (
<ListItemIcon
sx={{ my: 'auto', minWidth: !menu.icon ? 18 : 36, bgcolor: 'transparent', '&:hover': { bgcolor: 'transparent' } }}
>
<Dot size={4} color={isSelected ? 'primary' : 'secondary'} />
</ListItemIcon>
)}
<ListItemText
primary={
<Typography
variant="body1"
// color="inherit"
// color="white"
sx={{ my: 'auto' }}
>
{menu.title}
</Typography>
}
/>
{miniMenuOpened ? <RightOutlined /> : <DownOutlined />}
</Box>
{anchorEl && (
<PopperStyled
id={popperId}
open={miniMenuOpened}
anchorEl={anchorEl}
placement="right-start"
style={{
zIndex: 2001
}}
modifiers={[
{
name: 'offset',
options: {
offset: [-10, 0]
}
}
]}
>
{({ TransitionProps }) => (
<Transitions in={miniMenuOpened} {...TransitionProps}>
<Paper
sx={{
overflow: 'hidden',
mt: 1.5,
py: 0.5,
boxShadow: theme.shadows[8],
backgroundImage: 'none'
}}
>
<ClickAwayListener onClickAway={handleClose}>
<SimpleBar
sx={{
overflowX: 'hidden',
overflowY: 'auto',
maxHeight: 'calc(100vh - 170px)'
}}
>
{navCollapse}
</SimpleBar>
</ClickAwayListener>
</Paper>
</Transitions>
)}
</PopperStyled>
)}
</ListItemButton>
</>
)}
</>
);
};
NavCollapse.propTypes = {
menu: PropTypes.object,
level: PropTypes.number,
parentId: PropTypes.string,
setSelectedItems: PropTypes.func,
selectedItems: PropTypes.string,
setSelectedLevel: PropTypes.func,
selectedLevel: PropTypes.number
};
export default NavCollapse;

View File

@@ -0,0 +1,343 @@
import PropTypes from 'prop-types';
import { Fragment, useEffect, useState } from 'react';
import { useLocation } from 'react-router';
// material-ui
import { styled, useTheme } from '@mui/material/styles';
import {
Box,
ClickAwayListener,
List,
ListItemButton,
ListItemIcon,
ListItemText,
Paper,
Popper,
Typography,
useMediaQuery
} from '@mui/material';
// third-party
import { FormattedMessage } from 'react-intl';
// project import
import NavItem from './NavItem';
import NavCollapse from './NavCollapse';
import SimpleBar from 'components/third-party/SimpleBar';
import Transitions from 'components/@extended/Transitions';
import { MenuOrientation } from 'config';
import useConfig from 'hooks/useConfig';
import { dispatch, useSelector } from 'store';
import { activeID } from 'store/reducers/menu';
// assets
import { DownOutlined, RightOutlined } from '@ant-design/icons';
// ==============================|| NAVIGATION - LIST GROUP ||============================== //
const PopperStyled = styled(Popper)(({ theme }) => ({
overflow: 'visible',
zIndex: 1202,
minWidth: 180,
'&:before': {
content: '""',
display: 'block',
position: 'absolute',
top: 5,
left: 32,
width: 12,
height: 12,
transform: 'translateY(-50%) rotate(45deg)',
zIndex: 120,
borderWidth: '6px',
borderStyle: 'solid',
borderColor: `${theme.palette.background.paper} transparent transparent ${theme.palette.background.paper}`
}
}));
const NavGroup = ({ item, lastItem, remItems, lastItemId, setSelectedItems, selectedItems, setSelectedLevel, selectedLevel }) => {
const theme = useTheme();
const { pathname } = useLocation();
const { menuOrientation } = useConfig();
const menu = useSelector((state) => state.menu);
const { drawerOpen, selectedID } = menu;
const downLG = useMediaQuery(theme.breakpoints.down('lg'));
const [anchorEl, setAnchorEl] = useState(null);
const [currentItem, setCurrentItem] = useState(item);
const openMini = Boolean(anchorEl);
useEffect(() => {
if (lastItem) {
if (item.id === lastItemId) {
const localItem = { ...item };
const elements = remItems.map((ele) => ele.elements);
localItem.children = elements.flat(1);
setCurrentItem(localItem);
} else {
setCurrentItem(item);
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [item, lastItem, downLG]);
const checkOpenForParent = (child, id) => {
child.forEach((ele) => {
if (ele.children?.length) {
checkOpenForParent(ele.children, currentItem.id);
}
if (ele.url === pathname) {
dispatch(activeID(id));
}
});
};
const checkSelectedOnload = (data) => {
const childrens = data.children ? data.children : [];
childrens.forEach((itemCheck) => {
if (itemCheck.children?.length) {
checkOpenForParent(itemCheck.children, currentItem.id);
}
if (itemCheck.url === pathname) {
dispatch(activeID(currentItem.id));
}
});
};
useEffect(() => {
checkSelectedOnload(currentItem);
if (openMini) setAnchorEl(null);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [pathname, currentItem]);
const handleClick = (event) => {
if (!openMini) {
setAnchorEl(event?.currentTarget);
}
};
const handleClose = () => {
setAnchorEl(null);
};
const Icon = currentItem?.icon;
const itemIcon = currentItem?.icon ? (
<Icon
style={{
fontSize: 20,
stroke: '1.5',
color: selectedID === currentItem.id ? theme.palette.primary.main : theme.palette.secondary.dark
}}
/>
) : null;
const navCollapse = item.children?.map((menuItem) => {
switch (menuItem.type) {
case 'collapse':
return (
<NavCollapse
key={menuItem.id}
menu={menuItem}
setSelectedItems={setSelectedItems}
setSelectedLevel={setSelectedLevel}
selectedLevel={selectedLevel}
selectedItems={selectedItems}
level={1}
parentId={currentItem.id}
/>
);
case 'item':
return <NavItem key={menuItem.id} item={menuItem} level={1} />;
default:
}
});
const moreItems = remItems.map((itemRem, i) => (
<Fragment key={i}>
{itemRem.title && (
<Typography variant="caption" sx={{ pl: 2 }}>
{itemRem.title}
</Typography>
)}
{itemRem?.elements?.map((menu) => {
switch (menu.type) {
case 'collapse':
return (
<NavCollapse
key={menu.id}
menu={menu}
level={1}
parentId={currentItem.id}
setSelectedItems={setSelectedItems}
setSelectedLevel={setSelectedLevel}
selectedLevel={selectedLevel}
selectedItems={selectedItems}
/>
);
case 'item':
return <NavItem key={menu.id} item={menu} level={1} />;
default:
return (
<Typography key={menu.id} variant="h6" color="error" align="center">
Menu Items Error
</Typography>
);
}
})}
</Fragment>
));
// menu list collapse & items
const items = currentItem.children?.map((menu) => {
switch (menu.type) {
case 'collapse':
return (
<NavCollapse
key={menu.id}
menu={menu}
level={1}
parentId={currentItem.id}
setSelectedItems={setSelectedItems}
setSelectedLevel={setSelectedLevel}
selectedLevel={selectedLevel}
selectedItems={selectedItems}
/>
);
case 'item':
return <NavItem key={menu.id} item={menu} level={1} />;
default:
return (
<Typography key={menu.id} variant="h6" color="error" align="center">
Menu Items Error
</Typography>
);
}
});
const popperId = openMini ? `group-pop-${item.id}` : undefined;
return (
<>
{menuOrientation === MenuOrientation.VERTICAL || downLG ? (
<List
subheader={
item.title &&
drawerOpen && (
<Box sx={{ pl: 3, mb: 1.5 }}>
<Typography
variant="subtitle2"
sx={{ color: '#fff' }}
>
{item.title}
</Typography>
{item.caption && (
<Typography variant="caption" color="secondary">
{item.caption}
</Typography>
)}
</Box>
)
}
sx={{ mt: drawerOpen && item.title ? 1.5 : 0, py: 0, zIndex: 0 }}
>
{navCollapse}
</List>
) : (
<List>
<ListItemButton
selected={selectedID === currentItem.id}
sx={{
p: 1,
my: 0.5,
mr: 1,
display: 'flex',
alignItems: 'center',
backgroundColor: 'inherit',
'&.Mui-selected': {
bgcolor: 'transparent'
}
}}
onMouseEnter={handleClick}
onClick={handleClick}
onMouseLeave={handleClose}
aria-describedby={popperId}
>
{itemIcon && (
<ListItemIcon sx={{ minWidth: 28 }}>
{currentItem.id === lastItemId ? <DownOutlined style={{ fontSize: 20, stroke: '1.5' }} /> : itemIcon}
</ListItemIcon>
)}
<ListItemText
sx={{ mr: 1 }}
primary={
<Typography
variant="body1"
color={selectedID === currentItem.id ? theme.palette.primary.main : theme.palette.secondary.dark}
>
{currentItem.id === lastItemId ? <FormattedMessage id="More Items" /> : currentItem.title}
</Typography>
}
/>
{openMini ? (
<DownOutlined style={{ fontSize: 16, stroke: '1.5' }} />
) : (
<RightOutlined style={{ fontSize: 16, stroke: '1.5' }} />
)}
{anchorEl && (
<PopperStyled
id={popperId}
open={openMini}
anchorEl={anchorEl}
placement="bottom-start"
style={{
zIndex: 2001
}}
>
{({ TransitionProps }) => (
<Transitions in={openMini} {...TransitionProps}>
<Paper
sx={{
mt: 0.5,
py: 1.25,
boxShadow: theme.shadows[8],
backgroundImage: 'none'
}}
>
<ClickAwayListener onClickAway={handleClose}>
<SimpleBar
sx={{
overflowX: 'hidden',
overflowY: 'auto',
maxHeight: 'calc(100vh - 170px)'
}}
>
{currentItem.id !== lastItemId ? items : moreItems}
</SimpleBar>
</ClickAwayListener>
</Paper>
</Transitions>
)}
</PopperStyled>
)}
</ListItemButton>
</List>
)}
</>
);
};
NavGroup.propTypes = {
item: PropTypes.object,
lastItem: PropTypes.number,
remItems: PropTypes.array,
lastItemId: PropTypes.string,
setSelectedItems: PropTypes.func,
selectedItems: PropTypes.string,
setSelectedLevel: PropTypes.func,
selectedLevel: PropTypes.number
};
export default NavGroup;

View File

@@ -0,0 +1,283 @@
import PropTypes from 'prop-types';
import { forwardRef, useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
// material-ui
import { useTheme } from '@mui/material/styles';
import { Avatar, Chip, ListItemButton, ListItemIcon, ListItemText, Typography, useMediaQuery } from '@mui/material';
// project import
import Dot from 'components/@extended/Dot';
import { MenuOrientation, ThemeMode } from 'config';
import useConfig from 'hooks/useConfig';
// import { dispatch, useSelector } from 'store';
import { activeItem, openDrawer, setSelectedMenu } from 'store/reducers/menu';
// ==============================|| NAVIGATION - LIST ITEM ||============================== //
const NavItem = ({ item, level }) => {
const theme = useTheme();
const dispatch = useDispatch();
const { menuOrientation } = useConfig();
const { drawerOpen, openItem } = useSelector((state) => state.menu);
const downLG = useMediaQuery(theme.breakpoints.down('lg'));
let itemTarget = '_self';
if (item.target) {
itemTarget = '_blank';
}
let listItemProps = { component: forwardRef((props, ref) => <Link {...props} to={item.url} target={itemTarget} ref={ref} />) };
if (item?.external) {
listItemProps = { component: 'a', href: item.url, target: itemTarget };
}
const Icon = item.icon;
const isSelected = openItem.findIndex((id) => id === item.id) > -1;
const itemIcon = item.icon ? (
<Icon style={{ fontSize: drawerOpen ? '1rem' : '1.25rem', color: isSelected ? '#662582' : '#fff' }} />
) : (
false
);
// const { pathname } = useLocation();
const pathname = document.location.pathname;
// active menu item on page load
useEffect(() => {
if (pathname && pathname.includes('product-details')) {
if (item.url && item.url.includes('product-details')) {
dispatch(activeItem({ openItem: [item.id] }));
}
}
if (pathname && pathname.includes('kanban')) {
if (item.url && item.url.includes('kanban')) {
dispatch(activeItem({ openItem: [item.id] }));
}
}
if (pathname.includes(item.url)) {
dispatch(activeItem({ openItem: [item.id] }));
}
// eslint-disable-next-line
}, [pathname]);
useEffect(() => {
dispatch(setSelectedMenu(pathname));
}, [pathname]);
const textColor = theme.palette.mode === ThemeMode.DARK ? 'grey.400' : '#fff';
const iconSelectedColor = theme.palette.mode === ThemeMode.DARK && drawerOpen ? 'text.primary' : 'primary.main';
return (
<>
{menuOrientation === MenuOrientation.VERTICAL || downLG ? (
<ListItemButton
{...listItemProps}
disabled={item.disabled}
selected={isSelected}
onClick={() => {
// dispatch(setSelectedMenu(item));
}}
sx={{
zIndex: 1201,
pl: drawerOpen ? `${level * 28}px` : 1.5,
py: !drawerOpen && level === 1 ? 1.25 : 1,
...(drawerOpen && {
'&:hover': {
bgcolor: '#7b1fa2'
},
'&.Mui-selected': {
bgcolor: theme.palette.mode === ThemeMode.DARK ? 'divider' : 'primary.lighter',
borderRight: `2px solid ${theme.palette.primary.main}`,
color: iconSelectedColor,
'&:hover': {
color: iconSelectedColor,
bgcolor: theme.palette.mode === ThemeMode.DARK ? 'divider' : 'primary.lighter'
}
}
}),
...(!drawerOpen && {
bgcolor: '#662582',
'&:hover': {
bgcolor: '#662582'
},
'&.Mui-selected': {
'&:hover': {
bgcolor: 'transparent'
},
bgcolor: 'transparent'
}
})
}}
{...(downLG && {
onClick: () => {
dispatch(openDrawer(false));
}
})}
>
{itemIcon && (
<ListItemIcon
sx={{
minWidth: 28,
...(!drawerOpen && {
borderRadius: 1.5,
width: 36,
height: 36,
alignItems: 'center',
justifyContent: 'center',
'&:hover': {
bgcolor: '#7b1fa2'
}
}),
...(!drawerOpen &&
isSelected && {
bgcolor: theme.palette.mode === ThemeMode.DARK ? 'primary.900' : 'primary.lighter',
'&:hover': {
bgcolor: theme.palette.mode === ThemeMode.DARK ? 'primary.darker' : 'primary.lighter'
}
})
}}
>
{itemIcon}
</ListItemIcon>
)}
{(drawerOpen || (!drawerOpen && level !== 1)) && (
<ListItemText
primary={
<Typography variant="h6" sx={{ color: isSelected ? iconSelectedColor : textColor, whiteSpace: 'nowrap' }}>
{item.title}
</Typography>
}
/>
)}
{(drawerOpen || (!drawerOpen && level !== 1)) && item.chip && (
<Chip
color={item.chip.color}
variant={item.chip.variant}
size={item.chip.size}
label={item.chip.label}
avatar={item.chip.avatar && <Avatar>{item.chip.avatar}</Avatar>}
/>
)}
</ListItemButton>
) : (
<ListItemButton
{...listItemProps}
disabled={item.disabled}
selected={isSelected}
sx={{
zIndex: 1201,
...(drawerOpen && {
'&:hover': {
bgcolor: 'transparent'
},
'&.Mui-selected': {
bgcolor: 'transparent',
color: iconSelectedColor,
'&:hover': {
color: iconSelectedColor,
bgcolor: 'transparent'
}
}
}),
...(!drawerOpen && {
'&:hover': {
bgcolor: 'transparent'
},
'&.Mui-selected': {
'&:hover': {
bgcolor: 'transparent'
},
bgcolor: 'transparent'
}
})
}}
>
{itemIcon && (
<ListItemIcon
sx={{
minWidth: 36,
...(!drawerOpen && {
borderRadius: 1.5,
width: 36,
height: 36,
alignItems: 'center',
justifyContent: 'flex-start',
'&:hover': {
bgcolor: 'transparent'
}
}),
...(!drawerOpen &&
isSelected && {
bgcolor: 'transparent',
'&:hover': {
bgcolor: 'transparent'
}
})
}}
>
{itemIcon}
</ListItemIcon>
)}
{!itemIcon && (
<ListItemIcon
sx={{
color: isSelected ? 'primary.main' : 'secondary.main',
...(!drawerOpen && {
borderRadius: 1.5,
alignItems: 'center',
justifyContent: 'flex-start',
'&:hover': {
bgcolor: 'transparent'
}
}),
...(!drawerOpen &&
isSelected && {
bgcolor: 'transparent',
'&:hover': {
bgcolor: 'transparent'
}
})
}}
>
<Dot size={4} color={isSelected ? 'primary' : 'secondary'} />
</ListItemIcon>
)}
<ListItemText
primary={
<Typography variant="h6" color="inherit">
{item.title}
</Typography>
}
/>
{(drawerOpen || (!drawerOpen && level !== 1)) && item.chip && (
<Chip
color={item.chip.color}
variant={item.chip.variant}
size={item.chip.size}
label={item.chip.label}
avatar={item.chip.avatar && <Avatar>{item.chip.avatar}</Avatar>}
/>
)}
</ListItemButton>
)}
</>
);
};
NavItem.propTypes = {
item: PropTypes.object,
level: PropTypes.number
};
export default NavItem;

View File

@@ -0,0 +1,111 @@
import { useEffect, useLayoutEffect, useState } from 'react';
// material-ui
import { useTheme } from '@mui/material/styles';
import { Box, Typography, useMediaQuery } from '@mui/material';
import { Menu } from 'menu-items/dashboard';
import { useSelector } from 'store';
import useConfig from 'hooks/useConfig';
import { HORIZONTAL_MAX_ITEM, MenuOrientation } from 'config';
// project import
import NavGroup from './NavGroup';
import menuItem from 'menu-items';
// ==============================|| DRAWER CONTENT - NAVIGATION ||============================== //
const Navigation = () => {
const theme = useTheme();
const downLG = useMediaQuery(theme.breakpoints.down('lg'));
const { menuOrientation } = useConfig();
const { drawerOpen } = useSelector((state) => state.menu);
const [selectedItems, setSelectedItems] = useState('');
const [selectedLevel, setSelectedLevel] = useState(0);
const [menuItems, setMenuItems] = useState({ items: [] });
useEffect(() => {
handlerMenuItem();
// eslint-disable-next-line
}, []);
let getMenu = Menu();
const handlerMenuItem = () => {
const isFound = menuItem.items.some((element) => {
if (element.id === 'group-dashboard') {
return true;
}
return false;
});
if (getMenu?.id !== undefined && !isFound) {
menuItem.items.splice(0, 0, getMenu);
setMenuItems(menuItem);
}
};
useLayoutEffect(() => {
setMenuItems(menuItem);
// eslint-disable-next-line
}, [menuItem]);
const isHorizontal = menuOrientation === MenuOrientation.HORIZONTAL && !downLG;
const lastItem = isHorizontal ? HORIZONTAL_MAX_ITEM : null;
let lastItemIndex = menuItems.items.length - 1;
let remItems = [];
let lastItemId;
// first it checks menu item is more than giving HORIZONTAL_MAX_ITEM after that get lastItemid by giving horizontal max
// item and it sets horizontal menu by giving horizontal max item lastly slice menuItem from array and set into remItems
if (lastItem && lastItem < menuItems.items.length) {
lastItemId = menuItems.items[lastItem - 1].id;
lastItemIndex = lastItem - 1;
remItems = menuItems.items.slice(lastItem - 1, menuItems.items.length).map((item) => ({
title: item.title,
elements: item.children,
icon: item.icon
}));
}
const navGroups = menuItems.items.slice(0, lastItemIndex + 1).map((item) => {
switch (item.type) {
case 'group':
return (
<NavGroup
key={item.id}
setSelectedItems={setSelectedItems}
setSelectedLevel={setSelectedLevel}
selectedLevel={selectedLevel}
selectedItems={selectedItems}
lastItem={lastItem}
remItems={remItems}
lastItemId={lastItemId}
item={item}
/>
);
default:
return (
<Typography key={item.id} variant="h6" color="error" align="center">
Fix - Navigation Group
</Typography>
);
}
});
return (
<Box
sx={{
pt: drawerOpen ? (isHorizontal ? 0 : 2) : 0,
'& > ul:first-of-type': { mt: 0 },
display: isHorizontal ? { xs: 'block', lg: 'flex' } : 'block'
}}
>
{navGroups}
</Box>
);
};
export default Navigation;

View File

@@ -0,0 +1,99 @@
import PropTypes from 'prop-types';
import { forwardRef, useEffect } from 'react';
import { Link } from 'react-router-dom';
// material-ui
import { useTheme } from '@mui/material/styles';
import { useMediaQuery, Avatar, Chip, ListItemButton, ListItemText, Typography } from '@mui/material';
// project imports
import { ThemeMode } from 'config';
import { dispatch, useSelector } from 'store';
import { activeComponent, openComponentDrawer } from 'store/reducers/menu';
// ==============================|| NAVIGATION - LIST ITEM ||============================== //
const NavItem = ({ item }) => {
const theme = useTheme();
const matchesMD = useMediaQuery(theme.breakpoints.down('md'));
const menu = useSelector((state) => state.menu);
const { openComponent } = menu;
let itemTarget = '_self';
if (item.target) {
itemTarget = '_blank';
}
let listItemProps = { component: forwardRef((props, ref) => <Link {...props} to={item.url} target={itemTarget} ref={ref} />) };
if (item?.external) {
listItemProps = { component: 'a', href: item.url, target: itemTarget };
}
const itemHandler = (id) => {
dispatch(activeComponent({ openComponent: id }));
if (matchesMD) dispatch(openComponentDrawer({ componentDrawerOpen: false }));
};
// active menu item on page load
useEffect(() => {
const currentIndex = document.location.pathname
.toString()
.split('/')
.findIndex((id) => id === item.id);
if (currentIndex > -1) {
dispatch(activeComponent({ openComponent: item.id }));
}
// eslint-disable-next-line
}, []);
const textColor = theme.palette.mode === ThemeMode.DARK ? 'grey.400' : 'text.primary';
const iconSelectedColor = theme.palette.mode === ThemeMode.DARK ? 'text.primary' : 'primary.main';
return (
<ListItemButton
{...listItemProps}
disabled={item.disabled}
onClick={() => itemHandler(item.id)}
selected={openComponent === item.id}
sx={{
pl: 4,
py: 1,
mb: 0.5,
'&:hover': {
bgcolor: theme.palette.mode === ThemeMode.DARK ? 'divider' : 'primary.lighter'
},
'&.Mui-selected': {
bgcolor: theme.palette.mode === ThemeMode.DARK ? 'divider' : 'primary.lighter',
borderRight: `2px solid ${theme.palette.primary.main}`,
'&:hover': {
bgcolor: theme.palette.mode === ThemeMode.DARK ? 'divider' : 'primary.lighter'
}
}
}}
>
<ListItemText
primary={
<Typography variant="h6" sx={{ color: openComponent === item.id ? iconSelectedColor : textColor }}>
{item.title}
</Typography>
}
/>
{item.chip && (
<Chip
color={item.chip.color}
variant={item.chip.variant}
size={item.chip.size}
label={item.chip.label}
avatar={item.chip.avatar && <Avatar>{item.chip.avatar}</Avatar>}
/>
)}
</ListItemButton>
);
};
NavItem.propTypes = {
item: PropTypes.object
};
export default NavItem;

View File

@@ -0,0 +1,37 @@
// material-ui
import // useMediaQuery,
// useTheme
'@mui/material';
// project import
// import NavCard from './NavCard';
import Navigation from './Navigation';
// import { useSelector } from 'store';
import SimpleBar from 'components/third-party/SimpleBar';
// ==============================|| DRAWER CONTENT ||============================== //
const DrawerContent = () => {
// const theme = useTheme();
// const matchDownMD = useMediaQuery(theme.breakpoints.down('lg'));
// const menu = useSelector((state) => state.menu);
// const { drawerOpen } = menu;
return (
<SimpleBar
sx={{
'& .simplebar-content': {
display: 'flex',
flexDirection: 'column'
}
}}
>
<Navigation />
{/* no need navCrd just hided */}
{/* {drawerOpen && !matchDownMD && <NavCard />} */}
</SimpleBar>
);
};
export default DrawerContent;

View File

@@ -0,0 +1,22 @@
import PropTypes from 'prop-types';
// material-ui
import { styled } from '@mui/material/styles';
import { Box } from '@mui/material';
// ==============================|| DRAWER HEADER - STYLED ||============================== //
const DrawerHeaderStyled = styled(Box, { shouldForwardProp: (prop) => prop !== 'open' })(({ theme, open }) => ({
...theme.mixins.toolbar,
display: 'flex',
alignItems: 'center',
justifyContent: open ? 'flex-start' : 'center',
paddingLeft: theme.spacing(open ? 3 : 0)
}));
DrawerHeaderStyled.propTypes = {
theme: PropTypes.object,
open: PropTypes.bool
};
export default DrawerHeaderStyled;

View File

@@ -0,0 +1,58 @@
import PropTypes from 'prop-types';
// material-ui
import { useTheme } from '@mui/material/styles';
import { useMediaQuery } from '@mui/material';
// project import
import DrawerHeaderStyled from './DrawerHeaderStyled';
import { MenuOrientation } from 'config';
import useConfig from 'hooks/useConfig';
import logo from 'assets/images/logo-nearle9.png'
import logo1 from 'assets/images/logo-sm1.png'
// ==============================|| DRAWER HEADER ||============================== //
const DrawerHeader = ({ open }) => {
const theme = useTheme();
const downLG = useMediaQuery(theme.breakpoints.down('lg'));
const { menuOrientation } = useConfig();
const isHorizontal = menuOrientation === MenuOrientation.HORIZONTAL && !downLG;
return (
<DrawerHeaderStyled
theme={theme}
open={open}
sx={{
minHeight: isHorizontal ? 'unset' : '60px',
width: isHorizontal ? { xs: '100%', lg: '424px' } : 'inherit',
paddingTop: isHorizontal ? { xs: '10px', lg: '0' } : '8px',
paddingBottom: isHorizontal ? { xs: '18px', lg: '0' } : '8px',
paddingLeft: isHorizontal ? { xs: '24px', lg: '0' } : open ? '24px' : 0
}}
>
{/* <Logo isIcon={!open} sx={{ width: open ? 'auto' : 35, height: 35 }} /> */}
{(open) &&
<img src={logo}
// width='160px'
// height='45px'
// width='170px'
alt='logo'/>
}
{(!open) &&
<img src={logo1}
width='40px'
alt='logo'/>
}
</DrawerHeaderStyled>
);
};
DrawerHeader.propTypes = {
open: PropTypes.bool
};
export default DrawerHeader;

View File

@@ -0,0 +1,62 @@
import React from 'react';
// material-ui
import { useTheme } from '@mui/material/styles';
import { AppBar, Box, Container, useScrollTrigger } from '@mui/material';
// project imports
import Navigation from './DrawerContent/Navigation';
import useConfig from 'hooks/useConfig';
// ==============================|| HORIZONTAL MENU LIST ||============================== //
function ElevationScroll({ children, window }) {
const theme = useTheme();
// Note that you normally won't need to set the window ref as useScrollTrigger
// will default to window.
// This is only being set here because the demo is in an iframe.
const trigger = useScrollTrigger({
disableHysteresis: true,
threshold: 0,
target: window
});
theme.shadows[4] = theme.customShadows.z1;
return React.cloneElement(children, {
elevation: trigger ? 4 : 0
});
}
// ==============================|| HORIZONTAL MENU LIST ||============================== //
const CustomAppBar = () => {
const theme = useTheme();
const { container } = useConfig();
return (
<ElevationScroll>
<AppBar
sx={{
top: 60,
bgcolor: theme.palette.background.paper,
width: '100%',
height: 62,
justifyContent: 'center',
borderTop: `1px solid ${theme.palette.divider}`,
borderBottom: `1px solid ${theme.palette.divider}`,
zIndex: 1098,
color: theme.palette.grey[500]
}}
>
<Container maxWidth={container ? 'xl' : false}>
<Box sx={{ display: 'flex', alignItems: 'center' }}>
<Navigation />
</Box>
</Container>
</AppBar>
</ElevationScroll>
);
};
export default CustomAppBar;

View File

@@ -0,0 +1,51 @@
// material-ui
import { styled } from '@mui/material/styles';
import Drawer from '@mui/material/Drawer';
// project import
import { DRAWER_WIDTH, ThemeMode } from 'config';
const openedMixin = (theme) => ({
width: DRAWER_WIDTH,
// borderRight: `1px solid ${theme.palette.divider}`,
borderRight: 'none',
transition: theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen
}),
overflowX: 'hidden',
boxShadow: theme.palette.mode === ThemeMode.DARK ? theme.customShadows.z1 : 'none',
backgroundColor:'#662582',
});
const closedMixin = (theme) => ({
transition: theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen
}),
// overflowX: 'hidden',
width: theme.spacing(7.5),
borderRight: 'none',
boxShadow: theme.customShadows.z1,
backgroundColor:'#662582',
});
// ==============================|| DRAWER - MINI STYLED ||============================== //
const MiniDrawerStyled = styled(Drawer, { shouldForwardProp: (prop) => prop !== 'open' })(({ theme, open }) => ({
width: DRAWER_WIDTH,
flexShrink: 0,
whiteSpace: 'nowrap',
boxSizing: 'border-box',
...(open && {
...openedMixin(theme),
'& .MuiDrawer-paper': openedMixin(theme)
}),
...(!open && {
...closedMixin(theme),
'& .MuiDrawer-paper': closedMixin(theme)
})
}));
export default MiniDrawerStyled;

View File

@@ -0,0 +1,74 @@
import PropTypes from 'prop-types';
import { useMemo } from 'react';
// material-ui
import { useTheme } from '@mui/material/styles';
import { Box, Drawer, useMediaQuery } from '@mui/material';
// project import
import DrawerHeader from './DrawerHeader';
import DrawerContent from './DrawerContent';
import MiniDrawerStyled from './MiniDrawerStyled';
import { DRAWER_WIDTH } from 'config';
import { dispatch, useSelector } from 'store';
import { openDrawer } from 'store/reducers/menu';
// ==============================|| MAIN LAYOUT - DRAWER ||============================== //
const MainDrawer = ({ window }) => {
const theme = useTheme();
const matchDownMD = useMediaQuery(theme.breakpoints.down('lg'));
const menu = useSelector((state) => state.menu);
const { drawerOpen } = menu;
// responsive drawer container
const container = window !== undefined ? () => window().document.body : undefined;
// header content
const drawerContent = useMemo(() => <DrawerContent />, []);
const drawerHeader = useMemo(() => <DrawerHeader open={drawerOpen} />, [drawerOpen]);
return (
<Box component="nav" sx={{ flexShrink: { md: 0 }, zIndex: 1200 }} aria-label="mailbox folders">
{!matchDownMD ? (
<MiniDrawerStyled
variant="permanent"
open={drawerOpen}
>
{drawerHeader}
{drawerContent}
</MiniDrawerStyled>
) : (
<Drawer
container={container}
variant="temporary"
open={drawerOpen}
onClose={() => dispatch(openDrawer(!drawerOpen))}
ModalProps={{ keepMounted: true }}
sx={{
display: { xs: 'block', lg: 'none' },
'& .MuiDrawer-paper': {
boxSizing: 'border-box',
width: DRAWER_WIDTH,
borderRight: `1px solid ${theme.palette.divider}`,
backgroundImage: 'none',
boxShadow: 'inherit',
bgcolor:'#662582'
}
}}
>
{drawerHeader}
{drawerContent}
</Drawer>
)}
</Box>
);
};
MainDrawer.propTypes = {
window: PropTypes.object
};
export default MainDrawer;