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