Initial commit
This commit is contained in:
65
front/src/components/navigation/MainNav.js
Normal file
65
front/src/components/navigation/MainNav.js
Normal file
@@ -0,0 +1,65 @@
|
||||
import * as React from 'react';
|
||||
import Avatar from '@mui/material/Avatar';
|
||||
import Box from '@mui/material/Box';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import Stack from '@mui/material/Stack';
|
||||
import {List as ListIcon} from '@phosphor-icons/react/dist/ssr/List';
|
||||
// import NotificationsIcon from '@mui/icons-material/Notifications';
|
||||
|
||||
import {usePopover} from "../../hooks/usePopover";
|
||||
import {MobileNav} from "./MobileNav";
|
||||
import {UserPopover} from "../core/UserPopover";
|
||||
// import Tooltip from "@mui/material/Tooltip";
|
||||
// import {Badge} from "@mui/material";
|
||||
// import {useAlert} from "../../hooks/useAlert";
|
||||
|
||||
export function MainNav() {
|
||||
const [openNav, setOpenNav] = React.useState(false);
|
||||
// const {notImplement} = useAlert();
|
||||
|
||||
const userPopover = usePopover();
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box
|
||||
component="header"
|
||||
sx={{
|
||||
borderBottom: '1px solid var(--mui-palette-divider)',
|
||||
backgroundColor: 'var(--mui-palette-background-paper)',
|
||||
position: 'sticky',
|
||||
top: 0,
|
||||
zIndex: 'var(--mui-zIndex-appBar)',
|
||||
height: '64px'
|
||||
}}
|
||||
>
|
||||
<Stack direction="row" spacing={3}
|
||||
sx={{alignItems: 'center', justifyContent: 'space-between', minHeight: '64px', px: 2}}>
|
||||
<Stack sx={{alignItems: 'center'}} direction="row" spacing={3}>
|
||||
<IconButton onClick={() => setOpenNav(true)} sx={{display: {xl: 'none'}}}>
|
||||
<ListIcon/>
|
||||
</IconButton>
|
||||
</Stack>
|
||||
<Stack sx={{alignItems: 'center'}} direction="row" spacing={2}>
|
||||
{/*<Tooltip title="Уведомления" onClick={() => notImplement()}>*/}
|
||||
{/* <Badge badgeContent={10} color="success" variant="standart">*/}
|
||||
{/* <IconButton>*/}
|
||||
{/* <NotificationsIcon/>*/}
|
||||
{/* </IconButton>*/}
|
||||
{/* </Badge>*/}
|
||||
{/*</Tooltip>*/}
|
||||
<Avatar onClick={userPopover.handleOpen} ref={userPopover.anchorRef} src="/assets/avatar.png"
|
||||
sx={{cursor: 'pointer'}}/>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</Box>
|
||||
<UserPopover anchorEl={userPopover.anchorRef.current} onClose={userPopover.handleClose}
|
||||
open={userPopover.open}/>
|
||||
<MobileNav
|
||||
onClose={() => {
|
||||
setOpenNav(false);
|
||||
}}
|
||||
open={openNav}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
38
front/src/components/navigation/MobileNav.js
Normal file
38
front/src/components/navigation/MobileNav.js
Normal file
@@ -0,0 +1,38 @@
|
||||
import * as React from 'react';
|
||||
import Drawer from '@mui/material/Drawer';
|
||||
import {NavigationMenu} from "./NavigationMenu";
|
||||
|
||||
//Боковое меню
|
||||
export function MobileNav({open, onClose}) {
|
||||
return (
|
||||
<Drawer
|
||||
PaperProps={{
|
||||
sx: {
|
||||
'--MobileNav-background': 'var(--mui-palette-neutral-950)',
|
||||
'--MobileNav-color': 'var(--mui-palette-common-white)',
|
||||
'--NavItem-color': 'var(--mui-palette-neutral-300)',
|
||||
'--NavItem-hover-background': 'rgba(255, 255, 255, 0.04)',
|
||||
'--NavItem-active-background': 'var(--mui-palette-primary-main)',
|
||||
'--NavItem-active-color': 'var(--mui-palette-primary-contrastText)',
|
||||
'--NavItem-disabled-color': 'var(--mui-palette-neutral-500)',
|
||||
'--NavItem-icon-color': 'var(--mui-palette-neutral-400)',
|
||||
'--NavItem-icon-active-color': 'var(--mui-palette-primary-contrastText)',
|
||||
'--NavItem-icon-disabled-color': 'var(--mui-palette-neutral-600)',
|
||||
bgcolor: 'var(--MobileNav-background)',
|
||||
color: 'var(--MobileNav-color)',
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
maxWidth: '100%',
|
||||
scrollbarWidth: 'none',
|
||||
width: 'var(--MobileNav-width)',
|
||||
zIndex: 'var(--MobileNav-zIndex)',
|
||||
'&::-webkit-scrollbar': {display: 'none'},
|
||||
},
|
||||
}}
|
||||
onClose={onClose}
|
||||
open={open}
|
||||
>
|
||||
<NavigationMenu/>
|
||||
</Drawer>
|
||||
);
|
||||
}
|
||||
74
front/src/components/navigation/NavItem.js
Normal file
74
front/src/components/navigation/NavItem.js
Normal file
@@ -0,0 +1,74 @@
|
||||
import Stack from "@mui/material/Stack";
|
||||
import {isNavItemActive} from "../../lib/isNavItemActive";
|
||||
import {navIcons} from "../core/navIcons";
|
||||
import Box from "@mui/material/Box";
|
||||
import Typography from "@mui/material/Typography";
|
||||
import {Link} from "react-router-dom";
|
||||
|
||||
export function renderNavItems({items = [], pathname}) {
|
||||
const children = items.reduce((acc, curr) => {
|
||||
const {key, ...item} = curr;
|
||||
acc.push(<NavItem key={key} pathname={pathname} {...item} />);
|
||||
return acc;
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Stack key={"stack-NavItem-key"} component="ul" spacing={1} sx={{listStyle: 'none', m: 0, p: 0}}>
|
||||
{children}
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
function NavItem({disabled, external, href, icon, matcher, pathname, title}) {
|
||||
const active = isNavItemActive({disabled, external, href, matcher, pathname});
|
||||
const Icon = icon ? navIcons[icon] : null;
|
||||
|
||||
return (
|
||||
<li>
|
||||
<Link to={href} style={{ textDecoration: 'none' }}>
|
||||
<Box
|
||||
sx={{
|
||||
alignItems: 'center',
|
||||
borderRadius: 1,
|
||||
color: 'var(--NavItem-color)',
|
||||
cursor: 'pointer',
|
||||
display: 'flex',
|
||||
flex: '0 0 auto',
|
||||
gap: 1,
|
||||
p: '6px 16px',
|
||||
position: 'relative',
|
||||
textDecoration: 'none',
|
||||
whiteSpace: 'nowrap',
|
||||
...(disabled && {
|
||||
bgcolor: 'var(--NavItem-disabled-background)',
|
||||
color: 'var(--NavItem-disabled-color)',
|
||||
cursor: 'not-allowed',
|
||||
}),
|
||||
...(active && {
|
||||
bgcolor: 'var(--NavItem-active-background)',
|
||||
color: 'var(--NavItem-active-color)'
|
||||
}),
|
||||
}}
|
||||
>
|
||||
<Box sx={{alignItems: 'center', display: 'flex', justifyContent: 'center', flex: '0 0 auto'}}>
|
||||
{Icon ? (
|
||||
<Icon
|
||||
fill={active ? 'var(--NavItem-icon-active-color)' : 'var(--NavItem-icon-color)'}
|
||||
fontSize="var(--icon-fontSize-md)"
|
||||
weight={active ? 'fill' : undefined}
|
||||
/>
|
||||
) : null}
|
||||
</Box>
|
||||
<Box sx={{flex: '1 1 auto'}}>
|
||||
<Typography
|
||||
component="span"
|
||||
sx={{color: 'inherit', fontSize: '0.875rem', fontWeight: 500, lineHeight: '28px'}}
|
||||
>
|
||||
{title}
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
</Link>
|
||||
</li>
|
||||
);
|
||||
}
|
||||
56
front/src/components/navigation/NavigationMenu.js
Normal file
56
front/src/components/navigation/NavigationMenu.js
Normal file
@@ -0,0 +1,56 @@
|
||||
import Stack from "@mui/material/Stack";
|
||||
import Box from "@mui/material/Box";
|
||||
import {ThemeSwitch} from "../core/ThemeSwitch";
|
||||
import Divider from "@mui/material/Divider";
|
||||
import {renderNavItems} from "./NavItem";
|
||||
import {navItems} from "../../navItems";
|
||||
import React, {useEffect, useState} from "react";
|
||||
import {useLocation} from "react-router-dom";
|
||||
import {useUser} from "../../hooks/useUser";
|
||||
import Typography from "@mui/material/Typography";
|
||||
|
||||
function renderSpecialItems(items, label, pathname) {
|
||||
return (
|
||||
<Box>
|
||||
<hr/>
|
||||
<Typography pl={"20px"} pb={1} variant="subtitle2" color="textSecondary">{label}</Typography>
|
||||
{renderNavItems({items: items, pathname: pathname})}
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
export function NavigationMenu() {
|
||||
const location = useLocation();
|
||||
const pathname = location.pathname;
|
||||
const {user} = useUser();
|
||||
const [items, setItems] = useState(null)
|
||||
|
||||
const userChild = navItems.filter((item) => !item.forBarmen && !item.forAdmin)
|
||||
const barmenChild = navItems.filter((item) => item.forBarmen)
|
||||
const adminChild = navItems.filter((item) => item.forAdmin)
|
||||
|
||||
useEffect(() => {
|
||||
const role = !user ? "USER" : Object.keys(user).length === 0 ? "USER" : user.role
|
||||
const newState = (
|
||||
<Box component="nav" sx={{flex: '1 1 auto', p: '12px'}}>
|
||||
{renderNavItems({items: userChild, pathname: pathname})}
|
||||
{role !== "USER" && renderSpecialItems(barmenChild, "Для бармена:", pathname)}
|
||||
{role === "ADMIN" && renderSpecialItems(adminChild, "Для админа", pathname)}
|
||||
</Box>
|
||||
)
|
||||
setItems(newState)
|
||||
// eslint-disable-next-line
|
||||
}, [user, pathname]);
|
||||
|
||||
return (
|
||||
<>
|
||||
{/*верхняя стопка*/}
|
||||
<Stack spacing={2} sx={{p: 2, height: '63px'}}>
|
||||
<ThemeSwitch/>
|
||||
</Stack>
|
||||
<Divider sx={{borderColor: 'var(--mui-palette-neutral-700)'}}/>
|
||||
{/*меню навигации*/}
|
||||
{items}
|
||||
</>
|
||||
)
|
||||
}
|
||||
37
front/src/components/navigation/SideNav.js
Normal file
37
front/src/components/navigation/SideNav.js
Normal file
@@ -0,0 +1,37 @@
|
||||
import * as React from 'react';
|
||||
import Box from '@mui/material/Box';
|
||||
import {NavigationMenu} from "./NavigationMenu";
|
||||
|
||||
export function SideNav() {
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
'--SideNav-background': 'var(--mui-palette-neutral-950)',
|
||||
'--SideNav-color': 'var(--mui-palette-common-white)',
|
||||
'--NavItem-color': 'var(--mui-palette-neutral-300)',
|
||||
'--NavItem-hover-background': 'rgba(255, 255, 255, 0.04)',
|
||||
'--NavItem-active-background': 'var(--mui-palette-primary-main)',
|
||||
'--NavItem-active-color': 'var(--mui-palette-primary-contrastText)',
|
||||
'--NavItem-disabled-color': 'var(--mui-palette-neutral-500)',
|
||||
'--NavItem-icon-color': 'var(--mui-palette-neutral-400)',
|
||||
'--NavItem-icon-active-color': 'var(--mui-palette-primary-contrastText)',
|
||||
'--NavItem-icon-disabled-color': 'var(--mui-palette-neutral-600)',
|
||||
bgcolor: 'var(--SideNav-background)',
|
||||
color: 'var(--SideNav-color)',
|
||||
display: {xs: 'none', xl: 'flex'},
|
||||
flexDirection: 'column',
|
||||
height: '100%',
|
||||
left: 0,
|
||||
maxWidth: '100%',
|
||||
position: 'fixed',
|
||||
scrollbarWidth: 'none',
|
||||
top: 0,
|
||||
width: 'var(--SideNav-width)',
|
||||
zIndex: 'var(--SideNav-zIndex)',
|
||||
'&::-webkit-scrollbar': {display: 'none'},
|
||||
}}
|
||||
>
|
||||
<NavigationMenu/>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user