From 44577d19fd022d9b92bf0410a6587411c92c0a11 Mon Sep 17 00:00:00 2001 From: Nastya Date: Mon, 22 Jul 2024 21:32:41 +0300 Subject: [PATCH 01/30] customer v1.0.1 --- src/api/cart.ts | 2 +- src/api/history.ts | 2 +- src/api/recentlyPurchasedTariffs.ts | 2 +- src/api/wallet.ts | 2 +- src/index.tsx | 2 +- src/utils/hooks/usePipeSubscriber.ts | 50 ++++++++++++++++++++++++++++ 6 files changed, 55 insertions(+), 5 deletions(-) create mode 100644 src/utils/hooks/usePipeSubscriber.ts diff --git a/src/api/cart.ts b/src/api/cart.ts index ed136e4..65d63d1 100644 --- a/src/api/cart.ts +++ b/src/api/cart.ts @@ -3,7 +3,7 @@ import makeRequest from "@api/makeRequest"; import { parseAxiosError } from "@root/utils/parse-error"; -const API_URL = `${process.env.REACT_APP_DOMAIN}/customer/v1.0.0`; +const API_URL = `${process.env.REACT_APP_DOMAIN}/customer/v1.0.1`; export const patchCart = async ( tariffId: string diff --git a/src/api/history.ts b/src/api/history.ts index d44846f..99857ad 100644 --- a/src/api/history.ts +++ b/src/api/history.ts @@ -44,7 +44,7 @@ export type RawDetails = { Value: string | number | KeyValue[][]; }; -const API_URL = `${process.env.REACT_APP_DOMAIN}/customer/v1.0.0`; +const API_URL = `${process.env.REACT_APP_DOMAIN}/customer/v1.0.1`; export const getHistory = async (): Promise< [GetHistoryResponse | GetHistoryResponse2 | null, string?] diff --git a/src/api/recentlyPurchasedTariffs.ts b/src/api/recentlyPurchasedTariffs.ts index d154faa..39e9592 100644 --- a/src/api/recentlyPurchasedTariffs.ts +++ b/src/api/recentlyPurchasedTariffs.ts @@ -1,7 +1,7 @@ import makeRequest from "@api/makeRequest"; import { parseAxiosError } from "@root/utils/parse-error"; -const API_URL = `${process.env.REACT_APP_DOMAIN}/customer/v1.0.0`; +const API_URL = `${process.env.REACT_APP_DOMAIN}/customer/v1.0.1`; type GetRecentlyPurchasedTariffsResponse = { id: string; diff --git a/src/api/wallet.ts b/src/api/wallet.ts index dd25e4b..a2a037b 100644 --- a/src/api/wallet.ts +++ b/src/api/wallet.ts @@ -7,7 +7,7 @@ const isStaging = (() => { return host.includes("s") ? "s" : ""; })(); -const API_URL = `${process.env.REACT_APP_DOMAIN}/customer/v1.0.0`; +const API_URL = `${process.env.REACT_APP_DOMAIN}/customer/v1.0.1`; interface PaymentBody { type: string; diff --git a/src/index.tsx b/src/index.tsx index b0c6e67..7a60df8 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -79,7 +79,7 @@ const App = () => { }); useUserAccountFetcher({ - url: process.env.REACT_APP_DOMAIN + "/customer/v1.0.0/account", + url: process.env.REACT_APP_DOMAIN + "/customer/v1.0.1/account", userId, onNewUserAccount: setUserAccount, onError: (error) => { diff --git a/src/utils/hooks/usePipeSubscriber.ts b/src/utils/hooks/usePipeSubscriber.ts new file mode 100644 index 0000000..6e4da76 --- /dev/null +++ b/src/utils/hooks/usePipeSubscriber.ts @@ -0,0 +1,50 @@ +import { UserAccount, UserName, getAuthToken, useSSESubscription } from "@frontend/kitui" +import { useUserStore } from "@root/stores/user"; + +type Ping = [{ event: "ping" }] + +type SomeChange = [{ + "id": UserAccount["_id"], + "userId": UserAccount["userId"], + "cart": UserAccount["cart"], + "wallet": { + "cash": UserAccount["wallet"]["cash"], + "currency": UserAccount["wallet"]["currency"], + "spent": UserAccount["wallet"]["spent"], + "purchasesAmount": UserAccount["wallet"]["purchasesAmount"], + "money": UserAccount["wallet"]["money"], + "lastPaymentId": string; + }, + "name": UserName, + "status": UserAccount["status"], + "isDeleted": UserAccount["isDeleted"], + "createdAt": UserAccount["createdAt"]; + "updatedAt": UserAccount["updatedAt"]; + "from": string; + "partner": string; + }] + +type PipeMessage = Ping | SomeChange + +export const usePipeSubscriber = () => { + const token = getAuthToken(); + const userId = useUserStore((state) => state.userId); + + useSSESubscription({ + enabled: Boolean(token) && Boolean(userId), + url: + process.env.REACT_APP_DOMAIN + + `/customer/v1.0.1/account/pipe?Authorization=${token}`, + onNewData: (data) => { + let message = data as PipeMessage + //Пропускаем пингование + if ('event' in message[0] && message[0].event === "ping") return + + console.log("!pipe new message!:") + console.log(message) + console.log("произошёл мем") + + }, + marker: "pipe", + }); +} \ No newline at end of file From 479531c45f3901324e852220eb96e959279ddb33 Mon Sep 17 00:00:00 2001 From: Nastya Date: Thu, 25 Jul 2024 04:52:53 +0300 Subject: [PATCH 02/30] update kit && fix settings fields --- package.json | 2 +- src/index.tsx | 3 +++ src/pages/AccountSettings/AccountSettings.tsx | 6 ++++-- src/pages/AccountSettings/UserFields.tsx | 3 +++ src/stores/user.ts | 4 ++-- yarn.lock | 8 ++++---- 6 files changed, 17 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index aab76c0..fdbf799 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@emotion/react": "^11.10.5", "@emotion/styled": "^11.10.5", - "@frontend/kitui": "^1.0.82", + "@frontend/kitui": "^1.0.84", "@mui/icons-material": "^5.10.14", "@mui/material": "^5.10.14", "@popperjs/core": "^2.11.8", diff --git a/src/index.tsx b/src/index.tsx index 7a60df8..a20b291 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -56,6 +56,7 @@ import { verify } from "./pages/AccountSettings/helper"; import AfterPay from "./pages/AfterPay"; import { PageNotFound } from "./pages/PageNotFound"; import {setNotEnoughMoneyAmount} from "@stores/cart" +import { usePipeSubscriber } from "./utils/hooks/usePipeSubscriber"; pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.js`; @@ -93,6 +94,8 @@ const App = () => { }, }); + usePipeSubscriber() + verify(userId); if (location.state?.redirectTo) diff --git a/src/pages/AccountSettings/AccountSettings.tsx b/src/pages/AccountSettings/AccountSettings.tsx index 10a3649..567ee66 100644 --- a/src/pages/AccountSettings/AccountSettings.tsx +++ b/src/pages/AccountSettings/AccountSettings.tsx @@ -33,6 +33,8 @@ function AccountSettings() { const comment = useUserStore((state) => state.comment) const userId = useUserStore((state) => state.userId) ?? "" + console.log(user) + const [onChangeTypeLP, setOnChangeTypeLP] = useState("") const [readySend, setReadySend] = useState(false) @@ -51,10 +53,10 @@ function AccountSettings() { const type = onChangeTypeLP setOnChangeTypeLP("") setReadySend(false) - if (type === "email" && user?.email !== settingsFields.email.value) setSettingsField("email", user?.email || "") + if (type === "email" && user?.email !== settingsFields.email.value) setSettingsField("email", user?.email || user?.login || "") if (type === "password") setSettingsField("password", "") if (type === "all") { - setSettingsField("email", user?.email || "") + setSettingsField("email", user?.email || user?.login || "") setSettingsField("password", "") } } diff --git a/src/pages/AccountSettings/UserFields.tsx b/src/pages/AccountSettings/UserFields.tsx index 946d69d..8eaf572 100644 --- a/src/pages/AccountSettings/UserFields.tsx +++ b/src/pages/AccountSettings/UserFields.tsx @@ -19,7 +19,10 @@ export default function UserFields({ const upMd = useMediaQuery(theme.breakpoints.up("md")) const { settingsFields, user } = useUserStore((state) => state) + const a = useUserStore((state) => state) + console.log(a) + console.log(settingsFields) const textFieldProps = { gap: upMd ? "16px" : "10px", diff --git a/src/stores/user.ts b/src/stores/user.ts index ccd8835..63e4405 100644 --- a/src/stores/user.ts +++ b/src/stores/user.ts @@ -114,7 +114,7 @@ export const setUser = (user: User) => produce((state) => { state.user = user - state.settingsFields.email.value = user?.email ?? "" + state.settingsFields.email.value = user?.email || user?.login || "" state.settingsFields.phoneNumber.value = user?.phoneNumber ?? "" state.settingsFields.password.value = "" }) @@ -273,7 +273,7 @@ export const sendUserData = async () => { await Promise.all([ isPatchingUser && patchUser(userPayload).then(([user]) => user && setUser(user)), - isPatchingUserAccount && patchUserAccount(userAccountPayload).then(setUserAccount), + isPatchingUserAccount && patchUserAccount(userAccountPayload, "v1.0.1").then(setUserAccount), ]) } diff --git a/yarn.lock b/yarn.lock index bcb11a2..9853c78 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1626,10 +1626,10 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2" integrity sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q== -"@frontend/kitui@^1.0.82": - version "1.0.82" - resolved "https://penahub.gitlab.yandexcloud.net/api/v4/projects/21/packages/npm/@frontend/kitui/-/@frontend/kitui-1.0.82.tgz#696ab79a14357608c20bcdf47aadd5a77155f609" - integrity sha1-aWq3mhQ1dgjCC830eq3Vp3FV9gk= +"@frontend/kitui@^1.0.84": + version "1.0.84" + resolved "https://penahub.gitlab.yandexcloud.net/api/v4/projects/21/packages/npm/@frontend/kitui/-/@frontend/kitui-1.0.84.tgz#9b655b776433fb8ea6d0840897d941e66530df7f" + integrity sha1-m2Vbd2Qz+46m0IQIl9lB5mUw338= dependencies: immer "^10.0.2" reconnecting-eventsource "^1.6.2" From 74a28dfaabd58f02a1e4c9a160ae0fbcb6d53fe5 Mon Sep 17 00:00:00 2001 From: Nastya Date: Sun, 28 Jul 2024 03:17:16 +0300 Subject: [PATCH 03/30] =?UTF-8?q?pipe=20=D1=82=D1=80=D1=83=D0=B1=D0=B0=20?= =?UTF-8?q?=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D1=8F=D0=B5=D1=82=20=D1=81?= =?UTF-8?q?=D1=82=D0=BE=D1=80=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- src/model/auth.ts | 7 ++- src/stores/user.ts | 73 ++++++++++++++++------- src/utils/hooks/usePipeSubscriber.ts | 89 ++++++++++++++++------------ src/utils/hooks/useSSETab.ts | 1 + yarn.lock | 8 +-- 6 files changed, 111 insertions(+), 69 deletions(-) diff --git a/package.json b/package.json index fdbf799..34340cd 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@emotion/react": "^11.10.5", "@emotion/styled": "^11.10.5", - "@frontend/kitui": "^1.0.84", + "@frontend/kitui": "^1.0.85", "@mui/icons-material": "^5.10.14", "@mui/material": "^5.10.14", "@popperjs/core": "^2.11.8", diff --git a/src/model/auth.ts b/src/model/auth.ts index 0050435..fdcbdd6 100644 --- a/src/model/auth.ts +++ b/src/model/auth.ts @@ -1,4 +1,5 @@ import type { Attachment } from "@root/model/attachment" +import { UserAccount } from "@frontend/kitui" export type File = { name: "inn" | "rule" | "egrule" | "certificate"; @@ -8,21 +9,21 @@ export type File = { export interface Verification { _id: string; accepted: boolean; - status: "org" | "nko"; + status: UserAccount["status"]; updated_at: string; comment: string; files: File[]; } export type SendDocumentsArgs = { - status: "org" | "nko"; + status: UserAccount["status"]; inn: Attachment; rule: Attachment; certificate?: Attachment; }; export type UpdateDocumentsArgs = { - status: "org" | "nko"; + status: UserAccount["status"]; inn?: Attachment; rule?: Attachment; certificate?: Attachment; diff --git a/src/stores/user.ts b/src/stores/user.ts index 63e4405..7dfa1ac 100644 --- a/src/stores/user.ts +++ b/src/stores/user.ts @@ -17,18 +17,18 @@ import { User, UserAccount, UserName, getInitials, patchUserAccount } from "@fro import { setNotEnoughMoneyAmount } from "./cart"; interface UserStore { - userId: string | null; - user: User | null; - userAccount: UserAccount | null; - settingsFields: UserSettingsFieldStatus & UserAccountSettingsFieldStatus & { hasError: boolean }; - verificationStatus: VerificationStatus; - verificationType: "juridical" | "nko"; - isDocumentsDialogOpen: boolean; - dialogType: "juridical" | "nko" | ""; - documents: UserDocuments; - documentsUrl: UserDocumentsUrl; - comment: string; - initials: string; + userId: string | null; + user: User | null; + userAccount: UserAccount | null; + settingsFields: UserSettingsFieldStatus & UserAccountSettingsFieldStatus & { hasError: boolean }; + verificationStatus: VerificationStatus; + verificationType: "juridical" | "nko"; + isDocumentsDialogOpen: boolean; + dialogType: "juridical" | "nko" | ""; + documents: UserDocuments; + documentsUrl: UserDocumentsUrl; + comment: string; + initials: string; } const defaultFieldValues = { @@ -103,10 +103,22 @@ export const useUserStore = create()( export const setVerificationStatus = (verificationStatus: VerificationStatus) => useUserStore.setState({ verificationStatus }) -export const setVerificationType = (verificationType: "nko" | "org") => +export const setVerificationType = (verificationType: UserAccount["status"]) => useUserStore.setState({ verificationType: verificationType === "org" ? "juridical" : "nko", }) +export const setUserStatus = (status: UserAccount["status"]) => + useUserStore.setState( + produce((state) => { + if (state.userAccount !== null) state.userAccount.status = status + }) + ) +export const setWallet = (wallet: UserAccount["wallet"]) => + useUserStore.setState( + produce((state) => { + if (state.userAccount !== null) state.userAccount.wallet = wallet + }) + ) export const setUserId = (userId: string | null) => useUserStore.setState({ userId }) export const setUser = (user: User) => @@ -139,6 +151,21 @@ export const setUserAccount = (user: UserAccount) => } ) +export const setNewNames = (name: UserName) => + useUserStore.setState( + produce((state) => { + state.settingsFields.firstname.value = name.firstname ?? "" + state.settingsFields.secondname.value = name.secondname ?? "" + state.settingsFields.middlename.value = name.middlename ?? "" + state.settingsFields.orgname.value = name.orgname ?? "" + }), + false, + { + type: "setNewNames", + payload: name, + } + ) + export const setCart = (cart: string[]) => useUserStore.setState( produce((state) => { @@ -216,7 +243,7 @@ export const setUploadedDocument = (type: UserDocumentTypes, fileName: string, u }) ) -export const setSettingsField = (fieldName: UserSettingsField | keyof UserName, value: string) => +export const setSettingsField = (fieldName: UserSettingsField | keyof UserName, value: string) => useUserStore.setState( produce((state) => { if (!state.settingsFields) return @@ -247,15 +274,15 @@ export const sendUserData = async () => { if (!state.settingsFields) return const isPatchingUser = - state.settingsFields.email.touched || - state.settingsFields.password.touched || - state.settingsFields.phoneNumber.touched + state.settingsFields.email.touched || + state.settingsFields.password.touched || + state.settingsFields.phoneNumber.touched const isPatchingUserAccount = - state.settingsFields.firstname.touched || - state.settingsFields.secondname.touched || - state.settingsFields.middlename.touched || - state.settingsFields.orgname.touched + state.settingsFields.firstname.touched || + state.settingsFields.secondname.touched || + state.settingsFields.middlename.touched || + state.settingsFields.orgname.touched const userPayload: PatchUserRequest = {} @@ -283,11 +310,11 @@ export const addTariffToCart = async (tariffId: string) => { if (patchCartError === undefined) { setCart(patchCartResponse) } - return({patchCartResponse, patchCartError}) + return ({ patchCartResponse, patchCartError }) } export const removeTariffFromCart = async (tariffId: string) => { - setNotEnoughMoneyAmount(0); + setNotEnoughMoneyAmount(0); const [deleteCartResponse, deleteCartError] = await deleteCart(tariffId) if (!deleteCartError) { diff --git a/src/utils/hooks/usePipeSubscriber.ts b/src/utils/hooks/usePipeSubscriber.ts index 6e4da76..f584c1f 100644 --- a/src/utils/hooks/usePipeSubscriber.ts +++ b/src/utils/hooks/usePipeSubscriber.ts @@ -1,50 +1,63 @@ -import { UserAccount, UserName, getAuthToken, useSSESubscription } from "@frontend/kitui" -import { useUserStore } from "@root/stores/user"; +import { Ticket, UserAccount, UserName, getAuthToken, useSSESubscription } from "@frontend/kitui" +import { setCart, setNewNames, setUserStatus, setWallet, useUserStore } from "@root/stores/user"; +import { useSSETab } from "./useSSETab"; type Ping = [{ event: "ping" }] type SomeChange = [{ - "id": UserAccount["_id"], - "userId": UserAccount["userId"], - "cart": UserAccount["cart"], - "wallet": { - "cash": UserAccount["wallet"]["cash"], - "currency": UserAccount["wallet"]["currency"], - "spent": UserAccount["wallet"]["spent"], - "purchasesAmount": UserAccount["wallet"]["purchasesAmount"], - "money": UserAccount["wallet"]["money"], - "lastPaymentId": string; - }, - "name": UserName, - "status": UserAccount["status"], - "isDeleted": UserAccount["isDeleted"], - "createdAt": UserAccount["createdAt"]; - "updatedAt": UserAccount["updatedAt"]; - "from": string; - "partner": string; - }] + "id": UserAccount["_id"], + "userId": UserAccount["userId"], + "cart": UserAccount["cart"], + "wallet": { + "cash": UserAccount["wallet"]["cash"], + "currency": UserAccount["wallet"]["currency"], + "spent": UserAccount["wallet"]["spent"], + "purchasesAmount": UserAccount["wallet"]["purchasesAmount"], + "money": UserAccount["wallet"]["money"], + "lastPaymentId": string; + }, + "name": UserName, + "status": UserAccount["status"], + "isDeleted": UserAccount["isDeleted"], + "createdAt": UserAccount["createdAt"]; + "updatedAt": UserAccount["updatedAt"]; + "from": string; + "partner": string; +}] type PipeMessage = Ping | SomeChange export const usePipeSubscriber = () => { - const token = getAuthToken(); - const userId = useUserStore((state) => state.userId); + const token = getAuthToken(); + const userId = useUserStore((state) => state.userId); + const { isActiveSSETab, updateSSEValue } = useSSETab("pipe"); - useSSESubscription({ - enabled: Boolean(token) && Boolean(userId), - url: - process.env.REACT_APP_DOMAIN + - `/customer/v1.0.1/account/pipe?Authorization=${token}`, - onNewData: (data) => { - let message = data as PipeMessage - //Пропускаем пингование - if ('event' in message[0] && message[0].event === "ping") return + useSSESubscription({ + enabled: Boolean(token) && Boolean(userId) && isActiveSSETab, + url: + process.env.REACT_APP_DOMAIN + + `/customer/v1.0.1/account/pipe?Authorization=${token}`, + onNewData: (data) => { + let message = data[0] as PipeMessage + updateSSEValue(message) - console.log("!pipe new message!:") - console.log(message) - console.log("произошёл мем") + //Пропускаем пингование + if ('event' in message && message.event === "ping") return - }, - marker: "pipe", - }); + + if ('cart' in message) { + setCart(message.cart as string[]) + } + else if ('wallet' in message) { + setWallet(message.wallet as UserAccount["wallet"]) + } + else if ('name' in message) { + setNewNames(message.name as UserName) + } + else if ('status' in message) { + setUserStatus(message.status as UserAccount["status"]) + } + }, + marker: "pipe", + }); } \ No newline at end of file diff --git a/src/utils/hooks/useSSETab.ts b/src/utils/hooks/useSSETab.ts index 6ff9833..8f71636 100644 --- a/src/utils/hooks/useSSETab.ts +++ b/src/utils/hooks/useSSETab.ts @@ -74,6 +74,7 @@ export const useSSETab = ( }; const setOpenTime = () => { + //Время установлено - пропускаем if (openTimeSetted) { return; } diff --git a/yarn.lock b/yarn.lock index 9853c78..f98f0c0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1626,10 +1626,10 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2" integrity sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q== -"@frontend/kitui@^1.0.84": - version "1.0.84" - resolved "https://penahub.gitlab.yandexcloud.net/api/v4/projects/21/packages/npm/@frontend/kitui/-/@frontend/kitui-1.0.84.tgz#9b655b776433fb8ea6d0840897d941e66530df7f" - integrity sha1-m2Vbd2Qz+46m0IQIl9lB5mUw338= +"@frontend/kitui@^1.0.85": + version "1.0.85" + resolved "https://penahub.gitlab.yandexcloud.net/api/v4/projects/21/packages/npm/@frontend/kitui/-/@frontend/kitui-1.0.85.tgz#1a384c9ff3314175c1ba3d35d0979da7026a21ab" + integrity sha1-GjhMn/MxQXXBuj010JedpwJqIas= dependencies: immer "^10.0.2" reconnecting-eventsource "^1.6.2" From 434cd7f7ea0829823bfada6c82f62b713f0a667b Mon Sep 17 00:00:00 2001 From: Nastya Date: Mon, 29 Jul 2024 05:56:25 +0300 Subject: [PATCH 04/30] =?UTF-8?q?=D0=95=D0=B4=D0=B8=D0=BD=D1=8B=D0=B9=20?= =?UTF-8?q?=D1=81=D1=82=D0=BE=D1=80=20=D0=BD=D0=B5=D1=85=D0=B2=D0=B0=D1=82?= =?UTF-8?q?=D0=B0=D1=8E=D1=89=D0=B8=D1=85=20=D0=B4=D0=B5=D0=BD=D0=B5=D0=B3?= =?UTF-8?q?.=20=D0=9E=D0=BF=D1=82=D0=B8=D0=BC=D0=B8=D0=B7=D0=B0=D1=86?= =?UTF-8?q?=D0=B8=D1=8F=20=D0=B0=D0=B2=D1=82=D0=BE=D0=BF=D0=BE=D0=BA=D1=83?= =?UTF-8?q?=D0=BF=D0=BA=D0=B8=20=D1=81=20=D0=B8=D1=81=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=D0=BC=20pipe?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + src/api/makeRequest.ts | 2 +- src/api/wallet.ts | 6 +- src/components/CustomWrapperDrawer.tsx | 2 +- src/components/Drawers.tsx | 12 +- src/components/NavbarLanding/NavbarFull.tsx | 2 +- src/components/NavbarSite/DialogMenu.tsx | 2 +- src/components/NavbarSite/NavbarFull.tsx | 2 +- src/components/NavbarSite/NavbarPanel.tsx | 2 +- src/components/TotalPrice.tsx | 4 +- src/index.tsx | 30 ++- src/pages/AfterPay/index.tsx | 141 ++-------- src/pages/Payment/Payment.tsx | 272 +++++++++----------- src/pages/QuizPayment/QuizPayment.tsx | 2 +- src/stores/cart.ts | 22 -- src/stores/diffMoney.ts | 14 - src/stores/notEnoughMoneyAmount.ts | 27 ++ src/stores/user.ts | 7 +- src/utils/hooks/useAutoPay.ts | 41 +++ yarn.lock | 5 + 20 files changed, 256 insertions(+), 340 deletions(-) delete mode 100644 src/stores/cart.ts delete mode 100644 src/stores/diffMoney.ts create mode 100644 src/stores/notEnoughMoneyAmount.ts create mode 100644 src/utils/hooks/useAutoPay.ts diff --git a/package.json b/package.json index 34340cd..558caef 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "immer": "^10.0.2", "isomorphic-fetch": "^3.0.0", "js-big-decimal": "^2.0.7", + "moment": "^2.30.1", "notistack": "^3.0.1", "pdfjs-dist": "3.6.172", "react": "^18.2.0", diff --git a/src/api/makeRequest.ts b/src/api/makeRequest.ts index a356f5c..613e2df 100644 --- a/src/api/makeRequest.ts +++ b/src/api/makeRequest.ts @@ -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/cart"; +import { setNotEnoughMoneyAmount } from "@stores/notEnoughMoneyAmount"; interface MakeRequest { method?: Method | undefined; diff --git a/src/api/wallet.ts b/src/api/wallet.ts index a2a037b..a066f11 100644 --- a/src/api/wallet.ts +++ b/src/api/wallet.ts @@ -6,6 +6,10 @@ const isStaging = (() => { const host = window.location.hostname; return host.includes("s") ? "s" : ""; })(); +const isLocalhost = (() => { + const host = window.location.hostname; + return host.includes("localhost"); +})(); const API_URL = `${process.env.REACT_APP_DOMAIN}/customer/v1.0.1`; @@ -36,7 +40,7 @@ export const sendPayment = async ({ }, phoneNumber: "79000000000", login: "login_test", - returnUrl: `https://${isStaging}hub.pena.digital/afterpay?from=${ + returnUrl: `${isLocalhost ? "localhost:3000" : `https://${isStaging}hub.pena.digital`}/afterpay?from=${ fromSquiz ? "quiz" : "hub" }&purpose=${paymentPurpose}&userid=${userId}`, ...body, diff --git a/src/components/CustomWrapperDrawer.tsx b/src/components/CustomWrapperDrawer.tsx index 642b204..118a13e 100644 --- a/src/components/CustomWrapperDrawer.tsx +++ b/src/components/CustomWrapperDrawer.tsx @@ -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/cart"; +import { setNotEnoughMoneyAmount } from "@root/stores/notEnoughMoneyAmount"; const name: Record = { templategen: "Шаблонизатор", diff --git a/src/components/Drawers.tsx b/src/components/Drawers.tsx index 0a94792..0b34d73 100644 --- a/src/components/Drawers.tsx +++ b/src/components/Drawers.tsx @@ -19,8 +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, useCartStore } from "@root/stores/cart"; -import { useDiffMoney } from "@root/stores/diffMoney"; +import { setNotEnoughMoneyAmount, useNotEnoughMoneyAmount } from "@root/stores/notEnoughMoneyAmount"; function Drawers() { const [openNotificationsModal, setOpenNotificationsModal] = useState(false); @@ -35,8 +34,7 @@ function Drawers() { console.log("боковой cart", cart.priceAfterDiscounts) const userAccount = useUserStore((state) => state.userAccount); const tickets = useTicketStore((state) => state.tickets); - const notEnoughMoneyAmount = useCartStore(state => state.notEnoughMoneyAmount); - const { setNewDiff } = useDiffMoney() + const notEnoughMoneyAmount = useNotEnoughMoneyAmount(state => state.notEnoughMoneyAmount); const notificationsCount = tickets.filter( ({ user, top_message }) => user !== top_message.user_id && top_message.shown.me !== 1 @@ -69,10 +67,7 @@ function Drawers() { function handleReplenishWallet() { setIsDrawerOpen(false); - if (location.pathname.includes("/payment")) { - setNewDiff(notEnoughMoneyAmount) - } - navigate("/payment", { state: { notEnoughMoneyAmount } }); + navigate("/payment"); } return ( @@ -180,7 +175,6 @@ function Drawers() { { setIsDrawerOpen(false) - setNotEnoughMoneyAmount(0) }} sx={{ background: "rgba(0, 0, 0, 0.55)" }}> { const navigate = useNavigate(); diff --git a/src/components/TotalPrice.tsx b/src/components/TotalPrice.tsx index 3d2e3f9..91bbba8 100644 --- a/src/components/TotalPrice.tsx +++ b/src/components/TotalPrice.tsx @@ -8,7 +8,7 @@ import { Loader } from "./Loader"; import { currencyFormatter } from "@root/utils/currencyFormatter"; import { payCart } from "@root/api/cart"; import { setUserAccount } from "@root/stores/user"; -import { setNotEnoughMoneyAmount, useCartStore } from "@root/stores/cart"; +import { setNotEnoughMoneyAmount, useNotEnoughMoneyAmount } from "@root/stores/notEnoughMoneyAmount"; interface Props { priceBeforeDiscounts: number; @@ -19,7 +19,7 @@ interface Props { export default function TotalPrice({ priceAfterDiscounts, priceBeforeDiscounts, isConstructor = false }: Props) { const theme = useTheme(); const upMd = useMediaQuery(theme.breakpoints.up("md")); - const notEnoughMoneyAmount = useCartStore(state => state.notEnoughMoneyAmount); + const notEnoughMoneyAmount = useNotEnoughMoneyAmount(state => state.notEnoughMoneyAmount); const [loading, setLoading] = useState(false); const navigate = useNavigate(); diff --git a/src/index.tsx b/src/index.tsx index a20b291..a1c2df2 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useEffect } from "react"; import ReactDOM from "react-dom/client"; import { BrowserRouter, @@ -55,16 +55,20 @@ import OutdatedLink from "@root/pages/auth/OutdatedLink"; import { verify } from "./pages/AccountSettings/helper"; import AfterPay from "./pages/AfterPay"; import { PageNotFound } from "./pages/PageNotFound"; -import {setNotEnoughMoneyAmount} from "@stores/cart" +import { setNotEnoughMoneyAmount, useNotEnoughMoneyAmount } from "@stores/notEnoughMoneyAmount" import { usePipeSubscriber } from "./utils/hooks/usePipeSubscriber"; +import moment from "moment"; +import { payCart } from "./api/cart"; +import { useAfterPay } from "./utils/hooks/useAutoPay"; pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.js`; const App = () => { const location = useLocation(); - const userId = useUserStore((state) => state.userId); + const user = useUserStore(state => state.user); + const userId = useUserStore(state => state.userId); + const siteReadyPayCart = useNotEnoughMoneyAmount(state => state.siteReadyPayCart); const navigate = useNavigate(); - if(location.pathname !== "/cart"){setNotEnoughMoneyAmount(0)} useUserFetcher({ url: process.env.REACT_APP_DOMAIN + `/user/${userId}`, userId, @@ -98,6 +102,24 @@ const App = () => { verify(userId); + console.log(user) + console.log(userId) + console.log(siteReadyPayCart) + useAfterPay() + useEffect(() => { + if (userId !== null && siteReadyPayCart !== null && siteReadyPayCart[userId] !== undefined) { + const deadline = siteReadyPayCart[userId] + if (moment(deadline).isAfter(moment())) { + //Время ещё не вышло. У нас стоит флаг покупать корзину если время не вышло. + (async () => { + const [, payCartError] = await payCart(); + if (!payCartError) enqueueSnackbar("Товары успешно приобретены") + })() + + } + } + }, [user, userId, siteReadyPayCart]) + if (location.state?.redirectTo) return ( { - const [redirectUrl, setRedirectUrl] = useState("/"); - const theme = useTheme(); - const phone = useMediaQuery(theme.breakpoints.down(375)); - const userId = useUserStore((state) => state.user?._id); + const navigate = useNavigate(); const [searchParams] = useSearchParams(); - const paymentUserId = searchParams.get("userid"); - useEffect(() => { - const from = searchParams.get("from") || "hub"; - const purpose = searchParams.get("purpose"); + const userId = searchParams.get("userid"); + const from = searchParams.get("from") || "hub"; + const purpose = searchParams.get("purpose") - if (purpose === "paycart" || from !== "quiz") { - let tryCount = 0; + const host = window.location.hostname; + const domain = (host.includes("s") ? "s" : "") + from; + const pathname = from.includes("hub") ? "/tariffs" : "/list"; - if (userId !== paymentUserId) { - return; - } - - const payCartPendingRequestDeadline = localStorage.getItem( - "payCartPendingRequestDeadline" - ); - const deadline = payCartPendingRequestDeadline - ? Number(payCartPendingRequestDeadline) - : Date.now() + 20 * MINUTE; - - localStorage.setItem( - "payCartPendingRequestDeadline", - deadline.toString() - ); - - tryPayCart(); - - async function tryPayCart() { - tryCount += 1; - - - if (Date.now() > deadline) { - localStorage.removeItem("payCartPendingRequestDeadline"); - return; - } - - const [, payCartError] = await payCart(); - - if (!payCartError) { - localStorage.removeItem("payCartPendingRequestDeadline"); - return; - } - - setTimeout(tryPayCart, tryCount > 5 ? MINUTE : MINUTE / 6); - } - } - - const host = window.location.hostname; - const domain = (host.includes("s") ? "s" : "") + from; - const pathname = from === "hub" ? "/tariffs" : "/list"; - - setRedirectUrl( - `https://${domain}.pena.digital${pathname}?afterpay=${true}&userid=${userId}` - ); - }, []); - - return ( - - - - - Спасибо за оплату! - - - Ваш платеж принят и в течение 10 минут товары будут зачислены - - - - + navigate( + `https://${domain}.pena.digital${pathname}?purpose=${purpose}&userid=${userId}` ); + return null; }; diff --git a/src/pages/Payment/Payment.tsx b/src/pages/Payment/Payment.tsx index 88bb214..20dfd85 100644 --- a/src/pages/Payment/Payment.tsx +++ b/src/pages/Payment/Payment.tsx @@ -32,8 +32,7 @@ import PaymentMethodCard from "./PaymentMethodCard"; import { SorryModal } from "./SorryModal"; import { WarnModal } from "./WarnModal"; import { mutate } from "swr"; -import { useCartStore } from "@root/stores/cart"; -import { useDiffMoney } from "@root/stores/diffMoney"; +import { useNotEnoughMoneyAmount } from "@root/stores/notEnoughMoneyAmount"; type PaymentMethod = { label: string; @@ -55,119 +54,122 @@ type PaymentMethodType = (typeof paymentMethods)[number]["name"]; export default function Payment() { const theme = useTheme(); - 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(""); - const [selectedPaymentMethod, setSelectedPaymentMethod] = - useState(""); - const [warnModalOpen, setWarnModalOpen] = useState(false); - const [sorryModalOpen, setSorryModalOpen] = useState(false); - const [paymentValueField, setPaymentValueField] = useState("0"); - const [paymentLink, setPaymentLink] = useState(""); - const [fromSquiz, setIsFromSquiz] = useState(false); const location = useLocation(); - console.log("location", location); - console.log("location", location.state); - const verificationStatus = useUserStore((state) => state.verificationStatus); - const userId = useUserStore((state) => state.userId); const navigate = useNavigate(); const handleCustomBackNavigation = useHistoryTracker(); - const {diffMoney, setNewDiff} = useDiffMoney() + const userId = useUserStore((state) => state.userId); + const verificationStatus = useUserStore((state) => state.verificationStatus); - const notEnoughMoneyAmount = - (location.state?.notEnoughMoneyAmount as number) ?? 0; + 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(""); + const [selectedPaymentMethod, setSelectedPaymentMethod] = useState(""); + const [paymentValueField, setPaymentValueField] = useState("0"); + + const [fromSquiz, setIsFromSquiz] = useState(false); + + + + const [warnModalOpen, setWarnModalOpen] = useState(false); + const [sorryModalOpen, setSorryModalOpen] = useState(false); + + const notEnoughMoneyAmount = useNotEnoughMoneyAmount(state => state.notEnoughMoneyAmount) + console.log("notEnoughMoneyAmount notEnoughMoneyAmount notEnoughMoneyAmount notEnoughMoneyAmount notEnoughMoneyAmount ") + console.log(notEnoughMoneyAmount) const paymentValue = parseFloat( bigDecimal.multiply(parseFloat(paymentValueField), 100) ); - useEffect(() => { - console.log(diffMoney) - if (diffMoney > 0) { - setNewDiff(0) - setPaymentValueField((diffMoney / 100).toString()) - } - }, [diffMoney]) + //Тут записываем начальную сумму в инпут + useEffect(() => { + setPaymentValueField((notEnoughMoneyAmount / 100).toString());//Сколько нехватило на хабе + }, [notEnoughMoneyAmount]) useLayoutEffect(() => { - setPaymentValueField((notEnoughMoneyAmount / 100).toString()); + //Предустановленное значение - это либо 0, либо сколько нам нехватило на хабе, либо сколько нам нехватило на квизе const params = new URLSearchParams(window.location.search); const fromSquiz = params.get("action"); if (fromSquiz === "squizpay") { setIsFromSquiz(true); - setPaymentValueField((Number(params.get("dif") || "0") / 100).toString()); + setPaymentValueField((Number(params.get("dif") || "0") / 100).toString());//Сколько нехватило на квизе } + //Принимаем параметры из странички и очищаем url адрес до красивого состояния navigate(`/payment`, { replace: true, }); - }, [ ]); - - async function handleChoosePaymentClick() { - if (!selectedPaymentMethod) { - enqueueSnackbar("Введите метод оплаты"); - return; - } + }, []); + const handlePaymentClick = () => { if (Number(paymentValueField) === 0) { enqueueSnackbar("Введите сумму"); return; } - - if (selectedPaymentMethod !== "rspay") { - const [sendPaymentResponse, sendPaymentError] = await sendPayment({ - userId: userId ?? "", - fromSquiz, - body: { - type: selectedPaymentMethod, - amount: Number( - bigDecimal.floor( - bigDecimal.multiply(Number(paymentValueField), 100) - ) - ), - }, - paymentPurpose: notEnoughMoneyAmount ? "paycart" : "replenishwallet", - }); - - if (sendPaymentError) { - return enqueueSnackbar(sendPaymentError); - } - - if (sendPaymentResponse) { - setPaymentLink(sendPaymentResponse.link); - } - - return; - } else { - if (verificationStatus !== VerificationStatus.VERIFICATED) { - setWarnModalOpen(true); - - return; - } - + if (selectedPaymentMethod === "rspay") { if (Number(paymentValueField) < 900) { enqueueSnackbar("Минимальная сумма 900р"); - return; } - - const [sendRSPaymentResponse] = await sendRSPayment( - Number(paymentValueField) - ); - - if (sendRSPaymentResponse) { - return enqueueSnackbar(sendRSPaymentResponse); + if (verificationStatus !== VerificationStatus.VERIFICATED) { + setWarnModalOpen(true); + return; } - - enqueueSnackbar( - "Cпасибо за заявку, в течении 24 часов вам будет выставлен счёт для оплаты услуг." - ); - - navigate("/settings"); + startPayRS() + } else { + startPayCard() } } + const startPayRS = async () => { + const [sendRSPaymentResponse] = await sendRSPayment( + Number(paymentValueField) + ); + + if (sendRSPaymentResponse) { + return enqueueSnackbar(sendRSPaymentResponse); + } + + enqueueSnackbar( + "Cпасибо за заявку, в течении 24 часов вам будет выставлен счёт для оплаты услуг." + ); + + navigate("/settings"); + } + + const startPayCard = async () => { + + if (!selectedPaymentMethod) { + enqueueSnackbar("Введите метод оплаты"); + return + } + const [sendPaymentResponse, sendPaymentError] = await sendPayment({ + userId: userId ?? "", + fromSquiz, + body: { + type: selectedPaymentMethod, + amount: Number( + bigDecimal.floor( + bigDecimal.multiply(Number(paymentValueField), 100) + ) + ), + }, + paymentPurpose: notEnoughMoneyAmount ? "paycart" : "replenishwallet", + }); + + if (sendPaymentError) { + return enqueueSnackbar(sendPaymentError); + } + + //Произошёл запрос на пополнение счёта. Нам вернули ссылку для перехода на страницу пополнения. + if (sendPaymentResponse) { + document.location.href = sendPaymentResponse.link; + } + } + + async function handleApplyPromocode() { if (!promocodeField) return; @@ -250,7 +252,6 @@ export default function Payment() { image={image} onClick={() => { setSelectedPaymentMethod(name); - setPaymentLink(""); }} unpopular={false} /> @@ -261,7 +262,6 @@ export default function Payment() { image={rsPayLogo} onClick={async () => { setSelectedPaymentMethod("rspay"); - setPaymentLink(""); }} unpopular={false} /> @@ -297,76 +297,42 @@ export default function Payment() { > {upMd && Выберите способ оплаты} К оплате - {paymentLink ? ( - - {currencyFormatter.format( - Number(bigDecimal.divide(bigDecimal.floor(paymentValue), 100)) - )} - - ) : ( - { - const value = parseFloat( - e.target.value.replace(/^0+(?=\d\.)/, "") - ); - setPaymentValueField(isNaN(value) ? "" : value.toString()); - }} - id="payment-amount" - gap={upMd ? "16px" : "10px"} - color={"#F2F3F7"} - FormInputSx={{ mb: "28px" }} - /> - )} + { + const value = parseFloat( + e.target.value.replace(/^0+(?=\d\.)/, "") + ); + setPaymentValueField(isNaN(value) ? "" : value.toString()); + }} + id="payment-amount" + gap={upMd ? "16px" : "10px"} + color={"#F2F3F7"} + FormInputSx={{ mb: "28px" }} + /> - {paymentLink ? ( - - ) : ( - - )} + diff --git a/src/pages/QuizPayment/QuizPayment.tsx b/src/pages/QuizPayment/QuizPayment.tsx index db853eb..4855813 100644 --- a/src/pages/QuizPayment/QuizPayment.tsx +++ b/src/pages/QuizPayment/QuizPayment.tsx @@ -19,7 +19,7 @@ import { import { logout } from "@root/api/auth"; import { clearCustomTariffs } from "@root/stores/customTariffs"; import { clearTickets } from "@root/stores/tickets"; -import {setNotEnoughMoneyAmount} from "@stores/cart" +import {setNotEnoughMoneyAmount} from "@stores/notEnoughMoneyAmount" const params = new URLSearchParams(window.location.search); const action = params.get("action"); diff --git a/src/stores/cart.ts b/src/stores/cart.ts deleted file mode 100644 index 0a6b120..0000000 --- a/src/stores/cart.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { create } from "zustand"; -import { devtools } from "zustand/middleware"; - -interface CartStore { - notEnoughMoneyAmount: number; -} - -export const useCartStore = create()( - devtools( - (get, set) => ({ - notEnoughMoneyAmount: 0, - }), - { - name: "Cart", - enabled: process.env.NODE_ENV === "development", - trace: true, - actionsBlacklist: "rejected", - } - ) -); - -export const setNotEnoughMoneyAmount = (amount: number) => useCartStore.setState({ notEnoughMoneyAmount: amount }); diff --git a/src/stores/diffMoney.ts b/src/stores/diffMoney.ts deleted file mode 100644 index 2e3a49a..0000000 --- a/src/stores/diffMoney.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { HistoryRecord, HistoryRecord2 } from "@root/api/history"; -import { create } from "zustand"; -import { devtools, persist } from "zustand/middleware"; - - -type DiffMoneyType = { - diffMoney: number; - setNewDiff: (diff: number) => void -}; - -export const useDiffMoney = create((set) => ({ - diffMoney: 0, - setNewDiff: (diff: number) => set({diffMoney: diff}) - })); diff --git a/src/stores/notEnoughMoneyAmount.ts b/src/stores/notEnoughMoneyAmount.ts new file mode 100644 index 0000000..f8de0a1 --- /dev/null +++ b/src/stores/notEnoughMoneyAmount.ts @@ -0,0 +1,27 @@ +import { create } from "zustand"; +import { devtools } from "zustand/middleware"; + +interface CartStore { + notEnoughMoneyAmount: number; + siteReadyPayCart: Record | null; +} +const initialState: CartStore = { + notEnoughMoneyAmount: 0, + siteReadyPayCart: null +} + +//Была попытка оплатить корзину. Тут записанна недостающая сумма. +export const useNotEnoughMoneyAmount = create()( + 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 | null) => useNotEnoughMoneyAmount.setState({ siteReadyPayCart: flag }); diff --git a/src/stores/user.ts b/src/stores/user.ts index 7dfa1ac..a561afa 100644 --- a/src/stores/user.ts +++ b/src/stores/user.ts @@ -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 { setNotEnoughMoneyAmount } from "./cart"; +import { setNotEnoughMoneyAmount, setSiteReadyPayCart } from "./notEnoughMoneyAmount"; interface UserStore { userId: string | null; @@ -169,7 +169,10 @@ export const setNewNames = (name: UserName) => export const setCart = (cart: string[]) => useUserStore.setState( produce((state) => { - if (state.userAccount) state.userAccount.cart = cart + if (state.userAccount) { + state.userAccount.cart = cart + setSiteReadyPayCart(null) + } }) ) diff --git a/src/utils/hooks/useAutoPay.ts b/src/utils/hooks/useAutoPay.ts new file mode 100644 index 0000000..77a6163 --- /dev/null +++ b/src/utils/hooks/useAutoPay.ts @@ -0,0 +1,41 @@ +import { payCart } from "@root/api/cart"; +import { setSiteReadyPayCart } from "@root/stores/notEnoughMoneyAmount"; +import { useUserStore } from "@root/stores/user"; +import moment from "moment"; +import { enqueueSnackbar } from "notistack"; +import { useEffect } from "react"; +import { useNavigate, useSearchParams } from "react-router-dom"; + +export const useAfterPay = () => { + const navigate = useNavigate(); + const [searchParams, setSearchParams] = useSearchParams(); + const paymentUserId = searchParams.get("userid"); + const userId = useUserStore(store => store.userId) + + const purpose = searchParams.get("purpose"); + const from = searchParams.get("from") || "hub"; + + useEffect(() => { + //Звёзды сошлись, будем оплачивать корзину + if (from !== "quiz" && paymentUserId && paymentUserId === userId) { + //Чистим url адрес от параметров + navigate(`/tariffs`, { + replace: true, + }); + if (purpose === "paycart") { + (async () => { + + //Проверяем можем ли мы оплатить корзину здесь и сейчас + const [, payCartError] = await payCart(); + + if (payCartError) { + //Не получилось купить корзину. Ставим флаг, что сайт в состоянии ожидания пополнения счёта для оплаты (потом проверим .isAfter) + setSiteReadyPayCart({ [paymentUserId]: moment().add(20, 'minutes').format("x") }) + } else { + enqueueSnackbar("Товары успешно приобретены") + } + })() + } + } + }, [purpose, from, paymentUserId]) +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index f98f0c0..b1c11d4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8912,6 +8912,11 @@ mlly@^1.2.0, mlly@^1.4.2: pkg-types "^1.0.3" ufo "^1.3.2" +moment@^2.30.1: + version "2.30.1" + resolved "https://registry.yarnpkg.com/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" From 0b4c22e6712d098c7fdfb4bb9b5a7f8bdeb212f1 Mon Sep 17 00:00:00 2001 From: Nastya Date: Mon, 29 Jul 2024 06:42:54 +0300 Subject: [PATCH 05/30] =?UTF-8?q?fix=20=D0=B0=D0=B2=D1=82=D0=BE=D0=BF?= =?UTF-8?q?=D0=BE=D0=BA=D1=83=D0=BF=D0=BA=D0=B0=20=D0=BD=D0=B5=20=D0=BA?= =?UTF-8?q?=D0=BE=D0=BD=D1=84=D0=BB=D0=B8=D0=BA=D1=82=D1=83=D0=B5=D1=82=20?= =?UTF-8?q?=D1=81=20=D0=BF=D0=B5=D1=80=D0=B5=D1=85=D0=BE=D0=B4=D0=BE=D0=BC?= =?UTF-8?q?=20=D0=B8=D0=B7=20=D0=BA=D0=B2=D0=B8=D0=B7=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/utils/hooks/useAutoPay.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/utils/hooks/useAutoPay.ts b/src/utils/hooks/useAutoPay.ts index 77a6163..2614437 100644 --- a/src/utils/hooks/useAutoPay.ts +++ b/src/utils/hooks/useAutoPay.ts @@ -14,12 +14,13 @@ export const useAfterPay = () => { const purpose = searchParams.get("purpose"); const from = searchParams.get("from") || "hub"; + const action = searchParams.get("action"); useEffect(() => { //Звёзды сошлись, будем оплачивать корзину if (from !== "quiz" && paymentUserId && paymentUserId === userId) { - //Чистим url адрес от параметров - navigate(`/tariffs`, { + //Чистим url адрес от параметров. (Если нет action. Если есть - значит мы пришли из квиза) + if (action === null) navigate(`/tariffs`, { replace: true, }); if (purpose === "paycart") { From 6c865aaf5dddffc284ee97fbe7802fc9f0a24585 Mon Sep 17 00:00:00 2001 From: Nastya Date: Mon, 29 Jul 2024 07:06:40 +0300 Subject: [PATCH 06/30] fix --- src/pages/AfterPay/index.tsx | 7 ++++--- src/pages/Payment/Payment.tsx | 6 +++--- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/pages/AfterPay/index.tsx b/src/pages/AfterPay/index.tsx index 264f056..f257daf 100644 --- a/src/pages/AfterPay/index.tsx +++ b/src/pages/AfterPay/index.tsx @@ -17,8 +17,9 @@ export default () => { const domain = (host.includes("s") ? "s" : "") + from; const pathname = from.includes("hub") ? "/tariffs" : "/list"; - navigate( - `https://${domain}.pena.digital${pathname}?purpose=${purpose}&userid=${userId}` - ); + console.log(from, " from") + console.log(`https://${domain}.pena.digital${pathname}?purpose=${purpose}&userid=${userId}`) + + document.location.href = `https://${domain}.pena.digital${pathname}?purpose=${purpose}&userid=${userId}` return null; }; diff --git a/src/pages/Payment/Payment.tsx b/src/pages/Payment/Payment.tsx index 20dfd85..cc15371 100644 --- a/src/pages/Payment/Payment.tsx +++ b/src/pages/Payment/Payment.tsx @@ -32,7 +32,7 @@ import PaymentMethodCard from "./PaymentMethodCard"; import { SorryModal } from "./SorryModal"; import { WarnModal } from "./WarnModal"; import { mutate } from "swr"; -import { useNotEnoughMoneyAmount } from "@root/stores/notEnoughMoneyAmount"; +import { setNotEnoughMoneyAmount, useNotEnoughMoneyAmount } from "@root/stores/notEnoughMoneyAmount"; type PaymentMethod = { label: string; @@ -95,14 +95,14 @@ export default function Payment() { const fromSquiz = params.get("action"); if (fromSquiz === "squizpay") { setIsFromSquiz(true); - setPaymentValueField((Number(params.get("dif") || "0") / 100).toString());//Сколько нехватило на квизе + setNotEnoughMoneyAmount(Number(params.get("dif") || 0));//Сколько нехватило на квизе } //Принимаем параметры из странички и очищаем 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) { enqueueSnackbar("Введите сумму"); From 4ad6a64ccbbe4f83be687abf4b64af5330119666 Mon Sep 17 00:00:00 2001 From: Nastya Date: Fri, 2 Aug 2024 16:04:19 +0300 Subject: [PATCH 07/30] =?UTF-8?q?=D0=BB=D0=BE=D0=B3=D0=B8=D0=BA=D0=B0=20?= =?UTF-8?q?=D1=81=D0=BE=D1=81=D1=82=D0=BE=D1=8F=D0=BD=D0=B8=D1=8F=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=BA=D1=83=D0=BF=D0=BA=D0=B8=20=D1=81=D0=B0=D0=B9=D1=82?= =?UTF-8?q?=D0=B0=20=D0=B2=D1=8B=D0=BD=D0=B5=D1=81=D0=B5=D0=BD=D0=B0=20?= =?UTF-8?q?=D0=B2=20=D1=81=D1=82=D0=BE=D1=80=20=D0=B2=202=20=D0=BF=D0=BE?= =?UTF-8?q?=D0=BB=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Drawers.tsx | 8 ++- src/components/TotalPrice.tsx | 6 ++- src/index.tsx | 26 +++------- src/pages/AfterPay/index.tsx | 4 +- src/pages/Payment/Payment.tsx | 77 +++++++++++++++++++--------- src/stores/notEnoughMoneyAmount.ts | 11 ++++ src/stores/user.ts | 10 ++-- src/utils/hooks/useAutoPay.ts | 42 ++++++++++++--- src/utils/hooks/usePipeSubscriber.ts | 3 ++ 9 files changed, 128 insertions(+), 59 deletions(-) diff --git a/src/components/Drawers.tsx b/src/components/Drawers.tsx index 0b34d73..499f192 100644 --- a/src/components/Drawers.tsx +++ b/src/components/Drawers.tsx @@ -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, useNotEnoughMoneyAmount } from "@root/stores/notEnoughMoneyAmount"; +import { setNotEnoughMoneyAmount, startPayCartProcess, useNotEnoughMoneyAmount } from "@root/stores/notEnoughMoneyAmount"; function Drawers() { const [openNotificationsModal, setOpenNotificationsModal] = useState(false); @@ -33,8 +33,10 @@ function Drawers() { const cart = useCart(); console.log("боковой cart", cart.priceAfterDiscounts) 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 notificationsCount = tickets.filter( ({ user, top_message }) => user !== top_message.user_id && top_message.shown.me !== 1 @@ -49,6 +51,7 @@ function Drawers() { if (payCartError.includes("insufficient funds: ")) { const notEnoughMoneyAmount = parseInt(payCartError.replace(/^.*insufficient\sfunds:\s(?=\d+$)/, "")); setNotEnoughMoneyAmount(notEnoughMoneyAmount); + startPayCartProcess(userId) } setLoading(false); @@ -67,6 +70,7 @@ function Drawers() { function handleReplenishWallet() { setIsDrawerOpen(false); + if (siteReadyPayCart === null) startPayCartProcess(userId) navigate("/payment"); } @@ -242,7 +246,7 @@ function Drawers() { Здесь написана окончательная стоимость всех услуг сложенных в корзину с учётом всех скидок. - После нажатия кнопки оплатить, вы будете перенаправлены на форму оплаты, для оплаты ВСЕЙ корзины (рекомендуем перед оплатой, убрать все лишнее) + После нажатия кнопки оплатить (пополнить), вы будете перенаправлены на форму оплаты, для оплаты ВСЕЙ корзины (рекомендуем перед оплатой, убрать все лишнее) state.notEnoughMoneyAmount); + const userId = useUserStore(store => store.userId) || "" const [loading, setLoading] = useState(false); const navigate = useNavigate(); @@ -48,6 +49,7 @@ export default function TotalPrice({ priceAfterDiscounts, priceBeforeDiscounts, } function handleReplenishWallet() { + startPayCartProcess(userId) navigate("/payment", { state: { notEnoughMoneyAmount } }); } diff --git a/src/index.tsx b/src/index.tsx index a1c2df2..65168da 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -55,7 +55,7 @@ import OutdatedLink from "@root/pages/auth/OutdatedLink"; import { verify } from "./pages/AccountSettings/helper"; import AfterPay from "./pages/AfterPay"; import { PageNotFound } from "./pages/PageNotFound"; -import { setNotEnoughMoneyAmount, useNotEnoughMoneyAmount } from "@stores/notEnoughMoneyAmount" +import { setSiteReadyPayCart, useNotEnoughMoneyAmount } from "@stores/notEnoughMoneyAmount" import { usePipeSubscriber } from "./utils/hooks/usePipeSubscriber"; import moment from "moment"; import { payCart } from "./api/cart"; @@ -66,6 +66,7 @@ pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/b const App = () => { const location = useLocation(); const user = useUserStore(state => state.user); + const userAccount = useUserStore(state => state.userAccount); const userId = useUserStore(state => state.userId); const siteReadyPayCart = useNotEnoughMoneyAmount(state => state.siteReadyPayCart); const navigate = useNavigate(); @@ -102,23 +103,12 @@ const App = () => { verify(userId); - console.log(user) - console.log(userId) - console.log(siteReadyPayCart) - useAfterPay() - useEffect(() => { - if (userId !== null && siteReadyPayCart !== null && siteReadyPayCart[userId] !== undefined) { - const deadline = siteReadyPayCart[userId] - if (moment(deadline).isAfter(moment())) { - //Время ещё не вышло. У нас стоит флаг покупать корзину если время не вышло. - (async () => { - const [, payCartError] = await payCart(); - if (!payCartError) enqueueSnackbar("Товары успешно приобретены") - })() - - } - } - }, [user, userId, siteReadyPayCart]) + console.log(userAccount) + console.log(userId) + console.log(siteReadyPayCart) + + useAfterPay() + if (location.state?.redirectTo) return ( diff --git a/src/pages/AfterPay/index.tsx b/src/pages/AfterPay/index.tsx index f257daf..e37defe 100644 --- a/src/pages/AfterPay/index.tsx +++ b/src/pages/AfterPay/index.tsx @@ -2,7 +2,7 @@ import { useNavigate, useSearchParams } from "react-router-dom"; //Раньше эта страничка благодарила за покупку и перенаправляла сталкера своей дорогой. -//Чтобы не мелькать хабом перед перенаправлением на другие домены - логика останется на отдельном url адресе +//Чтобы не мелькать хабом перед перенаправлением на другие домены - логика останется на этом отдельном url адресе //Эта страничка ТОЛЬКО перенаправляет на нужный адрес. Процесс автопокупки после пополнения лежит на хуке useAutoPay export default () => { @@ -21,5 +21,5 @@ export default () => { console.log(`https://${domain}.pena.digital${pathname}?purpose=${purpose}&userid=${userId}`) document.location.href = `https://${domain}.pena.digital${pathname}?purpose=${purpose}&userid=${userId}` - return null; + return <>; }; diff --git a/src/pages/Payment/Payment.tsx b/src/pages/Payment/Payment.tsx index cc15371..4425c13 100644 --- a/src/pages/Payment/Payment.tsx +++ b/src/pages/Payment/Payment.tsx @@ -32,7 +32,7 @@ import PaymentMethodCard from "./PaymentMethodCard"; import { SorryModal } from "./SorryModal"; import { WarnModal } from "./WarnModal"; import { mutate } from "swr"; -import { setNotEnoughMoneyAmount, useNotEnoughMoneyAmount } from "@root/stores/notEnoughMoneyAmount"; +import { calcTimeOfReadyPayCart, cancelPayCartProcess, setNotEnoughMoneyAmount, useNotEnoughMoneyAmount } from "@root/stores/notEnoughMoneyAmount"; type PaymentMethod = { label: string; @@ -58,7 +58,7 @@ export default function Payment() { const navigate = useNavigate(); const handleCustomBackNavigation = useHistoryTracker(); - const userId = useUserStore((state) => state.userId); + const userId = useUserStore((state) => state.userId) || ""; const verificationStatus = useUserStore((state) => state.verificationStatus); const upMd = useMediaQuery(theme.breakpoints.up("md")); @@ -77,17 +77,29 @@ export default function Payment() { const [sorryModalOpen, setSorryModalOpen] = useState(false); const notEnoughMoneyAmount = useNotEnoughMoneyAmount(state => state.notEnoughMoneyAmount) - console.log("notEnoughMoneyAmount notEnoughMoneyAmount notEnoughMoneyAmount notEnoughMoneyAmount notEnoughMoneyAmount ") - console.log(notEnoughMoneyAmount) + const siteReadyPayCart = useNotEnoughMoneyAmount(state => state.siteReadyPayCart) const paymentValue = parseFloat( bigDecimal.multiply(parseFloat(paymentValueField), 100) ); - //Тут записываем начальную сумму в инпут + //Отмена состояния сайта "в процессе покупки корзины, просто нехватило деняк" useEffect(() => { - setPaymentValueField((notEnoughMoneyAmount / 100).toString());//Сколько нехватило на хабе - }, [notEnoughMoneyAmount]) + return () => { + //При выходе со страницы оплаты мы точно не в состоянии покупки корзины + cancelPayCartProcess() + } + }, []) + + console.log(siteReadyPayCart) + console.log(notEnoughMoneyAmount) + //Тут записываем начальную сумму в инпут (если стоит флаг что мы в процессе покупки) + useEffect(() => { + console.log(siteReadyPayCart) + console.log(notEnoughMoneyAmount) + if (siteReadyPayCart !== null && siteReadyPayCart[userId] !== undefined && calcTimeOfReadyPayCart(siteReadyPayCart[userId])) + setPaymentValueField((notEnoughMoneyAmount / 100).toString());//Сколько нехватило на хабе + }, [notEnoughMoneyAmount, siteReadyPayCart]) useLayoutEffect(() => { //Предустановленное значение - это либо 0, либо сколько нам нехватило на хабе, либо сколько нам нехватило на квизе @@ -297,23 +309,40 @@ export default function Payment() { > {upMd && Выберите способ оплаты} К оплате - { - const value = parseFloat( - e.target.value.replace(/^0+(?=\d\.)/, "") - ); - setPaymentValueField(isNaN(value) ? "" : value.toString()); - }} - id="payment-amount" - gap={upMd ? "16px" : "10px"} - color={"#F2F3F7"} - FormInputSx={{ mb: "28px" }} - /> + { + siteReadyPayCart?.[userId] && notEnoughMoneyAmount > 0 ? + + {currencyFormatter.format( + Number(bigDecimal.divide(bigDecimal.floor(paymentValue), 100)) + )} + + : + { + const value = parseFloat( + e.target.value.replace(/^0+(?=\d\.)/, "") + ); + setPaymentValueField(isNaN(value) ? "" : value.toString()); + }} + id="payment-amount" + gap={upMd ? "16px" : "10px"} + color={"#F2F3F7"} + FormInputSx={{ mb: "28px" }} + /> + } + + + + + ) + return ( + + + + + + Заполните форму, чтобы оставить заявку на создание квиза + + + + + + + + { + if (values.contact.length < 8) return enqueueSnackbar("Пожалуйста, оставьте контактные данные") + const resp = await sendContactFormRequest({ + contact: values.contact, + whoami: JSON.stringify({ + dogiebusiness: values.dogiebusiness, + imagination: values.imagination, + name: values.name, + time: moment(values.time).format("hh:mm") + }) + }) + console.log(resp) + //@ts-ignore + if (resp[0]?.status === 200) { + enqueueSnackbar("Запрос успешно отправлен") + setIsSending(true) + } + if (resp[1]) { + //@ts-ignore + enqueueSnackbar(resp[1]) + } + }} + > + {({ values, isSubmitting, setFieldValue }) => (<> +
+ setFieldValue("name", target.value)} + + /> + setFieldValue("dogiebusiness", target.value)} + + /> + setFieldValue("contact", target.value)} + desc="(Telegram, WhatsApp, номер телефона)" + /> + setFieldValue("imagination", target.value)} + rows={2} + /> + + + Во сколько вам можно позвонить? + Москва (GMT+3) + + setFieldValue("time", e)} + ampm={false} + value={values.time} + views={['hours', 'minutes']} format="hh:mm" + /> + + + + + + + + + )} +
+
+
+
+ ) +} diff --git a/src/pages/Tariffs/TariffsPage.tsx b/src/pages/Tariffs/TariffsPage.tsx index 6ce564b..537c21a 100644 --- a/src/pages/Tariffs/TariffsPage.tsx +++ b/src/pages/Tariffs/TariffsPage.tsx @@ -29,7 +29,8 @@ import { useDiscounts } from "@root/api/price"; import { Select } from "@components/Select"; import { Tabs } from "@components/Tabs"; -const subPages = ["Базовый тариф PenaQuiz", 'Убрать логотип "PenaQuiz"']; +const subPagesTime = ["Базовый тариф PenaQuiz", 'Убрать логотип "PenaQuiz"']; +const subPagesVolume = ["Заявки quiz", 'Заказать создание quiz']; const StepperText: Record = { volume: "Тарифы на объём", @@ -43,7 +44,8 @@ function TariffPage() { const isTablet = useMediaQuery(theme.breakpoints.down(1000)); const location = useLocation(); const tariffs = useTariffStore((state) => state.tariffs); - const [selectedItem, setSelectedItem] = useState(0); + const [selectedItemTime, setSelectedItemTime] = useState(0); + const [selectedItemVolume, setSelectedItemVolume] = useState(0); const purchasesAmount = useUserStore((state) => state.userAccount?.wallet.spent) ?? 0; const userId = useUserStore((state) => state.user?._id) ?? ""; @@ -68,25 +70,14 @@ function TariffPage() { } const filteredTariffs = tariffs.filter((tariff) => { - if (tariff.privileges[0] === undefined) return false; - if ( - (tariff.privileges[0].type === "day") === (unit === "time") && - !tariff.isDeleted && - !tariff.isCustom - ) { - if ( - ((selectedItem === 0 && unit === "time") || unit !== "time") && - tariff.privileges[0].serviceKey === "squiz" && - tariff.privileges[0].privilegeId !== "squizHideBadge" - ) - return true; + if (tariff.privileges[0] === undefined || tariff.isDeleted || tariff.isCustom) return false; + if (unit === "time") { + if (selectedItemTime === 0 && tariff.privileges[0].privilegeId === "quizUnlimTime") return true + if (selectedItemTime === 1 && tariff.privileges[0].privilegeId === "squizHideBadge") return true } - if ( - selectedItem === 1 && - unit === "time" && - tariff.privileges[0].privilegeId === "squizHideBadge" - ) { - return true; + if (unit === "volume") { + if (selectedItemVolume === 0 && tariff.privileges[0].privilegeId === "quizCnt") return true + if (selectedItemVolume === 1 && tariff.privileges[0].privilegeId === "quizManual") return true } return false; }); @@ -206,15 +197,32 @@ function TariffPage() { <> {isMobile ? ( + ) : ( + )} diff --git a/yarn.lock b/yarn.lock index b1c11d4..5730b77 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1138,6 +1138,13 @@ dependencies: regenerator-runtime "^0.14.0" +"@babel/runtime@^7.25.0": + version "7.25.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.0.tgz#3af9a91c1b739c569d5d80cc917280919c544ecb" + integrity sha512-7dRy4DwXwtzBrPbZflqxnvfxLF8kdZXPkhymtDeFoFqE6ldzjQFgYTtYIFARcLEYDrqfBfYcZt1WqFxRoyC9Rw== + dependencies: + regenerator-runtime "^0.14.0" + "@babel/template@^7.22.15", "@babel/template@^7.24.0", "@babel/template@^7.3.3": version "7.24.0" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.24.0.tgz#c6a524aa93a4a05d66aaf31654258fae69d87d50" @@ -2203,6 +2210,15 @@ "@mui/utils" "^5.15.14" prop-types "^15.8.1" +"@mui/private-theming@^5.16.6": + version "5.16.6" + resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.16.6.tgz#547671e7ae3f86b68d1289a0b90af04dfcc1c8c9" + integrity sha512-rAk+Rh8Clg7Cd7shZhyt2HGTTE5wYKNSJ5sspf28Fqm/PZ69Er9o6KX25g03/FG2dfpg5GCwZh/xOojiTfm3hw== + dependencies: + "@babel/runtime" "^7.23.9" + "@mui/utils" "^5.16.6" + prop-types "^15.8.1" + "@mui/styled-engine@^5.15.14": version "5.15.14" resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.15.14.tgz#168b154c4327fa4ccc1933a498331d53f61c0de2" @@ -2213,6 +2229,16 @@ csstype "^3.1.3" prop-types "^15.8.1" +"@mui/styled-engine@^5.16.6": + version "5.16.6" + resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.16.6.tgz#60110c106dd482dfdb7e2aa94fd6490a0a3f8852" + integrity sha512-zaThmS67ZmtHSWToTiHslbI8jwrmITcN93LQaR2lKArbvS7Z3iLkwRoiikNWutx9MBs8Q6okKvbZq1RQYB3v7g== + dependencies: + "@babel/runtime" "^7.23.9" + "@emotion/cache" "^11.11.0" + csstype "^3.1.3" + prop-types "^15.8.1" + "@mui/system@^5.15.15": version "5.15.15" resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.15.15.tgz#658771b200ce3c4a0f28e58169f02e5e718d1c53" @@ -2227,11 +2253,30 @@ csstype "^3.1.3" prop-types "^15.8.1" +"@mui/system@^5.16.5": + version "5.16.7" + resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.16.7.tgz#4583ca5bf3b38942e02c15a1e622ba869ac51393" + integrity sha512-Jncvs/r/d/itkxh7O7opOunTqbbSSzMTHzZkNLM+FjAOg+cYAZHrPDlYe1ZGKUYORwwb2XexlWnpZp0kZ4AHuA== + dependencies: + "@babel/runtime" "^7.23.9" + "@mui/private-theming" "^5.16.6" + "@mui/styled-engine" "^5.16.6" + "@mui/types" "^7.2.15" + "@mui/utils" "^5.16.6" + clsx "^2.1.0" + csstype "^3.1.3" + prop-types "^15.8.1" + "@mui/types@^7.2.14": version "7.2.14" resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.14.tgz#8a02ac129b70f3d82f2f9b76ded2c8d48e3fc8c9" integrity sha512-MZsBZ4q4HfzBsywtXgM1Ksj6HDThtiwmOKUXH1pKYISI9gAVXCNHNpo7TlGoGrBaYWZTdNoirIN7JsQcQUjmQQ== +"@mui/types@^7.2.15": + version "7.2.15" + resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.15.tgz#dadd232fe9a70be0d526630675dff3b110f30b53" + integrity sha512-nbo7yPhtKJkdf9kcVOF8JZHPZTmqXjJ/tI0bdWgHg5tp9AnIN4Y7f7wm9T+0SyGYJk76+GYZ8Q5XaTYAsUHN0Q== + "@mui/utils@^5.15.14": version "5.15.14" resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.15.14.tgz#e414d7efd5db00bfdc875273a40c0a89112ade3a" @@ -2242,6 +2287,31 @@ prop-types "^15.8.1" react-is "^18.2.0" +"@mui/utils@^5.16.5", "@mui/utils@^5.16.6": + version "5.16.6" + resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.16.6.tgz#905875bbc58d3dcc24531c3314a6807aba22a711" + integrity sha512-tWiQqlhxAt3KENNiSRL+DIn9H5xNVK6Jjf70x3PnfQPz1MPBdh7yyIcAyVBT9xiw7hP3SomRhPR7hzBMBCjqEA== + dependencies: + "@babel/runtime" "^7.23.9" + "@mui/types" "^7.2.15" + "@types/prop-types" "^15.7.12" + clsx "^2.1.1" + prop-types "^15.8.1" + react-is "^18.3.1" + +"@mui/x-date-pickers@^7.13.0": + version "7.13.0" + resolved "https://registry.yarnpkg.com/@mui/x-date-pickers/-/x-date-pickers-7.13.0.tgz#1afe20dc7ee30c9c1f91c232f3c61f94d2b8427b" + integrity sha512-cmpAfkzOjUgL4I8WenU4elm1QJO8vWpGmIPCezT3Q9wFjGL1QApQhJ5gMZ+X4tM6Gha9AhIWNQX5eXHKbSoyFQ== + dependencies: + "@babel/runtime" "^7.25.0" + "@mui/system" "^5.16.5" + "@mui/utils" "^5.16.5" + "@types/react-transition-group" "^4.4.10" + clsx "^2.1.1" + prop-types "^15.8.1" + react-transition-group "^4.4.5" + "@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" @@ -2873,7 +2943,7 @@ resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f" integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== -"@types/prop-types@*", "@types/prop-types@^15.7.11": +"@types/prop-types@*", "@types/prop-types@^15.7.11", "@types/prop-types@^15.7.12": version "15.7.12" resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.12.tgz#12bb1e2be27293c1406acb6af1c3f3a1481d98c6" integrity sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q== @@ -4449,6 +4519,11 @@ clsx@^2.0.0, clsx@^2.1.0: resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.0.tgz#e851283bcb5c80ee7608db18487433f7b23f77cb" integrity sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg== +clsx@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999" + integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA== + co@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" @@ -10334,6 +10409,11 @@ react-is@^18.0.0, react-is@^18.2.0: resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== +react-is@^18.3.1: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.3.1.tgz#e83557dc12eae63a99e003a46388b1dcbb44db7e" + integrity sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg== + react-pdf@^7.1.2: version "7.7.1" resolved "https://registry.yarnpkg.com/react-pdf/-/react-pdf-7.7.1.tgz#8f5c4716a8ca65a0889825ef01e3a37956291334" From c10a663609ca1874f04f2513591ba31181370853 Mon Sep 17 00:00:00 2001 From: Nastya Date: Mon, 19 Aug 2024 00:44:33 +0300 Subject: [PATCH 16/30] clear logs --- .../DocumentsDialog/DocumentItem.tsx | 2 -- .../DocumentsDialog/DocumentUploadItem.tsx | 2 -- src/pages/AccountSettings/UserFields.tsx | 3 --- src/pages/AfterPay/index.tsx | 3 --- src/pages/Payment/Payment.tsx | 7 ------- src/pages/QuizPayment/QuizPayment.tsx | 15 --------------- src/pages/TariffConstructor/TariffConstructor.tsx | 2 -- src/pages/TariffConstructor/TariffItem.tsx | 2 -- src/pages/Tariffs/ModalRequestCreate.tsx | 1 - src/pages/Tariffs/TariffsPage.tsx | 4 ++++ src/utils/hooks/useAutoPay.ts | 2 -- src/utils/routes/ProtectedRoute.tsx | 4 ---- 12 files changed, 4 insertions(+), 43 deletions(-) diff --git a/src/pages/AccountSettings/DocumentsDialog/DocumentItem.tsx b/src/pages/AccountSettings/DocumentsDialog/DocumentItem.tsx index 6ee36ef..f03b57d 100644 --- a/src/pages/AccountSettings/DocumentsDialog/DocumentItem.tsx +++ b/src/pages/AccountSettings/DocumentsDialog/DocumentItem.tsx @@ -63,10 +63,8 @@ export default function DocumentItem({ useEffect(() => { if (typeof documentUrl === 'string') { if (!documentUrl.includes("pena.digital")) { - console.log(documentUrl) fetch(documentUrl) .then(e => { - console.log(e) setReadyShowDocument(true) }) .catch(e => console.log(e)) diff --git a/src/pages/AccountSettings/DocumentsDialog/DocumentUploadItem.tsx b/src/pages/AccountSettings/DocumentsDialog/DocumentUploadItem.tsx index 5572813..3687f90 100644 --- a/src/pages/AccountSettings/DocumentsDialog/DocumentUploadItem.tsx +++ b/src/pages/AccountSettings/DocumentsDialog/DocumentUploadItem.tsx @@ -43,10 +43,8 @@ export default function DocumentUploadItem({ useEffect(() => { if (typeof urlOrFile === 'string') { if (!urlOrFile.includes("pena.digital")) { - console.log(documentUrl) fetch(documentUrl) .then(e => { - console.log(e) setReadyShowDocument(true) }) .catch(e => console.log(e)) diff --git a/src/pages/AccountSettings/UserFields.tsx b/src/pages/AccountSettings/UserFields.tsx index 8eaf572..96287e3 100644 --- a/src/pages/AccountSettings/UserFields.tsx +++ b/src/pages/AccountSettings/UserFields.tsx @@ -21,9 +21,6 @@ export default function UserFields({ const { settingsFields, user } = useUserStore((state) => state) const a = useUserStore((state) => state) - console.log(a) - console.log(settingsFields) - const textFieldProps = { gap: upMd ? "16px" : "10px", color: "#F2F3F7", diff --git a/src/pages/AfterPay/index.tsx b/src/pages/AfterPay/index.tsx index e37defe..26116b5 100644 --- a/src/pages/AfterPay/index.tsx +++ b/src/pages/AfterPay/index.tsx @@ -17,9 +17,6 @@ export default () => { const domain = (host.includes("s") ? "s" : "") + from; const pathname = from.includes("hub") ? "/tariffs" : "/list"; - console.log(from, " from") - console.log(`https://${domain}.pena.digital${pathname}?purpose=${purpose}&userid=${userId}`) - document.location.href = `https://${domain}.pena.digital${pathname}?purpose=${purpose}&userid=${userId}` return <>; }; diff --git a/src/pages/Payment/Payment.tsx b/src/pages/Payment/Payment.tsx index d862826..9909826 100644 --- a/src/pages/Payment/Payment.tsx +++ b/src/pages/Payment/Payment.tsx @@ -72,9 +72,6 @@ export default function Payment() { const [fromSquiz, setIsFromSquiz] = useState(false); const [cc, setCC] = useState(false); - console.log("fromSquiz") - console.log(fromSquiz) - const [warnModalOpen, setWarnModalOpen] = useState(false); const [sorryModalOpen, setSorryModalOpen] = useState(false); @@ -94,12 +91,8 @@ export default function Payment() { } }, []) - console.log(siteReadyPayCart) - console.log(notEnoughMoneyAmount) //Тут записываем начальную сумму в инпут (если стоит флаг что мы в процессе покупки) useEffect(() => { - console.log(siteReadyPayCart) - console.log(notEnoughMoneyAmount) if (siteReadyPayCart !== null && siteReadyPayCart[userId] !== undefined && calcTimeOfReadyPayCart(siteReadyPayCart[userId])) setPaymentValueField((notEnoughMoneyAmount / 100).toString());//Сколько нехватило на хабе }, [notEnoughMoneyAmount, siteReadyPayCart]) diff --git a/src/pages/QuizPayment/QuizPayment.tsx b/src/pages/QuizPayment/QuizPayment.tsx index e9033f2..08f6fab 100644 --- a/src/pages/QuizPayment/QuizPayment.tsx +++ b/src/pages/QuizPayment/QuizPayment.tsx @@ -21,7 +21,6 @@ import { clearCustomTariffs } from "@root/stores/customTariffs"; import { clearTickets } from "@root/stores/tickets"; import { setNotEnoughMoneyAmount, startPayCartProcess } from "@stores/notEnoughMoneyAmount" -console.log("выясняю парамсы") const params = new URLSearchParams(window.location.search); let action = params.get("action"); let dif = params.get("dif"); @@ -56,7 +55,6 @@ export default function QuizPayment() { if (first) { - console.log("чищу урл") navigate(`/quizpayment`, { replace: true, }); @@ -79,22 +77,9 @@ export default function QuizPayment() { } - // setAuthToken(data.data.accessToken) - console.log("собираюсь задать юзера и токен") setUserId(userId); setAuthToken(token); - // useUserFetcher({ - // url: process.env.REACT_APP_DOMAIN + `/user/${userId}`, - // userId, - // onNewUser: (user) => { - // setUser(user) - // navigate(`/payment?action=${action}&dif=${dif}`, { replace: true }) - - // }, - // onError: () => { }, - // }) - return; })(); } else { diff --git a/src/pages/TariffConstructor/TariffConstructor.tsx b/src/pages/TariffConstructor/TariffConstructor.tsx index 95ead4e..058a6e2 100644 --- a/src/pages/TariffConstructor/TariffConstructor.tsx +++ b/src/pages/TariffConstructor/TariffConstructor.tsx @@ -42,8 +42,6 @@ function TariffConstructor() { }} > {Object.entries(customTariffs).filter(([serviceKey]) => serviceKey === "squiz").map(([serviceKey, privileges], index) => { - console.log("privileges") - console.log(privileges) return ( { if (Number(value) < Number(sliderSettingsByType[measurement]?.min)) { diff --git a/src/pages/Tariffs/ModalRequestCreate.tsx b/src/pages/Tariffs/ModalRequestCreate.tsx index e6d5e2a..50a0c4e 100644 --- a/src/pages/Tariffs/ModalRequestCreate.tsx +++ b/src/pages/Tariffs/ModalRequestCreate.tsx @@ -209,7 +209,6 @@ export const ModalRequestCreate = ({ time: moment(values.time).format("hh:mm") }) }) - console.log(resp) //@ts-ignore if (resp[0]?.status === 200) { enqueueSnackbar("Запрос успешно отправлен") diff --git a/src/pages/Tariffs/TariffsPage.tsx b/src/pages/Tariffs/TariffsPage.tsx index 537c21a..95d7cd3 100644 --- a/src/pages/Tariffs/TariffsPage.tsx +++ b/src/pages/Tariffs/TariffsPage.tsx @@ -28,6 +28,7 @@ import TariffCard from "./TariffCard"; import { useDiscounts } from "@root/api/price"; import { Select } from "@components/Select"; import { Tabs } from "@components/Tabs"; +import { ModalRequestCreate } from "./ModalRequestCreate"; const subPagesTime = ["Базовый тариф PenaQuiz", 'Убрать логотип "PenaQuiz"']; const subPagesVolume = ["Заявки quiz", 'Заказать создание quiz']; @@ -46,9 +47,11 @@ function TariffPage() { const tariffs = useTariffStore((state) => state.tariffs); const [selectedItemTime, setSelectedItemTime] = useState(0); const [selectedItemVolume, setSelectedItemVolume] = useState(0); + const [isRequestCreate, setIsRequestCreate] = useState(false); const purchasesAmount = useUserStore((state) => state.userAccount?.wallet.spent) ?? 0; const userId = useUserStore((state) => state.user?._id) ?? ""; + const userPrivilegies = useUserStore(store => store); const discounts = useDiscounts(userId); const isUserNko = useUserStore((state) => state.userAccount?.status) === "nko"; @@ -255,6 +258,7 @@ function TariffPage() { {/* */} {/* */} {/*)}*/} + setIsRequestCreate(false)}/>
); } diff --git a/src/utils/hooks/useAutoPay.ts b/src/utils/hooks/useAutoPay.ts index b6a3ff2..d9e1a67 100644 --- a/src/utils/hooks/useAutoPay.ts +++ b/src/utils/hooks/useAutoPay.ts @@ -33,7 +33,6 @@ export const useAfterPay = () => { //Проверяем можем ли мы оплатить корзину здесь и сейчас const [, payCartError] = await payCart(); - console.log("попытка оплаты не удалась") if (payCartError) { //Не получилось купить корзину. Ставим флаг, что сайт в состоянии ожидания пополнения счёта для оплаты @@ -54,7 +53,6 @@ export const useAfterPay = () => { //Время ещё не вышло. У нас стоит флаг покупать корзину если время не вышло. (async () => { - console.log("Время ещё не вышло. У нас стоит флаг покупать корзину если время не вышло.") const [, payCartError] = await payCart(); if (!payCartError) { diff --git a/src/utils/routes/ProtectedRoute.tsx b/src/utils/routes/ProtectedRoute.tsx index d93d796..9ed892d 100644 --- a/src/utils/routes/ProtectedRoute.tsx +++ b/src/utils/routes/ProtectedRoute.tsx @@ -6,9 +6,5 @@ export default function PrivateRoute() { const location = useLocation() const user = useUserStore(state => state.user) - console.log("1 я рассуждаю кого выкинуть отсюда") - console.log(user) - console.log(location) - console.log("2 я рассуждаю кого выкинуть отсюда") return user ? : } From b7f2ee2e86d94416aff0d7e846e27056dfcad6b0 Mon Sep 17 00:00:00 2001 From: Nastya Date: Wed, 21 Aug 2024 09:39:31 +0300 Subject: [PATCH 17/30] =?UTF-8?q?quiz=20=D0=B2=20=D0=BA=D0=B2=D0=B8=D0=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Landing/Section2.tsx | 4 ++-- src/pages/Tariffs/Tariffs.tsx | 4 ++-- src/pages/Tariffs/TariffsPage.tsx | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pages/Landing/Section2.tsx b/src/pages/Landing/Section2.tsx index b2c4e4b..a72a95d 100644 --- a/src/pages/Landing/Section2.tsx +++ b/src/pages/Landing/Section2.tsx @@ -63,7 +63,7 @@ export default function Section2() { {/* {upMd ? : }*/} - {upMd ? + {upMd ? : : diff --git a/src/pages/Tariffs/TariffsPage.tsx b/src/pages/Tariffs/TariffsPage.tsx index 95d7cd3..b3d1cc1 100644 --- a/src/pages/Tariffs/TariffsPage.tsx +++ b/src/pages/Tariffs/TariffsPage.tsx @@ -31,7 +31,7 @@ import { Tabs } from "@components/Tabs"; import { ModalRequestCreate } from "./ModalRequestCreate"; const subPagesTime = ["Базовый тариф PenaQuiz", 'Убрать логотип "PenaQuiz"']; -const subPagesVolume = ["Заявки quiz", 'Заказать создание quiz']; +const subPagesVolume = ["Заявки квиз", 'Заказать создание квиза']; const StepperText: Record = { volume: "Тарифы на объём", From 27a428e515d9fbdde88d0846f79dd84a68bd63b1 Mon Sep 17 00:00:00 2001 From: Nastya Date: Wed, 21 Aug 2024 17:57:09 +0300 Subject: [PATCH 18/30] =?UTF-8?q?=D0=BA=D0=B0=D1=80=D1=82=D0=BE=D1=87?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=BF=D1=80=D0=B8=20=D0=BD=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D1=87=D0=B8=D0=B8=20=D0=BF=D1=80=D0=B8=D0=B2=D0=B8=D0=BB=D0=B5?= =?UTF-8?q?=D0=B3=D0=B8=D0=B8=20=D0=BF=D1=80=D0=B5=D0=B4=D0=BB=D0=B0=D0=B3?= =?UTF-8?q?=D0=B0=D1=8E=D1=82=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20=D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5?= =?UTF-8?q?=20=D0=BA=D0=B2=D0=B8=D0=B7=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 2 +- src/index.tsx | 24 ++++-- src/pages/Tariffs/ModalRequestCreate.tsx | 17 ++++- src/pages/Tariffs/TariffCard.tsx | 97 ++++++++++++++---------- src/pages/Tariffs/TariffsPage.tsx | 7 +- src/stores/user.ts | 22 ++++++ yarn.lock | 8 +- 7 files changed, 123 insertions(+), 54 deletions(-) diff --git a/package.json b/package.json index 32857b4..f7bbf48 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@emotion/react": "^11.10.5", "@emotion/styled": "^11.10.5", - "@frontend/kitui": "^1.0.85", + "@frontend/kitui": "^1.0.86", "@mui/icons-material": "^5.10.14", "@mui/material": "^5.10.14", "@mui/x-date-pickers": "^7.13.0", diff --git a/src/index.tsx b/src/index.tsx index ec05bef..18647ee 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -36,6 +36,8 @@ import { setUser, setUserAccount, useUserStore, + OriginalUserSquizAccount, + setQuizUserAccount } from "./stores/user"; import TariffConstructor from "./pages/TariffConstructor/TariffConstructor"; import { @@ -57,10 +59,8 @@ import OutdatedLink from "@root/pages/auth/OutdatedLink"; import { verify } from "./pages/AccountSettings/helper"; import AfterPay from "./pages/AfterPay"; import { PageNotFound } from "./pages/PageNotFound"; -import { setSiteReadyPayCart, useNotEnoughMoneyAmount } from "@stores/notEnoughMoneyAmount" +import { useNotEnoughMoneyAmount } from "@stores/notEnoughMoneyAmount" import { usePipeSubscriber } from "./utils/hooks/usePipeSubscriber"; -import moment from "moment"; -import { payCart } from "./api/cart"; import { useAfterPay } from "./utils/hooks/useAutoPay"; import { LocalizationProvider } from "@mui/x-date-pickers"; @@ -70,10 +70,7 @@ const localeText = ruRU.components.MuiLocalizationProvider.defaultProps.localeText; const App = () => { const location = useLocation(); - const user = useUserStore(state => state.user); - const userAccount = useUserStore(state => state.userAccount); const userId = useUserStore(state => state.userId); - const siteReadyPayCart = useNotEnoughMoneyAmount(state => state.siteReadyPayCart); const navigate = useNavigate(); useUserFetcher({ url: process.env.REACT_APP_DOMAIN + `/user/${userId}`, @@ -104,6 +101,21 @@ const App = () => { }, }); + useUserAccountFetcher({ + url: `${process.env.REACT_APP_DOMAIN}/squiz/account/get`, + userId, + onNewUserAccount: setQuizUserAccount, + onError: (error) => { + const errorMessage = getMessageFromFetchError(error); + if (errorMessage) { + enqueueSnackbar(errorMessage); + clearUserData(); + clearAuthToken(); + navigate("/signin"); + } + }, + }); + usePipeSubscriber() verify(userId); diff --git a/src/pages/Tariffs/ModalRequestCreate.tsx b/src/pages/Tariffs/ModalRequestCreate.tsx index 50a0c4e..a516d82 100644 --- a/src/pages/Tariffs/ModalRequestCreate.tsx +++ b/src/pages/Tariffs/ModalRequestCreate.tsx @@ -94,7 +94,11 @@ export const ModalRequestCreate = ({ if (isSending) return ( { + onClose() + setIsSending(false) + }} + > @@ -277,6 +281,13 @@ export const ModalRequestCreate = ({ ampm={false} value={values.time} views={['hours', 'minutes']} format="hh:mm" + sx={{ + border: "#c4c4c4 1px solid", + borderRadius: "4px", + "& .MuiInputBase-root": { + display: "flex" + } + }} /> @@ -292,6 +303,8 @@ export const ModalRequestCreate = ({ disabled={isSubmitting} sx={{ py: "12px", + bgcolor: "rgb(126, 42, 234)", + borderRadius: "8px", "&:hover": { backgroundColor: "#581CA7", }, diff --git a/src/pages/Tariffs/TariffCard.tsx b/src/pages/Tariffs/TariffCard.tsx index a5ba727..4cbb458 100644 --- a/src/pages/Tariffs/TariffCard.tsx +++ b/src/pages/Tariffs/TariffCard.tsx @@ -15,11 +15,12 @@ interface Props { text?: string; }; price?: ReactNode; + sendRequestToCreate?: () => void; } -export default function TariffCard({ icon, headerText, text, sx, price, buttonProps, discount }: Props) { - const theme = useTheme(); - const isMobile = useMediaQuery(theme.breakpoints.down(600)); +export default function TariffCard({ icon, headerText, text, sx, price, buttonProps, discount, sendRequestToCreate }: Props) { + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down(600)); return ( )} - {/* {headerText}} placement="top"> */} - - {headerText} - + {/* {headerText}} placement="top"> */} + + {headerText} + {/* ( @@ -100,29 +101,47 @@ export default function TariffCard({ icon, headerText, text, sx, price, buttonPr ))} placement="top" > */} - - - {text} - - + + + {text} + + {/* */} - {buttonProps && ( - - )} + + {buttonProps && ( + + )} + {Boolean(sendRequestToCreate) && ( + + )} + ); } diff --git a/src/pages/Tariffs/TariffsPage.tsx b/src/pages/Tariffs/TariffsPage.tsx index b3d1cc1..af9fb09 100644 --- a/src/pages/Tariffs/TariffsPage.tsx +++ b/src/pages/Tariffs/TariffsPage.tsx @@ -51,7 +51,8 @@ function TariffPage() { const purchasesAmount = useUserStore((state) => state.userAccount?.wallet.spent) ?? 0; const userId = useUserStore((state) => state.user?._id) ?? ""; - const userPrivilegies = useUserStore(store => store); + const userPrivilegies = useUserStore(store => store.quizUserAccount?.privileges); + console.log(userPrivilegies)//quizManual.amount > 0 const discounts = useDiscounts(userId); const isUserNko = useUserStore((state) => state.userAccount?.status) === "nko"; @@ -89,6 +90,7 @@ function TariffPage() { filteredTariffs: Tariff[], addFreeTariff = false ) => { + const isCC = userPrivilegies?.quizManual?.amount !== undefined && userPrivilegies?.quizManual?.amount > 0 const tariffElements = filteredTariffs .filter((tariff) => tariff.privileges.length > 0) .map((tariff, index) => { @@ -98,7 +100,7 @@ function TariffPage() { purchasesAmount, currentTariffs ?? [], isUserNko, - userId + userId, ); return ( @@ -127,6 +129,7 @@ function TariffPage() { text: "Выбрать", onClick: () => handleTariffItemClick(tariff._id), }} + sendRequestToCreate={() => setIsRequestCreate(true)} headerText={tariff.name} text={tariff.description || ""} price={ diff --git a/src/stores/user.ts b/src/stores/user.ts index 12f0d71..47563d9 100644 --- a/src/stores/user.ts +++ b/src/stores/user.ts @@ -16,6 +16,14 @@ import { patchCurrency, deleteCart, patchCart } from "@root/api/cart" import { User, UserAccount, UserName, getInitials, patchUserAccount } from "@frontend/kitui" import { cancelPayCartProcess, setNotEnoughMoneyAmount, setSiteReadyPayCart, useNotEnoughMoneyAmount } from "./notEnoughMoneyAmount"; +type Privilege = { + amount: number; + created_at: string; + id: string; + privilege_id: string; + privilege_name: string; + }; + interface UserStore { userId: string | null; user: User | null; @@ -29,8 +37,19 @@ interface UserStore { documentsUrl: UserDocumentsUrl; comment: string; initials: string; + quizUserAccount: OriginalUserSquizAccount | null; } + +export type OriginalUserSquizAccount = { + created_at: string; + deleted: boolean; + email: string; + id: string; + privileges: Record; + privilege_name: string; + }; + const defaultFieldValues = { value: "", error: null, @@ -58,6 +77,7 @@ const initialState: UserStore = { userId: null, user: null, userAccount: null, + quizUserAccount: null, settingsFields: { ...defaultFields }, verificationStatus: VerificationStatus.NOT_VERIFICATED, verificationType: "juridical", @@ -151,6 +171,8 @@ export const setUserAccount = (user: UserAccount) => } ) +export const setQuizUserAccount = (quizUserAccount: OriginalUserSquizAccount) => useUserStore.setState({ quizUserAccount }); + export const setNewNames = (name: UserName) => useUserStore.setState( produce((state) => { diff --git a/yarn.lock b/yarn.lock index 5730b77..95fed95 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1633,10 +1633,10 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.1.tgz#16308cea045f0fc777b6ff20a9f25474dd8293d2" integrity sha512-9TANp6GPoMtYzQdt54kfAyMmz1+osLlXdg2ENroU7zzrtflTLrrC/lgrIfaSe+Wu0b89GKccT7vxXA0MoAIO+Q== -"@frontend/kitui@^1.0.85": - version "1.0.85" - resolved "https://penahub.gitlab.yandexcloud.net/api/v4/projects/21/packages/npm/@frontend/kitui/-/@frontend/kitui-1.0.85.tgz#1a384c9ff3314175c1ba3d35d0979da7026a21ab" - integrity sha1-GjhMn/MxQXXBuj010JedpwJqIas= +"@frontend/kitui@^1.0.86": + version "1.0.86" + resolved "https://penahub.gitlab.yandexcloud.net/api/v4/projects/21/packages/npm/@frontend/kitui/-/@frontend/kitui-1.0.86.tgz#03a56b99403b62810134f3d7da01ea3fc8cc4f7f" + integrity sha1-A6VrmUA7YoEBNPPX2gHqP8jMT38= dependencies: immer "^10.0.2" reconnecting-eventsource "^1.6.2" From 5594e59219ceb641983a667d992b7094cf69a285 Mon Sep 17 00:00:00 2001 From: Nastya Date: Thu, 22 Aug 2024 09:18:25 +0300 Subject: [PATCH 19/30] =?UTF-8?q?=D0=BC=D0=BE=D0=B4=D0=B0=D0=BB=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=B7=D0=B0=D0=BF=D1=80=D0=BE=D1=81=D0=B0=20=D1=81?= =?UTF-8?q?=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D1=8F=20=D0=BA=D0=B2=D0=B8?= =?UTF-8?q?=D0=B7=D0=B0=20=D0=BE=D1=82=D0=BA=D1=80=D1=8B=D0=B2=D0=B0=D0=B5?= =?UTF-8?q?=D1=82=D1=81=D1=8F=20=D0=BE=D1=82=20=D1=81=D1=82=D0=BE=D1=80?= =?UTF-8?q?=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/pages/Tariffs/ModalRequestCreate.tsx | 25 ++++++++++++------------ src/pages/Tariffs/TariffsPage.tsx | 7 +++---- src/stores/requestSquizCreate.ts | 25 ++++++++++++++++++++++++ 3 files changed, 40 insertions(+), 17 deletions(-) create mode 100644 src/stores/requestSquizCreate.ts diff --git a/src/pages/Tariffs/ModalRequestCreate.tsx b/src/pages/Tariffs/ModalRequestCreate.tsx index a516d82..251e5c1 100644 --- a/src/pages/Tariffs/ModalRequestCreate.tsx +++ b/src/pages/Tariffs/ModalRequestCreate.tsx @@ -9,11 +9,7 @@ import moment, { Moment } from "moment" import { enqueueSnackbar } from "notistack" import { useState } from "react" import CloseIcon from "@root/assets/Icons/CloseIcon"; - -interface Props { - open: boolean - onClose: () => void -} +import { useRequestSquizCreate, RSCClose } from "@root/stores/requestSquizCreate" interface Values { @@ -83,19 +79,17 @@ const Field = ({ ) } -export const ModalRequestCreate = ({ - open, - onClose -}: Props) => { +export const ModalRequestCreate = () => { const theme = useTheme() const isMobile = useMediaQuery(theme.breakpoints.down(650)); const [isSending, setIsSending] = useState(false) + const open = useRequestSquizCreate(store => store.isRSCOpen) if (isSending) return ( { - onClose() + RSCClose() setIsSending(false) }} @@ -131,9 +125,14 @@ export const ModalRequestCreate = ({ )} {Boolean(sendRequestToCreate) && ( - + {isMobile ? + + + + : + + } + )} From 0ad89dd05f40dabbc701cb80b74155c83366a94f Mon Sep 17 00:00:00 2001 From: Nastya Date: Wed, 28 Aug 2024 23:16:59 +0300 Subject: [PATCH 26/30] =?UTF-8?q?=D1=83=D0=B1=D1=80=D0=B0=D1=82=D1=8C=20?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D0=B1=D0=B5=D0=BB=D1=8B=20=D0=BD=D0=B0=20=5F?= =?UTF-8?q?=20=D0=B2=20pdf=20=D0=B2=D0=B5=D1=80=D0=B8=D1=84=D0=B8=D0=BA?= =?UTF-8?q?=D0=B0=D1=86=D0=B8=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/verification.ts | 14 ++++++++++++++ src/utils/jsonToFormdata.ts | 4 +++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/api/verification.ts b/src/api/verification.ts index c3d7cbe..ebb86d3 100644 --- a/src/api/verification.ts +++ b/src/api/verification.ts @@ -72,6 +72,18 @@ 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({ method: "PUT", url: `${API_URL}`, @@ -93,6 +105,8 @@ 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({ method: "PATCH", diff --git a/src/utils/jsonToFormdata.ts b/src/utils/jsonToFormdata.ts index 3267290..d6d987a 100644 --- a/src/utils/jsonToFormdata.ts +++ b/src/utils/jsonToFormdata.ts @@ -29,6 +29,7 @@ export const jsonToFormdata = ( if (!key) continue const value = json[key] + if (typeof value !== "string") value.name = value.name.replace(/\s/g, '_') if (typeof value !== "string") { formData.append(key, convertBinaryStringToFile(value)) @@ -38,6 +39,7 @@ export const jsonToFormdata = ( formData.append(key, value) } - +console.log("formData") +console.log(formData) return formData } From 5117edfa4706734564ed33e64d28269787226ec8 Mon Sep 17 00:00:00 2001 From: Nastya Date: Thu, 29 Aug 2024 01:24:38 +0300 Subject: [PATCH 27/30] translate url verif && remove egrule --- package.json | 1 + src/api/verification.ts | 4 ++-- src/utils/jsonToFormdata.ts | 6 +++++- yarn.lock | 9 ++++++++- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index f7bbf48..5a0d9ff 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "react-slick": "^0.29.0", "slick-carousel": "^1.8.1", "swr": "^2.2.5", + "transliteration": "^2.3.5", "use-debounce": "^10.0.0", "web-vitals": "^2.1.0", "yup": "^1.1.1", diff --git a/src/api/verification.ts b/src/api/verification.ts index ebb86d3..712e12b 100644 --- a/src/api/verification.ts +++ b/src/api/verification.ts @@ -55,7 +55,7 @@ export const sendDocuments = async ( const sendDocumentsResponse = await makeRequest({ method: "POST", url: API_URL, - body: jsonToFormdata({ ...documents, egrule: documents.inn }), + body: jsonToFormdata({ ...documents}), useToken: true, withCredentials: true, }); @@ -88,7 +88,7 @@ export const updateDocuments = async ( method: "PUT", url: `${API_URL}`, body: jsonToFormdata( - documents.inn ? { ...documents, egrule: documents.inn } : documents + documents.inn ? { ...documents} : documents ), useToken: true, withCredentials: true, diff --git a/src/utils/jsonToFormdata.ts b/src/utils/jsonToFormdata.ts index d6d987a..3f36bfd 100644 --- a/src/utils/jsonToFormdata.ts +++ b/src/utils/jsonToFormdata.ts @@ -1,4 +1,5 @@ import type { Attachment } from "@root/model/attachment" +import { transliterate } from 'transliteration'; type KeyValue = { [key: string]: T; @@ -24,12 +25,15 @@ export const jsonToFormdata = ( json: KeyValue ): 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 const value = json[key] - if (typeof value !== "string") value.name = value.name.replace(/\s/g, '_') + if (typeof value !== "string") value.name = transliterate(value.name.replace(/\s/g, '_')) if (typeof value !== "string") { formData.append(key, convertBinaryStringToFile(value)) diff --git a/yarn.lock b/yarn.lock index 95fed95..9f9efca 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11855,6 +11855,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.yarnpkg.com/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" @@ -12885,7 +12892,7 @@ 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" integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== From 5540c2a07d107322e874562abd01a307f3c2c72e Mon Sep 17 00:00:00 2001 From: Nastya Date: Sat, 31 Aug 2024 04:39:40 +0300 Subject: [PATCH 28/30] =?UTF-8?q?=D0=BC=D0=BE=D0=B4=D0=B0=D0=BB=D0=BA?= =?UTF-8?q?=D0=B0=20=D0=B2=D0=BE=D1=81=D1=81=D1=82=D0=B0=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=BF=D0=B0=D1=80=D0=BE=D0=BB?= =?UTF-8?q?=D1=8F=20=D0=BE=D1=82=D0=BA=D1=80=D1=8B=D0=B2=D0=B0=D0=B5=D1=82?= =?UTF-8?q?=D1=81=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/index.tsx | 3 ++- src/utils/hooks/useAutoPay.ts | 14 +++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/index.tsx b/src/index.tsx index c7c59f2..9e53476 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -65,6 +65,7 @@ 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"; pdfjs.GlobalWorkerOptions.workerSrc = `//unpkg.com/pdfjs-dist@${pdfjs.version}/build/pdf.worker.min.js`; @@ -175,7 +176,7 @@ const App = () => { to="/" replace state={{ - redirectTo: window.location.pathname + window.location.search, + redirectTo: `changepwd/${window.location.search}`, }} /> } diff --git a/src/utils/hooks/useAutoPay.ts b/src/utils/hooks/useAutoPay.ts index 72578a4..c9ceec8 100644 --- a/src/utils/hooks/useAutoPay.ts +++ b/src/utils/hooks/useAutoPay.ts @@ -4,19 +4,19 @@ import { useUserStore } from "@root/stores/user"; import moment from "moment"; import { enqueueSnackbar } from "notistack"; import { useEffect } from "react"; -import { useNavigate, useSearchParams } from "react-router-dom"; -import { useCart } from "./useCart"; +import { useSearchParams } from "react-router-dom"; import { RSCOpen } from "@root/stores/requestSquizCreate"; +import { useCartTariffs } from "./useCartTariffs"; export const useAfterPay = () => { - const navigate = useNavigate(); const [searchParams, setSearchParams] = useSearchParams(); const userId = useUserStore(store => store.userId) const userAccount = useUserStore(state => state.userAccount); const siteReadyPayCart = useNotEnoughMoneyAmount(state => state.siteReadyPayCart); - const cart = useCart(); - console.log(cart) - const isCC = cart.services.length > 0 && cart.services[0].tariffs.some(t => t.privileges[0].privilegeId === "quizManual") + 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"); @@ -45,7 +45,7 @@ export const useAfterPay = () => { } else { enqueueSnackbar("Товары успешно приобретены") cancelPayCartProcess() - if (isCC) RSCOpen() + if (true) RSCOpen() } })() } From 80f8d051d40e69c802823a7a9991bf58ec1a4b94 Mon Sep 17 00:00:00 2001 From: Nastya Date: Sun, 1 Sep 2024 03:40:47 +0300 Subject: [PATCH 29/30] fix changepwd --- src/index.tsx | 6 +++++- src/pages/auth/RecoverPassword.tsx | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/index.tsx b/src/index.tsx index 9e53476..ac0895d 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -125,6 +125,10 @@ const App = () => { useAfterPay() +console.log("location") +console.log(location) +console.log("window.location") +console.log(window.location) if (location.state?.redirectTo) return ( @@ -176,7 +180,7 @@ const App = () => { to="/" replace state={{ - redirectTo: `changepwd/${window.location.search}`, + redirectTo: `/changepwd${location.search}`, }} /> } diff --git a/src/pages/auth/RecoverPassword.tsx b/src/pages/auth/RecoverPassword.tsx index 77a261b..544de32 100644 --- a/src/pages/auth/RecoverPassword.tsx +++ b/src/pages/auth/RecoverPassword.tsx @@ -75,6 +75,8 @@ 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"); From 96a206f233d4035fefa4553fb8938d6dc4d93679 Mon Sep 17 00:00:00 2001 From: Nastya Date: Thu, 17 Oct 2024 02:05:49 +0300 Subject: [PATCH 30/30] =?UTF-8?q?=D0=BA=D0=BE=D0=BD=D1=81=D1=83=D0=BB?= =?UTF-8?q?=D1=8C=D1=82=D0=B0=D0=BD=D1=82=20=D0=B1=D0=B5=D0=B7=20=D0=B2?= =?UTF-8?q?=D1=80=D0=B5=D0=BC=D0=B5=D0=BD=D0=B8=20=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/FloatingSupportChat/Chat.tsx | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/components/FloatingSupportChat/Chat.tsx b/src/components/FloatingSupportChat/Chat.tsx index 56d620b..a69f6ca 100644 --- a/src/components/FloatingSupportChat/Chat.tsx +++ b/src/components/FloatingSupportChat/Chat.tsx @@ -108,7 +108,7 @@ export default function Chat({ open = false, onclickArrow, sx }: Props) { const workingHoursMessage = "Здравствуйте, задайте ваш вопрос и наш оператор вам ответит в течение 10 минут"; const offHoursMessage = - "Здравствуйте, к сожалению, сейчас операторы не работают. Задайте ваш вопрос, и вам ответят в 10:00 по московскому времени"; + "Здравствуйте, задайте ваш вопрос и наш оператор вам ответит в течение 10 минут"; const date = new Date(); const currentHourUTC = date.getUTCHours(); const MscTime = 3; // Москва UTC+3; @@ -421,14 +421,6 @@ export default function Chat({ open = false, onclickArrow, sx }: Props) { > онлайн-консультант - - время работы 10:00-3:00 по мск -