From 33b695ef13946208f4d50491bd95e7a8b596b87d Mon Sep 17 00:00:00 2001 From: Nastya Date: Sun, 20 Jul 2025 15:17:39 +0300 Subject: [PATCH] =?UTF-8?q?fix=20recover=20and=20fix=20customer=20=D0=B7?= =?UTF-8?q?=D0=B0=D0=BF=D0=B8=D1=81=D1=8C=20=D0=B2=20=D1=81=D1=82=D0=BE?= =?UTF-8?q?=D1=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.tsx | 11 ++- src/pages/Payment/Payment.tsx | 12 +++ src/pages/Tariffs/Tabs.tsx | 8 +- src/pages/Tariffs/Tariffs.tsx | 98 ++++++++++++++++++++---- src/pages/auth/Signup.tsx | 2 +- src/stores/user.ts | 4 +- src/utils/generateHubWalletRequest.ts | 22 +++++- src/utils/hooks/useAuthRedirect.ts | 80 +++++++++++++++++++ src/utils/hooks/useUserAccountFetcher.ts | 44 +++++++++-- 9 files changed, 252 insertions(+), 29 deletions(-) create mode 100644 src/pages/Payment/Payment.tsx create mode 100644 src/utils/hooks/useAuthRedirect.ts diff --git a/src/App.tsx b/src/App.tsx index d6195646..e86c5fea 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -97,8 +97,17 @@ export default function App() { useUserAccountFetcher({ url: `${process.env.REACT_APP_DOMAIN}/customer/v1.0.1/account`, userId, - onNewUserAccount: setCustomerAccount, + onNewUserAccount: (account) => { + console.log("App: Setting customerAccount:", account); + console.log("App: customerAccount structure:", { + userId: account?.userId, + wallet: account?.wallet, + cart: account?.cart + }); + setCustomerAccount(account); + }, onError: (error) => { + console.log("App: Error in customerAccount fetcher:", error); const errorMessage = getMessageFromFetchError(error); if (errorMessage) { enqueueSnackbar(errorMessage); diff --git a/src/pages/Payment/Payment.tsx b/src/pages/Payment/Payment.tsx new file mode 100644 index 00000000..5a410641 --- /dev/null +++ b/src/pages/Payment/Payment.tsx @@ -0,0 +1,12 @@ +import { useAuthRedirect } from "../../utils/hooks/useAuthRedirect"; + +export default function Payment() { + // Используем хук авторизации + const { isProcessing } = useAuthRedirect(); + + // Если идет обработка авторизации, показываем загрузку + if (isProcessing) { + return
Идёт загрузка...
; + } + + // ... existing component code ... \ No newline at end of file diff --git a/src/pages/Tariffs/Tabs.tsx b/src/pages/Tariffs/Tabs.tsx index bcfeec11..1cae19d1 100644 --- a/src/pages/Tariffs/Tabs.tsx +++ b/src/pages/Tariffs/Tabs.tsx @@ -1,11 +1,13 @@ import { Tabs as MuiTabs } from "@mui/material"; import { CustomTab } from "./CustomTab"; +import { TypePages } from "./types"; type TabsProps = { names: string[]; items: string[]; - selectedItem: "day" | "count" | "dop" | "hide" | "create"; - setSelectedItem: (num: "day" | "count" | "dop") => void; + selectedItem: TypePages; + setSelectedItem: (num: TypePages) => void; + toDop: () => void; }; export const Tabs = ({ @@ -18,7 +20,7 @@ export const Tabs = ({ sx={{ m: "25px" }} TabIndicatorProps={{ sx: { display: "none" } }} value={selectedItem} - onChange={(event, newValue: "day" | "count" | "dop") => { + onChange={(event, newValue: TypePages) => { setSelectedItem(newValue); }} variant="scrollable" diff --git a/src/pages/Tariffs/Tariffs.tsx b/src/pages/Tariffs/Tariffs.tsx index 3d8321c6..318c8f46 100644 --- a/src/pages/Tariffs/Tariffs.tsx +++ b/src/pages/Tariffs/Tariffs.tsx @@ -46,11 +46,16 @@ function TariffPage() { const navigate = useNavigate(); const user = useUserStore((state) => state.customerAccount); const userWithWallet = useUserStore((state) => state.customerAccount); //c wallet + const userAccount = useUserStore((state) => state.userAccount); console.log("________________userWithWallet_____________USERRRRRRR") console.log(userWithWallet) - const { data: discounts } = useDiscounts(userId); + console.log("________________userAccount_____________") + console.log(userAccount) + console.log("________________customerAccount_____________") + console.log(user) + const { data: discounts, error: discountsError, isLoading: discountsLoading } = useDiscounts(userId); const [isRequestCreate, setIsRequestCreate] = useState(false); - const [openModal, setOpenModal] = useState({}); + const [openModal, setOpenModal] = useState<{ id?: string; price?: number }>({}); const { cashString, cashCop, cashRub } = useWallet(); const [selectedItem, setSelectedItem] = useState("day"); const { isTestServer } = useDomainDefine(); @@ -64,20 +69,70 @@ console.log("________34563875693785692576_____ TARIFFS") console.log(tariffs) useEffect(() => { - if (userWithWallet) { + if (userWithWallet && user) { let cs = currencyFormatter.format(Number(user.wallet.cash) / 100); let cc = Number(user.wallet.cash); let cr = Number(user.wallet.cash) / 100; setCash(cs, cc, cr); } - }, [userWithWallet]); + }, [userWithWallet, user]); + useEffect(() => { if (cc) { setIsRequestCreate(true) cancelCC() } }, []) - if (!user || !tariffs || !discounts) return ; + + // Добавляем логирование для диагностики + console.log("Tariffs loading state:", { + user: !!user, + userWithWallet: !!userWithWallet, + userId: userId, + tariffs: !!tariffs, + discounts: !!discounts, + tariffsLoading, + tariffsError, + discountsLoading, + discountsError, + userDetails: user ? { + id: user._id, + wallet: user.wallet, + cart: user.cart?.length + } : null + }); + + // Проверяем, что все данные загружены и нет ошибок + const isDataLoading = tariffsLoading || (userId && discountsLoading); + const hasErrors = tariffsError || discountsError; + + // Если userId есть, но customerAccount еще не загружен, показываем загрузку + const isCustomerAccountLoading = userId && !user; + const hasAllData = user && tariffs && (userId ? discounts : true); + + if (isDataLoading || isCustomerAccountLoading) { + console.log("Showing loading page because:", { + dataLoading: isDataLoading, + customerAccountLoading: isCustomerAccountLoading, + userId, + user: !!user + }); + return ; + } + + if (hasErrors) { + console.log("Showing loading page because of errors:", { tariffsError, discountsError }); + return ; + } + + if (!hasAllData) { + console.log("Showing loading page because:", { + noUser: !user, + noTariffs: !tariffs, + noDiscounts: userId && !discounts + }); + return ; + } const openModalHC = (tariffInfo: any) => setOpenModal(tariffInfo); const tryBuy = async ({ id, price }: { id: string; price: number }) => { @@ -99,21 +154,30 @@ console.log(tariffs) //Если нам хватает денежек - покупаем тариф const [data, payError] = await cartApi.pay(); + console.log("payError || !data") + console.log("payError", payError) + console.log("data", data) if (payError || !data) { + console.log("прошли 1 проверку_______") //если денег не хватило if (payError?.includes("insufficient funds") || payError?.includes("Payment Required")) { + console.log("прошли 2 проверку_______") let cashDif = Number(payError.split(":")[1]); - var link = document.createElement("a"); - link.href = generateHubWalletRequestURL({ + + if (!userId) { + enqueueSnackbar("Ошибка: ID пользователя не найден"); + return; + } + + const l = generateHubWalletRequestURL({ action: cc ? "createquizcc" : "buy", dif: cashDif.toString(), userid: userId, + wayback: "list", token }); - // link.href = `https://${isTestServer ? "s" : ""}hub.pena.digital/quizpayment?action=squizpay&dif=${cashDif}&data=${token}&userid=${userId}`; - // if (cc) link.href = link.href + "&cc=true"//после покупки тарифа и возвращения будем знать что надо открыть модалку - document.body.appendChild(link); - link.click(); + console.log(l) + window.location.href = l; return; } @@ -257,7 +321,7 @@ console.log(tariffs) tariffs={tariffs} user={user} - discounts={discounts} + discounts={discounts || []} openModalHC={openModalHC} userPrivilegies={userPrivilegies} startRequestCreate={startRequestCreate} @@ -304,7 +368,7 @@ console.log(tariffs) tariffs={tariffs} user={user} - discounts={discounts} + discounts={discounts || []} openModalHC={openModalHC} userPrivilegies={userPrivilegies} startRequestCreate={startRequestCreate} @@ -314,8 +378,12 @@ console.log(tariffs) 0} onClose={() => setOpenModal({})} - onConfirm={() => tryBuy(openModal)} - price={openModal.price} + onConfirm={() => { + if (openModal.id && openModal.price !== undefined) { + tryBuy({ id: openModal.id, price: openModal.price }); + } + }} + price={openModal.price || 0} /> setIsRequestCreate(false)} /> diff --git a/src/pages/auth/Signup.tsx b/src/pages/auth/Signup.tsx index 97cc5d12..204fbe88 100644 --- a/src/pages/auth/Signup.tsx +++ b/src/pages/auth/Signup.tsx @@ -242,7 +242,7 @@ export default function SignupDialog() { diff --git a/src/stores/user.ts b/src/stores/user.ts index 20352de0..99354f16 100644 --- a/src/stores/user.ts +++ b/src/stores/user.ts @@ -71,5 +71,7 @@ export const clearUserData = () => useUserStore.setState({ ...initialState }); export const setUserAccount = (userAccount: OriginalUserAccount) => useUserStore.setState({ userAccount }); -export const setCustomerAccount = (customerAccount: UserAccount) => +export const setCustomerAccount = (customerAccount: UserAccount) => { + console.log("setCustomerAccount called with:", customerAccount); useUserStore.setState({ customerAccount }); +}; diff --git a/src/utils/generateHubWalletRequest.ts b/src/utils/generateHubWalletRequest.ts index 597bb2c0..bfffc794 100644 --- a/src/utils/generateHubWalletRequest.ts +++ b/src/utils/generateHubWalletRequest.ts @@ -17,8 +17,24 @@ export const generateHubWalletRequestURL = ({ }) => { let currentDomain = window.location.host; if (currentDomain === "localhost") currentDomain += ":3000"; - let url = `https://${isTestServer ? "s" : ""}hub.pena.digital/payment?fromdomain=${currentDomain}&action=${action}&dif=${dif}&userid=${userid}&sec=${token}`; - if (additionalinformation) url += `&additionalinformation=${additionalinformation}`; - if (wayback) url += `&wayback=${wayback}`; + + // Используем более надежный способ генерации URL + const baseUrl = `http://localhost:3001/anyservicepayment`; + const params = new URLSearchParams({ + fromdomain: currentDomain, + action: action, + dif: dif, + userid: userid, + sec: token + }); + + if (additionalinformation) params.append('additionalinformation', additionalinformation); + if (wayback) params.append('wayback', wayback); + + let url = `${baseUrl}?${params.toString()}`; + + // Для продакшена раскомментировать эту строку: + // let url = `https://${isTestServer ? "s" : ""}hub.pena.digital/payment?${params.toString()}`; + return url; } \ No newline at end of file diff --git a/src/utils/hooks/useAuthRedirect.ts b/src/utils/hooks/useAuthRedirect.ts new file mode 100644 index 00000000..7f9ff030 --- /dev/null +++ b/src/utils/hooks/useAuthRedirect.ts @@ -0,0 +1,80 @@ +import { useEffect, useState } from "react"; +import { useNavigate, useSearchParams } from "react-router-dom"; +import { + clearAuthToken, + getMessageFromFetchError, + setAuthToken, + getAuthToken, +} from "@frontend/kitui"; +import { + clearUserData, + setUser, + setUserAccount, + setUserId, + useUserStore, +} from "@root/stores/user"; +import { logout } from "@root/api/auth"; +import { clearCustomTariffs } from "@root/stores/customTariffs"; +import { clearTickets } from "@root/stores/tickets"; +import { setNotEnoughMoneyAmount } from "@stores/cart"; + +export const useAuthRedirect = () => { + const navigate = useNavigate(); + const [searchParams] = useSearchParams(); + const [isProcessing, setIsProcessing] = useState(false); + const user = useUserStore((state) => state.user); + + const action = searchParams.get("action"); + const dif = searchParams.get("dif"); + const token = searchParams.get("data"); + const userId = searchParams.get("userid"); + const wayback = searchParams.get("wayback"); + + useEffect(() => { + if (isProcessing) return; + + // Если пользователь уже авторизован и это тот же пользователь + if (user?._id === userId) { + let returnUrl = `/payment?action=${action}&dif=${dif}&user=${userId}`; + if (wayback) returnUrl += `&wayback=${wayback}`; + navigate(returnUrl, { replace: true }); + return; + } + + // Если есть все необходимые параметры для авторизации + if (action && dif && token && userId) { + setIsProcessing(true); + + (async () => { + try { + // Очищаем старые данные если есть токен + if (getAuthToken()) { + clearAuthToken(); + clearUserData(); + clearCustomTariffs(); + clearTickets(); + setNotEnoughMoneyAmount(0); + await logout(); + } + + // Устанавливаем новый токен и ID пользователя + setAuthToken(token); + setUserId(userId); + + // Перенаправляем на страницу оплаты + let returnUrl = `/payment?action=${action}&dif=${dif}&user=${userId}`; + if (wayback) returnUrl += `&wayback=${wayback}`; + navigate(returnUrl, { replace: true }); + } catch (error) { + console.error("Auth redirect error:", error); + // В случае ошибки перенаправляем на главную страницу тарифов + navigate("/tariffs", { replace: true }); + } finally { + setIsProcessing(false); + } + })(); + } + }, [user, action, dif, token, userId, wayback, navigate, isProcessing]); + + return { isProcessing }; +}; \ No newline at end of file diff --git a/src/utils/hooks/useUserAccountFetcher.ts b/src/utils/hooks/useUserAccountFetcher.ts index f057114f..819e35fb 100644 --- a/src/utils/hooks/useUserAccountFetcher.ts +++ b/src/utils/hooks/useUserAccountFetcher.ts @@ -26,6 +26,7 @@ export const useUserAccountFetcher = ({ useEffect(() => { if (!userId) return; + console.log("useUserAccountFetcher: Starting request for userId:", userId, "url:", url); const controller = new AbortController(); makeRequest({ url, @@ -37,23 +38,56 @@ export const useUserAccountFetcher = ({ }) .then((result) => { devlog("User account", result); - console.log(result) + console.log("useUserAccountFetcher: Success for userId:", userId, "result:", result); if (result) onNewUserAccountRef.current(result); }) .catch((error) => { devlog("Error fetching user account", error); + console.log("useUserAccountFetcher: Error for userId:", userId, "error:", error); if (error.response?.status === 409) return; if (isAxiosError(error) && error.response?.status === 404) { - createUserAccount(controller.signal, url.replace("get", "create")) + console.log("useUserAccountFetcher: Creating user account for userId:", userId); + + // Формируем правильный URL для создания аккаунта + let createUrl = url; + if (url.includes("/customer/v1.0.1/account")) { + // Для customerAccount используем тот же URL (POST запрос) + createUrl = url; + } else if (url.includes("/squiz/account/get")) { + // Для userAccount заменяем get на create + createUrl = url.replace("get", "create"); + } + + console.log("useUserAccountFetcher: Create URL:", createUrl); + + createUserAccount(controller.signal, createUrl) .then((result) => { devlog("Created user account", result); - console.log("это пойдёт в стор: ") - console.log(result) - if (result) onNewUserAccountRef.current(result.created_account as T); + console.log("useUserAccountFetcher: Account created successfully:", result); + + // Проверяем структуру ответа и записываем в стор + if (result) { + // Если результат содержит created_account, используем его + if (result.created_account) { + console.log("useUserAccountFetcher: Using result.created_account"); + onNewUserAccountRef.current(result.created_account as T); + } + // Если результат сам является аккаунтом (для customerAccount) + else if (result.userId && result.wallet) { + console.log("useUserAccountFetcher: Using result directly as customerAccount"); + onNewUserAccountRef.current(result as T); + } + // Если ничего не подходит, логируем для диагностики + else { + console.log("useUserAccountFetcher: Unknown result structure:", result); + onNewUserAccountRef.current(result as T); + } + } }) .catch((error) => { if (error.response?.status === 409) return; devlog("Error creating user account", error); + console.log("useUserAccountFetcher: Error creating account:", error); onErrorRef.current?.(error); }); } else {