234 lines
7.4 KiB
TypeScript
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>
|
|
);
|
|
}
|