front-hub/src/components/CustomWrapperDrawer.tsx

234 lines
7.4 KiB
TypeScript

import { useState } from "react";
import { Box, SvgIcon, IconButton, Typography, CircularProgress, useMediaQuery, useTheme } from "@mui/material";
import ClearIcon from "@mui/icons-material/Clear";
import { currencyFormatter } from "@root/utils/currencyFormatter";
import { useUserStore, removeTariffFromCart, setCart } from "@root/stores/user";
import { enqueueSnackbar } from "notistack";
import { ServiceCartData, getMessageFromFetchError } from "@frontend/kitui";
import ExpandIcon from "@components/icons/ExpandIcon";
import { deleteCart } from "@root/api/cart";
import { ReactComponent as CrossIcon } from "@root/assets/Icons/cross.svg";
import type { MouseEvent } from "react";
import CustomTariffAccordion from "@root/components/CustomTariffAccordion";
import { setNotEnoughMoneyAmount } from "@root/stores/cart";
const name: Record<string, string> = {
templategen: "Шаблонизатор",
squiz: "Опросник",
reducer: "Скоращатель ссылок",
custom: "Мои тарифы",
};
interface Props {
serviceData: ServiceCartData;
}
export default function CustomWrapperDrawer({ serviceData }: Props) {
const [isExpanded, setIsExpanded] = useState<boolean>(false);
const [isLoading, setIsLoading] = useState<boolean>(false);
const theme = useTheme();
const upMd = useMediaQuery(theme.breakpoints.up("md"));
const upSm = useMediaQuery(theme.breakpoints.up("sm"));
const userAccount = useUserStore((state) => state.userAccount);
function handleItemDeleteClick(tariffId: string) {
removeTariffFromCart(tariffId)
.then(() => {
enqueueSnackbar("Тариф удален");
})
.catch((error) => {
const message = getMessageFromFetchError(error);
if (message) enqueueSnackbar(message);
});
}
const deleteService = async (event: MouseEvent<HTMLButtonElement>) => {
event.stopPropagation();
let cartItems: string[] = userAccount?.cart || [];
const errors: string[] = [];
setIsLoading(true);
setNotEnoughMoneyAmount(0);
for (const { id } of serviceData.tariffs) {
const [cartItemsResponse, deleteError] = await deleteCart(id);
if (deleteError) {
errors.push(deleteError);
} else {
cartItems = cartItemsResponse;
}
}
setCart(cartItems);
setIsLoading(false);
errors.forEach(enqueueSnackbar);
};
return (
<Box sx={{ display: "flex", alignItems: "center" }}>
<Box
sx={{
overflow: "hidden",
borderRadius: "12px",
width: "100%",
}}
>
<Box
sx={{
backgroundColor: "white",
"&:first-of-type": {
borderTopLeftRadius: "12px",
borderTopRightRadius: "12px",
},
"&:last-of-type": {
borderBottomLeftRadius: "12px",
borderBottomRightRadius: "12px",
},
"&:not(:last-of-type)": {
borderBottom: `1px solid ${theme.palette.gray.main}`,
},
}}
>
<Box
onClick={() => setIsExpanded((prev) => !prev)}
sx={{
height: "72px",
display: "flex",
gap: "10px",
alignItems: "center",
justifyContent: "space-between",
cursor: "pointer",
userSelect: "none",
}}
>
<ExpandIcon isExpanded={isExpanded} />
<Box
sx={{
width: "100%",
display: "flex",
justifyContent: "space-between",
}}
>
<Typography
sx={{
fontSize: upMd ? "20px" : "16px",
lineHeight: upMd ? undefined : "19px",
fontWeight: 500,
color: theme.palette.text.secondary,
px: 0,
}}
>
{name[serviceData.serviceKey]}
</Typography>
<Box
sx={{
display: "flex",
justifyContent: "flex-end",
height: "100%",
alignItems: "center",
}}
>
<Typography
sx={{
color: theme.palette.gray.dark,
fontSize: upSm ? "20px" : "16px",
fontWeight: 500,
}}
>
{currencyFormatter.format(serviceData.price / 100)}
</Typography>
</Box>
</Box>
{isLoading ? (
<Box>
<CircularProgress sx={{ color: "#666666" }} />
</Box>
) : (
<IconButton
onClick={deleteService}
sx={{
padding: "3px",
height: "30px",
width: "30px",
}}
>
<CrossIcon
style={{
height: "24px",
width: "24px",
stroke: theme.palette.purple.main,
}}
/>
</IconButton>
)}
</Box>
{isExpanded &&
serviceData.tariffs.map((tariff) => {
const privilege = tariff.privileges[0];
return tariff.privileges.length > 1 ? (
<CustomTariffAccordion key={tariff.id} tariffCartData={tariff} />
) : (
<Box
key={tariff.id + privilege.privilegeId}
sx={{
py: upMd ? "10px" : undefined,
pt: upMd ? undefined : "15px",
pb: upMd ? undefined : "20px",
display: "flex",
justifyContent: "space-between",
alignItems: "center",
gap: "15px",
}}
>
<Typography
sx={{
width: "200px",
fontSize: upMd ? undefined : "16px",
lineHeight: upMd ? undefined : "19px",
color: theme.palette.gray.dark,
}}
>
{privilege.description}
</Typography>
<Box
sx={{
display: "flex",
justifyContent: "space-between",
gap: "10px",
alignItems: "center",
}}
>
<Typography
sx={{
color: theme.palette.gray.dark,
fontSize: "20px",
fontWeight: 500,
}}
>
{currencyFormatter.format((tariff.price || privilege.price) / 100)}
</Typography>
<SvgIcon
sx={{
cursor: "pointer",
width: "30px",
color: theme.palette.purple.main,
}}
onClick={() => handleItemDeleteClick(tariff.id)}
component={ClearIcon}
/>
</Box>
</Box>
);
})}
</Box>
</Box>
</Box>
);
}