front-hub/src/components/NavbarSite/DialogMenu.tsx
Nastya 15cf5cd21f
Some checks failed
Deploy / CreateImage (push) Failing after 42s
Deploy / DeployService (push) Has been skipped
новая система покупок
2025-07-09 10:57:33 +03:00

266 lines
8.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useState } from "react";
import { Link, useLocation, useNavigate } from "react-router-dom";
import {
Box,
Button,
List,
ListItem,
Typography,
useMediaQuery,
useTheme,
} from "@mui/material";
import { clearUserData, useUserStore } from "@root/stores/user";
import { currencyFormatter } from "@root/utils/currencyFormatter";
import { cardShadow } from "@root/utils/theme";
import { AvatarButton, clearAuthToken } from "@frontend/kitui";
import { logout } from "@root/api/auth";
import { enqueueSnackbar } from "notistack";
import { clearCustomTariffs } from "@root/stores/customTariffs";
import { clearTickets } from "@root/stores/tickets";
import {setNotEnoughMoneyAmount} from "@stores/allTypesOfPurchases"
type MenuItem = {
name: string;
url: string;
subMenu?: MenuItem[];
};
const arrayMenu: MenuItem[] = [
{
name: "Тарифы",
url: "/tariffs",
subMenu: [
{ name: "Тарифы на время", url: "/tariffs/time" },
{ name: "Тарифы на объём", url: "/tariffs/volume" },
{ name: "Мой тариф", url: "/tariffconstructor" },
],
},
{ name: "Профиль", url: "/settings" },
{ name: "FAQ", url: "/faq" },
{ name: "Корзина", url: "/cart" },
{ name: "Поддержка", url: "/support" },
{ name: "История", url: "/history" },
{ name: "Мой кошелёк", url: "/wallet" },
];
interface DialogMenuProps {
handleClose: () => void;
}
export default function DialogMenu({ handleClose }: DialogMenuProps) {
const [activeSubMenuIndex, setActiveSubMenuIndex] = useState<number>(-1);
const theme = useTheme();
const location = useLocation();
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
const isMobile = useMediaQuery(theme.breakpoints.down(600));
const isMobileHeader = useMediaQuery(theme.breakpoints.down(550));
const user = useUserStore((state) => state.user);
const cash = useUserStore((state) => state.userAccount?.wallet.cash) ?? 0;
const initials = useUserStore((state) => state.initials);
const navigate = useNavigate();
const closeDialogMenu = () => {
setActiveSubMenuIndex(-1);
handleClose();
};
async function handleLogoutClick() {
clearAuthToken();
clearUserData();
clearCustomTariffs();
clearTickets();
setNotEnoughMoneyAmount(0)
navigate("/");
const [_, logoutError] = await logout();
if (logoutError) {
return enqueueSnackbar(logoutError);
}
}
const handleSubMenu = (index: number) =>
setActiveSubMenuIndex((activeIndex) =>
activeIndex !== index ? index : -1
);
return (
<Box sx={{ height: "100%", maxHeight: "calc(100vh - 51px)" }}>
<List
sx={{
maxWidth: "250px",
background: location.pathname === "/" ? "#333647" : "#FFFFFF",
height: "100%",
}}
>
<ListItem
sx={{
pl: 0,
pr: 0,
flexDirection: "column",
alignItems: isMobile ? "start" : "end",
}}
>
{arrayMenu.map(({ name, url, subMenu = [] }, index) => (
<Box sx={{ width: "100%" }} key={name + index}>
<Button
key={index}
component={Link}
to={url}
state={{ previousUrl: location.pathname }}
disableRipple
variant="text"
onClick={() =>
!subMenu.length ? closeDialogMenu() : handleSubMenu(index)
}
sx={{
padding: "10px 10px 10px 20px",
display: "block",
fontWeight: 500,
color:
location.pathname === url
? "#7E2AEA"
: location.pathname === "/"
? "white"
: "black",
textTransform: "none",
fontSize: "16px",
borderRadius: 0,
"&:hover, &:active": {
color: "#7E2AEA",
background:
index === activeSubMenuIndex
? theme.palette.background.default
: "none",
},
}}
>
<Box>{name}</Box>
</Button>
{subMenu.length ? (
<Box
sx={{
backgroundColor: theme.palette.background.paper,
width: "100%",
boxShadow: !isTablet ? cardShadow : null,
}}
>
{index === activeSubMenuIndex &&
subMenu.map(({ name, url }) => (
<Link
key={name + url}
style={{
paddingLeft: "30px",
display: "block",
textDecoration: "none",
}}
to={url}
onClick={closeDialogMenu}
state={{ previousUrl: location.pathname }}
>
<Typography
variant="body2"
sx={{
padding: "12px",
whiteSpace: "nowrap",
fontWeight: 400,
color:
location.pathname === url
? "#7E2AEA"
: location.pathname === "/"
? "white"
: "black",
}}
>
{name}
</Typography>
</Link>
))}
</Box>
) : (
<></>
)}
</Box>
))}
{isMobileHeader && (
<Button
variant="text"
onClick={() => handleLogoutClick()}
sx={{
mt: "25px",
padding: "10px 10px 10px 20px",
display: "block",
fontWeight: 500,
color: "black",
textTransform: "none",
fontSize: "16px",
borderRadius: 0,
"&:hover, &:active": {
color: "#7E2AEA",
background: "none",
},
}}
>
<Box>Выход</Box>
</Button>
)}
</ListItem>
{location.pathname === "/" ? (
<Button
component={Link}
to={user ? "/tariffs" : "/signin"}
state={user ? undefined : { backgroundLocation: location }}
variant="outlined"
sx={{
width: "188px",
color: "white",
border: "1px solid white",
ml: "40px",
mt: "35px",
textTransform: "none",
fontWeight: "400",
fontSize: "18px",
lineHeight: "24px",
borderRadius: "8px",
padding: "8px 17px",
}}
>
Личный кабинет
</Button>
) : isMobileHeader ? (
<Box
sx={{
width: "100%",
height: "72px",
background: "#F2F3F7",
display: "flex",
alignItems: "center",
position: "absolute",
bottom: "0",
}}
>
<AvatarButton component={Link} to="/settings" sx={{ ml: "27px" }}>
{initials}
</AvatarButton>
<Box sx={{ ml: "8px", whiteSpace: "nowrap" }}>
<Typography
sx={{
fontSize: "12px",
lineHeight: "14px",
color: theme.palette.gray.dark,
}}
>
Мой баланс
</Typography>
<Typography variant="body2" color={theme.palette.purple.main}>
{currencyFormatter.format(cash / 100)}
</Typography>
</Box>
</Box>
) : null}
</List>
</Box>
);
}