code handover

This commit is contained in:
joshikannan
2026-05-14 17:35:21 +05:30
commit c352a53cd0
303 changed files with 81712 additions and 0 deletions

View File

@@ -0,0 +1,321 @@
import PropTypes from 'prop-types';
// material-ui
import { styled, useTheme } from '@mui/material/styles';
import { Box, Button, Container, CardMedia, Divider, Stack, Grid, Link, Typography } from '@mui/material';
// third party
import { motion } from 'framer-motion';
// project import
import { ThemeDirection, ThemeMode } from 'config';
import useConfig from 'hooks/useConfig';
// assets
import { SendOutlined } from '@ant-design/icons';
import imgfooterlogo from 'assets/images/landing/codedthemes-logo.svg';
import imgfootersoc1 from 'assets/images/landing/img-soc1.svg';
import imgfootersoc2 from 'assets/images/landing/img-soc2.svg';
import imgfootersoc3 from 'assets/images/landing/img-soc3.svg';
import AnimateButton from 'components/@extended/AnimateButton';
const dashImage = require.context('assets/images/landing', true);
// link - custom style
const FooterLink = styled(Link)(({ theme }) => ({
color: theme.palette.text.secondary,
'&:hover': {
color: theme.palette.primary.main
},
'&:active': {
color: theme.palette.primary.main
}
}));
// ==============================|| LANDING - FOOTER PAGE ||============================== //
const FooterBlock = ({ isFull }) => {
const theme = useTheme();
const { presetColor } = useConfig();
const textColor = theme.palette.mode === ThemeMode.DARK ? 'text.primary' : 'background.paper';
const linkSX = {
color: theme.palette.common.white,
fontSize: '0.875rem',
fontWeight: 400,
opacity: '0.6',
cursor: 'pointer',
'&:hover': {
opacity: '1'
}
};
const frameworks = [
{ title: 'CodeIgniter', link: 'https://links.codedthemes.com/dEGKs' },
{
title: 'React MUI',
link: 'https://links.codedthemes.com/Aprwb'
},
{
title: 'Angular',
link: 'https://links.codedthemes.com/EIvof'
},
{
title: 'Bootstrap 5',
link: 'https://codedthemes.com/item/mantis-bootstrap-admin-dashboard/'
},
{
title: '.Net',
link: 'https://links.codedthemes.com/GPZhD'
}
];
return (
<>
{isFull && (
<Box
sx={{
position: 'relative',
bgcolor: theme.palette.grey.A700,
zIndex: 1,
mt: { xs: 0, md: 13.75 },
pt: { xs: 8, sm: 7.5, md: 18.75 },
pb: { xs: 2.5, md: 10 },
'&:after': {
content: '""',
position: 'absolute',
width: '100%',
height: '80%',
bottom: 0,
left: 0,
background:
theme.direction === ThemeDirection.RTL
? `linear-gradient(transparent 100%, rgb(31, 31, 31) 70%)`
: `linear-gradient(180deg, transparent 0%, ${theme.palette.grey.A700} 70%)`
}
}}
>
<CardMedia
component="img"
image={dashImage(`./img-footer-${presetColor}.png`)}
sx={{
display: { xs: 'none', md: 'block' },
width: '55%',
maxWidth: 700,
position: 'absolute',
top: '-28%',
right: 0
}}
/>
<Container>
<Grid container alignItems="center" justifyContent="space-between" spacing={2}>
<Grid item xs={12} md={6} sx={{ position: 'relative', zIndex: 1 }}>
<Grid container spacing={2} sx={{ [theme.breakpoints.down('md')]: { pr: 0, textAlign: 'center' } }}>
<Grid item xs={12}>
<Typography variant="subtitle1" sx={{ color: theme.palette.common.white }}>
Roadmap
</Typography>
</Grid>
<Grid item xs={12}>
<motion.div
initial={{ opacity: 0, translateY: 550 }}
animate={{ opacity: 1, translateY: 0 }}
transition={{
type: 'spring',
stiffness: 150,
damping: 30
}}
>
<Typography
variant="h2"
sx={{
color: theme.palette.common.white,
fontWeight: 700
}}
>
Upcoming Release
</Typography>
</motion.div>
</Grid>
<Grid item xs={12}>
<Typography variant="body1" sx={{ color: theme.palette.common.white }}>
What is next? Checkout the Upcoming release of Mantis React.
</Typography>
</Grid>
<Grid item xs={12} sx={{ my: 2 }}>
<Box sx={{ display: 'inline-block' }}>
<AnimateButton>
<Button
size="large"
variant="contained"
endIcon={<SendOutlined />}
component={Link}
href="https://links.codedthemes.com/RXnKQ"
target="_blank"
>
Roadmap
</Button>
</AnimateButton>
</Box>
</Grid>
</Grid>
</Grid>
</Grid>
</Container>
</Box>
)}
<Box sx={{ pt: isFull ? 0 : 10, pb: 10, bgcolor: theme.palette.grey.A700 }}>
<Container>
<Grid container spacing={2}>
<Grid item xs={12} md={4}>
<motion.div
initial={{ opacity: 0, translateY: 550 }}
animate={{ opacity: 1, translateY: 0 }}
transition={{
type: 'spring',
stiffness: 150,
damping: 30
}}
>
<Grid container spacing={2}>
<Grid item xs={12}>
<CardMedia component="img" image={imgfooterlogo} sx={{ width: 'auto' }} />
</Grid>
<Grid item xs={12}>
<Typography variant="subtitle1" sx={{ fontWeight: 400, color: theme.palette.common.white }}>
Since 2017, More than 50K+ Developers trust the CodedThemes Digital Product. Mantis React is Manage under their
Experienced Team Players.
</Typography>
</Grid>
</Grid>
</motion.div>
</Grid>
<Grid item xs={12} md={8}>
<Grid container spacing={{ xs: 5, md: 2 }}>
<Grid item xs={6} sm={3}>
<Stack spacing={{ xs: 3, md: 5 }}>
<Typography variant="h5" color={textColor} sx={{ fontWeight: 500 }}>
Help
</Typography>
<Stack spacing={{ xs: 1.5, md: 2.5 }}>
<FooterLink href="https://links.codedthemes.com/nOuhw" target="_blank" underline="none">
Blog
</FooterLink>
<FooterLink href="https://links.codedthemes.com/BQFrl" target="_blank" underline="none">
Documentation
</FooterLink>
<FooterLink href="https://links.codedthemes.com/rhzvh" target="_blank" underline="none">
Change Log
</FooterLink>
<FooterLink href="https://codedthemes.support-hub.io/" target="_blank" underline="none">
Support
</FooterLink>
</Stack>
</Stack>
</Grid>
<Grid item xs={6} sm={3}>
<Stack spacing={{ xs: 3, md: 5 }}>
<Typography variant="h5" color={textColor} sx={{ fontWeight: 500 }}>
Store Help
</Typography>
<Stack spacing={{ xs: 1.5, md: 2.5 }}>
<FooterLink href="https://mui.com/store/license/" target="_blank" underline="none">
License
</FooterLink>
<FooterLink href="https://mui.com/store/customer-refund-policy/" target="_blank" underline="none">
Refund Policy
</FooterLink>
<FooterLink
href="https://support.mui.com/hc/en-us/sections/360002564979-For-customers"
target="_blank"
underline="none"
>
Submit a Request
</FooterLink>
</Stack>
</Stack>
</Grid>
<Grid item xs={6} sm={3}>
<Stack spacing={{ xs: 3, md: 5 }}>
<Typography variant="h5" color={textColor} sx={{ fontWeight: 500 }}>
Mantis Eco-System
</Typography>
<Stack spacing={{ xs: 1.5, md: 2.5 }}>
{frameworks.map((item, index) => (
<FooterLink href={item.link} target="_blank" underline="none" key={index}>
{item.title}
{/* {item.isUpcoming && <Chip variant="outlined" size="small" label="Upcoming" sx={{ ml: 0.5 }} />} */}
</FooterLink>
))}
</Stack>
</Stack>
</Grid>
<Grid item xs={6} sm={3}>
<Stack spacing={{ xs: 3, md: 5 }}>
<Typography variant="h5" color={textColor} sx={{ fontWeight: 500 }}>
More Products
</Typography>
<Stack spacing={{ xs: 1.5, md: 2.5 }}>
<FooterLink href="https://links.codedthemes.com/zyACc" target="_blank" underline="none">
Berry React Material
</FooterLink>
<FooterLink href="https://links.codedthemes.com/WztNI" target="_blank" underline="none">
Free Berry React
</FooterLink>
<FooterLink href="https://links.codedthemes.com/sTUAK" target="_blank" underline="none">
Free Mantis React
</FooterLink>
</Stack>
</Stack>
</Grid>
</Grid>
</Grid>
</Grid>
</Container>
</Box>
<Divider sx={{ borderColor: 'grey.700' }} />
<Box
sx={{
py: 1.5,
bgcolor: theme.palette.mode === ThemeMode.DARK ? theme.palette.grey[50] : theme.palette.grey[800]
}}
>
<Container>
<Grid container spacing={2}>
<Grid item xs={12} sm={8}>
<Typography variant="subtitle2" color="secondary">
© Made with love by Team CodedThemes
</Typography>
</Grid>
<Grid item xs={12} sm={4}>
<Grid container spacing={2} alignItems="center" sx={{ justifyContent: 'flex-end' }}>
<Grid item>
<Link underline="none" sx={linkSX}>
<CardMedia component="img" image={imgfootersoc1} />
</Link>
</Grid>
<Grid item>
<Link underline="none" sx={linkSX}>
<CardMedia component="img" image={imgfootersoc2} />
</Link>
</Grid>
<Grid item>
<Link underline="none" sx={linkSX}>
<CardMedia component="img" image={imgfootersoc3} />
</Link>
</Grid>
</Grid>
</Grid>
</Grid>
</Container>
</Box>
</>
);
};
FooterBlock.propTypes = {
isFull: PropTypes.bool
};
export default FooterBlock;

