fix payment
All checks were successful
Deploy / CreateImage (push) Successful in 8m40s
Deploy / DeployService (push) Successful in 22s

This commit is contained in:
Nastya 2025-07-18 12:47:30 +03:00
parent e44c64165a
commit 6169e03d9a
3 changed files with 266 additions and 156 deletions

@ -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 = () => {
/>
<Route path={"/image/:srcImage"} element={<ChatImageNewWindow />} />
<Route element={<PrivateRoute />}>
<Route element={<ProtectedLayout />}>
<Route path="/tariffs" element={<Tariffs />} />

@ -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,6 +176,28 @@ export default function Payment() {
px: isTablet ? (upMd ? "40px" : "18px") : "20px",
}}
>
{/* Показываем состояние загрузки во время авторизации */}
{isProcessing && (
<Box
sx={{
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "center",
minHeight: "400px",
gap: 2,
}}
>
<CircularProgress size={60} />
<Typography variant="h6" color="text.secondary">
Идёт авторизация...
</Typography>
</Box>
)}
{/* Основной контент страницы */}
{!isProcessing && (
<>
<Box
sx={{
mt: "20px",
@ -334,6 +360,8 @@ export default function Payment() {
</Box>
<WarnModal open={warnModalOpen} setOpen={setWarnModalOpen} />
<SorryModal open={sorryModalOpen} setOpen={setSorryModalOpen} />
</>
)}
</SectionWrapper>
);
}

@ -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,
};
};