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

188 lines
6.0 KiB
TypeScript
Raw Normal View History

2023-11-05 23:33:40 +00:00
import { useState } from "react"
import { useLocation } from "react-router-dom"
import { Box, IconButton, Typography, useMediaQuery, useTheme } from "@mui/material"
import SectionWrapper from "@components/SectionWrapper"
import { useTariffStore } from "@root/stores/tariffs"
import { enqueueSnackbar } from "notistack"
import { Select } from "@root/components/Select"
import { Tabs } from "@root/components/Tabs"
import TariffCard from "./TariffCard"
import NumberIcon from "@root/components/NumberIcon"
import { currencyFormatter } from "@root/utils/currencyFormatter"
import { calcIndividualTariffPrices } from "@root/utils/calcTariffPrices"
import { Tariff, getMessageFromFetchError } from "@frontend/kitui"
import FreeTariffCard from "./FreeTariffCard"
import { addTariffToCart, useUserStore } from "@root/stores/user"
import { useDiscountStore } from "@root/stores/discounts"
import { Slider } from "./slider"
import { useCartStore } from "@root/stores/cart"
import ArrowBackIcon from "@mui/icons-material/ArrowBack"
import { usePrevLocation } from "@root/utils/hooks/handleCustomBackNavigation"
import { withErrorBoundary } from "react-error-boundary"
import { handleComponentError } from "@root/utils/handleComponentError"
2023-06-16 20:09:56 +00:00
2023-11-05 23:33:40 +00:00
const subPages = ["Шаблонизатор", "Опросник", "Сокращатель ссылок"]
2023-03-23 12:03:08 +00:00
2023-08-11 16:09:32 +00:00
const StepperText: Record<string, string> = {
2023-11-05 23:33:40 +00:00
volume: "Тарифы на объём",
time: "Тарифы на время",
}
2023-08-11 16:09:32 +00:00
function TariffPage() {
2023-11-05 23:33:40 +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 [selectedItem, setSelectedItem] = useState<number>(0)
const discounts = useDiscountStore((state) => state.discounts)
const purchasesAmount = useUserStore((state) => state.userAccount?.wallet.purchasesAmount) ?? 0
const cartTariffMap = useCartStore((state) => state.cartTariffMap)
const isUserNko = useUserStore(state => state.userAccount?.status) === "nko"
2023-03-23 12:03:08 +00:00
2023-11-05 23:33:40 +00:00
const handleCustomBackNavigation = usePrevLocation(location)
2023-11-05 23:33:40 +00:00
const unit: string = String(location.pathname).slice(9)
const currentTariffs = Object.values(cartTariffMap).filter((tariff): tariff is Tariff => typeof tariff === "object")
2023-08-21 15:58:48 +00:00
2023-11-05 23:33:40 +00:00
function handleTariffItemClick(tariffId: string) {
addTariffToCart(tariffId)
.then(() => {
enqueueSnackbar("Тариф добавлен в корзину")
})
.catch((error) => {
const message = getMessageFromFetchError(error)
if (message) enqueueSnackbar(message)
})
}
2023-06-26 16:13:29 +00:00
2023-11-05 23:33:40 +00:00
const filteredTariffs = tariffs.filter((tariff) => {
return (
tariff.privileges.map((p) => p.type).includes("day") === (unit === "time") &&
2023-08-19 18:37:11 +00:00
!tariff.isDeleted &&
!tariff.isCustom
2023-11-05 23:33:40 +00:00
)
})
2023-08-11 09:38:05 +00:00
2023-11-05 23:33:40 +00:00
const isCustomTariffs = tariffs.filter((tariff) => {
return (
tariff.privileges.map((p) => p.type).includes("day") === (unit === "time") &&
2023-08-19 18:37:11 +00:00
!tariff.isDeleted &&
tariff.isCustom
2023-11-05 23:33:40 +00:00
)
})
2023-08-19 18:37:11 +00:00
2023-11-05 23:33:40 +00:00
const createTariffElements = (filteredTariffs: Tariff[]) => {
const tariffElements = filteredTariffs
.filter((tariff) => tariff.privileges.length > 0)
.map((tariff, index) => {
const { priceBeforeDiscounts, priceAfterDiscounts } = calcIndividualTariffPrices(
tariff,
discounts,
purchasesAmount,
currentTariffs,
isUserNko,
)
2023-08-19 18:37:11 +00:00
2023-11-05 23:33:40 +00:00
return (
<TariffCard
key={tariff._id}
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.privileges.map((p) => `${p.name} - ${p.amount}`)}
price={
<>
{priceBeforeDiscounts !== priceAfterDiscounts && (
<Typography variant="oldPrice">{currencyFormatter.format(priceBeforeDiscounts / 100)}</Typography>
)}
<Typography variant="price">{currencyFormatter.format(priceAfterDiscounts / 100)}</Typography>
</>
}
/>
)
})
2023-08-16 18:06:40 +00:00
2023-11-05 23:33:40 +00:00
if (tariffElements.length < 6) tariffElements.push(<FreeTariffCard key="free_tariff_card" />)
else tariffElements.splice(5, 0, <FreeTariffCard key="free_tariff_card" />)
2023-08-11 09:38:05 +00:00
2023-11-05 23:33:40 +00:00
return tariffElements
}
2023-06-26 16:13:29 +00:00
2023-11-05 23:33:40 +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}
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)}
</Box>
<Typography
sx={{
mt: "40px",
fontSize: isMobile ? "24px" : "36px",
fontWeight: "500",
}}
>
Ранее вы
2023-11-05 23:33:40 +00:00
</Typography>
<Slider items={createTariffElements(isCustomTariffs)} />
</SectionWrapper>
)
}
export default withErrorBoundary(TariffPage, {
2023-11-05 23:33:40 +00:00
fallback: <Typography mt="8px" textAlign="center">Ошибка загрузки тарифов</Typography>,
onError: handleComponentError,
})