front-hub/src/pages/TariffConstructor/TariffItem.tsx

136 lines
4.9 KiB
TypeScript
Raw Normal View History

2023-06-17 16:01:02 +00:00
import { useThrottle } from "@frontend/kitui";
2023-05-27 11:50:21 +00:00
import { Box, SliderProps, Typography, useMediaQuery, useTheme } from "@mui/material";
import CustomSlider from "@root/components/CustomSlider";
2023-07-27 16:51:12 +00:00
import NumberInputWithUnitAdornment from "@root/components/NumberInputWithUnitAdornment";
2023-05-27 11:50:21 +00:00
import CalendarIcon from "@root/components/icons/CalendarIcon";
import PieChartIcon from "@root/components/icons/PieChartIcon";
2023-06-11 10:07:47 +00:00
import { Privilege, PrivilegeValueType } from "@root/model/privilege";
import { useCartStore } from "@root/stores/cart";
2023-06-16 20:09:56 +00:00
import { setCustomTariffsUserValue, useCustomTariffsStore } from "@root/stores/customTariffs";
import { useDiscountStore } from "@root/stores/discounts";
import { useUserStore } from "@root/stores/user";
2023-05-27 11:50:21 +00:00
import { getDeclension } from "@root/utils/declension";
2023-06-11 10:07:47 +00:00
import { useEffect, useState } from "react";
2023-05-27 11:50:21 +00:00
const sliderSettingsByType: Record<PrivilegeValueType, Partial<SliderProps>> = {
"день": {
2023-07-27 16:51:12 +00:00
max: 365,
2023-05-27 11:50:21 +00:00
step: 1,
},
"шаблон": {
max: 1000000,
step: 1000,
},
"МБ": {
max: 1000000,
step: 1000,
},
};
interface Props {
2023-07-27 16:51:12 +00:00
privilege: Privilege;
2023-05-27 11:50:21 +00:00
}
2023-07-27 16:51:12 +00:00
export default function TariffPrivilegeSlider({ privilege }: Props) {
2023-05-27 11:50:21 +00:00
const theme = useTheme();
const upMd = useMediaQuery(theme.breakpoints.up("md"));
2023-07-27 16:51:12 +00:00
const userValue = useCustomTariffsStore(state => state.userValuesMap[privilege.serviceKey]?.[privilege._id]) ?? 0;
const discounts = useDiscountStore(state => state.discounts);
const currentCartTotal = useCartStore(state => state.cart.priceAfterDiscounts);
const purchasesAmount = useUserStore(state => state.userAccount?.wallet.purchasesAmount) ?? 0;
2023-06-16 20:09:56 +00:00
const [value, setValue] = useState<number>(userValue);
2023-06-11 10:07:47 +00:00
const throttledValue = useThrottle(value, 200);
2023-05-27 11:50:21 +00:00
2023-06-11 10:07:47 +00:00
useEffect(function setStoreValue() {
setCustomTariffsUserValue(
2023-07-27 16:51:12 +00:00
privilege.serviceKey,
privilege._id,
throttledValue,
discounts,
currentCartTotal,
purchasesAmount
);
2023-07-27 16:51:12 +00:00
}, [currentCartTotal, discounts, purchasesAmount, privilege._id, privilege.serviceKey, throttledValue]);
function handleSliderChange(event: Event, value: number | number[]) {
if (Array.isArray(value)) throw new Error("Slider uses multiple values instead of one");
setValue(value);
}
const quantityText = `${value} ${getDeclension(value, privilege.value)}`;
const quantityElement = (
<Box sx={{
display: "flex",
gap: "15px",
alignItems: "center",
justifyContent: upMd ? "end" : undefined,
flexWrap: "wrap",
mt: upMd ? undefined : "12px",
}}>
<Typography variant="p1" color={theme.palette.brightPurple.main} textAlign="end">
{quantityText}
</Typography>
<Box sx={{
display: "flex",
gap: "15px",
alignItems: "center",
flexWrap: "wrap",
}}>
<Typography sx={{ fontSize: "16px", lineHeight: "19px", mt: "1px" }}>или</Typography>
<NumberInputWithUnitAdornment
id={"privilege_input_" + privilege._id}
adornmentText={getDeclension(0, privilege.value)}
onChange={value => setValue(value)}
/>
</Box>
</Box>
);
const icon = privilege.type === "day"
? <CalendarIcon color={theme.palette.orange.main} bgcolor="#FEDFD0" />
: <PieChartIcon color={theme.palette.orange.main} bgcolor="#FEDFD0" />;
2023-06-11 10:07:47 +00:00
2023-05-27 11:50:21 +00:00
return (
<Box>
<Typography sx={{ color: theme.palette.grey3.main, mb: "auto" }}>
2023-07-27 16:51:12 +00:00
{privilege.description}
2023-05-27 11:50:21 +00:00
</Typography>
<Box sx={{
display: "flex",
flexDirection: "column",
mt: "40px",
}}>
<Box sx={{
display: "flex",
2023-07-27 16:51:12 +00:00
// flexWrap: "wrap",
2023-05-27 11:50:21 +00:00
alignItems: "center",
mb: "8px",
justifyContent: "space-between",
2023-07-27 16:51:12 +00:00
gap: "10px",
2023-05-27 11:50:21 +00:00
}}>
<Box sx={{
display: "flex",
2023-07-27 16:51:12 +00:00
alignItems: "center",
2023-05-27 11:50:21 +00:00
gap: "22px",
}}>
{icon}
2023-07-27 16:51:12 +00:00
<Typography variant="h5">{privilege.name}</Typography>
2023-05-27 11:50:21 +00:00
</Box>
{upMd && quantityElement}
</Box>
<CustomSlider
value={value}
defaultValue={0}
min={0}
onChange={handleSliderChange}
2023-07-27 16:51:12 +00:00
{...sliderSettingsByType[privilege.value]}
2023-05-27 11:50:21 +00:00
/>
{!upMd && quantityElement}
</Box>
</Box>
);
}