View File

@@ -0,0 +1,251 @@
import PropTypes from 'prop-types';
import * as React from 'react';
import { useState } from 'react';
import { Link as RouterLink } from 'react-router-dom';
// material-ui
import AppBar from '@mui/material/AppBar';
import { useTheme } from '@mui/material/styles';
import {
useMediaQuery,
Box,
Button,
Chip,
Container,
Drawer,
Link,
List,
ListItemButton,
ListItemIcon,
ListItemText,
Stack,
Toolbar,
Typography,
useScrollTrigger
} from '@mui/material';
// project import
import { APP_DEFAULT_PATH, ThemeMode } from 'config';
import IconButton from 'components/@extended/IconButton';
import AnimateButton from 'components/@extended/AnimateButton';
import Logo from 'components/logo';
// assets
import { MenuOutlined, LineOutlined } from '@ant-design/icons';
// ==============================|| COMPONENTS - APP BAR ||============================== //
// elevation scroll
function ElevationScroll({ layout, children, window }) {
const theme = useTheme();
// const theme = useTheme();
const trigger = useScrollTrigger({
disableHysteresis: true,
threshold: 10,
target: window ? window() : undefined
});
const backColorScroll = theme.palette.mode === ThemeMode.DARK ? theme.palette.grey[50] : theme.palette.grey[800];
const backColor = layout !== 'landing' ? backColorScroll : 'transparent';
return React.cloneElement(children, {
style: {
backgroundColor: trigger ? backColorScroll : backColor
}
});
}
const Header = ({ handleDrawerOpen, layout = 'landing', ...others }) => {
const theme = useTheme();
const matchDownMd = useMediaQuery(theme.breakpoints.down('md'));
const [drawerToggle, setDrawerToggle] = useState(false);
/** Method called on multiple components with different event types */
const drawerToggler = (open) => (event) => {
if (event.type === 'keydown' && (event.key === 'Tab' || event.key === 'Shift')) {
return;
}
setDrawerToggle(open);
};
return (
<ElevationScroll layout={layout} {...others}>
<AppBar sx={{ bgcolor: 'transparent', color: theme.palette.text.primary, boxShadow: 'none' }}>
<Container disableGutters={matchDownMd}>
<Toolbar sx={{ px: { xs: 1.5, md: 0, lg: 0 }, py: 2 }}>
<Stack direction="row" sx={{ flexGrow: 1, display: { xs: 'none', md: 'block' } }} alignItems="center">
<Typography component="div" sx={{ textAlign: 'left', display: 'inline-block' }}>
<Logo reverse to="/" />
</Typography>
<Chip
label={process.env.REACT_APP_VERSION}
variant="outlined"
size="small"
color="secondary"
sx={{ mt: 0.5, ml: 1, fontSize: '0.725rem', height: 20, '& .MuiChip-label': { px: 0.5 } }}
/>
</Stack>
<Stack
direction="row"
sx={{
'& .header-link': { px: 1, '&:hover': { color: theme.palette.primary.main } },
display: { xs: 'none', md: 'block' }
}}
spacing={2}
>
<Link className="header-link" color="white" component={RouterLink} to="/login" target="_blank" underline="none">
Dashboard
</Link>
<Link
className="header-link"
color={handleDrawerOpen ? 'primary' : 'white'}
component={RouterLink}
to="/components-overview/buttons"
underline="none"
>
Components
</Link>
<Link className="header-link" color="white" href="https://links.codedthemes.com/BQFrl" target="_blank" underline="none">
Documentation
</Link>
<Box sx={{ display: 'inline-block' }}>
<AnimateButton>
<Button component={Link} href="https://links.codedthemes.com/Aprwb" disableElevation color="primary" variant="contained">
Purchase Now
</Button>
</AnimateButton>
</Box>
</Stack>
<Box
sx={{
width: '100%',
alignItems: 'center',
justifyContent: 'space-between',
display: { xs: 'flex', md: 'none' }
}}
>
<Typography component="div" sx={{ textAlign: 'left', display: 'inline-block' }}>
<Logo reverse to="/" />
</Typography>
<Stack direction="row" spacing={2}>
{layout === 'component' && (
<Button
variant="outlined"
size="small"
color="warning"
component={RouterLink}
to={APP_DEFAULT_PATH}
sx={{ mt: 0.5, height: 28 }}
>
Dashboard
</Button>
)}
{layout !== 'component' && (
<Button
variant="outlined"
size="small"
color="warning"
component={RouterLink}
to="/components-overview/buttons"
sx={{ mt: 0.5, height: 28 }}
>
All Components
</Button>
)}
<IconButton
color="secondary"
{...(layout === 'component' ? { onClick: handleDrawerOpen } : { onClick: drawerToggler(true) })}
sx={{
'&:hover': { bgcolor: theme.palette.mode === ThemeMode.DARK ? 'secondary.lighter' : 'secondary.dark' }
}}
>
<MenuOutlined style={{ color: theme.palette.mode === ThemeMode.DARK ? 'inherit' : theme.palette.grey[100] }} />
</IconButton>
</Stack>
<Drawer
anchor="top"
open={drawerToggle}
onClose={drawerToggler(false)}
sx={{ '& .MuiDrawer-paper': { backgroundImage: 'none' } }}
>
<Box
sx={{
width: 'auto',
'& .MuiListItemIcon-root': {
fontSize: '1rem',
minWidth: 28
}
}}
role="presentation"
onClick={drawerToggler(false)}
onKeyDown={drawerToggler(false)}
>
<List>
<Link style={{ textDecoration: 'none' }} href="/login" target="_blank">
<ListItemButton component="span">
<ListItemIcon>
<LineOutlined />
</ListItemIcon>
<ListItemText primary="Dashboard" primaryTypographyProps={{ variant: 'h6', color: 'text.primary' }} />
</ListItemButton>
</Link>
<Link style={{ textDecoration: 'none' }} href="/components-overview/buttons" target="_blank">
<ListItemButton component="span">
<ListItemIcon>
<LineOutlined />
</ListItemIcon>
<ListItemText primary="All Components" primaryTypographyProps={{ variant: 'h6', color: 'text.primary' }} />
</ListItemButton>
</Link>
<Link style={{ textDecoration: 'none' }} href="https://links.codedthemes.com/sTUAK" target="_blank">
<ListItemButton component="span">
<ListItemIcon>
<LineOutlined />
</ListItemIcon>
<ListItemText primary="Free Version" primaryTypographyProps={{ variant: 'h6', color: 'text.primary' }} />
</ListItemButton>
</Link>
<Link style={{ textDecoration: 'none' }} href="https://links.codedthemes.com/BQFrl" target="_blank">
<ListItemButton component="span">
<ListItemIcon>
<LineOutlined />
</ListItemIcon>
<ListItemText primary="Documentation" primaryTypographyProps={{ variant: 'h6', color: 'text.primary' }} />
</ListItemButton>
</Link>
<Link style={{ textDecoration: 'none' }} href="https://codedthemes.support-hub.io/" target="_blank">
<ListItemButton component="span">
<ListItemIcon>
<LineOutlined />
</ListItemIcon>
<ListItemText primary="Support" primaryTypographyProps={{ variant: 'h6', color: 'text.primary' }} />
</ListItemButton>
</Link>
<Link style={{ textDecoration: 'none' }} href="https://links.codedthemes.com/Aprwb" target="_blank">
<ListItemButton component="span">
<ListItemIcon>
<LineOutlined />
</ListItemIcon>
<ListItemText primary="Purchase Now" primaryTypographyProps={{ variant: 'h6', color: 'text.primary' }} />
<Chip color="primary" label="v1.0" size="small" />
</ListItemButton>
</Link>
</List>
</Box>
</Drawer>
</Box>
</Toolbar>
</Container>
</AppBar>
</ElevationScroll>
);
};
Header.propTypes = {
handleDrawerOpen: PropTypes.func,
layout: PropTypes.string
};
export default Header;

View File

