новая система покупок
This commit is contained in:
parent
b0b21c74c0
commit
291d059654
@ -8,10 +8,10 @@ on:
|
||||
|
||||
jobs:
|
||||
CreateImage:
|
||||
runs-on: [hubstaging]
|
||||
runs-on: [skeris]
|
||||
uses: http://gitea.pena/PenaDevops/actions.git/.gitea/workflows/build-image.yml@v1.1.6-p
|
||||
with:
|
||||
runner: hubstaging
|
||||
runner: skeris
|
||||
secrets:
|
||||
REGISTRY_USER: ${{ secrets.REGISTRY_USER }}
|
||||
REGISTRY_PASSWORD: ${{ secrets.REGISTRY_PASSWORD }}
|
||||
|
@ -2,3 +2,4 @@
|
||||
. "$(dirname -- "$0")/_/husky.sh"
|
||||
|
||||
yarn eslint . --fix
|
||||
yarn type-check
|
||||
|
@ -1,11 +1,11 @@
|
||||
FROM gitea.pena/penadevops/container-images/node:main as build
|
||||
FROM docker.io/library/node:lts-alpine as build
|
||||
|
||||
RUN apk update && rm -rf /var/cache/apk/*
|
||||
WORKDIR /usr/app
|
||||
COPY . .
|
||||
|
||||
RUN npm install --force && yarn cache clean
|
||||
RUN psstat.sh "npm run build"
|
||||
RUN npm run build
|
||||
|
||||
|
||||
FROM gitea.pena/penadevops/container-images/nginx:main as result
|
||||
|
@ -5,6 +5,10 @@
|
||||
"scripts": {
|
||||
"start": "NODE_OPTIONS=\"--max-old-space-size=1024\" craco start",
|
||||
"build": "craco build",
|
||||
"build:check": "tsc --noEmit && craco build",
|
||||
"type-check": "tsc --noEmit",
|
||||
"type-check:strict": "tsc --noEmit --strict",
|
||||
"pre-commit": "npm run type-check",
|
||||
"test": "craco test --env=node --transformIgnorePatterns \"node_modules/(?!@frontend)/\"",
|
||||
"test:cart": "vitest ./src/utils/calcCart",
|
||||
"eject": "craco eject",
|
||||
|
@ -12,7 +12,7 @@ import type {
|
||||
type RecoverResponse = {
|
||||
message: string;
|
||||
};
|
||||
|
||||
//tsignore
|
||||
const API_URL = `${process.env.REACT_APP_DOMAIN}/auth`;
|
||||
|
||||
export const register = async (
|
||||
|
@ -5,7 +5,7 @@ import { clearUserData } from "@root/stores/user";
|
||||
import { clearCustomTariffs } from "@root/stores/customTariffs";
|
||||
import { clearTickets } from "@root/stores/tickets";
|
||||
import { redirect } from "react-router-dom";
|
||||
import { setNotEnoughMoneyAmount } from "@stores/notEnoughMoneyAmount";
|
||||
import { setNotEnoughMoneyAmount } from "@stores/allTypesOfPurchases";
|
||||
|
||||
interface MakeRequest {
|
||||
method?: Method | undefined;
|
||||
|
@ -78,19 +78,23 @@ export const sendFile = async (
|
||||
export const createTicket = async (
|
||||
ticketNameField: string,
|
||||
ticketBodyField: string,
|
||||
isToken?: boolean
|
||||
isToken: boolean = true
|
||||
): Promise<[CreateTicketResponse | null, string?]> => {
|
||||
try {
|
||||
const createTicketResponse = await createTicketRequest({
|
||||
const createTicketResponse = await makeRequest<
|
||||
{ Title: string; Message: string; System: boolean },
|
||||
CreateTicketResponse
|
||||
>({
|
||||
method: "POST",
|
||||
url: `${API_URL}/create`,
|
||||
body: { Title: ticketNameField, Message: ticketBodyField, System: false },
|
||||
useToken: isToken
|
||||
useToken: isToken,
|
||||
});
|
||||
|
||||
return [createTicketResponse];
|
||||
} catch (nativeError) {
|
||||
const [error] = parseAxiosError(nativeError);
|
||||
|
||||
return [null, `Не удалось отправить файл. ${error}`];
|
||||
return [null, `Не удалось создать тикет. ${error}`];
|
||||
}
|
||||
};
|
||||
|
@ -72,18 +72,6 @@ export const updateDocuments = async (
|
||||
documents: UpdateDocumentsArgs
|
||||
): Promise<[Verification | "OK" | null, string?]> => {
|
||||
try {
|
||||
// .replace(/\s/g, '_')
|
||||
// if (documents.inn) {
|
||||
// documents.inn.append("name", "blob");
|
||||
// }
|
||||
// if (documents.rule) {
|
||||
// documents.rule.append("name", "blob");
|
||||
// }
|
||||
// if (documents.certificate) {
|
||||
// documents.certificate.append("name", "blob");
|
||||
// }
|
||||
console.log("documents")
|
||||
console.log(documents)
|
||||
const updateDocumentsResponse = await makeRequest<FormData, Verification>({
|
||||
method: "PUT",
|
||||
url: `${API_URL}`,
|
||||
@ -105,8 +93,6 @@ export const updateDocuments = async (
|
||||
export const updateDocument = async (
|
||||
body: FormData
|
||||
): Promise<[Verification | "OK" | null, string?]> => {
|
||||
console.log("body")
|
||||
console.log(body)
|
||||
try {
|
||||
const updateDocumentResponse = await makeRequest<FormData, Verification>({
|
||||
method: "PATCH",
|
||||
|
@ -20,31 +20,30 @@ interface PaymentBody {
|
||||
|
||||
export const sendPayment = async ({
|
||||
userId,
|
||||
wayback,
|
||||
body,
|
||||
fromSquiz,
|
||||
paymentPurpose,
|
||||
cc
|
||||
action,
|
||||
fromDomain,
|
||||
backWay,
|
||||
additionalinformation,
|
||||
}: {
|
||||
userId: string;
|
||||
wayback: string;
|
||||
body: PaymentBody;
|
||||
fromSquiz: boolean;
|
||||
paymentPurpose: "paycart" | "replenishwallet";
|
||||
cc?: boolean
|
||||
action?: string;
|
||||
fromDomain?: string;
|
||||
backWay?: string;
|
||||
additionalinformation?: string;
|
||||
}): Promise<[SendPaymentResponse | null, string?]> => {
|
||||
|
||||
console.log(" я sendPayment и вот мой wayback = " + wayback)
|
||||
// Правильно формируем returnUrl
|
||||
const domain = fromDomain || 'localhost:3000';
|
||||
const path = backWay ? `/${backWay}` : '';
|
||||
let returnUrl = `https://${domain}${path}?userid=${userId}&action=${action || 'buy'}`;
|
||||
|
||||
let returnUrl= `https://${isStaging}hub.pena.digital/afterpay?from=${
|
||||
fromSquiz ? "quiz" : "hub"
|
||||
}&purpose=${paymentPurpose}&userid=${userId}`
|
||||
// Добавляем additionalinformation если он есть
|
||||
if (additionalinformation) {
|
||||
returnUrl += `&additionalinformation=${encodeURIComponent(additionalinformation)}`;
|
||||
}
|
||||
|
||||
if (wayback) returnUrl += `&wayback=${wayback}`
|
||||
if (cc) returnUrl = returnLink + "&cc=true"
|
||||
|
||||
console.log("returnUrl")
|
||||
console.log(returnUrl)
|
||||
|
||||
const reqeustBody = {
|
||||
currency: "RUB",
|
||||
|
@ -13,7 +13,7 @@ import { ReactComponent as CrossIcon } from "@root/assets/Icons/cross.svg";
|
||||
|
||||
import type { MouseEvent } from "react";
|
||||
import CustomTariffAccordion from "@root/components/CustomTariffAccordion";
|
||||
import { setNotEnoughMoneyAmount } from "@root/stores/notEnoughMoneyAmount";
|
||||
import { setNotEnoughMoneyAmount } from "@root/stores/allTypesOfPurchases";
|
||||
|
||||
const name: Record<string, string> = {
|
||||
templategen: "Шаблонизатор",
|
||||
|
@ -19,7 +19,7 @@ import { Link, useNavigate } from "react-router-dom";
|
||||
import { withErrorBoundary } from "react-error-boundary";
|
||||
import { handleComponentError } from "@root/utils/handleComponentError";
|
||||
import ErrorOutlineIcon from "@mui/icons-material/ErrorOutline";
|
||||
import { setNotEnoughMoneyAmount, startPayCartProcess, useNotEnoughMoneyAmount } from "@root/stores/notEnoughMoneyAmount";
|
||||
import { setNotEnoughMoneyAmount, startPayCartProcess, allTypesOfPurchases } from "@root/stores/allTypesOfPurchases";
|
||||
import { RSCOpen } from "@root/stores/requestSquizCreate";
|
||||
|
||||
function Drawers() {
|
||||
@ -36,8 +36,8 @@ function Drawers() {
|
||||
const userAccount = useUserStore((state) => state.userAccount);
|
||||
const userId = useUserStore((state) => state.userId) || "";
|
||||
const tickets = useTicketStore((state) => state.tickets);
|
||||
const notEnoughMoneyAmount = useNotEnoughMoneyAmount(state => state.notEnoughMoneyAmount);
|
||||
const siteReadyPayCart = useNotEnoughMoneyAmount(state => state.siteReadyPayCart)
|
||||
const notEnoughMoneyAmount = allTypesOfPurchases(state => state.notEnoughMoneyAmount);
|
||||
const siteReadyPayCart = allTypesOfPurchases(state => state.siteReadyPayCart)
|
||||
|
||||
const notificationsCount = tickets.filter(
|
||||
({ user, top_message }) => user !== top_message.user_id && top_message.shown.me !== 1
|
||||
|
@ -151,8 +151,6 @@ export default function Chat({ open = false, onclickArrow, sx }: Props) {
|
||||
}, []),
|
||||
onFetchStateChange: setUnauthTicketMessageFetchState,
|
||||
});
|
||||
console.log("sessionData")
|
||||
console.log(sessionData)
|
||||
useSSESubscription<TicketMessage>({
|
||||
enabled: sseEnabled && isActiveSSETab && Boolean(sessionData),
|
||||
url:
|
||||
@ -160,10 +158,6 @@ export default function Chat({ open = false, onclickArrow, sx }: Props) {
|
||||
`/heruvym/v1.0.0/ticket?ticket=${sessionData?.ticketId}&s=${sessionData?.sessionId}`,
|
||||
|
||||
onNewData: (ticketMessages) => {
|
||||
console.log("Chat")
|
||||
|
||||
console.log("ticketMessages useSSESubscription ")
|
||||
console.log(ticketMessages)
|
||||
const isTicketClosed = ticketMessages.some(
|
||||
(message) => message.session_id === "close"
|
||||
);
|
||||
@ -176,13 +170,10 @@ export default function Chat({ open = false, onclickArrow, sx }: Props) {
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("under checking some close message -----------------------------------------")
|
||||
|
||||
updateSSEValue(ticketMessages);
|
||||
addOrUpdateUnauthMessages(ticketMessages);
|
||||
},
|
||||
onDisconnect: useCallback(() => {
|
||||
console.log("DISCONNECT")
|
||||
setUnauthIsPreventAutoscroll(false);
|
||||
setSseEnabled(false);
|
||||
}, []),
|
||||
|
@ -28,7 +28,7 @@ import {
|
||||
import { currencyFormatter } from "@root/utils/currencyFormatter";
|
||||
import { clearCustomTariffs } from "@root/stores/customTariffs";
|
||||
import { clearTickets } from "@root/stores/tickets";
|
||||
import {setNotEnoughMoneyAmount} from "@stores/notEnoughMoneyAmount"
|
||||
import {setNotEnoughMoneyAmount} from "@stores/allTypesOfPurchases"
|
||||
|
||||
interface Props {
|
||||
isLoggedIn: boolean;
|
||||
|
@ -17,7 +17,7 @@ import { logout } from "@root/api/auth";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
import { clearCustomTariffs } from "@root/stores/customTariffs";
|
||||
import { clearTickets } from "@root/stores/tickets";
|
||||
import {setNotEnoughMoneyAmount} from "@stores/notEnoughMoneyAmount"
|
||||
import {setNotEnoughMoneyAmount} from "@stores/allTypesOfPurchases"
|
||||
|
||||
type MenuItem = {
|
||||
name: string;
|
||||
|
@ -17,7 +17,7 @@ import { currencyFormatter } from "@root/utils/currencyFormatter";
|
||||
import { clearTickets } from "@root/stores/tickets";
|
||||
|
||||
import type { ReactNode } from "react";
|
||||
import {setNotEnoughMoneyAmount} from "@stores/notEnoughMoneyAmount"
|
||||
import {setNotEnoughMoneyAmount} from "@stores/allTypesOfPurchases"
|
||||
|
||||
interface Props {
|
||||
children: ReactNode;
|
||||
|
@ -18,7 +18,7 @@ import { clearTickets } from "@root/stores/tickets";
|
||||
import { currencyFormatter } from "@root/utils/currencyFormatter";
|
||||
|
||||
import walletIcon from "@root/assets/Icons/wallet_icon.svg";
|
||||
import {setNotEnoughMoneyAmount} from "@stores/notEnoughMoneyAmount"
|
||||
import {setNotEnoughMoneyAmount} from "@stores/allTypesOfPurchases"
|
||||
|
||||
export const NavbarPanel = () => {
|
||||
const navigate = useNavigate();
|
||||
|
@ -40,7 +40,6 @@ export default function ProtectedLayout() {
|
||||
process.env.REACT_APP_DOMAIN +
|
||||
`/heruvym/v1.0.0/subscribe?Authorization=${token}`,
|
||||
onNewData: (data) => {
|
||||
console.log("ProtectedLayout")
|
||||
updateSSEValue(data);
|
||||
updateTickets(data.filter((d) => Boolean(d.id)));
|
||||
setTicketCount(data.length);
|
||||
|
@ -8,7 +8,7 @@ import { Loader } from "./Loader";
|
||||
import { currencyFormatter } from "@root/utils/currencyFormatter";
|
||||
import { payCart } from "@root/api/cart";
|
||||
import { setUserAccount, useUserStore } from "@root/stores/user";
|
||||
import { setNotEnoughMoneyAmount, startPayCartProcess, useNotEnoughMoneyAmount } from "@root/stores/notEnoughMoneyAmount";
|
||||
import { setNotEnoughMoneyAmount, startPayCartProcess, allTypesOfPurchases } from "@root/stores/allTypesOfPurchases";
|
||||
import { RSCOpen } from "@root/stores/requestSquizCreate";
|
||||
import { useCart } from "@root/utils/hooks/useCart";
|
||||
|
||||
@ -21,7 +21,7 @@ interface Props {
|
||||
export default function TotalPrice({ priceAfterDiscounts, priceBeforeDiscounts, isConstructor = false }: Props) {
|
||||
const theme = useTheme();
|
||||
const upMd = useMediaQuery(theme.breakpoints.up("md"));
|
||||
const notEnoughMoneyAmount = useNotEnoughMoneyAmount(state => state.notEnoughMoneyAmount);
|
||||
const notEnoughMoneyAmount = allTypesOfPurchases(state => state.notEnoughMoneyAmount);
|
||||
const userId = useUserStore(store => store.userId) || ""
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const navigate = useNavigate();
|
||||
|
@ -1,4 +1,3 @@
|
||||
import React, { useEffect } from "react";
|
||||
import ReactDOM from "react-dom/client";
|
||||
import {
|
||||
BrowserRouter,
|
||||
@ -13,7 +12,6 @@ import { AdapterMoment } from "@mui/x-date-pickers/AdapterMoment";
|
||||
import Faq from "./pages/Faq/Faq";
|
||||
import Wallet from "./pages/Wallet";
|
||||
import Payment from "./pages/Payment/Payment";
|
||||
import QuizPayment from "./pages/QuizPayment/QuizPayment";
|
||||
import Support from "./pages/Support/Support";
|
||||
import ChatImageNewWindow from "./pages/Support/ChatImageNewWindow";
|
||||
import AccountSettings from "./pages/AccountSettings/AccountSettings";
|
||||
@ -57,15 +55,13 @@ import PrivacyPolicy from "@root/docs/content/PrivacyPolicy";
|
||||
import RecoverPassword from "@root/pages/auth/RecoverPassword";
|
||||
import OutdatedLink from "@root/pages/auth/OutdatedLink";
|
||||
import { verify } from "./pages/AccountSettings/helper";
|
||||
import AfterPay from "./pages/AfterPay";
|
||||
import { PageNotFound } from "./pages/PageNotFound";
|
||||
import { useNotEnoughMoneyAmount } from "@stores/notEnoughMoneyAmount"
|
||||
import { usePipeSubscriber } from "./utils/hooks/usePipeSubscriber";
|
||||
import { useAfterPay } from "./utils/hooks/useAutoPay";
|
||||
import { LocalizationProvider } from "@mui/x-date-pickers";
|
||||
import { ModalRequestCreate } from "./pages/Tariffs/ModalRequestCreate";
|
||||
import * as crutch from "./useUserAccountFetcher";
|
||||
import { useCart } from "./utils/hooks/useCart";
|
||||
import { useTryBuy } from "./utils/hooks/useTryBuy";
|
||||
import AnyServicePayment from "./pages/AnyServicePayment/AnyServicePayment";
|
||||
|
||||
pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.js`;
|
||||
|
||||
@ -75,6 +71,7 @@ const App = () => {
|
||||
const location = useLocation();
|
||||
const userId = useUserStore(state => state.userId);
|
||||
const navigate = useNavigate();
|
||||
|
||||
useUserFetcher({
|
||||
url: process.env.REACT_APP_DOMAIN + `/user/${userId}`,
|
||||
userId,
|
||||
@ -119,17 +116,11 @@ const App = () => {
|
||||
},
|
||||
});
|
||||
|
||||
usePipeSubscriber()
|
||||
usePipeSubscriber();
|
||||
useTryBuy();
|
||||
|
||||
verify(userId);
|
||||
|
||||
useAfterPay()
|
||||
|
||||
console.log("location")
|
||||
console.log(location)
|
||||
console.log("window.location")
|
||||
console.log(window.location)
|
||||
|
||||
if (location.state?.redirectTo)
|
||||
return (
|
||||
<Navigate
|
||||
@ -197,6 +188,7 @@ console.log(window.location)
|
||||
/>
|
||||
|
||||
<Route path={"/image/:srcImage"} element={<ChatImageNewWindow />} />
|
||||
|
||||
<Route element={<PrivateRoute />}>
|
||||
<Route element={<ProtectedLayout />}>
|
||||
<Route path="/tariffs" element={<Tariffs />} />
|
||||
@ -217,8 +209,8 @@ console.log(window.location)
|
||||
/>
|
||||
</Route>
|
||||
</Route>
|
||||
<Route path="/anyservicepayment" element={<AnyServicePayment />} />
|
||||
<Route path="/ppdd" element={<PPofData />} />
|
||||
<Route path="/quizpayment" element={<QuizPayment />} />
|
||||
<Route element={<Docs />}>
|
||||
<Route path={"/docs/oferta"} element={<Oferta />} />
|
||||
<Route
|
||||
@ -227,7 +219,6 @@ console.log(window.location)
|
||||
/>
|
||||
<Route path={"/docs/privacy"} element={<PrivacyPolicy />} />
|
||||
</Route>
|
||||
<Route path="/afterpay" element={<AfterPay />} />
|
||||
<Route path="*" element={<PageNotFound />} />
|
||||
</Routes>
|
||||
</>
|
||||
|
2
src/model/autoPay.ts
Normal file
2
src/model/autoPay.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export type FromDomain = "quiz" | "squiz" | "hub" | "shub" | "localhost:3000";
|
||||
export type Action = "topupwallet" | "createquizcc" | "buy";
|
@ -67,7 +67,7 @@ export default function DocumentItem({
|
||||
.then(e => {
|
||||
setReadyShowDocument(true)
|
||||
})
|
||||
.catch(e => console.log(e))
|
||||
.catch(e => console.error(e))
|
||||
}
|
||||
}
|
||||
}, [])
|
||||
|
@ -47,7 +47,7 @@ export default function DocumentUploadItem({
|
||||
.then(e => {
|
||||
setReadyShowDocument(true)
|
||||
})
|
||||
.catch(e => console.log(e))
|
||||
.catch(e => console.error(e))
|
||||
}
|
||||
} else {
|
||||
setReadyShowDocument(true)
|
||||
|
@ -1,28 +0,0 @@
|
||||
import { useNavigate, useSearchParams } from "react-router-dom";
|
||||
|
||||
|
||||
//Раньше эта страничка благодарила за покупку и перенаправляла сталкера своей дорогой.
|
||||
//Чтобы не мелькать хабом перед перенаправлением на другие домены - логика останется на этом отдельном url адресе
|
||||
|
||||
//Эта страничка ТОЛЬКО перенаправляет на нужный адрес. Процесс автопокупки после пополнения лежит на хуке useAutoPay
|
||||
export default () => {
|
||||
const navigate = useNavigate();
|
||||
const [searchParams] = useSearchParams();
|
||||
|
||||
const userId = searchParams.get("userid");
|
||||
const from = searchParams.get("from") || "hub";
|
||||
const purpose = searchParams.get("purpose")
|
||||
const isCC = searchParams.get("cc")
|
||||
|
||||
const host = window.location.hostname;
|
||||
const domain = (host.includes("s") ? "s" : "") + from;
|
||||
const pathname = from.includes("hub") ? "/tariffs" : "/list";
|
||||
|
||||
let link = `https://${domain}.pena.digital${pathname}?purpose=${purpose}&userid=${userId}`
|
||||
|
||||
console.log("isCC")
|
||||
if (isCC) link = link + "&cc=true"
|
||||
|
||||
document.location.href = link
|
||||
return <></>;
|
||||
};
|
105
src/pages/AnyServicePayment/AnyServicePayment.tsx
Normal file
105
src/pages/AnyServicePayment/AnyServicePayment.tsx
Normal file
@ -0,0 +1,105 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { ApologyPage } from "../ApologyPage";
|
||||
import { useNavigate, useSearchParams } from "react-router-dom";
|
||||
import {
|
||||
clearAuthToken,
|
||||
getMessageFromFetchError,
|
||||
setAuthToken,
|
||||
useUserAccountFetcher,
|
||||
useUserFetcher,
|
||||
getAuthToken,
|
||||
} from "@frontend/kitui";
|
||||
import {
|
||||
clearUserData,
|
||||
setUserId,
|
||||
useUserStore,
|
||||
} from "@root/stores/user";
|
||||
import { logout } from "@root/api/auth";
|
||||
import { clearCustomTariffs } from "@root/stores/customTariffs";
|
||||
import { clearTickets } from "@root/stores/tickets";
|
||||
import { cancelPayCartProcess, setAction, setBackWay, setFromDomain, setNotEnoughMoneyAmount, startPayCartProcess } from "@stores/allTypesOfPurchases"
|
||||
import { Action, FromDomain } from "@root/model/autoPay";
|
||||
//http://localhost:3001/payment?fromdomain=localhost:3000&action=buy&dif=96900&userid=68773ec66816e2c659b36dad&sec=
|
||||
let first = true;
|
||||
|
||||
export default function AnyServicePayment() {
|
||||
const navigate = useNavigate();
|
||||
const [searchParams] = useSearchParams();
|
||||
const [message, setMessage] = useState("Идёт загрузка");
|
||||
const user = useUserStore((state) => state.user);
|
||||
|
||||
let URLfromDomain = searchParams.get("fromdomain");//домен откуда произошёл запрос на финансовые работы
|
||||
let URLaction = searchParams.get("action");//что мы, собсна, хотим: оплатить, пополнить, купить и создать квиз
|
||||
let URLuserId = searchParams.get("userid");//тот кто начал всё это действо
|
||||
const URLwayBack = searchParams.get("wayback") ?? "";//путь по которому нужно будет пройти после того как закончим манипуляции (без домена)
|
||||
let URLmoneyDifferent = Number(searchParams.get("dif"));//сколько нужно деняк
|
||||
let URLtoken = searchParams.get("sec");
|
||||
const URLadditionalinformation = searchParams.get("additionalinformation") ?? "";//дополнительная информация
|
||||
|
||||
useEffect(
|
||||
function redirectIfSignedIn() {
|
||||
console.log("---------------------------")
|
||||
console.log(URLfromDomain)
|
||||
console.log(URLaction)
|
||||
console.log(URLuserId)
|
||||
console.log(URLwayBack)
|
||||
console.log(URLmoneyDifferent)
|
||||
console.log(URLtoken)
|
||||
console.log(URLadditionalinformation)
|
||||
console.log("---------------------------")
|
||||
if (!first && user?._id === URLuserId) {
|
||||
let returnUrl = `/payment?fromdomain=${URLfromDomain}&action=${URLaction}&dif=${URLmoneyDifferent}&userid=${URLuserId}`
|
||||
if (URLwayBack) returnUrl += `&wayback=${URLwayBack}`
|
||||
if (URLadditionalinformation) returnUrl += `&additionalinformation=${URLadditionalinformation}`
|
||||
console.log("AnyServicePayment - формируем URL для payment:", returnUrl);
|
||||
navigate(returnUrl, {
|
||||
replace: true,
|
||||
});
|
||||
}
|
||||
},
|
||||
[navigate, user]
|
||||
);
|
||||
|
||||
if (first) {
|
||||
navigate(`/anyservicepayment`, {
|
||||
replace: true,
|
||||
});
|
||||
try {
|
||||
first = false;
|
||||
|
||||
if (user?._id === URLuserId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (URLaction && URLmoneyDifferent && URLtoken) {
|
||||
(async () => {
|
||||
if (getAuthToken()) {
|
||||
clearAuthToken();
|
||||
clearUserData();
|
||||
clearCustomTariffs();
|
||||
clearTickets();
|
||||
setNotEnoughMoneyAmount(0)
|
||||
await logout();
|
||||
}
|
||||
|
||||
setAuthToken(URLtoken);
|
||||
setUserId(URLuserId);
|
||||
return;
|
||||
})();
|
||||
} else {
|
||||
var link = document.createElement("a");
|
||||
link.href = `https://${URLfromDomain}/${URLwayBack}`;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
}
|
||||
} catch (e) {
|
||||
setMessage("Произошла ошибка");
|
||||
var link = document.createElement("a");
|
||||
link.href = `https://${URLfromDomain}/${URLwayBack}`;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
}
|
||||
}
|
||||
|
||||
return <ApologyPage message={message} />;
|
||||
}
|
@ -11,11 +11,8 @@ import {
|
||||
} from "@mui/material";
|
||||
import { activatePromocode } from "@root/api/promocode";
|
||||
import { sendPayment, sendRSPayment } from "@root/api/wallet";
|
||||
import b2bLogo from "@root/assets/bank-logo/b2b.png";
|
||||
import tinkoffLogo from "@root/assets/bank-logo/logo-tinkoff.png";
|
||||
import rsPayLogo from "@root/assets/bank-logo/rs-pay.png";
|
||||
import sberpayLogo from "@root/assets/bank-logo/sberpay.png";
|
||||
import spbLogo from "@root/assets/bank-logo/spb.png";
|
||||
import umoneyLogo from "@root/assets/bank-logo/umaney.png";
|
||||
import bankCardLogo from "@root/assets/bank-logo/bankcard.png";
|
||||
import InputTextfield from "@root/components/InputTextfield";
|
||||
@ -25,14 +22,15 @@ import { currencyFormatter } from "@root/utils/currencyFormatter";
|
||||
import { useHistoryTracker } from "@root/utils/hooks/useHistoryTracker";
|
||||
import { cardShadow } from "@root/utils/theme";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
import { useEffect, useLayoutEffect, useState } from "react";
|
||||
import { useLocation, useNavigate } from "react-router-dom";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import CollapsiblePromocodeField from "./CollapsiblePromocodeField";
|
||||
import PaymentMethodCard from "./PaymentMethodCard";
|
||||
import { SorryModal } from "./SorryModal";
|
||||
import { WarnModal } from "./WarnModal";
|
||||
import { mutate } from "swr";
|
||||
import { calcTimeOfReadyPayCart, cancelPayCartProcess, setNotEnoughMoneyAmount, startPayCartProcess, useNotEnoughMoneyAmount } from "@root/stores/notEnoughMoneyAmount";
|
||||
import { allTypesOfPurchases, cancelPayCartProcess } from "@root/stores/allTypesOfPurchases";
|
||||
import { useAutoPay } from "./useAutoPay";
|
||||
|
||||
type PaymentMethod = {
|
||||
label: string;
|
||||
@ -54,86 +52,69 @@ type PaymentMethodType = (typeof paymentMethods)[number]["name"];
|
||||
|
||||
export default function Payment() {
|
||||
const theme = useTheme();
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const handleCustomBackNavigation = useHistoryTracker();
|
||||
|
||||
const userId = useUserStore((state) => state.userId) || "";
|
||||
const verificationStatus = useUserStore((state) => state.verificationStatus);
|
||||
|
||||
const upMd = useMediaQuery(theme.breakpoints.up("md"));
|
||||
const upSm = useMediaQuery(theme.breakpoints.up("sm"));
|
||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||
|
||||
const [promocodeField, setPromocodeField] = useState<string>("");
|
||||
const [selectedPaymentMethod, setSelectedPaymentMethod] = useState<PaymentMethodType | null>("");
|
||||
const [paymentValueField, setPaymentValueField] = useState<string>("0");
|
||||
const [paymentLink, setPaymentLink] = useState<string>("");
|
||||
const [fromSquiz, setIsFromSquiz] = useState<boolean>(false);
|
||||
const location = useLocation();
|
||||
const verificationStatus = useUserStore((state) => state.verificationStatus);
|
||||
const userId = useUserStore((state) => state.userId);
|
||||
const navigate = useNavigate();
|
||||
const handleCustomBackNavigation = useHistoryTracker();
|
||||
const [cc, setCC] = useState<boolean>(false);
|
||||
|
||||
const userId = useUserStore((state) => state.userId) || "";
|
||||
const notEnoughMoneyAmount = allTypesOfPurchases(state => state.notEnoughMoneyAmount);
|
||||
const siteReadyPayCart = allTypesOfPurchases(state => state.siteReadyPayCart)
|
||||
const verificationStatus = useUserStore((state) => state.verificationStatus);
|
||||
const action = allTypesOfPurchases(state => state.action);
|
||||
const fromDomain = allTypesOfPurchases(state => state.fromDomain);
|
||||
const backWay = allTypesOfPurchases(state => state.backWay);
|
||||
const additionalinformation = allTypesOfPurchases(state => state.additionalinformation);
|
||||
|
||||
console.log("Payment - значения из Zustand store:");
|
||||
console.log("action:", action);
|
||||
console.log("fromDomain:", fromDomain);
|
||||
console.log("backWay:", backWay);
|
||||
console.log("additionalinformation:", additionalinformation);
|
||||
console.log("notEnoughMoneyAmount:", notEnoughMoneyAmount);
|
||||
|
||||
const [promocodeField, setPromocodeField] = useState<string>("");
|
||||
const [selectedPaymentMethod, setSelectedPaymentMethod] = useState<PaymentMethodType | null>("");
|
||||
|
||||
const [paymentValueField, setPaymentValueField] = useAutoPay();
|
||||
|
||||
const [warnModalOpen, setWarnModalOpen] = useState<boolean>(false);
|
||||
const [sorryModalOpen, setSorryModalOpen] = useState<boolean>(false);
|
||||
|
||||
const notEnoughMoneyAmount = useNotEnoughMoneyAmount(state => state.notEnoughMoneyAmount)
|
||||
const siteReadyPayCart = useNotEnoughMoneyAmount(state => state.siteReadyPayCart)
|
||||
const [fromSquiz, setIsFromSquiz] = useState<boolean>(false);
|
||||
const [waybackToSomeSite, setWaybackToSomeSite] = useState<string>("");
|
||||
|
||||
|
||||
const { diffMoney, setNewDiff } = useDiffMoney()
|
||||
|
||||
const notEnoughMoneyAmount =
|
||||
(location.state?.notEnoughMoneyAmount as number) ?? 0;
|
||||
|
||||
const paymentValue = parseFloat(
|
||||
bigDecimal.multiply(parseFloat(paymentValueField), 100)
|
||||
// paymentValue в копейках для API
|
||||
const paymentValue = Number(
|
||||
bigDecimal.multiply(parseFloat(paymentValueField || "0"), 100)
|
||||
);
|
||||
|
||||
//Отмена состояния сайта "в процессе покупки корзины, просто нехватило деняк"
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
//При выходе со страницы оплаты мы точно не в состоянии покупки корзины
|
||||
cancelPayCartProcess()
|
||||
cancelPayCartProcess();
|
||||
}
|
||||
}, [])
|
||||
|
||||
//Тут записываем начальную сумму в инпут (если стоит флаг что мы в процессе покупки)
|
||||
useEffect(() => {
|
||||
if (siteReadyPayCart !== null && siteReadyPayCart[userId] !== undefined && calcTimeOfReadyPayCart(siteReadyPayCart[userId]))
|
||||
setPaymentValueField((notEnoughMoneyAmount / 100).toString());//Сколько нехватило на хабе
|
||||
}, [notEnoughMoneyAmount, siteReadyPayCart])
|
||||
|
||||
useLayoutEffect(() => {
|
||||
//Предустановленное значение - это либо 0, либо сколько нам нехватило на хабе, либо сколько нам нехватило на квизе
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const fromSquiz = params.get("action");
|
||||
const userid = params.get("user");
|
||||
const currentCC = params.get("cc");
|
||||
if (currentCC) setCC(true)
|
||||
|
||||
if (fromSquiz === "squizpay" && userid !== null) {
|
||||
setIsFromSquiz(true);
|
||||
}
|
||||
//Принимаем параметры из странички и очищаем url адрес до красивого состояния
|
||||
navigate(`/payment`, {
|
||||
replace: true,
|
||||
});
|
||||
}, []);
|
||||
//https://shub.pena.digital/quizpayment?action=squizpay&dif=9800&data=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY2ODVhNTc4OTgzZWU3N2Y4ZTFlNjNkYyIsImF1ZCI6InBlbmEiLCJpc3MiOiJwZW5hLWF1dGgtc2VydmljZSIsImlhdCI6MTcyMjIyMjgzMywiZXhwIjoxNzI3NDA2ODMzfQ.My1KJWFk034MiMdImQSlzf5p4Sn5Dhboj2VvPQteh59tD_CwXyPtePEyev3thV_58IbOOgJ5cgeBm0JKn7atgMgRMpNQVdeYKtf6HYvVoAqkrMcT1LHgAlEQ0TcaXssFKCQGuiCVltHY3UE-kQv5TeydBpO3U9BDKvMqRqv5-Xo&userid=6685a578983ee77f8e1e63dc
|
||||
const handlePaymentClick = () => {
|
||||
if (Number(paymentValueField) === 0) {
|
||||
// Проверяем оба источника данных
|
||||
const hasPaymentValue = Number(paymentValueField) > 0;
|
||||
const hasNotEnoughMoney = notEnoughMoneyAmount > 0;
|
||||
|
||||
console.log("handlePaymentClick - проверка:");
|
||||
console.log("paymentValueField:", paymentValueField);
|
||||
console.log("Number(paymentValueField):", Number(paymentValueField));
|
||||
console.log("notEnoughMoneyAmount:", notEnoughMoneyAmount);
|
||||
console.log("hasPaymentValue:", hasPaymentValue);
|
||||
console.log("hasNotEnoughMoney:", hasNotEnoughMoney);
|
||||
|
||||
if (!hasPaymentValue && !hasNotEnoughMoney) {
|
||||
enqueueSnackbar("Введите сумму");
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectedPaymentMethod === "rspay") {
|
||||
if (Number(paymentValueField) < 900) {
|
||||
const amountToCheck = hasPaymentValue ? Number(paymentValueField) : Number(bigDecimal.divide(notEnoughMoneyAmount, 100));
|
||||
if (amountToCheck < 900) {
|
||||
enqueueSnackbar("Минимальная сумма 900р");
|
||||
return;
|
||||
}
|
||||
@ -148,9 +129,11 @@ export default function Payment() {
|
||||
}
|
||||
|
||||
const startPayRS = async () => {
|
||||
const [sendRSPaymentResponse] = await sendRSPayment(
|
||||
Number(paymentValueField)
|
||||
);
|
||||
// Определяем сумму для оплаты
|
||||
const hasPaymentValue = Number(paymentValueField) > 0;
|
||||
const amountInRubles = hasPaymentValue ? Number(paymentValueField) : Number(bigDecimal.divide(notEnoughMoneyAmount, 100));
|
||||
|
||||
const [sendRSPaymentResponse] = await sendRSPayment(amountInRubles);
|
||||
|
||||
if (sendRSPaymentResponse) {
|
||||
return enqueueSnackbar(sendRSPaymentResponse);
|
||||
@ -169,19 +152,29 @@ export default function Payment() {
|
||||
enqueueSnackbar("Введите метод оплаты");
|
||||
return
|
||||
}
|
||||
|
||||
// Определяем сумму для оплаты
|
||||
const hasPaymentValue = Number(paymentValueField) > 0;
|
||||
const amountInRubles = hasPaymentValue ? Number(paymentValueField) : Number(bigDecimal.divide(notEnoughMoneyAmount, 100));
|
||||
const amountInKopecks = Number(bigDecimal.floor(bigDecimal.multiply(amountInRubles, 100)));
|
||||
|
||||
console.log("startPayCard - параметры:");
|
||||
console.log("action:", action);
|
||||
console.log("fromDomain:", fromDomain);
|
||||
console.log("backWay:", backWay);
|
||||
console.log("amountInRubles:", amountInRubles);
|
||||
console.log("amountInKopecks:", amountInKopecks);
|
||||
|
||||
const [sendPaymentResponse, sendPaymentError] = await sendPayment({
|
||||
userId: userId ?? "",
|
||||
fromSquiz,
|
||||
userId,
|
||||
body: {
|
||||
type: selectedPaymentMethod,
|
||||
amount: Number(
|
||||
bigDecimal.floor(
|
||||
bigDecimal.multiply(Number(paymentValueField), 100)
|
||||
)
|
||||
),
|
||||
amount: amountInKopecks,
|
||||
},
|
||||
paymentPurpose: notEnoughMoneyAmount ? "paycart" : "replenishwallet",
|
||||
cc
|
||||
action: action || undefined,
|
||||
fromDomain: fromDomain || undefined,
|
||||
backWay: backWay || undefined,
|
||||
additionalinformation: additionalinformation || undefined,
|
||||
});
|
||||
|
||||
if (sendPaymentError) {
|
||||
@ -277,7 +270,6 @@ export default function Payment() {
|
||||
image={image}
|
||||
onClick={() => {
|
||||
setSelectedPaymentMethod(name);
|
||||
setPaymentLink("");
|
||||
}}
|
||||
unpopular={false}
|
||||
/>
|
||||
@ -288,7 +280,6 @@ export default function Payment() {
|
||||
image={rsPayLogo}
|
||||
onClick={async () => {
|
||||
setSelectedPaymentMethod("rspay");
|
||||
setPaymentLink("");
|
||||
}}
|
||||
unpopular={false}
|
||||
/>
|
||||
@ -335,7 +326,7 @@ export default function Payment() {
|
||||
}}
|
||||
>
|
||||
{currencyFormatter.format(
|
||||
Number(bigDecimal.divide(bigDecimal.floor(paymentValue), 100))
|
||||
Number(bigDecimal.divide(notEnoughMoneyAmount, 100))
|
||||
)}
|
||||
</Typography>
|
||||
:
|
||||
|
109
src/pages/Payment/useAutoPay.ts
Normal file
109
src/pages/Payment/useAutoPay.ts
Normal file
@ -0,0 +1,109 @@
|
||||
import React, { useEffect, useState, useRef } from "react";
|
||||
import { useNavigate, useSearchParams } from "react-router-dom";
|
||||
import { cancelPayCartProcess, setNotEnoughMoneyAmount, startPayCartProcess } from "@root/stores/allTypesOfPurchases";
|
||||
import { useUserStore } from "@root/stores/user";
|
||||
import { setAction, setBackWay, setFromDomain, setAdditionalinformation } from "@root/stores/allTypesOfPurchases";
|
||||
import { Action, FromDomain } from "@root/model/autoPay";
|
||||
|
||||
export const useAutoPay = (): [string, React.Dispatch<React.SetStateAction<string>>] => {
|
||||
const navigate = useNavigate();
|
||||
const [searchParams] = useSearchParams();
|
||||
const hasProcessed = useRef(false);
|
||||
|
||||
const userId = useUserStore(store => store.userId)
|
||||
const [paymentValueField, setPaymentValueField] = useState<string>("0");
|
||||
|
||||
useEffect(() => {
|
||||
// Если уже обработали, не выполняем повторно
|
||||
if (hasProcessed.current) {
|
||||
console.log("useAutoPay - уже обработано, пропускаем");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log("useAutoPay - useEffect запущен");
|
||||
|
||||
// Сначала извлекаем все параметры
|
||||
let URLfromDomain = searchParams.get("fromdomain");//домен откуда произошёл запрос на финансовые работы
|
||||
let URLaction = searchParams.get("action");//что мы, собсна, хотим: оплатить, пополнить, купить и создать квиз
|
||||
let URLuserId = searchParams.get("userid");//тот кто начал всё это действо
|
||||
const URLwayBack = searchParams.get("wayback") ?? "";//путь по которому нужно будет пройти после того как закончим манипуляции (без домена)
|
||||
let URLmoneyDifferent = Number(searchParams.get("dif"));//сколько нужно деняк (в копейках)
|
||||
const URLadditionalinformation = searchParams.get("additionalinformation") ?? "";//дополнительная информация
|
||||
|
||||
console.log("useAutoPay - извлеченные параметры:");
|
||||
console.log("URLfromDomain:", URLfromDomain);
|
||||
console.log("URLaction:", URLaction);
|
||||
console.log("URLuserId:", URLuserId);
|
||||
console.log("URLwayBack:", URLwayBack);
|
||||
console.log("URLmoneyDifferent (копейки):", URLmoneyDifferent);
|
||||
console.log("URLadditionalinformation:", URLadditionalinformation);
|
||||
console.log("userId:", userId);
|
||||
|
||||
// Если нет URL параметров, но мы уже на странице /payment, не делаем ничего
|
||||
if (!URLfromDomain && !URLaction && !URLuserId && URLmoneyDifferent === 0) {
|
||||
console.log("useAutoPay - нет URL параметров, но мы уже на /payment, пропускаем");
|
||||
hasProcessed.current = true;
|
||||
return;
|
||||
}
|
||||
|
||||
//Анализ нужно ли вообще вмешательство этого хука
|
||||
const condition1 = URLuserId !== null && URLuserId && URLuserId === userId;
|
||||
const condition2 = URLfromDomain === "quiz" || URLfromDomain === "squiz" || URLfromDomain === "hub" || URLfromDomain === "shub" || URLfromDomain === "localhost:3000";
|
||||
const condition3 = URLaction === "topupwallet" || URLaction === "createquizcc" || URLaction === "buy";
|
||||
const condition4 = !Number.isNaN(URLmoneyDifferent);
|
||||
|
||||
console.log("useAutoPay - проверка условий:");
|
||||
console.log("condition1 (userId совпадает):", condition1);
|
||||
console.log("condition2 (fromDomain валидный):", condition2);
|
||||
console.log("condition3 (action валидный):", condition3);
|
||||
console.log("condition4 (moneyDifferent валидный):", condition4);
|
||||
|
||||
if (condition1 && condition2 && condition3 && condition4) {
|
||||
console.log("useAutoPay - условия выполнены, устанавливаем значения");
|
||||
|
||||
// Ставим флаг, что сайт в состоянии ожидания пополнения счёта для оплаты
|
||||
startPayCartProcess(URLuserId);
|
||||
|
||||
console.log("useAutoPay - устанавливаем fromDomain:", URLfromDomain);
|
||||
setFromDomain(URLfromDomain as FromDomain);
|
||||
|
||||
const processedBackWay = URLwayBack.startsWith('/') ? URLwayBack.slice(1) : URLwayBack;
|
||||
console.log("useAutoPay - устанавливаем backWay:", processedBackWay);
|
||||
setBackWay(processedBackWay);
|
||||
|
||||
console.log("useAutoPay - устанавливаем action:", URLaction);
|
||||
setAction(URLaction as Action);
|
||||
|
||||
console.log("useAutoPay - устанавливаем additionalinformation:", URLadditionalinformation);
|
||||
setAdditionalinformation(URLadditionalinformation);
|
||||
|
||||
// URLmoneyDifferent в копейках, конвертируем в рубли для отображения
|
||||
const rubles = URLmoneyDifferent / 100;
|
||||
setPaymentValueField(rubles.toString());
|
||||
setNotEnoughMoneyAmount(URLmoneyDifferent);
|
||||
|
||||
console.log("useAutoPay - установлено paymentValueField (рубли):", rubles.toString());
|
||||
console.log("useAutoPay - установлено backWay:", processedBackWay);
|
||||
console.log("useAutoPay - установлено additionalinformation:", URLadditionalinformation);
|
||||
|
||||
// Только после установки всех значений делаем навигацию
|
||||
navigate("/payment", { replace: true });
|
||||
} else {
|
||||
console.log("useAutoPay - условия не выполнены, отменяем процесс");
|
||||
console.log("Причины:");
|
||||
if (!condition1) console.log("- userId не совпадает");
|
||||
if (!condition2) console.log("- fromDomain не валидный:", URLfromDomain);
|
||||
if (!condition3) console.log("- action не валидный:", URLaction);
|
||||
if (!condition4) console.log("- moneyDifferent не валидный:", URLmoneyDifferent);
|
||||
cancelPayCartProcess();
|
||||
}
|
||||
|
||||
// Отмечаем, что обработали
|
||||
hasProcessed.current = true;
|
||||
|
||||
// Убираем cleanup функцию, так как она вызывается слишком рано
|
||||
// Cleanup будет в Payment компоненте при размонтировании
|
||||
}, [searchParams, userId, navigate])
|
||||
|
||||
return [paymentValueField, setPaymentValueField];
|
||||
}
|
@ -1,113 +0,0 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { ApologyPage } from "../ApologyPage";
|
||||
import { redirect, useNavigate } from "react-router-dom";
|
||||
import {
|
||||
clearAuthToken,
|
||||
getMessageFromFetchError,
|
||||
setAuthToken,
|
||||
useUserAccountFetcher,
|
||||
useUserFetcher,
|
||||
getAuthToken,
|
||||
} from "@frontend/kitui";
|
||||
import {
|
||||
clearUserData,
|
||||
setUser,
|
||||
setUserAccount,
|
||||
setUserId,
|
||||
useUserStore,
|
||||
} from "@root/stores/user";
|
||||
import { logout } from "@root/api/auth";
|
||||
import { clearCustomTariffs } from "@root/stores/customTariffs";
|
||||
import { clearTickets } from "@root/stores/tickets";
|
||||
import { setNotEnoughMoneyAmount, startPayCartProcess } from "@stores/notEnoughMoneyAmount"
|
||||
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
let action = params.get("action");
|
||||
let dif = params.get("dif");
|
||||
let token = params.get("data");
|
||||
let userId = params.get("userid");
|
||||
let currentCC = params.get("cc");
|
||||
|
||||
let first = true;
|
||||
|
||||
export default function QuizPayment() {
|
||||
const navigate = useNavigate();
|
||||
const [message, setMessage] = useState("Идёт загрузка");
|
||||
const user = useUserStore((state) => state.user);
|
||||
const currentUserId = useUserStore((state) => state.user?._id);
|
||||
const fromSquiz = params.get("action");
|
||||
|
||||
useEffect(
|
||||
function redirectIfSignedIn() {
|
||||
if (!first && user?._id === userId) {
|
||||
let returnUrl = `/payment?action=${action}&dif=${dif}&user=${userId}`
|
||||
if (wayback) returnUrl += `&wayback=${wayback}`
|
||||
navigate(returnUrl, {
|
||||
replace: true,
|
||||
});
|
||||
}
|
||||
},
|
||||
[navigate, user]
|
||||
|
||||
useEffect(() => {
|
||||
if (!first && userId !== null && currentUserId === userId) {
|
||||
if (fromSquiz === "squizpay") {
|
||||
setNotEnoughMoneyAmount(Number(params.get("dif") || 0));//Сколько нехватило на квизе
|
||||
startPayCartProcess(userId)
|
||||
let link = `/payment?action=${action}&dif=${dif}&user=${userId}`
|
||||
if (currentCC) link = link + "&cc=true"
|
||||
navigate(link, {
|
||||
replace: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
[currentUserId]
|
||||
);
|
||||
|
||||
|
||||
if (first) {
|
||||
navigate(`/quizpayment`, {
|
||||
replace: true,
|
||||
});
|
||||
try {
|
||||
first = false;
|
||||
|
||||
if (user?._id === userId) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (action && dif && token) {
|
||||
(async () => {
|
||||
if (getAuthToken()) {
|
||||
clearAuthToken();
|
||||
clearUserData();
|
||||
clearCustomTariffs();
|
||||
clearTickets();
|
||||
setNotEnoughMoneyAmount(0)
|
||||
logout();
|
||||
}
|
||||
|
||||
|
||||
setUserId(userId);
|
||||
setAuthToken(token);
|
||||
|
||||
return;
|
||||
})();
|
||||
} else {
|
||||
var link = document.createElement("a");
|
||||
link.href = "https://quiz.pena.digital/tariffs";
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
}
|
||||
} catch (e) {
|
||||
setMessage("Произошла ошибка");
|
||||
var link = document.createElement("a");
|
||||
link.href = "https://quiz.pena.digital/tariffs";
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
}
|
||||
}
|
||||
|
||||
return <ApologyPage message={message} />;
|
||||
}
|
@ -101,17 +101,8 @@ function SupportChat() {
|
||||
`/heruvym/v1.0.0/ticket?ticket=${ticketId}&Authorization=${token}`,
|
||||
|
||||
onNewData: (ticketMessages) => {
|
||||
console.log("SupportChat")
|
||||
console.log("ticketMessages")
|
||||
console.log(ticketMessages)
|
||||
const data = ticketMessages.filter(t => {
|
||||
if (typeof t === "object" && t !== null && "event" in t && t.event !== "ping") {
|
||||
console.log("---------------------------------------------------")
|
||||
console.log(t)
|
||||
console.log(typeof t === "object")
|
||||
console.log("event" in t)
|
||||
console.log(t.event !== "ping")
|
||||
console.log("---------------------------------------------------")
|
||||
return true
|
||||
}
|
||||
})
|
||||
@ -235,9 +226,6 @@ function SupportChat() {
|
||||
setDisableFileButton(false);
|
||||
};
|
||||
|
||||
console.log("messages messmessagesmessagesmessages messages")
|
||||
console.log(messages)
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
@ -353,8 +341,6 @@ function SupportChat() {
|
||||
message?.files?.length > 0 &&
|
||||
isFileImage()
|
||||
) {
|
||||
console.log("message NEWNEWNENWNEW _WE__WE_W_EW_E_WENWNEWNENWEWNE")
|
||||
console.log(message)
|
||||
return (
|
||||
<ChatImage
|
||||
unAuthenticated
|
||||
|
@ -84,7 +84,6 @@ export const ModalRequestCreate = () => {
|
||||
const isMobile = useMediaQuery(theme.breakpoints.down(650));
|
||||
const [isSending, setIsSending] = useState(false)
|
||||
const open = useRequestSquizCreate(store => store.isRSCOpen)
|
||||
console.log(open)
|
||||
|
||||
if (isSending) return (
|
||||
<Modal
|
||||
|
@ -51,7 +51,6 @@ function TariffPage() {
|
||||
useUserStore((state) => state.userAccount?.wallet.spent) ?? 0;
|
||||
const userId = useUserStore((state) => state.user?._id) ?? "";
|
||||
const userPrivilegies = useUserStore(store => store.quizUserAccount?.privileges);
|
||||
console.log(userPrivilegies)
|
||||
const discounts = useDiscounts(userId);
|
||||
const isUserNko =
|
||||
useUserStore((state) => state.userAccount?.status) === "nko";
|
||||
|
@ -75,8 +75,6 @@ export default function RecoverPassword() {
|
||||
useEffect(() => {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const authToken = params.get("auth");
|
||||
console.log("authToken")
|
||||
console.log(authToken)
|
||||
setTokenUser(authToken);
|
||||
|
||||
history.pushState(null, document.title, "/changepwd");
|
||||
|
67
src/stores/allTypesOfPurchases.ts
Normal file
67
src/stores/allTypesOfPurchases.ts
Normal file
@ -0,0 +1,67 @@
|
||||
import moment from "moment";
|
||||
import { create } from "zustand";
|
||||
import { devtools, persist } from "zustand/middleware";
|
||||
import type { Action, FromDomain } from "@root/model/autoPay";
|
||||
|
||||
interface CartStore {
|
||||
notEnoughMoneyAmount: number;
|
||||
siteReadyPayCart: Record<string, string> | null;
|
||||
fromDomain: FromDomain | null;
|
||||
backWay: string;
|
||||
action: Action | null;
|
||||
additionalinformation: string;
|
||||
}
|
||||
const initialState: CartStore = {
|
||||
notEnoughMoneyAmount: 0,
|
||||
siteReadyPayCart: null,
|
||||
fromDomain: null,
|
||||
backWay: "",
|
||||
action: null,
|
||||
additionalinformation: ""
|
||||
}
|
||||
|
||||
//Была попытка оплатить корзину. Тут записанна недостающая сумма.
|
||||
export const allTypesOfPurchases = create<CartStore>()(
|
||||
devtools(
|
||||
persist(
|
||||
() => initialState,
|
||||
{
|
||||
name: 'siteReadyPayCart', // Ключ для localStorage
|
||||
partialize: (state) => ({
|
||||
// Сохраняем ТОЛЬКО siteReadyPayCart
|
||||
siteReadyPayCart: state.siteReadyPayCart
|
||||
}),
|
||||
}
|
||||
),
|
||||
{
|
||||
name: "cartStore",
|
||||
enabled: process.env.NODE_ENV === "development",
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
export const setSiteReadyPayCart = (flag: Record<string, string> | null) => allTypesOfPurchases.setState({ siteReadyPayCart: flag });
|
||||
export const setNotEnoughMoneyAmount = (amount: number) => allTypesOfPurchases.setState({ notEnoughMoneyAmount: amount });
|
||||
export const setFromDomain = (fromDomain: FromDomain) => allTypesOfPurchases.setState({ fromDomain });
|
||||
export const setBackWay = (backWay: string) => allTypesOfPurchases.setState({ backWay });
|
||||
export const setAction = (action: Action) => allTypesOfPurchases.setState({ action });
|
||||
export const setAdditionalinformation = (additionalinformation: string) => allTypesOfPurchases.setState({ additionalinformation });
|
||||
|
||||
export const startPayCartProcess = (userId: string) => setSiteReadyPayCart({ [userId]: moment().add(20, 'minutes').format("X") });
|
||||
export const cancelPayCartProcess = () => {
|
||||
setSiteReadyPayCart(null);
|
||||
allTypesOfPurchases.setState({
|
||||
fromDomain: null,
|
||||
backWay: "",
|
||||
action: null
|
||||
})
|
||||
};
|
||||
|
||||
|
||||
export const calcTimeOfReadyPayCart = (deadline: string) => {
|
||||
const ready = Number(deadline) > Number(moment().format("X"))
|
||||
if (!ready) {
|
||||
cancelPayCartProcess()
|
||||
}
|
||||
return ready
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
import moment from "moment";
|
||||
import { create } from "zustand";
|
||||
import { devtools } from "zustand/middleware";
|
||||
|
||||
interface CartStore {
|
||||
notEnoughMoneyAmount: number;
|
||||
siteReadyPayCart: Record<string, string> | null;
|
||||
}
|
||||
const initialState: CartStore = {
|
||||
notEnoughMoneyAmount: 0,
|
||||
siteReadyPayCart: null
|
||||
}
|
||||
|
||||
//Была попытка оплатить корзину. Тут записанна недостающая сумма.
|
||||
export const useNotEnoughMoneyAmount = create<CartStore>()(
|
||||
devtools(
|
||||
(get, set) => initialState,
|
||||
{
|
||||
name: "notEnoughMoneyAmount",
|
||||
enabled: process.env.NODE_ENV === "development",
|
||||
trace: true,
|
||||
actionsBlacklist: "rejected",
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
export const setNotEnoughMoneyAmount = (amount: number) => useNotEnoughMoneyAmount.setState({ notEnoughMoneyAmount: amount });
|
||||
|
||||
export const setSiteReadyPayCart = (flag: Record<string, string> | null) => useNotEnoughMoneyAmount.setState({ siteReadyPayCart: flag });
|
||||
export const startPayCartProcess = (userId: string) => setSiteReadyPayCart({ [userId]: moment().add(20, 'minutes').format("X") });
|
||||
export const cancelPayCartProcess = () => setSiteReadyPayCart(null);
|
||||
export const calcTimeOfReadyPayCart = (deadline: string) => {
|
||||
const ready = Number(deadline) > Number(moment().format("X"))
|
||||
if (!ready) {
|
||||
cancelPayCartProcess()
|
||||
}
|
||||
return ready
|
||||
}
|
@ -14,7 +14,7 @@ import { patchUser } from "@root/api/user"
|
||||
import { UserAccountSettingsFieldStatus, VerificationStatus } from "@root/model/account"
|
||||
import { patchCurrency, deleteCart, patchCart } from "@root/api/cart"
|
||||
import { User, UserAccount, UserName, getInitials, patchUserAccount } from "@frontend/kitui"
|
||||
import { cancelPayCartProcess, setNotEnoughMoneyAmount, setSiteReadyPayCart, useNotEnoughMoneyAmount } from "./notEnoughMoneyAmount";
|
||||
import { cancelPayCartProcess, setNotEnoughMoneyAmount, setSiteReadyPayCart, allTypesOfPurchases } from "./allTypesOfPurchases";
|
||||
|
||||
type Privilege = {
|
||||
amount: number;
|
||||
|
@ -17,7 +17,6 @@ export const useUserAccountFetcher = <T = UserAccount>({
|
||||
onNewUserAccount: (response: T) => void;
|
||||
onError?: (error: any) => void;
|
||||
}) => {
|
||||
console.log("начало работы useUserAccountFetcher")
|
||||
const onNewUserAccountRef = useRef(onNewUserAccount);
|
||||
const onErrorRef = useRef(onError);
|
||||
useLayoutEffect(() => {
|
||||
|
@ -1,72 +0,0 @@
|
||||
import { payCart } from "@root/api/cart";
|
||||
import { calcTimeOfReadyPayCart, cancelPayCartProcess, setNotEnoughMoneyAmount, setSiteReadyPayCart, startPayCartProcess, useNotEnoughMoneyAmount } from "@root/stores/notEnoughMoneyAmount";
|
||||
import { useUserStore } from "@root/stores/user";
|
||||
import moment from "moment";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
import { useEffect } from "react";
|
||||
import { useSearchParams } from "react-router-dom";
|
||||
import { RSCOpen } from "@root/stores/requestSquizCreate";
|
||||
import { useCartTariffs } from "./useCartTariffs";
|
||||
|
||||
export const useAfterPay = () => {
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const userId = useUserStore(store => store.userId)
|
||||
const userAccount = useUserStore(state => state.userAccount);
|
||||
const siteReadyPayCart = useNotEnoughMoneyAmount(state => state.siteReadyPayCart);
|
||||
const cartTariffs = useCartTariffs();
|
||||
console.log("cartTariffs")
|
||||
// console.log(cartTariffs)
|
||||
// const isCC = cartTariffs !== null && cartTariffs !== undefined && cartTariffs.length > 0 && cartTariffs.some(t => t.privileges[0].privilegeId === "quizManual")
|
||||
|
||||
const purpose = searchParams.get("purpose");
|
||||
const from = searchParams.get("from");
|
||||
const action = searchParams.get("action");
|
||||
const paymentUserId = searchParams.get("userid");
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
//Звёзды сошлись, будем оплачивать корзину
|
||||
if (from !== "quiz" && paymentUserId && paymentUserId === userId) {
|
||||
//Чистим url адрес от параметров. (Если нет action. Если есть - значит мы пришли из квиза)
|
||||
if (action === null) setSearchParams({}, { replace: true })
|
||||
// navigate(`/tariffs`, {
|
||||
// replace: true,
|
||||
// });
|
||||
|
||||
if (purpose === "paycart") {
|
||||
(async () => {
|
||||
|
||||
//Проверяем можем ли мы оплатить корзину здесь и сейчас
|
||||
const [, payCartError] = await payCart();
|
||||
|
||||
if (payCartError) {
|
||||
//Не получилось купить корзину. Ставим флаг, что сайт в состоянии ожидания пополнения счёта для оплаты
|
||||
startPayCartProcess(paymentUserId)
|
||||
} else {
|
||||
enqueueSnackbar("Товары успешно приобретены")
|
||||
cancelPayCartProcess()
|
||||
if (true) RSCOpen()
|
||||
}
|
||||
})()
|
||||
}
|
||||
}
|
||||
}, [purpose, from, paymentUserId])
|
||||
|
||||
useEffect(() => {
|
||||
if (userId !== null && siteReadyPayCart !== null && siteReadyPayCart[userId] !== undefined) {
|
||||
const deadline = siteReadyPayCart[userId]
|
||||
if (calcTimeOfReadyPayCart(deadline)) {
|
||||
|
||||
//Время ещё не вышло. У нас стоит флаг покупать корзину если время не вышло.
|
||||
(async () => {
|
||||
const [, payCartError] = await payCart();
|
||||
|
||||
if (!payCartError) {
|
||||
enqueueSnackbar("Товары успешно приобретены")
|
||||
cancelPayCartProcess()
|
||||
}
|
||||
})()
|
||||
}
|
||||
}
|
||||
}, [userAccount, userId, siteReadyPayCart])
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
import { Ticket, UserAccount, UserName, getAuthToken, useSSESubscription } from "@frontend/kitui"
|
||||
import { setCart, setNewNames, setUserStatus, setWallet, useUserStore } from "@root/stores/user";
|
||||
import { useSSETab } from "./useSSETab";
|
||||
import { cancelPayCartProcess } from "@root/stores/notEnoughMoneyAmount";
|
||||
import { cancelPayCartProcess } from "@root/stores/allTypesOfPurchases";
|
||||
|
||||
type Ping = [{ event: "ping" }]
|
||||
|
||||
|
112
src/utils/hooks/useReauthorization.ts
Normal file
112
src/utils/hooks/useReauthorization.ts
Normal file
@ -0,0 +1,112 @@
|
||||
import { clearAuthToken, getAuthToken, setAuthToken } from '@frontend/kitui';
|
||||
import { logout } from '@root/api/auth';
|
||||
import { setNotEnoughMoneyAmount } from '@root/stores/allTypesOfPurchases';
|
||||
import { clearCustomTariffs } from '@root/stores/customTariffs';
|
||||
import { clearTickets } from '@root/stores/tickets';
|
||||
import { clearUserData, setUserId, useUserStore } from '@root/stores/user';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { useLocation, useNavigate } from 'react-router-dom';
|
||||
|
||||
interface QuizAuthParams {
|
||||
action?: string;
|
||||
dif?: string;
|
||||
data?: string;
|
||||
userid?: string;
|
||||
wayback?: string;
|
||||
}
|
||||
|
||||
export const useReauthorization = () => {
|
||||
const userId = useUserStore(store => store.userId);
|
||||
const user = useUserStore(store => store.user);
|
||||
const { search } = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const [isProcessing, setIsProcessing] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
// Этот эффект сработает при каждом изменении query-параметров
|
||||
const params = new URLSearchParams(search);
|
||||
|
||||
// Обработка старых параметров (userid, sec)
|
||||
const URLuserId = params.get('userid');
|
||||
const URLtoken = params.get('sec');
|
||||
|
||||
// Обработка новых параметров авторизации
|
||||
const quizParams: QuizAuthParams = {
|
||||
action: params.get("action") || undefined,
|
||||
dif: params.get("dif") || undefined,
|
||||
data: params.get("data") || undefined,
|
||||
userid: params.get("userid") || undefined,
|
||||
wayback: params.get("wayback") || undefined,
|
||||
};
|
||||
|
||||
const { action, dif, data: token, userid: quizUserId, wayback } = quizParams;
|
||||
|
||||
// Если есть новые параметры авторизации, обрабатываем их
|
||||
if (action && dif && token && quizUserId) {
|
||||
// Если пользователь уже авторизован и это тот же пользователь, перенаправляем на payment
|
||||
if (user?._id === quizUserId) {
|
||||
let returnUrl = `/payment?action=${action}&dif=${dif}&user=${quizUserId}`;
|
||||
if (wayback) returnUrl += `&wayback=${wayback}`;
|
||||
navigate(returnUrl, { replace: true });
|
||||
return;
|
||||
}
|
||||
|
||||
// Если уже обрабатываем авторизацию, не запускаем повторно
|
||||
if (isProcessing) {
|
||||
return;
|
||||
}
|
||||
|
||||
setIsProcessing(true);
|
||||
|
||||
const processQuizAuth = async () => {
|
||||
try {
|
||||
// Если есть текущий токен, очищаем данные
|
||||
if (getAuthToken()) {
|
||||
clearAuthToken();
|
||||
clearUserData();
|
||||
clearCustomTariffs();
|
||||
clearTickets();
|
||||
setNotEnoughMoneyAmount(0);
|
||||
await logout();
|
||||
}
|
||||
|
||||
// Устанавливаем новый токен и ID пользователя
|
||||
setAuthToken(token);
|
||||
setUserId(quizUserId);
|
||||
} catch (error) {
|
||||
console.error("Ошибка авторизации:", error);
|
||||
|
||||
// Перенаправляем на внешний сайт в случае ошибки
|
||||
const link = document.createElement("a");
|
||||
link.href = "https://quiz.pena.digital/tariffs";
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
} finally {
|
||||
setIsProcessing(false);
|
||||
}
|
||||
};
|
||||
|
||||
processQuizAuth();
|
||||
return;
|
||||
}
|
||||
|
||||
// Обработка старых параметров (userid, sec)
|
||||
if (URLuserId !== userId && URLtoken) {
|
||||
// Если есть токен в URL, устанавливаем его
|
||||
// Очищаем данные только если токен действительно изменился
|
||||
if (getAuthToken() !== URLtoken) {
|
||||
clearAuthToken();
|
||||
clearUserData();
|
||||
clearCustomTariffs();
|
||||
clearTickets();
|
||||
setNotEnoughMoneyAmount(0);
|
||||
// Не вызываем logout() чтобы избежать перенаправления
|
||||
}
|
||||
setAuthToken(URLtoken);
|
||||
}
|
||||
}, [search, userId, user?._id, navigate, isProcessing]);
|
||||
|
||||
return {
|
||||
isProcessing,
|
||||
};
|
||||
};
|
29
src/utils/hooks/useTryBuy.ts
Normal file
29
src/utils/hooks/useTryBuy.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import { payCart } from "@root/api/cart";
|
||||
import { allTypesOfPurchases, calcTimeOfReadyPayCart, cancelPayCartProcess } from "@root/stores/allTypesOfPurchases"
|
||||
import { useUserStore } from "@root/stores/user";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
import { useEffect } from "react"
|
||||
|
||||
export const useTryBuy = () => {
|
||||
const userId = useUserStore(store => store.userId)
|
||||
const userAccount = useUserStore(state => state.userAccount);
|
||||
const siteReadyPayCart = allTypesOfPurchases(state => state.siteReadyPayCart);
|
||||
|
||||
useEffect(() => {
|
||||
if (userId !== null && siteReadyPayCart !== null && siteReadyPayCart[userId] !== undefined) {
|
||||
const deadline = siteReadyPayCart[userId]
|
||||
if (calcTimeOfReadyPayCart(deadline)) {
|
||||
|
||||
//Время ещё не вышло. У нас стоит флаг покупать корзину если время не вышло.
|
||||
(async () => {
|
||||
const [, payCartError] = await payCart();
|
||||
|
||||
if (!payCartError) {
|
||||
enqueueSnackbar("Товары успешно приобретены")
|
||||
cancelPayCartProcess()
|
||||
}
|
||||
})()
|
||||
}
|
||||
}
|
||||
}, [userAccount, userId, siteReadyPayCart])
|
||||
}
|
@ -26,8 +26,6 @@ export const jsonToFormdata = (
|
||||
): FormData => {
|
||||
const formData = new FormData()
|
||||
if (json.egrule !== undefined) delete json.egrule
|
||||
console.log("json")
|
||||
console.log(json)
|
||||
|
||||
for (const key in json) {
|
||||
if (!key) continue
|
||||
@ -43,7 +41,5 @@ export const jsonToFormdata = (
|
||||
|
||||
formData.append(key, value)
|
||||
}
|
||||
console.log("formData")
|
||||
console.log(formData)
|
||||
return formData
|
||||
}
|
||||
|
70
yarn.lock
70
yarn.lock
@ -1059,6 +1059,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.27.1.tgz#9fce313d12c9a77507f264de74626e87fd0dc541"
|
||||
integrity sha512-1x3D2xEk2fRo3PAhwQwu5UubzgiVWSXTBfWpVd2Mx2AzRqJuDJCsgaDVZ7HB5iGzDW1Hl1sWN2mFyKjmR9uAog==
|
||||
|
||||
"@babel/runtime@^7.25.7", "@babel/runtime@^7.27.6":
|
||||
version "7.27.6"
|
||||
resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.6.tgz#ec4070a04d76bae8ddbb10770ba55714a417b7c6"
|
||||
integrity sha512-vbavdySgbTTrmFE+EsiqUTzlOr5bzlnJtUv9PynGCAKvfQqjIXbvFdumPM/GxMDfyuGMJaJAU6TO4zc1Jf1i8Q==
|
||||
|
||||
"@babel/template@^7.27.1", "@babel/template@^7.3.3":
|
||||
version "7.27.2"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.27.2.tgz#fa78ceed3c4e7b63ebf6cb39e5852fca45f6809d"
|
||||
@ -2104,11 +2109,30 @@
|
||||
csstype "^3.1.3"
|
||||
prop-types "^15.8.1"
|
||||
|
||||
"@mui/types@^7.4.4":
|
||||
version "7.4.4"
|
||||
resolved "https://registry.npmjs.org/@mui/types/-/types-7.4.4.tgz#0c5cd56905231e27096b41d096f1c948c26bdd5d"
|
||||
integrity sha512-p63yhbX52MO/ajXC7hDHJA5yjzJekvWD3q4YDLl1rSg+OXLczMYPvTuSuviPRCgRX8+E42RXz1D/dz9SxPSlWg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.27.6"
|
||||
|
||||
"@mui/types@~7.2.15":
|
||||
version "7.2.24"
|
||||
resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.24.tgz#5eff63129d9c29d80bbf2d2e561bd0690314dec2"
|
||||
integrity sha512-3c8tRt/CbWZ+pEg7QpSwbdxOk36EfmhbKf6AGZsD1EcLDLTSZoxxJ86FVtcjxvjuhdyBiWKSTGZFaXCnidO2kw==
|
||||
|
||||
"@mui/utils@^5.16.6 || ^6.0.0 || ^7.0.0":
|
||||
version "7.2.0"
|
||||
resolved "https://registry.npmjs.org/@mui/utils/-/utils-7.2.0.tgz#31062697b41aa8ea8ef04e3d3fadca1dec3e1de1"
|
||||
integrity sha512-O0i1GQL6MDzhKdy9iAu5Yr0Sz1wZjROH1o3aoztuivdCXqEeQYnEjTDiRLGuFxI9zrUbTHBwobMyQH5sNtyacw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.27.6"
|
||||
"@mui/types" "^7.4.4"
|
||||
"@types/prop-types" "^15.7.15"
|
||||
clsx "^2.1.1"
|
||||
prop-types "^15.8.1"
|
||||
react-is "^19.1.0"
|
||||
|
||||
"@mui/utils@^5.17.1":
|
||||
version "5.17.1"
|
||||
resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.17.1.tgz#72ba4ffa79f7bdf69d67458139390f18484b6e6b"
|
||||
@ -2121,6 +2145,27 @@
|
||||
prop-types "^15.8.1"
|
||||
react-is "^19.0.0"
|
||||
|
||||
"@mui/x-date-pickers@^7.13.0":
|
||||
version "7.29.4"
|
||||
resolved "https://registry.npmjs.org/@mui/x-date-pickers/-/x-date-pickers-7.29.4.tgz#b8808cb8e28c1d4e528b37b336effc8074e65faf"
|
||||
integrity sha512-wJ3tsqk/y6dp+mXGtT9czciAMEO5Zr3IIAHg9x6IL0Eqanqy0N3chbmQQZv3iq0m2qUpQDLvZ4utZBUTJdjNzw==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.25.7"
|
||||
"@mui/utils" "^5.16.6 || ^6.0.0 || ^7.0.0"
|
||||
"@mui/x-internals" "7.29.0"
|
||||
"@types/react-transition-group" "^4.4.11"
|
||||
clsx "^2.1.1"
|
||||
prop-types "^15.8.1"
|
||||
react-transition-group "^4.4.5"
|
||||
|
||||
"@mui/x-internals@7.29.0":
|
||||
version "7.29.0"
|
||||
resolved "https://registry.npmjs.org/@mui/x-internals/-/x-internals-7.29.0.tgz#1f353b697ed1bf5594ac549556ade2e6841f4bf5"
|
||||
integrity sha512-+Gk6VTZIFD70XreWvdXBwKd8GZ2FlSCuecQFzm6znwqXg1ZsndavrhG9tkxpxo2fM1Zf7Tk8+HcOO0hCbhTQFA==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.25.7"
|
||||
"@mui/utils" "^5.16.6 || ^6.0.0 || ^7.0.0"
|
||||
|
||||
"@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1":
|
||||
version "5.1.1-v1"
|
||||
resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz#dbf733a965ca47b1973177dc0bb6c889edcfb129"
|
||||
@ -2807,6 +2852,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.14.tgz#1433419d73b2a7ebfc6918dcefd2ec0d5cd698f2"
|
||||
integrity sha512-gNMvNH49DJ7OJYv+KAKn0Xp45p8PLl6zo2YnvDIbTd4J6MER2BmWN49TG7n9LvkyihINxeKW8+3bfS2yDC9dzQ==
|
||||
|
||||
"@types/prop-types@^15.7.15":
|
||||
version "15.7.15"
|
||||
resolved "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.15.tgz#e6e5a86d602beaca71ce5163fadf5f95d70931c7"
|
||||
integrity sha512-F6bEyamV9jKGAFBEmlQnesRPGOQqS2+Uwi0Em15xenOxHaf2hv6L8YCVn3rPdPJOiJfPiCnLIRyvwVaqMY3MIw==
|
||||
|
||||
"@types/q@^1.5.1":
|
||||
version "1.5.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.8.tgz#95f6c6a08f2ad868ba230ead1d2d7f7be3db3837"
|
||||
@ -2834,7 +2884,7 @@
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react-transition-group@^4.4.10":
|
||||
"@types/react-transition-group@^4.4.10", "@types/react-transition-group@^4.4.11":
|
||||
version "4.4.12"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.12.tgz#b5d76568485b02a307238270bfe96cb51ee2a044"
|
||||
integrity sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==
|
||||
@ -8903,6 +8953,11 @@ mlly@^1.7.3, mlly@^1.7.4:
|
||||
pkg-types "^1.3.0"
|
||||
ufo "^1.5.4"
|
||||
|
||||
moment@^2.30.1:
|
||||
version "2.30.1"
|
||||
resolved "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae"
|
||||
integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==
|
||||
|
||||
ms@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||
@ -10344,7 +10399,7 @@ react-is@^18.0.0:
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e"
|
||||
integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==
|
||||
|
||||
react-is@^19.0.0:
|
||||
react-is@^19.0.0, react-is@^19.1.0:
|
||||
version "19.1.0"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-19.1.0.tgz#805bce321546b7e14c084989c77022351bbdd11b"
|
||||
integrity sha512-Oe56aUPnkHyyDxxkvqtd7KkdQP5uIUfHxd5XTb3wE9d/kRnZLmKbDB0GWk919tdQ+mxxPtG6EAs6RMT6i1qtHg==
|
||||
@ -11854,6 +11909,13 @@ tr46@~0.0.3:
|
||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a"
|
||||
integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==
|
||||
|
||||
transliteration@^2.3.5:
|
||||
version "2.3.5"
|
||||
resolved "https://registry.npmjs.org/transliteration/-/transliteration-2.3.5.tgz#8f92309575f69e4a8a525dab4ff705ebcf961c45"
|
||||
integrity sha512-HAGI4Lq4Q9dZ3Utu2phaWgtm3vB6PkLUFqWAScg/UW+1eZ/Tg6Exo4oC0/3VUol/w4BlefLhUUSVBr/9/ZGQOw==
|
||||
dependencies:
|
||||
yargs "^17.5.1"
|
||||
|
||||
tryer@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8"
|
||||
@ -12893,9 +12955,9 @@ yargs@^16.2.0:
|
||||
y18n "^5.0.5"
|
||||
yargs-parser "^20.2.2"
|
||||
|
||||
yargs@^17.3.1:
|
||||
yargs@^17.3.1, yargs@^17.5.1:
|
||||
version "17.7.2"
|
||||
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269"
|
||||
resolved "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269"
|
||||
integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==
|
||||
dependencies:
|
||||
cliui "^8.0.1"
|
||||
|
Loading…
Reference in New Issue
Block a user