front-hub/src/pages/Tariffs/TariffsPage.tsx

274 lines
8.6 KiB
TypeScript
Raw Normal View History

2023-11-10 14:51:50 +00:00
import SectionWrapper from "@components/SectionWrapper";
2024-05-28 13:38:01 +00:00
import {
Tariff,
calcTariffPrice,
getMessageFromFetchError,
} from "@frontend/kitui";
2023-11-10 14:51:50 +00:00
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
2024-05-28 13:38:01 +00:00
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";
2023-11-10 14:51:50 +00:00
import { usePrevLocation } from "@root/utils/hooks/handleCustomBackNavigation";
import { useCartTariffs } from "@root/utils/hooks/useCartTariffs";
import { enqueueSnackbar } from "notistack";
import { useState } from "react";
2023-11-10 14:51:50 +00:00
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";
2024-03-27 13:11:53 +00:00
import { Select } from "@components/Select";
import { Tabs } from "@components/Tabs";
2024-08-18 21:44:33 +00:00
import { ModalRequestCreate } from "./ModalRequestCreate";
2023-11-10 14:51:50 +00:00
const subPagesTime = ["Базовый тариф PenaQuiz", 'Убрать логотип "PenaQuiz"'];
const subPagesVolume = ["Заявки quiz", 'Заказать создание quiz'];
2023-03-23 12:03:08 +00:00
2023-08-11 16:09:32 +00:00
const StepperText: Record<string, string> = {
2024-05-28 13:38:01 +00:00
volume: "Тарифы на объём",
time: "Тарифы на время",
2023-11-10 14:51:50 +00:00
};
2023-08-11 16:09:32 +00:00
function TariffPage() {
2024-05-28 13:38:01 +00:00
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 [selectedItemTime, setSelectedItemTime] = useState<number>(0);
const [selectedItemVolume, setSelectedItemVolume] = useState<number>(0);
2024-08-18 21:44:33 +00:00
const [isRequestCreate, setIsRequestCreate] = useState(false);
2024-05-28 13:38:01 +00:00
const purchasesAmount =
useUserStore((state) => state.userAccount?.wallet.spent) ?? 0;
const userId = useUserStore((state) => state.user?._id) ?? "";
2024-08-18 21:44:33 +00:00
const userPrivilegies = useUserStore(store => store);
2024-05-28 13:38:01 +00:00
const discounts = useDiscounts(userId);
const isUserNko =
useUserStore((state) => state.userAccount?.status) === "nko";
const currentTariffs = useCartTariffs();
2023-12-15 21:53:29 +00:00
2024-05-28 13:38:01 +00:00
const handleCustomBackNavigation = usePrevLocation(location);
2023-12-15 21:53:29 +00:00
2024-05-28 13:38:01 +00:00
const unit: string = String(location.pathname).slice(9);
2023-12-15 21:53:29 +00:00
2024-05-28 13:38:01 +00:00
function handleTariffItemClick(tariffId: string) {
addTariffToCart(tariffId)
.then(() => {
enqueueSnackbar("Тариф добавлен в корзину");
})
.catch((error) => {
const message = getMessageFromFetchError(error);
if (message) enqueueSnackbar(message);
});
}
2023-11-10 14:51:50 +00:00
2024-05-28 13:38:01 +00:00
const filteredTariffs = tariffs.filter((tariff) => {
if (tariff.privileges[0] === undefined || tariff.isDeleted || tariff.isCustom) return false;
if (unit === "time") {
if (selectedItemTime === 0 && tariff.privileges[0].privilegeId === "quizUnlimTime") return true
if (selectedItemTime === 1 && tariff.privileges[0].privilegeId === "squizHideBadge") return true
2024-05-28 13:38:01 +00:00
}
if (unit === "volume") {
if (selectedItemVolume === 0 && tariff.privileges[0].privilegeId === "quizCnt") return true
if (selectedItemVolume === 1 && tariff.privileges[0].privilegeId === "quizManual") return true
2024-05-28 13:38:01 +00:00
}
return false;
});
2023-11-10 14:51:50 +00:00
2024-05-28 13:38:01 +00:00
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
);
2023-11-10 14:51:50 +00:00
2024-05-28 13:38:01 +00:00
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(
Math.trunc(priceBeforeDiscounts) / 100
)}
</Typography>
)}
<Typography variant="price">
{currencyFormatter.format(
Math.trunc(priceAfterDiscounts) / 100
)}
</Typography>
</>
}
/>
);
});
2024-03-22 19:53:00 +00:00
2024-05-28 13:38:01 +00:00
if (addFreeTariff) {
if (tariffElements.length < 6)
tariffElements.push(<FreeTariffCard key="free_tariff_card" />);
else
tariffElements.splice(5, 0, <FreeTariffCard key="free_tariff_card" />);
}
2023-11-10 14:51:50 +00:00
2024-05-28 13:38:01 +00:00
return tariffElements;
};
2023-12-15 21:53:29 +00:00
2024-05-28 13:38:01 +00:00
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}
2024-03-22 19:53:00 +00:00
sx={{
2024-05-28 13:38:01 +00:00
p: 0,
height: "28px",
width: "28px",
color: "black",
marginRight: "10px",
2024-03-22 19:53:00 +00:00
}}
2024-05-28 13:38:01 +00:00
>
<ArrowBackIcon />
</IconButton>
)}
<Typography
sx={{
marginBottom: "23px",
mt: "20px",
fontSize: isMobile ? "24px" : "36px",
fontWeight: "500",
}}
2023-12-15 21:53:29 +00:00
>
2024-05-28 13:38:01 +00:00
{StepperText[unit]}
</Typography>
</Box>
{unit === "time" && (
<>
{isMobile ? (
<Select
items={subPagesTime}
selectedItem={selectedItemTime}
setSelectedItem={setSelectedItemTime}
2024-05-28 13:38:01 +00:00
/>
) : (
<Tabs
items={subPagesTime}
selectedItem={selectedItemTime}
setSelectedItem={setSelectedItemTime}
/>
)}
</>
)}
{unit === "volume" && (
<>
{isMobile ? (
<Select
items={subPagesVolume}
selectedItem={selectedItemVolume}
setSelectedItem={setSelectedItemVolume}
/>
) : (
<Tabs
items={subPagesVolume}
selectedItem={selectedItemVolume}
setSelectedItem={setSelectedItemVolume}
2024-05-28 13:38:01 +00:00
/>
)}
</>
)}
<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)} />*/}
{/* </>*/}
{/*)}*/}
2024-08-18 21:44:33 +00:00
<ModalRequestCreate open={isRequestCreate} onClose={() => setIsRequestCreate(false)}/>
2024-05-28 13:38:01 +00:00
</SectionWrapper>
);
}
export default withErrorBoundary(TariffPage, {
2024-05-28 13:38:01 +00:00
fallback: (
<Typography mt="8px" textAlign="center">
Ошибка загрузки тарифов
</Typography>
),
onError: handleComponentError,
2023-11-10 14:51:50 +00:00
});