198 lines
7.1 KiB
TypeScript
198 lines
7.1 KiB
TypeScript
import SectionWrapper from "@components/SectionWrapper";
|
||
import { getMessageFromFetchError } from "@frontend/kitui";
|
||
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
|
||
import { Box, IconButton, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||
import NumberIcon from "@root/components/NumberIcon";
|
||
import { FullTariff } from "@root/model/tariff";
|
||
import { useCartStore } from "@root/stores/cart";
|
||
import { useDiscountStore } from "@root/stores/discounts";
|
||
import { useTariffStore } from "@root/stores/tariffs";
|
||
import { addTariffToCart, useUserStore } from "@root/stores/user";
|
||
import { calcIndividualTariffPrices } from "@root/utils/calcTariffPrices";
|
||
import { currencyFormatter } from "@root/utils/currencyFormatter";
|
||
import { handleComponentError } from "@root/utils/handleComponentError";
|
||
import { usePrevLocation } from "@root/utils/hooks/handleCustomBackNavigation";
|
||
import { useRecentlyPurchasedTariffs } from "@utils/hooks/useRecentlyPurchasedTariffs";
|
||
import { enqueueSnackbar } from "notistack";
|
||
import { useState } from "react";
|
||
import { withErrorBoundary } from "react-error-boundary";
|
||
import { useLocation } from "react-router-dom";
|
||
import FreeTariffCard from "./FreeTariffCard";
|
||
import TariffCard from "./TariffCard";
|
||
|
||
const subPages = ["Опросник", /*"Шаблонизатор",*/ /*"Сокращатель ссылок"*/];
|
||
|
||
const StepperText: Record<string, string> = {
|
||
volume: "Тарифы на объём",
|
||
time: "Тарифы на время",
|
||
};
|
||
|
||
|
||
|
||
function TariffPage() {
|
||
const theme = useTheme();
|
||
const upMd = useMediaQuery(theme.breakpoints.up("md"));
|
||
const isMobile = useMediaQuery(theme.breakpoints.down(600));
|
||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||
const location = useLocation();
|
||
const tariffs = useTariffStore((state) => state.tariffs);
|
||
const [selectedItem, setSelectedItem] = useState<number>(0);
|
||
const discounts = useDiscountStore((state) => state.discounts);
|
||
const purchasesAmount = useUserStore((state) => state.userAccount?.wallet.spent) ?? 0;
|
||
const cartTariffMap = useCartStore((state) => state.cartTariffMap);
|
||
const isUserNko = useUserStore((state) => state.userAccount?.status) === "nko";
|
||
|
||
const { recentlyPurchased } = useRecentlyPurchasedTariffs();
|
||
const handleCustomBackNavigation = usePrevLocation(location);
|
||
|
||
const unit: string = String(location.pathname).slice(9);
|
||
const currentTariffs = Object.values(cartTariffMap).filter((tariff): tariff is FullTariff => typeof tariff === "object");
|
||
|
||
function handleTariffItemClick(tariffId: string) {
|
||
addTariffToCart(tariffId)
|
||
.then(() => {
|
||
enqueueSnackbar("Тариф добавлен в корзину");
|
||
})
|
||
.catch((error) => {
|
||
const message = getMessageFromFetchError(error);
|
||
if (message) enqueueSnackbar(message);
|
||
});
|
||
}
|
||
|
||
const filteredTariffs = tariffs.filter((tariff) => {
|
||
if (tariff.privileges[0] === undefined) return false
|
||
if (
|
||
tariff.privileges[0].type === "day" === (unit === "time") &&
|
||
!tariff.isDeleted &&
|
||
!tariff.isCustom
|
||
) {
|
||
if (selectedItem === 0 && tariff.privileges[0].serviceKey === "squiz") return true
|
||
if (selectedItem === 1 && tariff.privileges[0].serviceKey === "templategen") return true
|
||
}
|
||
return false
|
||
});
|
||
|
||
const createTariffElements = (filteredTariffs: FullTariff[], addFreeTariff = false) => {
|
||
const tariffElements = filteredTariffs
|
||
.filter((tariff) => tariff.privileges.length > 0)
|
||
.map((tariff, index) => {
|
||
const { priceBeforeDiscounts, priceAfterDiscounts } = calcIndividualTariffPrices(
|
||
tariff,
|
||
discounts,
|
||
purchasesAmount,
|
||
currentTariffs,
|
||
isUserNko
|
||
);
|
||
|
||
return (
|
||
<TariffCard
|
||
key={tariff._id}
|
||
discount={(priceBeforeDiscounts - priceAfterDiscounts) ? `${((priceBeforeDiscounts - priceAfterDiscounts) / (priceBeforeDiscounts / 100)).toFixed(0)}%` : ""}
|
||
icon={
|
||
<NumberIcon
|
||
number={index + 1}
|
||
color={unit === "time" ? theme.palette.purple.main : theme.palette.orange.main}
|
||
backgroundColor={unit === "time" ? "#EEE4FC" : "#FEDFD0"}
|
||
/>
|
||
}
|
||
buttonProps={{
|
||
text: "Выбрать",
|
||
onClick: () => handleTariffItemClick(tariff._id),
|
||
}}
|
||
headerText={tariff.name}
|
||
text={tariff.description ||""}
|
||
price={
|
||
<>
|
||
{priceBeforeDiscounts !== priceAfterDiscounts && (
|
||
<Typography variant="oldPrice">{currencyFormatter.format(priceBeforeDiscounts / 100)}</Typography>
|
||
)}
|
||
<Typography variant="price">{currencyFormatter.format(priceAfterDiscounts / 100)}</Typography>
|
||
</>
|
||
}
|
||
/>
|
||
);
|
||
});
|
||
|
||
if (addFreeTariff) {
|
||
if (tariffElements.length < 6) tariffElements.push(<FreeTariffCard key="free_tariff_card" />);
|
||
else tariffElements.splice(5, 0, <FreeTariffCard key="free_tariff_card" />);
|
||
}
|
||
|
||
return tariffElements;
|
||
};
|
||
|
||
return (
|
||
<SectionWrapper
|
||
maxWidth="lg"
|
||
sx={{
|
||
mt: "20px",
|
||
mb: upMd ? "100px" : "63px",
|
||
px: isTablet ? (isMobile ? "18px" : "40px") : "20px",
|
||
display: "flex",
|
||
flexDirection: "column",
|
||
}}
|
||
>
|
||
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||
{isMobile && (
|
||
<IconButton
|
||
onClick={handleCustomBackNavigation}
|
||
sx={{ p: 0, height: "28px", width: "28px", color: "black", marginRight: "10px" }}
|
||
>
|
||
<ArrowBackIcon />
|
||
</IconButton>
|
||
)}
|
||
<Typography
|
||
sx={{
|
||
marginBottom: "23px",
|
||
mt: "20px",
|
||
fontSize: isMobile ? "24px" : "36px",
|
||
fontWeight: "500",
|
||
}}
|
||
>
|
||
{StepperText[unit]}
|
||
</Typography>
|
||
</Box>
|
||
{/* {isMobile ? (
|
||
<Select items={subPages} selectedItem={selectedItem} setSelectedItem={setSelectedItem} />
|
||
) : (
|
||
<Tabs items={subPages} selectedItem={selectedItem} setSelectedItem={setSelectedItem} />
|
||
)} */}
|
||
<Box
|
||
sx={{
|
||
justifyContent: "left",
|
||
mt: "40px",
|
||
mb: "30px",
|
||
display: "grid",
|
||
gap: "40px",
|
||
gridTemplateColumns: `repeat(auto-fit, minmax(300px, ${isTablet ? "436px" : "360px"}))`,
|
||
}}
|
||
>
|
||
{createTariffElements(filteredTariffs, true)}
|
||
</Box>
|
||
{/*{recentlyPurchased.length > 0 && (*/}
|
||
{/* <>*/}
|
||
{/* <Typography*/}
|
||
{/* sx={{*/}
|
||
{/* mt: "40px",*/}
|
||
{/* fontSize: isMobile ? "24px" : "36px",*/}
|
||
{/* fontWeight: "500",*/}
|
||
{/* }}*/}
|
||
{/* >*/}
|
||
{/* Ранее вы*/}
|
||
{/* </Typography>*/}
|
||
{/* <Slider items={createTariffElements(recentlyPurchased)} />*/}
|
||
{/* </>*/}
|
||
{/*)}*/}
|
||
</SectionWrapper>
|
||
);
|
||
}
|
||
|
||
export default withErrorBoundary(TariffPage, {
|
||
fallback: (
|
||
<Typography mt="8px" textAlign="center">
|
||
Ошибка загрузки тарифов
|
||
</Typography>
|
||
),
|
||
onError: handleComponentError,
|
||
});
|