front-hub/src/pages/Tariffs/TariffsPage.tsx
nflnkr fdd38aa42f temporarily fix cart history
remove console clutter
upgrade typescript version
2024-03-12 20:07:56 +03:00

198 lines
7.1 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 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,
});