frontPanel/src/pages/Tariffs/Tariffs.tsx

342 lines
11 KiB
TypeScript
Raw Normal View History

import { activatePromocode } from "@api/promocode";
import { useToken } from "@frontend/kitui";
import {
Box,
Typography,
useMediaQuery,
useTheme,
} from "@mui/material";
import { useUserStore } from "@root/user";
import { useDomainDefine } from "@utils/hooks/useDomainDefine";
import { enqueueSnackbar } from "notistack";
import { useEffect, useState } from "react";
import { withErrorBoundary } from "react-error-boundary";
2025-07-11 16:21:36 +00:00
import { useNavigate } from "react-router-dom";
2024-03-22 19:01:48 +00:00
import CollapsiblePromocodeField from "./CollapsiblePromocodeField";
import { Tabs } from "./Tabs";
import { createTariffElements } from "./tariffsUtils/createTariffElements";
import { currencyFormatter } from "./tariffsUtils/currencyFormatter";
2024-04-06 09:07:30 +00:00
import { useWallet, setCash } from "@root/cash";
2024-05-15 11:44:10 +00:00
import { cartApi } from "@api/cart";
2024-05-02 08:38:57 +00:00
2025-07-11 16:21:36 +00:00
import { TariffCardDisplaySelector } from "./TariffCardDisplaySelector";
import { ModalRequestCreate } from "./ModalRequestCreate";
import { cancelCC, useCC } from "@/stores/cc";
import { NavSelect } from "./NavSelect";
import { useTariffs } from '@utils/hooks/useTariffs';
import { useDiscounts } from '@utils/hooks/useDiscounts';
2025-07-11 16:21:36 +00:00
import { PaymentConfirmationModal } from "./components/PaymentConfirmationModal";
import { TariffsHeader } from "./components/TariffsHeader";
import { inCart, outCart } from "./utils";
const StepperText: Record<string, string> = {
day: "Тарифы на время",
count: "Тарифы на объём",
dop: "Доп. услуги",
};
2024-01-09 12:00:42 +00:00
function TariffPage() {
const userPrivilegies = useUserStore(store => store.userAccount?.privileges);
const theme = useTheme();
const token = useToken();
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
const isMobile = useMediaQuery(theme.breakpoints.down(600));
2024-01-28 20:08:06 +00:00
const userId = useUserStore((state) => state.userId);
const navigate = useNavigate();
const user = useUserStore((state) => state.customerAccount);
2025-07-11 16:21:36 +00:00
const userWithWallet = useUserStore((state) => state.customerAccount); //c wallet
console.log("________________userWithWallet_____________USERRRRRRR")
console.log(userWithWallet)
const { data: discounts } = useDiscounts(userId);
const [isRequestCreate, setIsRequestCreate] = useState(false);
const [openModal, setOpenModal] = useState({});
const { cashString, cashCop, cashRub } = useWallet();
const [selectedItem, setSelectedItem] = useState<TypePages>("day");
const { isTestServer } = useDomainDefine();
2024-03-22 19:01:48 +00:00
const [promocodeField, setPromocodeField] = useState<string>("");
const cc = useCC(store => store.cc)
2024-01-09 12:00:42 +00:00
const { data: tariffs, error: tariffsError, isLoading: tariffsLoading } = useTariffs();
2024-01-09 12:00:42 +00:00
console.log("________34563875693785692576_____ TARIFFS")
console.log(tariffs)
2024-01-09 12:00:42 +00:00
useEffect(() => {
2025-07-11 16:21:36 +00:00
if (userWithWallet) {
let cs = currencyFormatter.format(Number(user.wallet.cash) / 100);
let cc = Number(user.wallet.cash);
let cr = Number(user.wallet.cash) / 100;
setCash(cs, cc, cr);
}
2025-07-11 16:21:36 +00:00
}, [userWithWallet]);
useEffect(() => {
if (cc) {
setIsRequestCreate(true)
cancelCC()
}
}, [])
if (!user || !tariffs || !discounts) return <LoadingPage />;
const openModalHC = (tariffInfo: any) => setOpenModal(tariffInfo);
const tryBuy = async ({ id, price }: { id: string; price: number }) => {
openModalHC({});
//Если в корзине что-то было - выкладываем содержимое и запоминаем чо там лежало
if (user.cart.length > 0) {
outCart(user.cart);
}
//Добавляем желаемый тариф в корзину
2024-05-15 11:44:10 +00:00
const [_, addError] = await cartApi.add(id);
if (addError) {
//Развращаем товары в корзину
inCart();
return;
}
//Если нам хватает денежек - покупаем тариф
2024-05-15 11:44:10 +00:00
const [data, payError] = await cartApi.pay();
2024-05-15 11:44:10 +00:00
if (payError || !data) {
//если денег не хватило
if (payError?.includes("insufficient funds") || payError?.includes("Payment Required")) {
2024-05-15 13:51:41 +00:00
let cashDif = Number(payError.split(":")[1]);
var link = document.createElement("a");
link.href = `https://${isTestServer ? "s" : ""}hub.pena.digital/quizpayment?action=squizpay&dif=${cashDif}&data=${token}&userid=${userId}`;
2024-08-19 00:41:16 +00:00
if (cc) link.href = link.href + "&cc=true"//после покупки тарифа и возвращения будем знать что надо открыть модалку
document.body.appendChild(link);
link.click();
2024-04-17 14:16:49 +00:00
return;
}
2024-05-15 13:51:41 +00:00
//другая ошибка
enqueueSnackbar("Произошла ошибка. Попробуйте позже");
2024-05-15 11:44:10 +00:00
return;
}
2024-05-15 11:44:10 +00:00
setCash(
currencyFormatter.format(Number(data.wallet.cash) / 100),
Number(data.wallet.cash),
Number(data.wallet.cash) / 100,
);
//cc - пометка что мы хотим заказать квиз. Если хотели, то открываем модалку
if (cc) setIsRequestCreate(true)
cancelCC()//но в любом случае в конце перехотим
2024-05-15 11:44:10 +00:00
enqueueSnackbar("Тариф успешно приобретён");
//Развращаем товары в корзину
inCart();
};
2025-01-10 11:01:50 +00:00
const filteredTariffs = tariffs.filter((tariff, i) => {
return (
tariff.privileges[0].serviceKey === "squiz" &&
!tariff.isDeleted &&
!tariff.isCustom &&
tariff.privileges[0]?.type === selectedItem
);
});
const filteredBaseTariffs = filteredTariffs.filter((tariff) => {
return tariff.privileges[0].privilegeId !== "squizHideBadge";
});
2024-05-15 11:44:10 +00:00
async function handleApplyPromocode() {
2024-03-22 19:01:48 +00:00
if (!promocodeField) return;
2024-05-15 11:44:10 +00:00
const [greetings, error] = await activatePromocode(promocodeField);
2024-05-15 11:44:10 +00:00
if (error) {
enqueueSnackbar(error);
return;
}
2024-05-02 08:43:10 +00:00
2024-05-15 11:44:10 +00:00
enqueueSnackbar(greetings);
2024-03-22 19:01:48 +00:00
}
const startRequestCreate = () => {
setIsRequestCreate(true)
}
2025-07-11 16:21:36 +00:00
if (!userWithWallet) return null;
return (
<>
2025-07-11 16:21:36 +00:00
<TariffsHeader cashString={cashString} />
2024-03-22 19:01:48 +00:00
<Box
sx={{
p: "25px",
pb: 0,
}}
>
<CollapsiblePromocodeField
fieldValue={promocodeField}
onFieldChange={setPromocodeField}
onPromocodeApply={handleApplyPromocode}
/>
</Box>
{isMobile ?
<NavSelect
selectedItem={selectedItem}
setSelectedItem={setSelectedItem}
/>
:
<Tabs
names={Object.values(StepperText)}
items={Object.keys(StepperText)}
selectedItem={selectedItem}
setSelectedItem={setSelectedItem}
toDop={() => setSelectedItem("dop")}
/>
}
2024-01-16 12:28:30 +00:00
<Box
sx={{
justifyContent: "left",
display: selectedItem === "dop" ? "flex" : "grid",
gap: "40px",
p: "20px",
gridTemplateColumns: `repeat(auto-fit, minmax(300px, ${isTablet ? "436px" : "360px"
}))`,
flexDirection: selectedItem === "dop" ? "column" : undefined,
}}
>
{selectedItem === "day" &&
createTariffElements(
filteredBaseTariffs,
true,
user,
discounts,
openModalHC,
)}
{selectedItem === "count" &&
createTariffElements(
filteredTariffs,
true,
user,
discounts,
openModalHC,
)}
2025-07-11 16:21:36 +00:00
{(selectedItem === "hide" || selectedItem === "create" || selectedItem === "premium" || selectedItem === "analytics" || selectedItem === "custom")
&& (
2025-07-11 16:21:36 +00:00
<TariffCardDisplaySelector
selectedItem={selectedItem}
content={[
{
title: `Убрать логотип "PenaQuiz"`,
onClick: () => setSelectedItem("hide")
},
{
title: "Создать квиз на заказ",
onClick: () => setSelectedItem("create")
},
2025-07-11 16:21:36 +00:00
{
title: "Премиум функции",
onClick: () => setSelectedItem("premium")
},
{
title: "Расширенная аналитика",
onClick: () => setSelectedItem("analytics")
},
{
title: "Кастомные тарифы",
onClick: () => setSelectedItem("custom")
},
]}
tariffs={tariffs}
user={user}
discounts={discounts}
openModalHC={openModalHC}
userPrivilegies={userPrivilegies}
startRequestCreate={startRequestCreate}
/>
)}
2025-07-11 16:21:36 +00:00
{selectedItem === "dop" && (
<TariffCardDisplaySelector
selectedItem={selectedItem}
content={
selectedItem === "dop"
? [
{
title: `Убрать логотип "PenaQuiz"`,
onClick: () => setSelectedItem("hide")
},
{
title: "Создать квиз на заказ",
onClick: () => setSelectedItem("create")
},
]
: [
{
title: `Убрать логотип "PenaQuiz"`,
onClick: () => setSelectedItem("hide")
},
{
title: "Создать квиз на заказ",
onClick: () => setSelectedItem("create")
},
{
title: "Премиум функции",
onClick: () => setSelectedItem("premium")
},
{
title: "Расширенная аналитика",
onClick: () => setSelectedItem("analytics")
},
{
title: "Кастомные тарифы",
onClick: () => setSelectedItem("custom")
},
]
}
tariffs={tariffs}
user={user}
discounts={discounts}
openModalHC={openModalHC}
userPrivilegies={userPrivilegies}
startRequestCreate={startRequestCreate}
/>
)}
</Box>
2025-07-11 16:21:36 +00:00
<PaymentConfirmationModal
open={Object.values(openModal).length > 0}
onClose={() => setOpenModal({})}
2025-07-11 16:21:36 +00:00
onConfirm={() => tryBuy(openModal)}
price={openModal.price}
/>
<ModalRequestCreate open={isRequestCreate} onClose={() => setIsRequestCreate(false)} />
</>
);
}
export const Tariffs = withErrorBoundary(TariffPage, {
fallback: (
<Typography mt="8px" textAlign="center">
Ошибка загрузки тарифов
</Typography>
),
onError: () => { },
});
const LoadingPage = () => (
<Box
sx={{
height: "100vh",
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
>
<Typography sx={{ textAlign: "center" }}>
{"Подождите, пожалуйста, идёт загрузка"}
</Typography>
</Box>
);