@@ -0,0 +1,74 @@
import PropTypes from 'prop-types';
import { lazy, Suspense } from 'react';
import { Outlet } from 'react-router-dom';
// material-ui
import { Container, Toolbar } from '@mui/material';
// project import
import { dispatch, useSelector } from 'store';
import { openComponentDrawer } from 'store/reducers/menu';
// material-ui
import { styled } from '@mui/material/styles';
import LinearProgress from '@mui/material/LinearProgress';
const Header = lazy(() => import('./Header'));
const FooterBlock = lazy(() => import('./FooterBlock'));
// ==============================|| Loader ||============================== //
const LoaderWrapper = styled('div')(({ theme }) => ({
position: 'fixed',
top: 0,
left: 0,
zIndex: 2001,
width: '100%',
'& > * + *': {
marginTop: theme.spacing(2)
}
}));
const Loader = () => (
<LoaderWrapper>
<LinearProgress color="primary" />
</LoaderWrapper>
);
// ==============================|| MINIMAL LAYOUT ||============================== //
const CommonLayout = ({ layout = 'blank' }) => {
const menu = useSelector((state) => state.menu);
const { componentDrawerOpen } = menu;
const handleDrawerOpen = () => {
dispatch(openComponentDrawer({ componentDrawerOpen: !componentDrawerOpen }));
};
return (
<>
{(layout === 'landing' || layout === 'simple') && (
<Suspense fallback={<Loader />}>
<Header layout={layout} />
<Outlet />
<FooterBlock isFull={layout === 'landing'} />
</Suspense>
)}
{layout === 'component' && (
<Suspense fallback={<Loader />}>
<Container maxWidth="lg" sx={{ px: { xs: 0, sm: 2 } }}>
<Header handleDrawerOpen={handleDrawerOpen} layout="component" />
<Toolbar sx={{ my: 2 }} />
</Container>
</Suspense>
)}
{layout === 'blank' && <Outlet />}
</>
);
};
CommonLayout.propTypes = {
layout: PropTypes.string
};
export default CommonLayout;

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,344 @@
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, ThemeMode } 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"
// color={theme.palette.mode === ThemeMode.DARK ? 'textSecondary' : 'text.secondary'}
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,285 @@
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 [selectedItem, setSelectedItem] = useState(null);
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));
setSelectedItem(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,59 @@
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 Logo from 'components/logo';
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;

View File

@@ -0,0 +1,23 @@
import { Link as RouterLink } from 'react-router-dom';
// material-ui
import { Link, Stack, Typography } from '@mui/material';
const Footer = () => (
<Stack direction="row" justifyContent="space-between" alignItems="center" sx={{ p: '24px 16px 0px', mt: 'auto' }}>
<Typography variant="caption">&copy; All rights reserved</Typography>
<Stack spacing={1.5} direction="row" justifyContent="space-between" alignItems="center">
<Link component={RouterLink} to="#" target="_blank" variant="caption" color="textPrimary">
About us
</Link>
<Link component={RouterLink} to="#" target="_blank" variant="caption" color="textPrimary">
Privacy
</Link>
<Link component={RouterLink} to="#" target="_blank" variant="caption" color="textPrimary">
Terms
</Link>
</Stack>
</Stack>
);
export default Footer;

View File

@@ -0,0 +1,35 @@
import PropTypes from 'prop-types';
// material-ui
import { styled } from '@mui/material/styles';
import AppBar from '@mui/material/AppBar';
// project import
import { DRAWER_WIDTH } from 'config';
// ==============================|| HEADER - APP BAR STYLED ||============================== //
const AppBarStyled = styled(AppBar, { shouldForwardProp: (prop) => prop !== 'open' })(({ theme, open }) => ({
zIndex: theme.zIndex.drawer + 1,
transition: theme.transitions.create(['width', 'margin'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen
}),
...(!open && {
width: `calc(100% - ${theme.spacing(7.5)})`
}),
...(open && {
marginLeft: DRAWER_WIDTH,
width: `calc(100% - ${DRAWER_WIDTH}px)`,
transition: theme.transitions.create(['width', 'margin'], {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen
})
})
}));
AppBarStyled.propTypes = {
open: PropTypes.bool
};
export default AppBarStyled;

View File

@@ -0,0 +1,301 @@
import { useRef, useState } from 'react';
import { Link } from 'react-router-dom';
// material-ui
import { useTheme } from '@mui/material/styles';
import {
Button,
Box,
CardMedia,
ClickAwayListener,
Grid,
List,
ListItemButton,
ListItemIcon,
ListItemText,
ListSubheader,
Paper,
Popper,
Stack,
Typography
} from '@mui/material';
// project import
import MainCard from 'components/MainCard';
import Dot from 'components/@extended/Dot';
import IconButton from 'components/@extended/IconButton';
import Transitions from 'components/@extended/Transitions';
import { DRAWER_WIDTH, ThemeMode } from 'config';
// assets
import { ArrowRightOutlined, WindowsOutlined } from '@ant-design/icons';
import backgroundVector from 'assets/images/mega-menu/back.svg';
import imageChart from 'assets/images/mega-menu/chart.svg';
import AnimateButton from 'components/@extended/AnimateButton';
// ==============================|| HEADER CONTENT - MEGA MENU SECTION ||============================== //
const MegaMenuSection = () => {
const theme = useTheme();
const anchorRef = useRef(null);
const [open, setOpen] = useState(false);
const handleToggle = () => {
setOpen((prevOpen) => !prevOpen);
};
const handleClose = (event) => {
if (anchorRef.current && anchorRef.current.contains(event.target)) {
return;
}
setOpen(false);
};
const iconBackColorOpen = theme.palette.mode === ThemeMode.DARK ? 'grey.200' : 'grey.300';
const iconBackColor = theme.palette.mode === ThemeMode.DARK ? 'background.default' : 'grey.100';
return (
<Box sx={{ flexShrink: 0, ml: 0.75 }}>
<IconButton
color="secondary"
variant="light"
sx={{ color: 'text.primary', bgcolor: open ? iconBackColorOpen : iconBackColor }}
aria-label="open profile"
ref={anchorRef}
aria-controls={open ? 'profile-grow' : undefined}
aria-haspopup="true"
// onClick={handleToggle}
>
<WindowsOutlined />
</IconButton>
<Popper
placement="bottom"
open={open}
anchorEl={anchorRef.current}
role={undefined}
transition
disablePortal
popperOptions={{
modifiers: [
{
name: 'offset',
options: {
offset: [-180, 9]
}
}
]
}}
>
{({ TransitionProps }) => (
<Transitions type="grow" position="top" in={open} {...TransitionProps}>
<Paper
sx={{
boxShadow: theme.customShadows.z1,
minWidth: 750,
width: {
md: `calc(100vw - 100px)`,
lg: `calc(100vw - ${DRAWER_WIDTH + 100}px)`,
xl: `calc(100vw - ${DRAWER_WIDTH + 140}px)`
},
maxWidth: 1024
}}
>
<ClickAwayListener onClickAway={handleClose}>
<MainCard elevation={0} border={false} content={false}>
<Grid container>
<Grid
item
md={4}
sx={{
background: `url(${backgroundVector}), linear-gradient(183.77deg, ${theme.palette.primary.main} 11.46%, ${theme.palette.primary[700]} 100.33%)`
}}
>
<Box sx={{ p: 4.5, pb: 3 }}>
<Stack sx={{ color: 'background.paper' }}>
<Typography variant="h2" sx={{ fontSize: '1.875rem', mb: 1 }}>
Explore Components
</Typography>
<Typography variant="h6">
Try our pre made component pages to check how it feels and suits as per your need.
</Typography>
<Stack direction="row" justifyContent="space-between" alignItems="flex-end" sx={{ mt: -1 }}>
<AnimateButton>
<Button
variant="contained"
color="secondary"
sx={{
bgcolor: 'background.paper',
color: 'text.primary',
'&:hover': { bgcolor: 'background.paper', color: 'text.primary' }
}}
endIcon={<ArrowRightOutlined />}
component={Link}
to="/components-overview/buttons"
target="_blank"
>
View All
</Button>
</AnimateButton>
<CardMedia component="img" src={imageChart} alt="Chart" sx={{ mr: -2.5, mb: -2.5, width: 124 }} />
</Stack>
</Stack>
</Box>
</Grid>
<Grid item md={8}>
<Box
sx={{
p: 4,
'& .MuiList-root': {
pb: 0
},
'& .MuiListSubheader-root': {
p: 0,
pb: 1.5
},
'& .MuiListItemButton-root': {
p: 0.5,
'&:hover': {
background: 'transparent',
'& .MuiTypography-root': {
color: 'primary.main'
}
}
}
}}
>
<Grid container spacing={6}>
<Grid item xs={4}>
<List
component="nav"
aria-labelledby="nested-list-user"
subheader={
<ListSubheader id="nested-list-user">
<Typography variant="subtitle1" color="textPrimary">
Authentication
</Typography>
</ListSubheader>
}
>
<ListItemButton disableRipple component={Link} target="_blank" to="/auth/login">
<ListItemIcon>
<Dot size={7} color="secondary" variant="outlined" />
</ListItemIcon>
<ListItemText primary="Login" />
</ListItemButton>
<ListItemButton disableRipple component={Link} target="_blank" to="/auth/register">
<ListItemIcon>
<Dot size={7} color="secondary" variant="outlined" />
</ListItemIcon>
<ListItemText primary="Register" />
</ListItemButton>
<ListItemButton disableRipple component={Link} target="_blank" to="/auth/reset-password">
<ListItemIcon>
<Dot size={7} color="secondary" variant="outlined" />
</ListItemIcon>
<ListItemText primary="Reset Password" />
</ListItemButton>
<ListItemButton disableRipple component={Link} target="_blank" to="/auth/forgot-password">
<ListItemIcon>
<Dot size={7} color="secondary" variant="outlined" />
</ListItemIcon>
<ListItemText primary="Forgot Password" />
</ListItemButton>
<ListItemButton disableRipple component={Link} target="_blank" to="/auth/code-verification">
<ListItemIcon>
<Dot size={7} color="secondary" variant="outlined" />
</ListItemIcon>
<ListItemText primary="Verification Code" />
</ListItemButton>
</List>
</Grid>
<Grid item xs={4}>
<List
component="nav"
aria-labelledby="nested-list-user"
subheader={
<ListSubheader id="nested-list-user">
<Typography variant="subtitle1" color="textPrimary">
Other Pages
</Typography>
</ListSubheader>
}
>
<ListItemButton disableRipple component={Link} target="_blank" to="/">
<ListItemIcon>
<Dot size={7} color="secondary" variant="outlined" />
</ListItemIcon>
<ListItemText primary="About us" />
</ListItemButton>
<ListItemButton disableRipple component={Link} target="_blank" to="/contact-us">
<ListItemIcon>
<Dot size={7} color="secondary" variant="outlined" />
</ListItemIcon>
<ListItemText primary="Contact us" />
</ListItemButton>
<ListItemButton disableRipple component={Link} to="/pricing">
<ListItemIcon>
<Dot size={7} color="secondary" variant="outlined" />
</ListItemIcon>
<ListItemText primary="Pricing" />
</ListItemButton>
<ListItemButton disableRipple component={Link} to="/apps/profiles/user/payment">
<ListItemIcon>
<Dot size={7} color="secondary" variant="outlined" />
</ListItemIcon>
<ListItemText primary="Payment" />
</ListItemButton>
<ListItemButton disableRipple component={Link} target="_blank" to="/maintenance/under-construction">
<ListItemIcon>
<Dot size={7} color="secondary" variant="outlined" />
</ListItemIcon>
<ListItemText primary="Construction" />
</ListItemButton>
<ListItemButton disableRipple component={Link} target="_blank" to="/maintenance/coming-soon">
<ListItemIcon>
<Dot size={7} color="secondary" variant="outlined" />
</ListItemIcon>
<ListItemText primary="Coming Soon" />
</ListItemButton>
</List>
</Grid>
<Grid item xs={4}>
<List
component="nav"
aria-labelledby="nested-list-user"
subheader={
<ListSubheader id="nested-list-user">
<Typography variant="subtitle1" color="textPrimary">
SAAS Pages
</Typography>
</ListSubheader>
}
>
<ListItemButton disableRipple component={Link} target="_blank" to="/maintenance/404">
<ListItemIcon>
<Dot size={7} color="secondary" variant="outlined" />
</ListItemIcon>
<ListItemText primary="404 Error" />
</ListItemButton>
<ListItemButton disableRipple component={Link} target="_blank" to="/">
<ListItemIcon>
<Dot size={7} color="secondary" variant="outlined" />
</ListItemIcon>
<ListItemText primary="Landing" />
</ListItemButton>
</List>
</Grid>
</Grid>
</Box>
</Grid>
</Grid>
</MainCard>
</ClickAwayListener>
</Paper>
</Transitions>
)}
</Popper>
</Box>
);
};
export default MegaMenuSection;

View File

@@ -0,0 +1,252 @@
import { useRef, useState } from 'react';
// material-ui
import { useTheme } from '@mui/material/styles';
import {
Avatar,
Box,
ClickAwayListener,
Divider,
List,
ListItemButton,
ListItemAvatar,
ListItemText,
ListItemSecondaryAction,
Paper,
Popper,
Typography,
useMediaQuery
} from '@mui/material';
// project import
import MainCard from 'components/MainCard';
import IconButton from 'components/@extended/IconButton';
import Transitions from 'components/@extended/Transitions';
import { ThemeMode } from 'config';
// assets
import avatar2 from 'assets/images/users/avatar-2.png';
import avatar3 from 'assets/images/users/avatar-3.png';
import avatar4 from 'assets/images/users/avatar-4.png';
import avatar5 from 'assets/images/users/avatar-5.png';
import { MailOutlined, CloseOutlined } from '@ant-design/icons';
// sx styles
const avatarSX = {
width: 48,
height: 48
};
const actionSX = {
mt: '6px',
ml: 1,
top: 'auto',
right: 'auto',
alignSelf: 'flex-start',
transform: 'none'
};
// ==============================|| HEADER CONTENT - MESSAGES ||============================== //
const Message = () => {
const theme = useTheme();
const matchesXs = useMediaQuery(theme.breakpoints.down('md'));
const anchorRef = useRef(null);
const [open, setOpen] = useState(false);
const handleToggle = () => {
setOpen((prevOpen) => !prevOpen);
};
const handleClose = (event) => {
if (anchorRef.current && anchorRef.current.contains(event.target)) {
return;
}
setOpen(false);
};
const iconBackColorOpen = theme.palette.mode === ThemeMode.DARK ? 'grey.200' : 'grey.300';
const iconBackColor = theme.palette.mode === ThemeMode.DARK ? 'background.default' : 'grey.100';
return (
<Box sx={{ flexShrink: 0, ml: 0.75 }}>
<IconButton
color="secondary"
variant="light"
sx={{ color: 'text.primary', bgcolor: open ? iconBackColorOpen : iconBackColor }}
aria-label="open profile"
ref={anchorRef}
aria-controls={open ? 'profile-grow' : undefined}
aria-haspopup="true"
onClick={handleToggle}
>
<MailOutlined />
</IconButton>
<Popper
placement={matchesXs ? 'bottom' : 'bottom-end'}
open={open}
anchorEl={anchorRef.current}
role={undefined}
transition
disablePortal
sx={{
maxHeight: 'calc(100vh - 250px)',
overflow: 'auto'
}}
popperOptions={{
modifiers: [
{
name: 'offset',
options: {
offset: [matchesXs ? -60 : 0, 9]
}
}
]
}}
>
{({ TransitionProps }) => (
<Transitions type="grow" position={matchesXs ? 'top' : 'top-right'} in={open} {...TransitionProps}>
<Paper
sx={{
boxShadow: theme.customShadows.z1,
width: '100%',
minWidth: 285,
maxWidth: 420,
[theme.breakpoints.down('md')]: {
maxWidth: 285
}
}}
>
<ClickAwayListener onClickAway={handleClose}>
<MainCard
title="Message"
elevation={0}
border={false}
content={false}
secondary={
<IconButton size="small" onClick={handleToggle}>
<CloseOutlined />
</IconButton>
}
>
<List
component="nav"
sx={{
p: 0,
'& .MuiListItemButton-root': {
py: 1.5,
'& .MuiAvatar-root': avatarSX,
'& .MuiListItemSecondaryAction-root': { ...actionSX, position: 'relative' }
}
}}
>
<ListItemButton>
<ListItemAvatar>
<Avatar alt="profile user" src={avatar2} />
</ListItemAvatar>
<ListItemText
primary={
<Typography variant="h6">
It&apos;s{' '}
<Typography component="span" variant="subtitle1">
Cristina danny&apos;s
</Typography>{' '}
birthday today.
</Typography>
}
secondary="2 min ago"
/>
<ListItemSecondaryAction>
<Typography variant="caption" noWrap>
3:00 AM
</Typography>
</ListItemSecondaryAction>
</ListItemButton>
<Divider />
<ListItemButton>
<ListItemAvatar>
<Avatar alt="profile user" src={avatar3} />
</ListItemAvatar>
<ListItemText
primary={
<Typography variant="h6">
<Typography component="span" variant="subtitle1">
Aida Burg
</Typography>{' '}
commented your post.
</Typography>
}
secondary="5 August"
/>
<ListItemSecondaryAction>
<Typography variant="caption" noWrap>
6:00 PM
</Typography>
</ListItemSecondaryAction>
</ListItemButton>
<Divider />
<ListItemButton>
<ListItemAvatar>
<Avatar alt="profile user" src={avatar4} />
</ListItemAvatar>
<ListItemText
primary={
<Typography component="span" variant="subtitle1">
There was a failure to your setup.
</Typography>
}
secondary="7 hours ago"
/>
<ListItemSecondaryAction>
<Typography variant="caption" noWrap>
2:45 PM
</Typography>
</ListItemSecondaryAction>
</ListItemButton>
<Divider />
<ListItemButton>
<ListItemAvatar>
<Avatar alt="profile user" src={avatar5} />
</ListItemAvatar>
<ListItemText
primary={
<Typography variant="h6">
<Typography component="span" variant="subtitle1">
Cristina Danny
</Typography>{' '}
invited to join{' '}
<Typography component="span" variant="subtitle1">
Meeting.
</Typography>
</Typography>
}
secondary="Daily scrum meeting time"
/>
<ListItemSecondaryAction>
<Typography variant="caption" noWrap>
9:10 PM
</Typography>
</ListItemSecondaryAction>
</ListItemButton>
<Divider />
<ListItemButton sx={{ textAlign: 'center' }}>
<ListItemText
primary={
<Typography variant="h6" color="primary">
View All
</Typography>
}
/>
</ListItemButton>
</List>
</MainCard>
</ClickAwayListener>
</Paper>
</Transitions>
)}
</Popper>
</Box>
);
};
export default Message;

View File

@@ -0,0 +1,108 @@
import { useEffect, useRef, useState } from 'react';
// material-ui
import { useTheme } from '@mui/material/styles';
import { AppBar, Box, ClickAwayListener, Paper, Popper, Toolbar } from '@mui/material';
// project import
import Search from './Search';
import Profile from './Profile';
import IconButton from 'components/@extended/IconButton';
import Transitions from 'components/@extended/Transitions';
import { ThemeMode } from 'config';
// assets
import { MoreOutlined } from '@ant-design/icons';
// ==============================|| HEADER CONTENT - MOBILE ||============================== //
const MobileSection = () => {
const theme = useTheme();
const [open, setOpen] = useState(false);
const anchorRef = useRef(null);
const handleToggle = () => {
setOpen((prevOpen) => !prevOpen);
};
const handleClose = (event) => {
if (anchorRef.current && anchorRef.current.contains(event.target)) {
return;
}
setOpen(false);
};
const prevOpen = useRef(open);
useEffect(() => {
if (prevOpen.current === true && open === false) {
anchorRef.current.focus();
}
prevOpen.current = open;
}, [open]);
const iconBackColorOpen = theme.palette.mode === ThemeMode.DARK ? 'grey.200' : 'grey.300';
const iconBackColor = theme.palette.mode === ThemeMode.DARK ? 'background.default' : 'grey.100';
return (
<>
<Box sx={{ flexShrink: 0, ml: 0.75 }}>
<IconButton
// sx={{ color: 'text.primary', bgcolor: open ? iconBackColorOpen : iconBackColor }}
sx={{ color: '#fff', bgcolor: 'transparent', ml: { xs: 0, lg: -2 },
fontSize:'25px',
':hover':{
color: '#fff', bgcolor: 'transparent'
} }}
aria-label="open more menu"
ref={anchorRef}
aria-controls={open ? 'menu-list-grow' : undefined}
aria-haspopup="true"
onClick={handleToggle}
color="secondary"
variant="light"
>
<MoreOutlined />
</IconButton>
</Box>
<Popper
placement="bottom-end"
open={open}
anchorEl={anchorRef.current}
role={undefined}
transition
disablePortal
style={{ width: '100%' }}
popperOptions={{
modifiers: [
{
name: 'offset',
options: {
offset: [0, 9]
}
}
]
}}
>
{({ TransitionProps }) => (
<Transitions type="fade" in={open} {...TransitionProps}>
<Paper sx={{ boxShadow: theme.customShadows.z1 }}>
<ClickAwayListener onClickAway={handleClose}>
<AppBar color="inherit">
<Toolbar>
{/* <Search /> */}
<Profile />
</Toolbar>
</AppBar>
</ClickAwayListener>
</Paper>
</Transitions>
)}
</Popper>
</>
);
};
export default MobileSection;

View File

@@ -0,0 +1,309 @@
import { useRef, useState } from 'react';
// material-ui
import { useTheme } from '@mui/material/styles';
import {
Avatar,
Badge,
Box,
ClickAwayListener,
Divider,
List,
ListItemButton,
ListItemAvatar,
ListItemText,
ListItemSecondaryAction,
Paper,
Popper,
Tooltip,
Typography,
useMediaQuery
} from '@mui/material';
// project import
import MainCard from 'components/MainCard';
import IconButton from 'components/@extended/IconButton';
import Transitions from 'components/@extended/Transitions';
import { ThemeMode } from 'config';
// assets
import { BellOutlined, CheckCircleOutlined, GiftOutlined, MessageOutlined, SettingOutlined } from '@ant-design/icons';
// sx styles
const avatarSX = {
width: 36,
height: 36,
fontSize: '1rem'
};
const actionSX = {
mt: '6px',
ml: 1,
top: 'auto',
right: 'auto',
alignSelf: 'flex-start',
transform: 'none'
};
// ==============================|| HEADER CONTENT - NOTIFICATION ||============================== //
const Notification = () => {
const theme = useTheme();
const matchesXs = useMediaQuery(theme.breakpoints.down('md'));
const anchorRef = useRef(null);
const [read, setRead] = useState(0);
const [open, setOpen] = useState(false);
const handleToggle = () => {
setOpen((prevOpen) => !prevOpen);
};
const handleClose = (event) => {
if (anchorRef.current && anchorRef.current.contains(event.target)) {
return;
}
setOpen(false);
};
const iconBackColorOpen = theme.palette.mode === ThemeMode.DARK ? 'grey.200' : 'grey.300';
const iconBackColor = theme.palette.mode === ThemeMode.DARK ? 'background.default' : 'grey.100';
return (
<Box sx={{ flexShrink: 0, ml: 0.75 }}>
<Tooltip title='Notifications'>
<IconButton
// color="secondary"
// variant="light"
// sx={{ color: 'text.primary', bgcolor: open ? iconBackColorOpen : iconBackColor }}
sx={{ color: '#fff',
fontSize:'20px',
// bgcolor: open ? iconBackColorOpen : iconBackColor
':hover':{
bgcolor:'transparent',
color: '#fff',
},
// bgcolor:'transparent'
}}
aria-label="open profile"
ref={anchorRef}
aria-controls={open ? 'profile-grow' : undefined}
aria-haspopup="true"
// onClick={handleToggle}
>
<Badge badgeContent={read}
// color="primary"
sx={{
"& .MuiBadge-badge": {
color: "#662582",
backgroundColor: "white"
}
}}
>
<BellOutlined />
</Badge>
</IconButton>
</Tooltip>
<Popper
placement={matchesXs ? 'bottom' : 'bottom-end'}
open={open}
anchorEl={anchorRef.current}
role={undefined}
transition
disablePortal
popperOptions={{
modifiers: [
{
name: 'offset',
options: {
offset: [matchesXs ? -5 : 0, 9]
}
}
]
}}
>
{({ TransitionProps }) => (
<Transitions type="grow" position={matchesXs ? 'top' : 'top-right'} sx={{ overflow: 'hidden' }} in={open} {...TransitionProps}>
<Paper
sx={{
boxShadow: theme.customShadows.z1,
width: '100%',
minWidth: 285,
maxWidth: 420,
[theme.breakpoints.down('md')]: {
maxWidth: 285
}
}}
>
<ClickAwayListener onClickAway={handleClose}>
<MainCard
title="Notification"
elevation={0}
border={false}
content={false}
secondary={
<>
{read > 0 && (
<Tooltip title="Mark as all read">
<IconButton color="success" size="small" onClick={() => setRead(0)}>
<CheckCircleOutlined style={{ fontSize: '1.15rem' }} />
</IconButton>
</Tooltip>
)}
</>
}
>
<List
component="nav"
sx={{
p: 0,
'& .MuiListItemButton-root': {
py: 0.5,
'&.Mui-selected': { bgcolor: 'grey.50', color: 'text.primary' },
'& .MuiAvatar-root': avatarSX,
'& .MuiListItemSecondaryAction-root': { ...actionSX, position: 'relative' }
}
}}
>
<ListItemButton selected={read > 0}>
<ListItemAvatar>
<Avatar
sx={{
color: 'success.main',
bgcolor: 'success.lighter'
}}
>
<GiftOutlined />
</Avatar>
</ListItemAvatar>
<ListItemText
primary={
<Typography variant="h6">
It&apos;s{' '}
<Typography component="span" variant="subtitle1">
Cristina danny&apos;s
</Typography>{' '}
birthday today.
</Typography>
}
secondary="2 min ago"
/>
<ListItemSecondaryAction>
<Typography variant="caption" noWrap>
3:00 AM
</Typography>
</ListItemSecondaryAction>
</ListItemButton>
<Divider />
<ListItemButton selected={read > 0}>
<ListItemAvatar>
<Avatar
sx={{
color: 'primary.main',
bgcolor: 'primary.lighter'
}}
>
<MessageOutlined />
</Avatar>
</ListItemAvatar>
<ListItemText
primary={
<Typography variant="h6">
<Typography component="span" variant="subtitle1">
Aida Burg
</Typography>{' '}
commented your post.
</Typography>
}
secondary="5 August"
/>
<ListItemSecondaryAction>
<Typography variant="caption" noWrap>
6:00 PM
</Typography>
</ListItemSecondaryAction>
</ListItemButton>
<Divider />
<ListItemButton>
<ListItemAvatar>
<Avatar
sx={{
color: 'error.main',
bgcolor: 'error.lighter'
}}
>
<SettingOutlined />
</Avatar>
</ListItemAvatar>
<ListItemText
primary={
<Typography variant="h6">
Your Profile is Complete &nbsp;
<Typography component="span" variant="subtitle1">
60%
</Typography>{' '}
</Typography>
}
secondary="7 hours ago"
/>
<ListItemSecondaryAction>
<Typography variant="caption" noWrap>
2:45 PM
</Typography>
</ListItemSecondaryAction>
</ListItemButton>
<Divider />
<ListItemButton>
<ListItemAvatar>
<Avatar
sx={{
color: 'primary.main',
bgcolor: 'primary.lighter'
}}
>
C
</Avatar>
</ListItemAvatar>
<ListItemText
primary={
<Typography variant="h6">
<Typography component="span" variant="subtitle1">
Cristina Danny
</Typography>{' '}
invited to join{' '}
<Typography component="span" variant="subtitle1">
Meeting.
</Typography>
</Typography>
}
secondary="Daily scrum meeting time"
/>
<ListItemSecondaryAction>
<Typography variant="caption" noWrap>
9:10 PM
</Typography>
</ListItemSecondaryAction>
</ListItemButton>
<Divider />
<ListItemButton sx={{ textAlign: 'center', py: `${12}px !important` }}>
<ListItemText
primary={
<Typography variant="h6" color="primary">
View All
</Typography>
}
/>
</ListItemButton>
</List>
</MainCard>
</ClickAwayListener>
</Paper>
</Transitions>
)}
</Popper>
</Box>
);
};
export default Notification;

View File

@@ -0,0 +1,76 @@
import PropTypes from 'prop-types';
import { useState } from 'react';
// material-ui
import { List, ListItemButton, ListItemIcon, ListItemText } from '@mui/material';
// assets
import { EditOutlined, ProfileOutlined, LogoutOutlined, UserOutlined, WalletOutlined, CommentOutlined } from '@ant-design/icons';
import { useNavigate } from 'react-router';
import { useDispatch } from 'react-redux';
import { clearFcmToken } from 'store/reducers/fcmSlice';
import { logoutUser } from 'store/reducers/loginUserSlice';
// ==============================|| HEADER PROFILE - PROFILE TAB ||============================== //
const ProfileTab = ({ handleLogout }) => {
const dispatch = useDispatch();
const [selectedIndex, setSelectedIndex] = useState(0);
const navigate = useNavigate();
const handleListItemClick = (event, index) => {
setSelectedIndex(index);
};
return (
<List component="nav" sx={{ p: 0, '& .MuiListItemIcon-root': { minWidth: 32 } }}>
<ListItemButton
selected={selectedIndex === 0}
onClick={(event) => {
handleListItemClick(event, 0);
navigate('/viewprofile');
}}
>
<ListItemIcon>
<EditOutlined />
</ListItemIcon>
<ListItemText primary="View Profile" />
</ListItemButton>
<ListItemButton selected={selectedIndex === 2} onClick={(event) => handleListItemClick(event, 1)}>
<ListItemIcon>
<CommentOutlined />
</ListItemIcon>
<ListItemText primary="Support Ticket" />
</ListItemButton>
{/* <ListItemButton selected={selectedIndex === 4} onClick={(event) => handleListItemClick(event, 4)}>
<ListItemIcon>
<WalletOutlined />
</ListItemIcon>
<ListItemText primary="Billing" />
</ListItemButton> */}
<ListItemButton
selected={selectedIndex === 3}
// onClick={handleLogout}
onClick={() => {
handleLogout();
dispatch(clearFcmToken()); // ✅ dispatch the action
dispatch(logoutUser()); // ✅ dispatch logout user as initial state
}}
// onClick={()=>{
// navigate('/login')
// }}
>
<ListItemIcon>
<LogoutOutlined />
</ListItemIcon>
<ListItemText primary="Logout" />
</ListItemButton>
</List>
);
};
ProfileTab.propTypes = {
handleLogout: PropTypes.func
};
export default ProfileTab;

View File

@@ -0,0 +1,53 @@
import { useState } from 'react';
// material-ui
import { List, ListItemButton, ListItemIcon, ListItemText } from '@mui/material';
// assets
import { CommentOutlined, LockOutlined, QuestionCircleOutlined, UserOutlined, UnorderedListOutlined } from '@ant-design/icons';
// ==============================|| HEADER PROFILE - SETTING TAB ||============================== //
const SettingTab = () => {
const [selectedIndex, setSelectedIndex] = useState(0);
const handleListItemClick = (event, index) => {
setSelectedIndex(index);
};
return (
<List component="nav" sx={{ p: 0, '& .MuiListItemIcon-root': { minWidth: 32 } }}>
<ListItemButton selected={selectedIndex === 0} onClick={(event) => handleListItemClick(event, 0)}>
<ListItemIcon>
<QuestionCircleOutlined />
</ListItemIcon>
<ListItemText primary="Support" />
</ListItemButton>
<ListItemButton selected={selectedIndex === 1} onClick={(event) => handleListItemClick(event, 1)}>
<ListItemIcon>
<UserOutlined />
</ListItemIcon>
<ListItemText primary="Account Settings" />
</ListItemButton>
<ListItemButton selected={selectedIndex === 2} onClick={(event) => handleListItemClick(event, 2)}>
<ListItemIcon>
<LockOutlined />
</ListItemIcon>
<ListItemText primary="Privacy Center" />
</ListItemButton>
<ListItemButton selected={selectedIndex === 3} onClick={(event) => handleListItemClick(event, 3)}>
<ListItemIcon>
<CommentOutlined />
</ListItemIcon>
<ListItemText primary="Feedback" />
</ListItemButton>
<ListItemButton selected={selectedIndex === 4} onClick={(event) => handleListItemClick(event, 4)}>
<ListItemIcon>
<UnorderedListOutlined />
</ListItemIcon>
<ListItemText primary="History" />
</ListItemButton>
</List>
);
};
export default SettingTab;

View File

@@ -0,0 +1,240 @@
import PropTypes from 'prop-types';
import { useRef, useState } from 'react';
import { useNavigate } from 'react-router';
// material-ui
import { useTheme } from '@mui/material/styles';
import { Box, ButtonBase, CardContent, ClickAwayListener, Grid, Paper, Popper, Stack, Tab, Tabs, Tooltip, Typography } from '@mui/material';
// project import
import ProfileTab from './ProfileTab';
import SettingTab from './SettingTab';
import Avatar from 'components/@extended/Avatar';
import MainCard from 'components/MainCard';
import Transitions from 'components/@extended/Transitions';
import IconButton from 'components/@extended/IconButton';
import { ThemeMode } from 'config';
// import useAuth from 'hooks/useAuth';
// assets
import avatar1 from 'assets/images/users/avatar-1.png';
import { LogoutOutlined, SettingOutlined, UserOutlined } from '@ant-design/icons';
import { clearFcmToken } from 'store/reducers/fcmSlice';
import { useDispatch } from 'react-redux';
import { logoutUser } from 'store/reducers/loginUserSlice';
// tab panel wrapper
function TabPanel({ children, value, index, ...other }) {
return (
<div role="tabpanel" hidden={value !== index} id={`profile-tabpanel-${index}`} aria-labelledby={`profile-tab-${index}`} {...other}>
{value === index && children}
</div>
);
}
TabPanel.propTypes = {
children: PropTypes.node,
index: PropTypes.any.isRequired,
value: PropTypes.any.isRequired
};
function a11yProps(index) {
return {
id: `profile-tab-${index}`,
'aria-controls': `profile-tabpanel-${index}`
};
}
// ==============================|| HEADER CONTENT - PROFILE ||============================== //
const Profile = () => {
const theme = useTheme();
const navigate = useNavigate();
const dispatch = useDispatch();
// const { logout, user } = useAuth();
const handleLogout = async () => {
try {
// await logout();
// navigate(`/login`, {
// state: {
// from: ''
// }
// });
localStorage.removeItem('firstname');
localStorage.removeItem('appuserid');
localStorage.removeItem('authname');
localStorage.removeItem('roleid');
localStorage.removeItem('tenantid');
localStorage.clear();
navigate('/login');
} catch (err) {
console.error(err);
}
};
const anchorRef = useRef(null);
const [open, setOpen] = useState(false);
const handleToggle = () => {
setOpen((prevOpen) => !prevOpen);
};
const handleClose = (event) => {
if (anchorRef.current && anchorRef.current.contains(event.target)) {
return;
}
setOpen(false);
};
const [value, setValue] = useState(0);
const handleChange = (event, newValue) => {
setValue(newValue);
};
const iconBackColorOpen = theme.palette.mode === ThemeMode.DARK ? 'grey.200' : 'grey.300';
return (
<Box sx={{ flexShrink: 0, ml: 0.75 }}>
<Tooltip title="Profile">
<ButtonBase
sx={{
p: 0.25,
// bgcolor: open ? iconBackColorOpen : 'transparent',
borderRadius: 1
// '&:hover': { bgcolor: theme.palette.mode === ThemeMode.DARK ? 'secondary.light' : 'secondary.lighter' },
// '&:focus-visible': {
// outline: `2px solid ${theme.palette.secondary.dark}`,
// outlineOffset: 2
// }
}}
aria-label="open profile"
ref={anchorRef}
aria-controls={open ? 'profile-grow' : undefined}
aria-haspopup="true"
onClick={handleToggle}
>
<Stack direction="row" spacing={2} alignItems="center" sx={{ p: 0.5 }}>
<Avatar alt="profile user" src={avatar1} size="xs" />
<Typography variant="subtitle1">{/* {user?.name} */}</Typography>
</Stack>
</ButtonBase>
</Tooltip>
<Popper
placement="bottom-end"
open={open}
anchorEl={anchorRef.current}
role={undefined}
transition
disablePortal
popperOptions={{
modifiers: [
{
name: 'offset',
options: {
offset: [0, 9]
}
}
]
}}
>
{({ TransitionProps }) => (
<Transitions type="grow" position="top-right" in={open} {...TransitionProps}>
<Paper
sx={{
boxShadow: theme.customShadows.z1,
width: 290,
minWidth: 240,
maxWidth: 290,
[theme.breakpoints.down('md')]: {
maxWidth: 250
}
}}
>
<ClickAwayListener onClickAway={handleClose}>
<MainCard elevation={0} border={false} content={false}>
<CardContent sx={{ px: 2.5, pt: 3 }}>
<Grid container justifyContent="space-between" alignItems="center">
<Grid item>
<Stack direction="row" spacing={1.25} alignItems="center">
<Avatar alt="profile user" src={avatar1} sx={{ width: 32, height: 32 }} />
<Stack>
<Typography variant="h6">
{/* {user?.name} */}
{localStorage.getItem('firstname') || ''}
</Typography>
<Typography variant="body2" color="textSecondary">
{/* UI/UX Designer */}
Partner
</Typography>
</Stack>
</Stack>
</Grid>
<Grid item>
<Tooltip title="Logout">
<IconButton
size="large"
sx={{ color: 'text.primary' }}
// onClick={handleLogout}>
onClick={() => {
handleLogout();
dispatch(clearFcmToken()); // ✅ dispatch the action dispatch(logoutUser()); // ✅ dispatch logout user as initial state dispatch(logoutUser()); // ✅ dispatch logout user as initial state
dispatch(logoutUser()); // ✅ dispatch logout user as initial state
}}
>
<LogoutOutlined />
</IconButton>
</Tooltip>
</Grid>
</Grid>
</CardContent>
<Box sx={{ borderBottom: 1, borderColor: 'divider' }}>
<Tabs variant="fullWidth" value={value} onChange={handleChange} aria-label="profile tabs">
<Tab
sx={{
display: 'flex',
flexDirection: 'row',
// justifyContent: 'center',
justifyContent: 'flex-start',
alignItems: 'center',
textTransform: 'capitalize'
}}
icon={<UserOutlined style={{ marginBottom: 0, marginRight: '10px' }} />}
label="Profile"
{...a11yProps(0)}
/>
{/* <Tab
sx={{
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
textTransform: 'capitalize'
}}
icon={<SettingOutlined style={{ marginBottom: 0, marginRight: '10px' }} />}
label="Setting"
{...a11yProps(1)}
/> */}
</Tabs>
</Box>
<TabPanel value={value} index={0} dir={theme.direction}>
<ProfileTab handleLogout={handleLogout} />
</TabPanel>
<TabPanel value={value} index={1} dir={theme.direction}>
<SettingTab />
</TabPanel>
</MainCard>
</ClickAwayListener>
</Paper>
</Transitions>
)}
</Popper>
</Box>
);
};
export default Profile;

View File

@@ -0,0 +1,30 @@
// material-ui
import { Box, FormControl, InputAdornment, OutlinedInput } from '@mui/material';
// assets
import { SearchOutlined } from '@ant-design/icons';
// ==============================|| HEADER CONTENT - SEARCH ||============================== //
const Search = () => (
<Box sx={{ width: '100%', ml: { xs: 0, md: 1 } }}>
<FormControl sx={{ width: { xs: '100%', md: 224 } }}>
<OutlinedInput
size="small"
id="header-search"
startAdornment={
<InputAdornment position="start" sx={{ mr: -0.5 }}>
<SearchOutlined />
</InputAdornment>
}
aria-describedby="header-search-text"
inputProps={{
'aria-label': 'weight'
}}
placeholder="Ctrl + K"
/>
</FormControl>
</Box>
);
export default Search;

View File

@@ -0,0 +1,309 @@
import { useMemo, useState } from 'react';
// material-ui
import {
Box,
useMediaQuery,
Stack,
Tooltip,
IconButton,
Popper,
ClickAwayListener,
List,
ListItem,
ListItemButton,
ListItemText,
Grid,
ListItemIcon,
Typography
} from '@mui/material';
import { TbBoxMultiple1 } from 'react-icons/tb';
import { GrMultiple } from 'react-icons/gr';
import { TbUserEdit } from 'react-icons/tb';
import Transitions from 'components/@extended/Transitions';
// project import
import Search from './Search';
import Message from './Message';
import Profile from './Profile';
import Notification from './Notification';
import MobileSection from './MobileSection';
import MegaMenuSection from './MegaMenuSection';
import { useNavigate } from 'react-router';
import SportsMotorsportsOutlinedIcon from '@mui/icons-material/SportsMotorsportsOutlined';
import {
MailOutlined,
// DashboardOutlined,
UserOutlined,
CustomerServiceOutlined,
WindowsOutlined
} from '@ant-design/icons';
import { useTheme } from '@mui/material/styles';
// ==============================|| HEADER - CONTENT ||============================== //
const HeaderContent = () => {
const matchesXs = useMediaQuery((theme) => theme.breakpoints.down('md'));
// eslint-disable-next-line react-hooks/exhaustive-deps
const megaMenu = useMemo(() => <MegaMenuSection />, []);
const [open, setOpen] = useState(false);
const [anchorEl, setAnchorEl] = useState(null);
const theme = useTheme();
// eslint-disable-next-line react-hooks/exhaustive-deps
// const megaMenu = useMemo(() => <MegaMenuSection />, []);
const iconBackColorOpen = 'grey.300';
const iconBackColor = 'grey.100';
const navigate = useNavigate();
const handleToggle = (e) => {
setOpen(!open);
setAnchorEl(e.currentTarget);
};
const handleClickAway = () => {
setOpen(false);
};
return (
<>
{/* {!matchesXs && <Search />} */}
<Stack width="100%" direction="row" justifyContent="space-between" spacing={2} alignItems="center">
{/* {!matchesXs && megaMenu} */}
<Typography variant="h5" sx={{ ml: 2, color: '#fff' }} noWrap>
{localStorage.getItem('firstname') || ''}
</Typography>
{matchesXs && <Box sx={{ ml: 1 }} />}
<Stack direction={'row'} spacing={2}>
<Box sx={{ flexShrink: 0, ml: 0.75 }}>
<Tooltip title="Quick Menu" placement="left-start">
<IconButton
// color="secondary"
// variant="light"
// sx={{
// color: 'text.primary',
// bgcolor: open ? iconBackColorOpen : iconBackColor
// }}
sx={{
color: '#fff',
fontSize: '20px',
// bgcolor: open ? iconBackColorOpen : iconBackColor
bgcolor: 'transparent'
// border:'1px solid #fff'
}}
aria-label="open profile"
// ref={anchorRef}
// aria-controls={open ? 'profile-grow' : undefined}
aria-haspopup="true"
onClick={handleToggle}
>
<WindowsOutlined />
</IconButton>
</Tooltip>
<Popper
open={open}
placement="bottom"
anchorEl={anchorEl}
role={undefined}
// transition
disablePortal
popperOptions={{
modifiers: [
{
name: 'offset',
options: {
offset: 0
}
}
]
}}
sx={{
// backgroundColor:'white',
// border:1,
p: 0,
zIndex: 5000,
boxShadow: theme.customShadows.z1
}}
>
<Transitions type="grow" position="top" sx={{ overflow: 'hidden' }} in={open}>
{/* <Box sx={{
backgroundColor: 'white',
border: '1px solid #e0e0e0 !important',
borderRadius: 1,
}}> */}
<Box
sx={
{
// boxShadow: theme.customShadows.z1,
}
}
>
<ClickAwayListener onClickAway={handleClickAway}>
{/* <List disablePadding> */}
<List
component="nav"
sx={{
mt: 1.5,
p: 0,
width: '100%',
minWidth: 200,
maxWidth: 290,
bgcolor: theme.palette.background.paper,
borderRadius: 0.5,
[theme.breakpoints.down('md')]: {
maxWidth: 250
}
}}
>
<ListItemButton
selected={location.pathname === '/nearle/orders/create'}
onClick={() => {
// console.log(const location = useLocation();)
navigate('/nearle/orders/create');
handleClickAway();
}}
>
<ListItemText
primary={
<Grid container>
<ListItemIcon sx={{ mr: 1, fontSize: '20px' }}>
<TbBoxMultiple1 />
</ListItemIcon>
<Typography color="textPrimary">Create Order</Typography>
</Grid>
}
/>
</ListItemButton>
<ListItemButton
selected={location.pathname === '/nearle/orders/createorders'}
onClick={() => {
// console.log(const location = useLocation();)
navigate('/nearle/orders/createorders');
handleClickAway();
}}
>
<ListItemText
primary={
<Grid container>
<ListItemIcon sx={{ mr: 1, fontSize: '20px' }}>
<GrMultiple />
</ListItemIcon>
<Typography color="textPrimary">Create Multiple Order</Typography>
</Grid>
}
/>
</ListItemButton>
<ListItemButton
selected={location.pathname === '/nearle/customer/create'}
onClick={() => {
navigate('/nearle/customer/create');
handleClickAway();
}}
>
<ListItemText
primary={
<Grid container>
<ListItemIcon sx={{ mr: 1, fontSize: '20px' }}>
<TbUserEdit />
</ListItemIcon>
<Typography color="textPrimary">Create Customer</Typography>
</Grid>
}
/>
</ListItemButton>
{/* <ListItemButton
selected={location.pathname === '/clients/create'}
onClick={() => {
navigate('/clients/create')
handleClickAway()
}} >
<ListItemText
primary={
<Grid container>
<ListItemIcon sx={{ mr: 1, fontSize: '20px' }}>
<CustomerServiceOutlined />
</ListItemIcon>
<Typography color="textPrimary">Create Client</Typography>
</Grid>
}
/>
</ListItemButton> */}
{/* <ListItemButton
selected={location.pathname === '/riders/create'}
onClick={() => {
navigate('/riders/create')
handleClickAway()
}} >
<ListItemText
primary={
<Grid container>
<ListItemIcon sx={{ mr: 1, fontSize: '20px' }}>
<SportsMotorsportsOutlinedIcon />
</ListItemIcon>
<Typography color="textPrimary">Create Rider</Typography>
</Grid>
}
/>
</ListItemButton> */}
{/* <ListItem disablePadding>
<ListItemButton sx={{ p: 2 }} onClick={() => {
navigate('/create_order')
handleClickAway()
}}>
<ListItemIcon sx={{ mr: 1, fontSize: '20px' }}>
<MailOutlined />
</ListItemIcon>
<ListItemText primary="Create Order" />
</ListItemButton>
</ListItem>
<ListItem disablePadding>
<ListItemButton sx={{ p: 2 }} onClick={() => {
navigate('/create_client')
handleClickAway()
}}>
<ListItemIcon sx={{ mr: 1, fontSize: '20px' }}>
<CustomerServiceOutlined />
</ListItemIcon>
<ListItemText primary="Create Client" />
</ListItemButton>
</ListItem>
<ListItem disablePadding>
<ListItemButton sx={{ p: 2 }} onClick={() => {
navigate('/create_staff')
handleClickAway()
}}>
<ListItemIcon sx={{ mr: 1, fontSize: '20px' }}>
<UserOutlined />
</ListItemIcon>
<ListItemText primary="Create Staff" />
</ListItemButton>
</ListItem> */}
</List>
</ClickAwayListener>
{/* </Box> */}
</Box>
</Transitions>
</Popper>
</Box>
<Notification />
{/* <Message /> */}
{/* {!matchesXs && <Profile />}
{matchesXs && <MobileSection />} */}
<Tooltip title="Notifications">
<Profile />
</Tooltip>
</Stack>
</Stack>
</>
);
};
export default HeaderContent;

View File

@@ -0,0 +1,89 @@
import { useMemo } from 'react';
// material-ui
import { useTheme } from '@mui/material/styles';
import { AppBar, Toolbar, useMediaQuery } from '@mui/material';
// project import
import AppBarStyled from './AppBarStyled';
import HeaderContent from './HeaderContent';
import IconButton from 'components/@extended/IconButton';
import { MenuOrientation, ThemeMode } from 'config';
import useConfig from 'hooks/useConfig';
import { dispatch, useSelector } from 'store';
import { openDrawer } from 'store/reducers/menu';
// assets
import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons';
// ==============================|| MAIN LAYOUT - HEADER ||============================== //
const Header = () => {
const theme = useTheme();
const downLG = useMediaQuery(theme.breakpoints.down('lg'));
const { menuOrientation } = useConfig();
const menu = useSelector((state) => state.menu);
const { drawerOpen } = menu;
const isHorizontal = menuOrientation === MenuOrientation.HORIZONTAL && !downLG;
// header content
const headerContent = useMemo(() => <HeaderContent />, []);
const iconBackColorOpen = theme.palette.mode === ThemeMode.DARK ? 'grey.200' : 'grey.300';
const iconBackColor = theme.palette.mode === ThemeMode.DARK ? 'background.default' : 'grey.100';
// common header
const mainHeader = (
<Toolbar>
{!isHorizontal ? (
<IconButton
aria-label="open drawer"
onClick={() => dispatch(openDrawer(!drawerOpen))}
edge="start"
// color="secondary"
// variant="light"
// sx={{ color: 'text.primary', bgcolor: drawerOpen ? iconBackColorOpen : iconBackColor, ml: { xs: 0, lg: -2 } }}
sx={{ color: '#fff', bgcolor: 'transparent', ml: { xs: 0, lg: -2 },
fontSize:'25px',
':hover':{
color: '#fff', bgcolor: 'transparent'
} }}
>
{!drawerOpen ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />}
</IconButton>
) : null}
{headerContent}
</Toolbar>
);
// app-bar params
const appBar = {
position: 'fixed',
color: 'inherit',
elevation: 0,
sx: {
borderBottom: `1px solid ${theme.palette.divider}`,
zIndex: 1200,
width: isHorizontal ? '100%' : drawerOpen ? 'calc(100% - 260px)' : { xs: '100%', lg: 'calc(100% - 60px)' },
// boxShadow: theme.customShadows.z1
bgcolor:'#662582'
}
};
return (
<>
{!downLG ? (
<AppBarStyled open={drawerOpen} {...appBar}>
{mainHeader}
</AppBarStyled>
) : (
<AppBar {...appBar}>{mainHeader}</AppBar>
)}
</>
);
};
export default Header;

View File

@@ -0,0 +1,67 @@
import { useEffect } from 'react';
import { Outlet } from 'react-router-dom';
// material-ui
import { useTheme } from '@mui/material/styles';
import { useMediaQuery, Box, Container, Toolbar } from '@mui/material';
// project import
import Drawer from './Drawer';
import Header from './Header';
import Footer from './Footer';
import HorizontalBar from './Drawer/HorizontalBar';
import Breadcrumbs from 'components/@extended/Breadcrumbs';
import { MenuOrientation } from 'config';
import navigation from 'menu-items';
import useConfig from 'hooks/useConfig';
import { dispatch } from 'store';
import { openDrawer } from 'store/reducers/menu';
// ==============================|| MAIN LAYOUT ||============================== //
const MainLayout = () => {
const theme = useTheme();
const matchDownXL = useMediaQuery(theme.breakpoints.down('xl'));
const downLG = useMediaQuery(theme.breakpoints.down('lg'));
const { container, miniDrawer, menuOrientation } = useConfig();
const isHorizontal = menuOrientation === MenuOrientation.HORIZONTAL && !downLG;
// set media wise responsive drawer
useEffect(() => {
if (!miniDrawer) {
// dispatch(openDrawer(!matchDownXL));
dispatch(openDrawer(false));
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [matchDownXL]);
return (
<Box sx={{ display: 'flex', width: '100%' }}>
<Header />
{!isHorizontal ? <Drawer /> : <HorizontalBar />}
<Box component="main" sx={{ width: 'calc(100% - 260px)', flexGrow: 1, p: { xs: 2, sm: 3 } }}>
<Toolbar sx={{ mt: isHorizontal ? 8 : 'inherit' }} />
<Container
// maxWidth={container ? 'xl' : false}
maxWidth
sx={{
...(container && { px: { xs: 0, sm: 2 } }),
position: 'relative',
minHeight: 'calc(100vh - 110px)',
display: 'flex',
flexDirection: 'column'
}}
>
{/* <Breadcrumbs navigation={navigation} title titleBottom card={false} divider={false} /> */}
<Outlet />
{/* <Footer /> */}
</Container>
</Box>
</Box>
);
};
export default MainLayout;