front-hub/src/pages/Tariffs/TariffsPage.tsx
2024-03-27 16:11:53 +03:00

220 lines
8.5 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 { Tariff, calcTariffPrice, 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 { useTariffStore } from "@root/stores/tariffs";
import { addTariffToCart, useUserStore } from "@root/stores/user";
import { currencyFormatter } from "@root/utils/currencyFormatter";
import { handleComponentError } from "@root/utils/handleComponentError";
import { usePrevLocation } from "@root/utils/hooks/handleCustomBackNavigation";
import { useCartTariffs } from "@root/utils/hooks/useCartTariffs";
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";
import { useDiscounts } from "@root/api/price";
import { Select } from "@components/Select";
import { Tabs } from "@components/Tabs";
const subPages = ["Базовый тариф PenaQuiz", 'Убрать логотип "PenaQuiz"'];
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 = useDiscounts();
const purchasesAmount = useUserStore((state) => state.userAccount?.wallet.spent) ?? 0;
const userId = useUserStore(state => state.user?._id) ?? "";
const isUserNko = useUserStore((state) => state.userAccount?.status) === "nko";
const currentTariffs = useCartTariffs();
const handleCustomBackNavigation = usePrevLocation(location);
const unit: string = String(location.pathname).slice(9);
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 && unit === "time") || unit !== "time") &&
tariff.privileges[0].serviceKey === "squiz" &&
tariff.privileges[0].privilegeId !== "squizHideBadge"
)
return true;
}
if (
selectedItem === 1 &&
unit === "time" &&
tariff.privileges[0].privilegeId === "squizHideBadge"
) {
return true;
}
return false;
});
const createTariffElements = (filteredTariffs: Tariff[], addFreeTariff = false) => {
const tariffElements = filteredTariffs
.filter((tariff) => tariff.privileges.length > 0)
.map((tariff, index) => {
const { priceBeforeDiscounts, priceAfterDiscounts } = calcTariffPrice(
tariff,
discounts ?? [],
purchasesAmount,
currentTariffs ?? [],
isUserNko,
userId,
);
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>
{unit === "time" && (
<>
{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,
});