diff --git a/src/index.tsx b/src/index.tsx index 36a32b0..db7020a 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -71,6 +71,10 @@ const App = () => { const location = useLocation(); const userId = useUserStore(state => state.userId); const navigate = useNavigate(); + + // Используем обновленный хук useReauthorization для обработки авторизации + const { isProcessing } = useReauthorization(); + useUserFetcher({ url: process.env.REACT_APP_DOMAIN + `/user/${userId}`, userId, @@ -188,6 +192,7 @@ const App = () => { /> } /> + }> }> } /> diff --git a/src/pages/Payment/Payment.tsx b/src/pages/Payment/Payment.tsx index 02402de..afd14a2 100644 --- a/src/pages/Payment/Payment.tsx +++ b/src/pages/Payment/Payment.tsx @@ -8,6 +8,7 @@ import { Typography, useMediaQuery, useTheme, + CircularProgress, } from "@mui/material"; import { activatePromocode } from "@root/api/promocode"; import { sendPayment, sendRSPayment } from "@root/api/wallet"; @@ -31,6 +32,7 @@ import { WarnModal } from "./WarnModal"; import { mutate } from "swr"; import { allTypesOfPurchases } from "@root/stores/allTypesOfPurchases"; import { useAutoPay } from "@root/utils/hooks/useAutoPay"; +import { useReauthorization } from "@root/utils/hooks/useReauthorization"; type PaymentMethod = { label: string; @@ -61,6 +63,8 @@ export default function Payment() { const navigate = useNavigate(); const handleCustomBackNavigation = useHistoryTracker(); + // Используем обновленный хук useReauthorization для обработки авторизации + const { isProcessing } = useReauthorization(); //Логика сбора данных из урла "чё мы ваще пришли на эту страницу" useAutoPay(); @@ -172,168 +176,192 @@ export default function Payment() { px: isTablet ? (upMd ? "40px" : "18px") : "20px", }} > - - {window.history.length > 1 && ( - - - - )} - Способ оплаты - - {!upMd && ( - - Выберите способ оплаты - + {/* Показываем состояние загрузки во время авторизации */} + {isProcessing && ( + + + + Идёт авторизация... + + )} - - + + {/* Основной контент страницы */} + {!isProcessing && ( + <> - {paymentMethods.map(({ name, label, image, unpopular = false }) => ( - { - setSelectedPaymentMethod(name); - }} - unpopular={false} - /> - ))} - { - setSelectedPaymentMethod("rspay"); + {window.history.length > 1 && ( + + + + )} + Способ оплаты + + {!upMd && ( + + Выберите способ оплаты + + )} + + - - - - - - {upMd && Выберите способ оплаты} - К оплате - { - siteReadyPayCart?.[userId] && notEnoughMoneyAmount > 0 ? - + + {paymentMethods.map(({ name, label, image, unpopular = false }) => ( + { + setSelectedPaymentMethod(name); + }} + unpopular={false} + /> + ))} + { + setSelectedPaymentMethod("rspay"); }} - > - {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" }} + unpopular={false} /> - } + + + + + + {upMd && Выберите способ оплаты} + К оплате + { + 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" }} + /> + } + + + - - - - - + + + + )} ); } diff --git a/src/utils/hooks/useReauthorization.ts b/src/utils/hooks/useReauthorization.ts index a06bd70..cc57937 100644 --- a/src/utils/hooks/useReauthorization.ts +++ b/src/utils/hooks/useReauthorization.ts @@ -3,21 +3,94 @@ import { logout } from '@root/api/auth'; import { setNotEnoughMoneyAmount } from '@root/stores/allTypesOfPurchases'; import { clearCustomTariffs } from '@root/stores/customTariffs'; import { clearTickets } from '@root/stores/tickets'; -import { clearUserData, useUserStore } from '@root/stores/user'; -import { useEffect } from 'react'; -import { useLocation } from 'react-router-dom'; +import { clearUserData, setUserId, useUserStore } from '@root/stores/user'; +import { useEffect, useState } from 'react'; +import { useLocation, useNavigate } from 'react-router-dom'; + +interface QuizAuthParams { + action?: string; + dif?: string; + data?: string; + userid?: string; + wayback?: string; +} export const useReauthorization = () => { - const userId = useUserStore(store => store.userId) + const userId = useUserStore(store => store.userId); + const user = useUserStore(store => store.user); const { search } = useLocation(); + const navigate = useNavigate(); + const [isProcessing, setIsProcessing] = useState(false); useEffect(() => { // Этот эффект сработает при каждом изменении query-параметров const params = new URLSearchParams(search); + // Обработка старых параметров (userid, sec) const URLuserId = params.get('userid'); const URLtoken = params.get('sec'); + // Обработка новых параметров авторизации + const quizParams: QuizAuthParams = { + action: params.get("action") || undefined, + dif: params.get("dif") || undefined, + data: params.get("data") || undefined, + userid: params.get("userid") || undefined, + wayback: params.get("wayback") || undefined, + }; + + const { action, dif, data: token, userid: quizUserId, wayback } = quizParams; + + // Если есть новые параметры авторизации, обрабатываем их + if (action && dif && token && quizUserId) { + // Если пользователь уже авторизован и это тот же пользователь, перенаправляем на payment + if (user?._id === quizUserId) { + let returnUrl = `/payment?action=${action}&dif=${dif}&user=${quizUserId}`; + if (wayback) returnUrl += `&wayback=${wayback}`; + navigate(returnUrl, { replace: true }); + return; + } + + // Если уже обрабатываем авторизацию, не запускаем повторно + if (isProcessing) { + return; + } + + setIsProcessing(true); + + const processQuizAuth = async () => { + try { + // Если есть текущий токен, очищаем данные + if (getAuthToken()) { + clearAuthToken(); + clearUserData(); + clearCustomTariffs(); + clearTickets(); + setNotEnoughMoneyAmount(0); + await logout(); + } + + // Устанавливаем новый токен и ID пользователя + setAuthToken(token); + setUserId(quizUserId); + } catch (error) { + console.error("Ошибка авторизации:", error); + + // Перенаправляем на внешний сайт в случае ошибки + const link = document.createElement("a"); + link.href = "https://quiz.pena.digital/tariffs"; + document.body.appendChild(link); + link.click(); + } finally { + setIsProcessing(false); + } + }; + + processQuizAuth(); + return; + } + + // Обработка старых параметров (userid, sec) if (URLuserId !== userId && URLtoken) { // Если есть токен в URL, устанавливаем его // Очищаем данные только если токен действительно изменился @@ -31,5 +104,9 @@ export const useReauthorization = () => { } setAuthToken(URLtoken); } - }, [search]); + }, [search, userId, user?._id, navigate, isProcessing]); + + return { + isProcessing, + }; }; \ No newline at end of file