fix
This commit is contained in:
parent
73e8a03a22
commit
17a697893d
59
src/App.tsx
59
src/App.tsx
@ -44,6 +44,7 @@ import RecoverPassword from "./pages/auth/RecoverPassword";
|
||||
import { InfoPrivilege } from "./pages/InfoPrivilege";
|
||||
import OutdatedLink from "./pages/auth/OutdatedLink";
|
||||
import { useAfterpay } from "@utils/hooks/useAfterpay";
|
||||
import { useUserAccountFetcher } from "@utils/hooks/useUserAccountFetcher";
|
||||
|
||||
const MyQuizzesFull = lazy(() => import("./pages/createQuize/MyQuizzesFull"));
|
||||
|
||||
@ -92,65 +93,13 @@ const LazyLoading = ({ children, fallback }: SuspenseProps) => (
|
||||
<Suspense fallback={fallback ?? <></>}>{children}</Suspense>
|
||||
);
|
||||
|
||||
export function useUserAccountFetcher<T = UserAccount>({
|
||||
onError,
|
||||
onNewUserAccount,
|
||||
url,
|
||||
userId,
|
||||
}: {
|
||||
url: string;
|
||||
userId: string | null;
|
||||
onNewUserAccount: (response: T) => void;
|
||||
onError?: (error: any) => void;
|
||||
}) {
|
||||
const onNewUserAccountRef = useRef(onNewUserAccount);
|
||||
const onErrorRef = useRef(onError);
|
||||
useLayoutEffect(() => {
|
||||
onNewUserAccountRef.current = onNewUserAccount;
|
||||
onErrorRef.current = onError;
|
||||
}, [onError, onNewUserAccount]);
|
||||
useEffect(() => {
|
||||
if (!userId) return;
|
||||
const controller = new AbortController();
|
||||
makeRequest<never, T>({
|
||||
url,
|
||||
contentType: true,
|
||||
method: "GET",
|
||||
useToken: true,
|
||||
withCredentials: false,
|
||||
signal: controller.signal,
|
||||
})
|
||||
.then((result) => {
|
||||
devlog("User account", result);
|
||||
onNewUserAccountRef.current(result);
|
||||
})
|
||||
.catch((error) => {
|
||||
devlog("Error fetching user account", error);
|
||||
if (isAxiosError(error) && error.response?.status === 404) {
|
||||
createUserAccount(controller.signal, url.replace("get", "create"))
|
||||
.then((result) => {
|
||||
devlog("Created user account", result);
|
||||
onNewUserAccountRef.current(result as T);
|
||||
})
|
||||
.catch((error) => {
|
||||
devlog("Error creating user account", error);
|
||||
onErrorRef.current?.(error);
|
||||
});
|
||||
} else {
|
||||
onErrorRef.current?.(error);
|
||||
}
|
||||
});
|
||||
return () => controller.abort();
|
||||
}, [url, userId]);
|
||||
}
|
||||
|
||||
export default function App() {
|
||||
const userId = useUserStore((state) => state.userId);
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
useUserFetcher({
|
||||
url: process.env.REACT_APP_DOMAIN + `/user/${userId}`,
|
||||
url: `${process.env.REACT_APP_DOMAIN}/user/${userId}`,
|
||||
userId,
|
||||
onNewUser: setUser,
|
||||
onError: (error) => {
|
||||
@ -164,7 +113,7 @@ export default function App() {
|
||||
});
|
||||
|
||||
useUserAccountFetcher<UserAccount>({
|
||||
url: process.env.REACT_APP_DOMAIN + "/customer/account",
|
||||
url: `${process.env.REACT_APP_DOMAIN}/customer/account`,
|
||||
userId,
|
||||
onNewUserAccount: setCustomerAccount,
|
||||
onError: (error) => {
|
||||
@ -179,7 +128,7 @@ export default function App() {
|
||||
});
|
||||
|
||||
useUserAccountFetcher<OriginalUserAccount>({
|
||||
url: process.env.REACT_APP_DOMAIN + "/squiz/account/get",
|
||||
url: `${process.env.REACT_APP_DOMAIN}/squiz/account/get`,
|
||||
userId,
|
||||
onNewUserAccount: setUserAccount,
|
||||
onError: (error) => {
|
||||
|
@ -8,7 +8,7 @@ import type {
|
||||
} from "@frontend/kitui";
|
||||
import { parseAxiosError } from "../utils/parse-error";
|
||||
|
||||
const API_URL = process.env.REACT_APP_DOMAIN + "/auth";
|
||||
const API_URL = `${process.env.REACT_APP_DOMAIN}/auth`;
|
||||
|
||||
export const register = async (
|
||||
login: string,
|
||||
@ -79,11 +79,11 @@ export const recover = async (
|
||||
formData.append("email", email);
|
||||
formData.append(
|
||||
"RedirectionURL",
|
||||
process.env.REACT_APP_DOMAIN + "/changepwd",
|
||||
`${process.env.REACT_APP_DOMAIN}/changepwd`,
|
||||
);
|
||||
|
||||
const recoverResponse = await makeRequest<unknown, unknown>({
|
||||
url: process.env.REACT_APP_DOMAIN + "/codeword/recover",
|
||||
url: `${process.env.REACT_APP_DOMAIN}/codeword/recover`,
|
||||
body: formData,
|
||||
useToken: false,
|
||||
withCredentials: true,
|
||||
|
@ -3,13 +3,13 @@ import { makeRequest } from "@api/makeRequest";
|
||||
|
||||
import { parseAxiosError } from "@utils/parse-error";
|
||||
|
||||
const API_URL = process.env.REACT_APP_DOMAIN + "/customer";
|
||||
const API_URL = `${process.env.REACT_APP_DOMAIN}/customer/cart/`;
|
||||
|
||||
export const payCart = async (): Promise<[UserAccount | null, string?]> => {
|
||||
const payCart = async (): Promise<[UserAccount | null, string?]> => {
|
||||
try {
|
||||
const payCartResponse = await makeRequest<never, UserAccount>({
|
||||
method: "POST",
|
||||
url: `${API_URL}/cart/pay`,
|
||||
url: `${API_URL}/pay`,
|
||||
useToken: true,
|
||||
});
|
||||
|
||||
@ -20,3 +20,41 @@ export const payCart = async (): Promise<[UserAccount | null, string?]> => {
|
||||
return [null, `Не удалось оплатить товар из корзины. ${error}`];
|
||||
}
|
||||
};
|
||||
|
||||
const addCartItem = async (id: string): Promise<[unknown | null, string?]> => {
|
||||
try {
|
||||
const addedItem = await makeRequest<never, unknown>({
|
||||
method: "PATCH",
|
||||
url: `${API_URL}?id=${id}`,
|
||||
});
|
||||
|
||||
return [addedItem];
|
||||
} catch (nativeError) {
|
||||
const [error] = parseAxiosError(nativeError);
|
||||
|
||||
return [null, `Не удалось добавить товар в корзину. ${error}`];
|
||||
}
|
||||
};
|
||||
|
||||
const deleteCartItem = async (
|
||||
id: string,
|
||||
): Promise<[unknown | null, string?]> => {
|
||||
try {
|
||||
const deletedItem = await makeRequest<never, unknown>({
|
||||
method: "DELETE",
|
||||
url: `${API_URL}?id=${id}`,
|
||||
});
|
||||
|
||||
return [deletedItem];
|
||||
} catch (nativeError) {
|
||||
const [error] = parseAxiosError(nativeError);
|
||||
|
||||
return [null, `Не удалось удалить товар из корзины. ${error}`];
|
||||
}
|
||||
};
|
||||
|
||||
export const cartApi = {
|
||||
pay: payCart,
|
||||
add: addCartItem,
|
||||
delete: deleteCartItem,
|
||||
};
|
||||
|
@ -2,7 +2,7 @@ import { makeRequest } from "@api/makeRequest";
|
||||
|
||||
import { parseAxiosError } from "@utils/parse-error";
|
||||
|
||||
const API_URL = process.env.REACT_APP_DOMAIN + "/feedback";
|
||||
const API_URL = `${process.env.REACT_APP_DOMAIN}/feedback`;
|
||||
|
||||
type SendContactFormBody = {
|
||||
contact: string;
|
||||
|
@ -3,7 +3,7 @@ import { parseAxiosError } from "@utils/parse-error";
|
||||
|
||||
import type { Discount } from "@model/discounts";
|
||||
|
||||
const API_URL = process.env.REACT_APP_DOMAIN + "/price/discount";
|
||||
const API_URL = `${process.env.REACT_APP_DOMAIN}/price/discount`;
|
||||
|
||||
export const getDiscounts = async (
|
||||
userId: string,
|
||||
|
@ -5,23 +5,26 @@ import { parseAxiosError } from "@utils/parse-error";
|
||||
type ActivatePromocodeRequest = { codeword: string } | { fastLink: string };
|
||||
type ActivatePromocodeResponse = { greetings: string };
|
||||
|
||||
const API_URL = process.env.REACT_APP_DOMAIN + "/codeword/promocode";
|
||||
const API_URL = `${process.env.REACT_APP_DOMAIN}/codeword/promocode`;
|
||||
|
||||
export const activatePromocode = async (promocode: string) => {
|
||||
export const activatePromocode = async (
|
||||
promocode: string,
|
||||
): Promise<[string | null, string?]> => {
|
||||
try {
|
||||
const response = await makeRequest<
|
||||
ActivatePromocodeRequest,
|
||||
ActivatePromocodeResponse
|
||||
>({
|
||||
method: "POST",
|
||||
url: API_URL + "/activate",
|
||||
url: `${API_URL}/activate`,
|
||||
body: { codeword: promocode },
|
||||
contentType: true,
|
||||
});
|
||||
|
||||
return response.greetings;
|
||||
return [response.greetings];
|
||||
} catch (nativeError) {
|
||||
const [error] = parseAxiosError(nativeError);
|
||||
throw new Error(error);
|
||||
|
||||
return [null, `Ошибка при активации промокода. ${error}`];
|
||||
}
|
||||
};
|
||||
|
@ -20,7 +20,7 @@ import {
|
||||
import { replaceSpacesToEmptyLines } from "../utils/replaceSpacesToEmptyLines";
|
||||
import { parseAxiosError } from "@utils/parse-error";
|
||||
|
||||
const API_URL = process.env.REACT_APP_DOMAIN + "/squiz";
|
||||
const API_URL = "/squiz";
|
||||
|
||||
export const createQuestion = async (
|
||||
body: CreateQuestionRequest,
|
||||
|
@ -13,8 +13,8 @@ type AddedQuizImagesResponse = {
|
||||
[key: string]: string;
|
||||
};
|
||||
|
||||
const API_URL = process.env.REACT_APP_DOMAIN + "/squiz";
|
||||
const IMAGES_URL = process.env.REACT_APP_DOMAIN + "/squizstorer";
|
||||
const API_URL = `${process.env.REACT_APP_DOMAIN}/squiz`;
|
||||
const IMAGES_URL = `${process.env.REACT_APP_DOMAIN}/squizstorer`;
|
||||
|
||||
export const createQuiz = async (
|
||||
body?: Partial<CreateQuizRequest>,
|
||||
|
@ -1,6 +1,8 @@
|
||||
import { makeRequest } from "@api/makeRequest";
|
||||
import { RawResult } from "@model/result/result";
|
||||
|
||||
import { parseAxiosError } from "@utils/parse-error";
|
||||
|
||||
interface IResultListBody {
|
||||
to: number;
|
||||
from: string;
|
||||
@ -29,46 +31,102 @@ export interface IAnswerResult {
|
||||
question_id: number;
|
||||
}
|
||||
|
||||
const API_URL = process.env.REACT_APP_DOMAIN + `/squiz`;
|
||||
const API_URL = `${process.env.REACT_APP_DOMAIN}/squiz`;
|
||||
|
||||
const getResultList = async (quizId: number, page: number, body: any) => {
|
||||
return makeRequest<IResultListBody, RawResult>({
|
||||
method: "POST",
|
||||
url: `${API_URL}/results/getResults/${quizId}`,
|
||||
body: { page: page, limit: 10, ...body },
|
||||
});
|
||||
const getResultList = async (
|
||||
quizId: number,
|
||||
page: number,
|
||||
body: any,
|
||||
): Promise<[RawResult | null, string?]> => {
|
||||
try {
|
||||
const resultList = await makeRequest<IResultListBody, RawResult>({
|
||||
method: "POST",
|
||||
url: `${API_URL}/results/getResults/${quizId}`,
|
||||
body: { page: page, limit: 10, ...body },
|
||||
});
|
||||
|
||||
return [resultList];
|
||||
} catch (nativeError) {
|
||||
const [error] = parseAxiosError(nativeError);
|
||||
|
||||
return [null, `Не удалось получить результат. ${error}`];
|
||||
}
|
||||
};
|
||||
|
||||
const deleteResult = async (resultId: number) => {
|
||||
return makeRequest<unknown, unknown>({
|
||||
method: "DELETE",
|
||||
url: `${API_URL}/results/delete/${resultId}`,
|
||||
body: {},
|
||||
});
|
||||
const deleteResult = async (
|
||||
resultId: number,
|
||||
): Promise<[unknown | null, string?]> => {
|
||||
try {
|
||||
const deletedResult = await makeRequest<unknown, unknown>({
|
||||
method: "DELETE",
|
||||
url: `${API_URL}/results/delete/${resultId}`,
|
||||
body: {},
|
||||
});
|
||||
|
||||
return [deletedResult];
|
||||
} catch (nativeError) {
|
||||
const [error] = parseAxiosError(nativeError);
|
||||
|
||||
return [null, `Не удалось удалить результат. ${error}`];
|
||||
}
|
||||
};
|
||||
|
||||
const obsolescenceResult = (idResultArray: number[]) => {
|
||||
return makeRequest<unknown, unknown>({
|
||||
method: "PATCH",
|
||||
url: `${API_URL}/result/seen`,
|
||||
body: { answers: idResultArray },
|
||||
});
|
||||
const obsolescenceResult = async (
|
||||
idResultArray: number[],
|
||||
): Promise<[unknown | null, string?]> => {
|
||||
try {
|
||||
const obsolescencedResult = await makeRequest<unknown, unknown>({
|
||||
method: "PATCH",
|
||||
url: `${API_URL}/result/seen`,
|
||||
body: { answers: idResultArray },
|
||||
});
|
||||
|
||||
return [obsolescencedResult];
|
||||
} catch (nativeError) {
|
||||
const [error] = parseAxiosError(nativeError);
|
||||
|
||||
return [null, `Не удалось изменить результат. ${error}`];
|
||||
}
|
||||
};
|
||||
|
||||
const getAnswerResultList = (resultId: number) => {
|
||||
return makeRequest<unknown, IAnswerResult[]>({
|
||||
method: "GET",
|
||||
url: `${API_URL}/result/${resultId}`,
|
||||
});
|
||||
const getAnswerResultList = async (
|
||||
resultId: number,
|
||||
): Promise<[IAnswerResult[] | null, string?]> => {
|
||||
try {
|
||||
const answerResultList = await makeRequest<unknown, IAnswerResult[]>({
|
||||
method: "GET",
|
||||
url: `${API_URL}/result/${resultId}`,
|
||||
});
|
||||
|
||||
return [answerResultList];
|
||||
} catch (nativeError) {
|
||||
const [error] = parseAxiosError(nativeError);
|
||||
|
||||
return [null, `Не удалось получить список результатов. ${error}`];
|
||||
}
|
||||
};
|
||||
|
||||
const AnswerResultListEx = (quizId: number, body: any) => {
|
||||
return makeRequest<unknown, unknown>({
|
||||
method: "POST",
|
||||
url: `${API_URL}/results/${quizId}/export`,
|
||||
body: body,
|
||||
responseType: "blob",
|
||||
});
|
||||
const AnswerResultListEx = async (
|
||||
quizId: number,
|
||||
body: any,
|
||||
): Promise<[unknown | null, string?]> => {
|
||||
try {
|
||||
const answerResultListEx = await makeRequest<unknown, unknown>({
|
||||
method: "POST",
|
||||
url: `${API_URL}/results/${quizId}/export`,
|
||||
body: body,
|
||||
responseType: "blob",
|
||||
});
|
||||
|
||||
return [answerResultListEx];
|
||||
} catch (nativeError) {
|
||||
const [error] = parseAxiosError(nativeError);
|
||||
|
||||
return [
|
||||
null,
|
||||
`Не удалось получить список устаревших результатов. ${error}`,
|
||||
];
|
||||
}
|
||||
};
|
||||
|
||||
export const resultApi = {
|
||||
|
@ -27,7 +27,7 @@ type TRequest = {
|
||||
from: number;
|
||||
};
|
||||
|
||||
const API_URL = process.env.REACT_APP_DOMAIN + "/squiz/statistic";
|
||||
const API_URL = `${process.env.REACT_APP_DOMAIN}/squiz/statistic`;
|
||||
|
||||
export const getDevices = async (
|
||||
quizId: string,
|
||||
|
23
src/api/tariff.ts
Normal file
23
src/api/tariff.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { makeRequest } from "@api/makeRequest";
|
||||
|
||||
import { parseAxiosError } from "@utils/parse-error";
|
||||
|
||||
import type { GetTariffsResponse } from "@frontend/kitui";
|
||||
|
||||
const API_URL = `${process.env.REACT_APP_DOMAIN}/strator/tariff`;
|
||||
|
||||
export const getTariffs = async (
|
||||
page: number,
|
||||
): Promise<[GetTariffsResponse | null, string?]> => {
|
||||
try {
|
||||
const tariffs = await makeRequest<never, GetTariffsResponse>({
|
||||
method: "GET",
|
||||
url: `${API_URL}?page=${page}&limit=100`,
|
||||
});
|
||||
return [tariffs];
|
||||
} catch (nativeError) {
|
||||
const [error] = parseAxiosError(nativeError);
|
||||
|
||||
return [null, `Ошибка при получении списка тарифов. ${error}`];
|
||||
}
|
||||
};
|
@ -1,9 +1,12 @@
|
||||
import { makeRequest } from "@api/makeRequest";
|
||||
import { createTicket as createTicketRequest } from "@frontend/kitui";
|
||||
import { parseAxiosError } from "../utils/parse-error";
|
||||
|
||||
import { SendTicketMessageRequest } from "@frontend/kitui";
|
||||
|
||||
const API_URL = process.env.REACT_APP_DOMAIN + "/heruvym";
|
||||
import type { CreateTicketResponse } from "@frontend/kitui";
|
||||
|
||||
const API_URL = `${process.env.REACT_APP_DOMAIN}/heruvym`;
|
||||
|
||||
export const sendTicketMessage = async (
|
||||
ticketId: string,
|
||||
@ -44,3 +47,46 @@ export const shownMessage = async (id: string): Promise<[null, string?]> => {
|
||||
return [null, `Не удалось прочесть сообщение. ${error}`];
|
||||
}
|
||||
};
|
||||
|
||||
export const sendFile = async (
|
||||
ticketId: string,
|
||||
file: File,
|
||||
): Promise<[unknown | null, string?]> => {
|
||||
try {
|
||||
const body = new FormData();
|
||||
|
||||
body.append(file.name, file);
|
||||
body.append("ticket", ticketId);
|
||||
|
||||
const sendResponse = await makeRequest<FormData, unknown>({
|
||||
method: "POST",
|
||||
url: `${process.env.REACT_APP_DOMAIN}/heruvym/sendFiles`,
|
||||
body,
|
||||
});
|
||||
|
||||
return [sendResponse];
|
||||
} catch (nativeError) {
|
||||
const [error] = parseAxiosError(nativeError);
|
||||
|
||||
return [null, `Не удалось отправить файл. ${error}`];
|
||||
}
|
||||
};
|
||||
|
||||
export const createTicket = async (
|
||||
message: string,
|
||||
useToken: boolean,
|
||||
): Promise<[CreateTicketResponse | null, string?]> => {
|
||||
try {
|
||||
const createdTicket = await createTicketRequest({
|
||||
url: `${process.env.REACT_APP_DOMAIN}/heruvym/create`,
|
||||
body: { Title: "Unauth title", Message: message },
|
||||
useToken,
|
||||
});
|
||||
|
||||
return [createdTicket];
|
||||
} catch (nativeError) {
|
||||
const [error] = parseAxiosError(nativeError);
|
||||
|
||||
return [null, `Не удалось создать тикет. ${error}`];
|
||||
}
|
||||
};
|
||||
|
62
src/api/user.ts
Normal file
62
src/api/user.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import { makeRequest } from "@api/makeRequest";
|
||||
|
||||
import { parseAxiosError } from "@utils/parse-error";
|
||||
|
||||
import type { UserAccount } from "@frontend/kitui";
|
||||
import type { OriginalUserAccount } from "@root/user";
|
||||
|
||||
export const getUser = async (): Promise<[UserAccount | null, string?]> => {
|
||||
try {
|
||||
const user = await makeRequest<never, UserAccount>({
|
||||
method: "GET",
|
||||
url: `${process.env.REACT_APP_DOMAIN}/customer/account`,
|
||||
});
|
||||
|
||||
return [user];
|
||||
} catch (nativeError) {
|
||||
const [error] = parseAxiosError(nativeError);
|
||||
|
||||
return [null, `Не удалось получить пользователя. ${error}`];
|
||||
}
|
||||
};
|
||||
|
||||
export const getAccount = async (): Promise<
|
||||
[OriginalUserAccount | null, string?]
|
||||
> => {
|
||||
try {
|
||||
const controller = new AbortController();
|
||||
|
||||
const account = await makeRequest<never, OriginalUserAccount>({
|
||||
url: `${process.env.REACT_APP_DOMAIN}/squiz/account/get`,
|
||||
contentType: true,
|
||||
method: "GET",
|
||||
useToken: true,
|
||||
withCredentials: false,
|
||||
signal: controller.signal,
|
||||
});
|
||||
|
||||
return [account];
|
||||
} catch (nativeError) {
|
||||
const [error] = parseAxiosError(nativeError);
|
||||
|
||||
return [null, `Не удалось получить данные аккаунта. ${error}`];
|
||||
}
|
||||
};
|
||||
|
||||
export const recoverUser = async (
|
||||
password: string,
|
||||
): Promise<[unknown | null, string?]> => {
|
||||
try {
|
||||
const recoverResponse = await makeRequest<{ password: string }, unknown>({
|
||||
url: `${process.env.REACT_APP_DOMAIN}/user`,
|
||||
method: "PATCH",
|
||||
body: { password },
|
||||
});
|
||||
|
||||
return [recoverResponse];
|
||||
} catch (nativeError) {
|
||||
const [error] = parseAxiosError(nativeError);
|
||||
|
||||
return [null, `Не удалось восстановить пароль. ${error}`];
|
||||
}
|
||||
};
|
@ -19,9 +19,10 @@ import { useQuizStore } from "@root/quizes/store";
|
||||
import { useQuestionsStore } from "@root/questions/store";
|
||||
import AddressIcon from "@icons/ContactFormIcon/AddressIcon";
|
||||
|
||||
import type { AxiosError } from "axios";
|
||||
import { DeleteModal } from "./DeleteModal";
|
||||
|
||||
import type { AnyTypedQuizQuestion } from "@model/questionTypes/shared";
|
||||
|
||||
interface CardAnswerProps {
|
||||
isNew: boolean;
|
||||
idResult: number;
|
||||
@ -50,29 +51,31 @@ export const CardAnswer: FC<CardAnswerProps> = ({
|
||||
const theme = useTheme();
|
||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||
const [resultsAnswer, setResultsAnswer] = useState<IAnswerResult[]>([]);
|
||||
const [questionsResultState, setQuestionsResultState] = useState([]);
|
||||
const [questionsResultState, setQuestionsResultState] = useState<
|
||||
AnyTypedQuizQuestion[]
|
||||
>([]);
|
||||
const { editQuizId } = useQuizStore();
|
||||
const { questions } = useQuestionsStore();
|
||||
const openResults = async () => {
|
||||
setIsOpen(!isOpen);
|
||||
if (!isOpen) {
|
||||
try {
|
||||
const resAnswer = await resultApi.getAnswerList(idResult);
|
||||
const resAnswerOnly = resAnswer.filter((res) => res.Result !== true);
|
||||
const resQuiz = resAnswer.filter((res) => res.Result === true);
|
||||
setResultsAnswer(resAnswerOnly);
|
||||
const idResults = resQuiz[0].question_id;
|
||||
const questionsResult = questions.filter(
|
||||
(q) => q.backendId === idResults,
|
||||
);
|
||||
setQuestionsResultState(questionsResult);
|
||||
} catch (nativeError) {
|
||||
const error = nativeError as AxiosError;
|
||||
const [resAnswer, answerError] = await resultApi.getAnswerList(idResult);
|
||||
|
||||
if (error.response?.statusText === "Payment Required") {
|
||||
openPrePaymentModal();
|
||||
}
|
||||
if (answerError || !resAnswer) {
|
||||
openPrePaymentModal();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
const resAnswerOnly = resAnswer.filter((res) => res.Result !== true);
|
||||
const resQuiz = resAnswer.filter((res) => res.Result === true);
|
||||
setResultsAnswer(resAnswerOnly);
|
||||
const idResults = resQuiz[0].question_id;
|
||||
const questionsResult = questions.filter(
|
||||
(q) => q.type && q.backendId === idResults,
|
||||
) as AnyTypedQuizQuestion[];
|
||||
|
||||
setQuestionsResultState(questionsResult);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -78,17 +78,20 @@ export const QuizAnswersPage: FC = () => {
|
||||
|
||||
const PaginationHC = async (e: ChangeEvent<unknown>, value: number) => {
|
||||
setPage(value);
|
||||
try {
|
||||
if (editQuizId !== null) {
|
||||
const result = await resultApi.getList(
|
||||
editQuizId,
|
||||
value - 1,
|
||||
parseFilters(filterNew, filterDate),
|
||||
);
|
||||
setResults(result);
|
||||
if (editQuizId !== null) {
|
||||
const [result, resultError] = await resultApi.getList(
|
||||
editQuizId,
|
||||
value - 1,
|
||||
parseFilters(filterNew, filterDate),
|
||||
);
|
||||
|
||||
if (resultError || !result) {
|
||||
console.error("An error occurred while receiving data: ", resultError);
|
||||
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("An error occurred while receiving data: ", error);
|
||||
|
||||
setResults(result);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -98,11 +98,18 @@ export const QuizSettingsMenu: FC<QuizSettingsMenuProps> = ({
|
||||
}}
|
||||
onclickUpdate={async () => {
|
||||
if (editQuizId !== null) {
|
||||
const result = await resultApi.getList(
|
||||
const [result, resultError] = await resultApi.getList(
|
||||
editQuizId,
|
||||
page - 1,
|
||||
parseFilters(filterNew, filterDate),
|
||||
);
|
||||
|
||||
if (resultError || !result) {
|
||||
console.error(resultError);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
setResults(result);
|
||||
} else {
|
||||
console.error("editQuizId is null");
|
||||
|
@ -37,11 +37,18 @@ export const useGetData = (filterNew: string, filterDate: string): void => {
|
||||
|
||||
setQuestions(questions);
|
||||
|
||||
const result = await resultApi.getList(
|
||||
const [result, resultError] = await resultApi.getList(
|
||||
editQuizId,
|
||||
0,
|
||||
parseFilters(filterNew, filterDate),
|
||||
);
|
||||
|
||||
if (resultError || !result) {
|
||||
console.error(resultError);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.total_count === 0) {
|
||||
console.error("No results found");
|
||||
}
|
||||
|
@ -33,6 +33,9 @@ import { currencyFormatter } from "./tariffsUtils/currencyFormatter";
|
||||
import { useWallet, setCash } from "@root/cash";
|
||||
import { handleLogoutClick } from "@utils/HandleLogoutClick";
|
||||
import { getDiscounts } from "@api/discounts";
|
||||
import { cartApi } from "@api/cart";
|
||||
import { getUser } from "@api/user";
|
||||
import { getTariffs } from "@api/tariff";
|
||||
|
||||
import type { Discount } from "@model/discounts";
|
||||
|
||||
@ -62,25 +65,20 @@ function TariffPage() {
|
||||
|
||||
const getTariffsList = async (): Promise<Tariff[]> => {
|
||||
const tariffsList: Tariff[] = [];
|
||||
const { tariffs, totalPages } = await makeRequest<
|
||||
never,
|
||||
GetTariffsResponse
|
||||
>({
|
||||
method: "GET",
|
||||
url: process.env.REACT_APP_DOMAIN + "/strator/tariff?page=1&limit=100",
|
||||
});
|
||||
const [tariffsResponse, tariffsResponseError] = await getTariffs(1);
|
||||
|
||||
tariffsList.push(...tariffs);
|
||||
if (tariffsResponseError || !tariffsResponse) {
|
||||
return tariffsList;
|
||||
}
|
||||
|
||||
for (let page = 2; page <= totalPages; page += 1) {
|
||||
const tariffsResult = await makeRequest<never, GetTariffsResponse>({
|
||||
method: "GET",
|
||||
url:
|
||||
process.env.REACT_APP_DOMAIN +
|
||||
`/strator/tariff?page=${page}&limit=100`,
|
||||
});
|
||||
tariffsList.push(...tariffsResponse.tariffs);
|
||||
|
||||
tariffsList.push(...tariffsResult.tariffs);
|
||||
for (let page = 2; page <= tariffsResponse.totalPages; page += 1) {
|
||||
const [tariffsResult] = await getTariffs(1);
|
||||
|
||||
if (tariffsResult) {
|
||||
tariffsList.push(...tariffsResult.tariffs);
|
||||
}
|
||||
}
|
||||
|
||||
return tariffsList;
|
||||
@ -88,10 +86,12 @@ function TariffPage() {
|
||||
|
||||
useEffect(() => {
|
||||
const get = async () => {
|
||||
const user = await makeRequest({
|
||||
method: "GET",
|
||||
url: process.env.REACT_APP_DOMAIN + "/customer/account",
|
||||
});
|
||||
const [user, userError] = await getUser();
|
||||
|
||||
if (userError) {
|
||||
return;
|
||||
}
|
||||
|
||||
const tariffsList = await getTariffsList();
|
||||
|
||||
if (userId) {
|
||||
@ -123,27 +123,22 @@ function TariffPage() {
|
||||
outCart(user.cart);
|
||||
}
|
||||
//Добавляем желаемый тариф в корзину
|
||||
await makeRequest({
|
||||
method: "PATCH",
|
||||
url: process.env.REACT_APP_DOMAIN + `/customer/cart?id=${id}`,
|
||||
});
|
||||
//Если нам хватает денежек - покупаем тариф
|
||||
const [_, addError] = await cartApi.add(id);
|
||||
|
||||
try {
|
||||
const data = await makeRequest({
|
||||
method: "POST",
|
||||
url: process.env.REACT_APP_DOMAIN + "/customer/cart/pay",
|
||||
});
|
||||
setCash(
|
||||
currencyFormatter.format(Number(data.wallet.cash) / 100),
|
||||
Number(data.wallet.cash),
|
||||
Number(data.wallet.cash) / 100,
|
||||
);
|
||||
enqueueSnackbar("Тариф успешно приобретён");
|
||||
} catch (e) {
|
||||
if (addError) {
|
||||
//Развращаем товары в корзину
|
||||
inCart();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//Если нам хватает денежек - покупаем тариф
|
||||
const [data, payError] = await cartApi.pay();
|
||||
|
||||
if (payError || !data) {
|
||||
//если денег не хватило
|
||||
if (e.response.data.message.includes("insufficient funds")) {
|
||||
let cashDif = Number(e.response.data.message.split(":")[1]);
|
||||
if (addError) {
|
||||
let cashDif = Number(addError.split(":")[1]);
|
||||
var link = document.createElement("a");
|
||||
link.href = `https://${isTestServer ? "s" : ""}hub.pena.digital/quizpayment?action=squizpay&dif=${cashDif}&data=${token}&userid=${userId}`;
|
||||
document.body.appendChild(link);
|
||||
@ -152,7 +147,18 @@ function TariffPage() {
|
||||
}
|
||||
//другая ошибка
|
||||
enqueueSnackbar("Произошла ошибка. Попробуйте позже");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
setCash(
|
||||
currencyFormatter.format(Number(data.wallet.cash) / 100),
|
||||
Number(data.wallet.cash),
|
||||
Number(data.wallet.cash) / 100,
|
||||
);
|
||||
|
||||
enqueueSnackbar("Тариф успешно приобретён");
|
||||
|
||||
//Развращаем товары в корзину
|
||||
inCart();
|
||||
};
|
||||
@ -179,31 +185,32 @@ function TariffPage() {
|
||||
return tariff.privileges[0].privilegeId !== "squizHideBadge";
|
||||
});
|
||||
|
||||
function handleApplyPromocode() {
|
||||
async function handleApplyPromocode() {
|
||||
if (!promocodeField) return;
|
||||
|
||||
activatePromocode(promocodeField)
|
||||
.then(async (greetings) => {
|
||||
enqueueSnackbar(greetings);
|
||||
const [greetings, error] = await activatePromocode(promocodeField);
|
||||
|
||||
if (!userId) {
|
||||
return;
|
||||
}
|
||||
if (error) {
|
||||
enqueueSnackbar(error);
|
||||
|
||||
const [discounts, discountsError] = await getDiscounts(userId);
|
||||
return;
|
||||
}
|
||||
|
||||
if (discountsError) {
|
||||
throw new Error(discountsError);
|
||||
}
|
||||
enqueueSnackbar(greetings);
|
||||
|
||||
if (discounts?.length) {
|
||||
setDiscounts(discounts);
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
if (error.message !== "" && typeof error.message === "string")
|
||||
enqueueSnackbar(error.message);
|
||||
});
|
||||
if (!userId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const [discounts, discountsError] = await getDiscounts(userId);
|
||||
|
||||
if (discountsError) {
|
||||
throw new Error(discountsError);
|
||||
}
|
||||
|
||||
if (discounts?.length) {
|
||||
setDiscounts(discounts);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
@ -396,19 +403,18 @@ export const inCart = () => {
|
||||
let saveCart = JSON.parse(localStorage.getItem("saveCart") || "[]");
|
||||
if (Array.isArray(saveCart)) {
|
||||
saveCart.forEach(async (id: string) => {
|
||||
try {
|
||||
await makeRequest({
|
||||
method: "PATCH",
|
||||
url: process.env.REACT_APP_DOMAIN + `/customer/cart?id=${id}`,
|
||||
});
|
||||
const [_, addError] = await cartApi.add(id);
|
||||
|
||||
if (addError) {
|
||||
console.error(addError);
|
||||
} else {
|
||||
let index = saveCart.indexOf("green");
|
||||
|
||||
if (index !== -1) {
|
||||
saveCart.splice(index, 1);
|
||||
}
|
||||
|
||||
localStorage.setItem("saveCart", JSON.stringify(saveCart));
|
||||
} catch (e) {
|
||||
console.error("Я не смог добавить тариф в корзину :( " + id);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
@ -418,16 +424,16 @@ export const inCart = () => {
|
||||
const outCart = (cart: string[]) => {
|
||||
//Сделаем муторно и подольше, зато при прерывании сессии данные потеряются минимально
|
||||
cart.forEach(async (id: string) => {
|
||||
try {
|
||||
await makeRequest({
|
||||
method: "DELETE",
|
||||
url: process.env.REACT_APP_DOMAIN + `/customer/cart?id=${id}`,
|
||||
});
|
||||
let saveCart = JSON.parse(localStorage.getItem("saveCart") || "[]");
|
||||
saveCart = saveCart.push(id);
|
||||
localStorage.setItem("saveCart", JSON.stringify(saveCart));
|
||||
} catch (e) {
|
||||
console.error("Я не смог удалить из корзины тариф :(");
|
||||
const [_, deleteError] = await cartApi.delete(id);
|
||||
|
||||
if (deleteError) {
|
||||
console.error(deleteError);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
let saveCart = JSON.parse(localStorage.getItem("saveCart") || "[]");
|
||||
saveCart = saveCart.push(id);
|
||||
localStorage.setItem("saveCart", JSON.stringify(saveCart));
|
||||
});
|
||||
};
|
||||
|
@ -21,6 +21,7 @@ import { useUserStore } from "@root/user";
|
||||
import { makeRequest } from "@api/makeRequest";
|
||||
import { setAuthToken } from "@frontend/kitui";
|
||||
import { parseAxiosError } from "@utils/parse-error";
|
||||
import { recoverUser } from "@api/user";
|
||||
interface Values {
|
||||
password: string;
|
||||
}
|
||||
@ -55,21 +56,17 @@ export default function RecoverPassword() {
|
||||
onSubmit: async (values, formikHelpers) => {
|
||||
if (tokenUser) {
|
||||
setAuthToken(tokenUser || "");
|
||||
try {
|
||||
const response = await makeRequest<unknown, unknown>({
|
||||
url: process.env.REACT_APP_DOMAIN + "/user/",
|
||||
method: "PATCH",
|
||||
body: { password: values.password },
|
||||
});
|
||||
const [_, recoverError] = await recoverUser(values.password);
|
||||
|
||||
if (recoverError) {
|
||||
setAuthToken("");
|
||||
enqueueSnackbar(
|
||||
`Извините, произошла ошибка, попробуйте повторить позже. ${recoverError}`,
|
||||
);
|
||||
} else {
|
||||
setIsDialogOpen(false);
|
||||
navigate("/");
|
||||
enqueueSnackbar("Пароль успешно сменён");
|
||||
} catch (nativeError) {
|
||||
const [error] = parseAxiosError(nativeError);
|
||||
setAuthToken("");
|
||||
enqueueSnackbar(
|
||||
`Извините, произошла ошибка, попробуйте повторить позже. ${error}`,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
enqueueSnackbar("Неверный url-адрес");
|
||||
|
@ -7,7 +7,7 @@ import {
|
||||
} from "@root/user";
|
||||
import { clearAuthToken, getMessageFromFetchError } from "@frontend/kitui";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
import { useUserAccountFetcher } from "../../App";
|
||||
import { useUserAccountFetcher } from "@utils/hooks/useUserAccountFetcher";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import moment from "moment";
|
||||
|
||||
@ -17,7 +17,7 @@ export default function AvailablePrivilege() {
|
||||
const userId = useUserStore((state) => state.userId);
|
||||
const navigate = useNavigate();
|
||||
useUserAccountFetcher<OriginalUserAccount>({
|
||||
url: process.env.REACT_APP_DOMAIN + "/squiz/account/get",
|
||||
url: `${process.env.REACT_APP_DOMAIN}/squiz/account/get`,
|
||||
userId,
|
||||
onNewUserAccount: setUserAccount,
|
||||
onError: (error) => {
|
||||
|
@ -20,6 +20,7 @@ import { enqueueSnackbar } from "notistack";
|
||||
import { useDomainDefine } from "@utils/hooks/useDomainDefine";
|
||||
import CopyIcon from "@icons/CopyIcon";
|
||||
import ChartIcon from "@icons/ChartIcon";
|
||||
import { cartApi } from "@api/cart";
|
||||
|
||||
interface Props {
|
||||
quiz: Quiz;
|
||||
@ -55,17 +56,17 @@ export default function QuizCard({
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const pay = async () => {
|
||||
try {
|
||||
await makeRequest({
|
||||
method: "POST",
|
||||
url: process.env.REACT_APP_DOMAIN + "/customer/cart/pay",
|
||||
});
|
||||
inCart();
|
||||
} catch (e) {
|
||||
const [_, payError] = await cartApi.pay();
|
||||
|
||||
if (payError) {
|
||||
enqueueSnackbar(
|
||||
"Попробуйте снова купить тариф после зачисления средств",
|
||||
);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
inCart();
|
||||
};
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
const fromSquiz = params.get("action");
|
||||
|
@ -129,7 +129,7 @@ export const quizStore = create<QuizStore>()(
|
||||
config: {
|
||||
noStartPage: false,
|
||||
type: "", // quiz или form
|
||||
logo: process.env.REACT_APP_DOMAIN + "/img/logo",
|
||||
logo: `${process.env.REACT_APP_DOMAIN}/img/logo`,
|
||||
startpage: {
|
||||
description: "", // приветственный текст опроса
|
||||
button: "", // текст на кнопке начала опроса
|
||||
|
@ -39,15 +39,16 @@ export const deleteResult = async (resultId: number) =>
|
||||
.results.find((r) => r.id === resultId);
|
||||
if (!result) return;
|
||||
|
||||
try {
|
||||
await resultApi.delete(Number(result.id));
|
||||
removeResult(resultId);
|
||||
} catch (error) {
|
||||
devlog("Error delete result", error);
|
||||
const [_, deleteError] = await resultApi.delete(Number(result.id));
|
||||
|
||||
const message = getMessageFromFetchError(error) ?? "";
|
||||
enqueueSnackbar(`Не удалось удалить результат. ${message}`);
|
||||
if (deleteError) {
|
||||
devlog("Error delete result", deleteError);
|
||||
enqueueSnackbar(deleteError);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
removeResult(resultId);
|
||||
});
|
||||
|
||||
export const obsolescenceResult = async (
|
||||
@ -68,17 +69,24 @@ export const obsolescenceResult = async (
|
||||
if (typeof lossDebouncer === "number") clearTimeout(lossDebouncer);
|
||||
lossDebouncer = setTimeout(async () => {
|
||||
//стреляем на лишение новизны
|
||||
try {
|
||||
await resultApi.obsolescence(lossId);
|
||||
lossId = [];
|
||||
} catch (error) {
|
||||
devlog("Error", error);
|
||||
const [_, obsolescenceError] = await resultApi.obsolescence(lossId);
|
||||
|
||||
const message = getMessageFromFetchError(error) ?? "";
|
||||
enqueueSnackbar(`Ошибка. ${message}`);
|
||||
if (obsolescenceError) {
|
||||
devlog("Error", obsolescenceError);
|
||||
|
||||
enqueueSnackbar(obsolescenceError);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
lossId = [];
|
||||
}, 3000);
|
||||
const resultList = await resultApi.getList(editQuizId);
|
||||
const [resultList, resultError] = await resultApi.getList(editQuizId);
|
||||
|
||||
if (resultError || !resultList) {
|
||||
return;
|
||||
}
|
||||
|
||||
setResults(resultList);
|
||||
},
|
||||
);
|
||||
@ -90,30 +98,28 @@ export const ExportResults = async (
|
||||
openPrePaymentModal: () => void,
|
||||
editQuizId: number,
|
||||
) => {
|
||||
try {
|
||||
const data = await resultApi.export(
|
||||
editQuizId,
|
||||
parseFilters(filterNew, filterDate),
|
||||
);
|
||||
const [data, resultError] = await resultApi.export(
|
||||
editQuizId,
|
||||
parseFilters(filterNew, filterDate),
|
||||
);
|
||||
|
||||
console.log(typeof data);
|
||||
if (resultError) {
|
||||
openPrePaymentModal();
|
||||
|
||||
const blob = new Blob([data as BlobPart], {
|
||||
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8",
|
||||
});
|
||||
|
||||
const link = document.createElement("a");
|
||||
link.href = window.URL.createObjectURL(data as Blob);
|
||||
console.log(link);
|
||||
link.download = `report_${new Date().getTime()}.xlsx`;
|
||||
link.click();
|
||||
} catch (nativeError) {
|
||||
const error = nativeError as AxiosError;
|
||||
|
||||
if (error.response?.statusText === "Payment Required") {
|
||||
openPrePaymentModal();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(typeof data);
|
||||
|
||||
const blob = new Blob([data as BlobPart], {
|
||||
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=utf-8",
|
||||
});
|
||||
|
||||
const link = document.createElement("a");
|
||||
link.href = window.URL.createObjectURL(data as Blob);
|
||||
console.log(link);
|
||||
link.download = `report_${new Date().getTime()}.xlsx`;
|
||||
link.click();
|
||||
};
|
||||
|
||||
function setProducedState<A extends string | { type: string }>(
|
||||
|
@ -13,7 +13,7 @@ import {
|
||||
useUserStore,
|
||||
} from "@root/user";
|
||||
import { parseAxiosError } from "@utils/parse-error";
|
||||
import { useUserAccountFetcher } from "../App";
|
||||
import { useUserAccountFetcher } from "@utils/hooks/useUserAccountFetcher";
|
||||
import type { Discount } from "@model/discounts";
|
||||
import {
|
||||
clearAuthToken,
|
||||
@ -23,6 +23,8 @@ import {
|
||||
} from "@frontend/kitui";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { isAxiosError } from "axios";
|
||||
import { activatePromocode } from "@api/promocode";
|
||||
import { getAccount } from "@api/user";
|
||||
|
||||
export function CheckFastlink() {
|
||||
const user = useUserStore();
|
||||
@ -50,40 +52,28 @@ export function CheckFastlink() {
|
||||
|
||||
const fetchPromocode = async () => {
|
||||
if (promocode.length > 0) {
|
||||
try {
|
||||
const response = await makeRequest<
|
||||
{ codeword: string } | { fastLink: string },
|
||||
{ greetings: string }
|
||||
>({
|
||||
url:
|
||||
process.env.REACT_APP_DOMAIN + "/codeword/promocode" + "/activate",
|
||||
method: "POST",
|
||||
contentType: true,
|
||||
body: { fastLink: promocode },
|
||||
});
|
||||
enqueueSnackbar(
|
||||
response.greetings !== ""
|
||||
? response.greetings
|
||||
: "Промокод успешно активирован",
|
||||
);
|
||||
localStorage.setItem("fl", "");
|
||||
const controller = new AbortController();
|
||||
const responseAccount = await makeRequest<never, any>({
|
||||
url: process.env.REACT_APP_DOMAIN + "/squiz/account/get",
|
||||
contentType: true,
|
||||
method: "GET",
|
||||
useToken: true,
|
||||
withCredentials: false,
|
||||
signal: controller.signal,
|
||||
});
|
||||
setUserAccount(responseAccount);
|
||||
mutate("discounts");
|
||||
return response.greetings;
|
||||
} catch (nativeError) {
|
||||
const [error] = parseAxiosError(nativeError);
|
||||
enqueueSnackbar(error);
|
||||
const [greetings, activationError] = await activatePromocode(promocode);
|
||||
|
||||
if (activationError || !greetings) {
|
||||
enqueueSnackbar(activationError);
|
||||
localStorage.setItem("fl", "");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
enqueueSnackbar(
|
||||
greetings !== "" ? greetings : "Промокод успешно активирован",
|
||||
);
|
||||
localStorage.setItem("fl", "");
|
||||
const [responseAccount, accountError] = await getAccount();
|
||||
|
||||
if (accountError || !responseAccount) {
|
||||
return;
|
||||
}
|
||||
|
||||
setUserAccount(responseAccount);
|
||||
mutate("discounts");
|
||||
return greetings;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
import {
|
||||
createTicket,
|
||||
TicketMessage,
|
||||
useSSESubscription,
|
||||
useTicketMessages,
|
||||
@ -23,6 +22,7 @@ import {
|
||||
} from "@root/ticket";
|
||||
import { enqueueSnackbar } from "notistack";
|
||||
import { getMessageFromFetchError } from "@utils/backendMessageHandler";
|
||||
import { createTicket, sendFile as sendFileRequest } from "@api/ticket";
|
||||
|
||||
type ModalWarningType =
|
||||
| "errorType"
|
||||
@ -100,7 +100,7 @@ export default () => {
|
||||
}, [isChatOpened]);
|
||||
|
||||
useTicketsFetcher({
|
||||
url: process.env.REACT_APP_DOMAIN + "/heruvym/getTickets",
|
||||
url: `${process.env.REACT_APP_DOMAIN}/heruvym/getTickets`,
|
||||
ticketsPerPage: 10,
|
||||
ticketApiPage: 0,
|
||||
onSuccess: (result) => {
|
||||
@ -128,7 +128,7 @@ export default () => {
|
||||
});
|
||||
|
||||
useTicketMessages({
|
||||
url: process.env.REACT_APP_DOMAIN + "/heruvym/getMessages",
|
||||
url: `${process.env.REACT_APP_DOMAIN}/heruvym/getMessages`,
|
||||
isUnauth: true,
|
||||
ticketId: ticket.sessionData?.ticketId,
|
||||
messagesPerPage: ticket.messagesPerPage,
|
||||
@ -146,9 +146,7 @@ export default () => {
|
||||
useSSESubscription<TicketMessage>({
|
||||
enabled:
|
||||
sseEnabled && isActiveSSETab && Boolean(ticket.sessionData?.sessionId),
|
||||
url:
|
||||
process.env.REACT_APP_DOMAIN +
|
||||
`/heruvym/ticket?ticket=${ticket.sessionData?.ticketId}&s=${ticket.sessionData?.sessionId}`,
|
||||
url: `${process.env.REACT_APP_DOMAIN}/heruvym/ticket?ticket=${ticket.sessionData?.ticketId}&s=${ticket.sessionData?.sessionId}`,
|
||||
onNewData: (ticketMessages) => {
|
||||
const isTicketClosed = ticketMessages.some(
|
||||
(message) => message.session_id === "close",
|
||||
@ -195,25 +193,21 @@ export default () => {
|
||||
let successful = false;
|
||||
setIsMessageSending(true);
|
||||
if (!ticket.sessionData?.ticketId) {
|
||||
try {
|
||||
const data = await createTicket({
|
||||
url: process.env.REACT_APP_DOMAIN + "/heruvym/create",
|
||||
body: {
|
||||
Title: "Unauth title",
|
||||
Message: messageField,
|
||||
},
|
||||
useToken: Boolean(user),
|
||||
});
|
||||
successful = true;
|
||||
setTicketData({
|
||||
ticketId: data.Ticket,
|
||||
sessionId: data.sess,
|
||||
});
|
||||
} catch (error: any) {
|
||||
const [data, createError] = await createTicket(
|
||||
messageField,
|
||||
Boolean(user),
|
||||
);
|
||||
|
||||
if (createError || !data) {
|
||||
successful = false;
|
||||
const errorMessage = getMessageFromFetchError(error);
|
||||
if (errorMessage) enqueueSnackbar(errorMessage);
|
||||
|
||||
enqueueSnackbar(createError);
|
||||
} else {
|
||||
successful = true;
|
||||
|
||||
setTicketData({ ticketId: data.Ticket, sessionId: data.sess });
|
||||
}
|
||||
|
||||
setIsMessageSending(false);
|
||||
} else {
|
||||
const [_, sendTicketMessageError] = await sendTicketMessage(
|
||||
@ -234,45 +228,29 @@ export default () => {
|
||||
const sendFile = async (file: File) => {
|
||||
if (file === undefined) return true;
|
||||
|
||||
let data;
|
||||
let ticketId = ticket.sessionData?.ticketId;
|
||||
if (!ticket.sessionData?.ticketId) {
|
||||
try {
|
||||
data = await createTicket({
|
||||
url: process.env.REACT_APP_DOMAIN + "/heruvym/create",
|
||||
body: {
|
||||
Title: "Unauth title",
|
||||
Message: "",
|
||||
},
|
||||
useToken: Boolean(user),
|
||||
});
|
||||
setTicketData({
|
||||
ticketId: data.Ticket,
|
||||
sessionId: data.sess,
|
||||
});
|
||||
} catch (error: any) {
|
||||
const errorMessage = getMessageFromFetchError(error);
|
||||
if (errorMessage) enqueueSnackbar(errorMessage);
|
||||
const [data, createError] = await createTicket("", Boolean(user));
|
||||
ticketId = data?.Ticket;
|
||||
|
||||
if (createError || !data) {
|
||||
enqueueSnackbar(createError);
|
||||
} else {
|
||||
setTicketData({ ticketId: data.Ticket, sessionId: data.sess });
|
||||
}
|
||||
|
||||
setIsMessageSending(false);
|
||||
}
|
||||
|
||||
const ticketId = ticket.sessionData?.ticketId || data?.Ticket;
|
||||
if (ticketId !== undefined) {
|
||||
if (file.size > MAX_FILE_SIZE) return setModalWarningType("errorSize");
|
||||
try {
|
||||
const body = new FormData();
|
||||
|
||||
body.append(file.name, file);
|
||||
body.append("ticket", ticketId);
|
||||
await makeRequest({
|
||||
url: process.env.REACT_APP_DOMAIN + "/heruvym/sendFiles",
|
||||
body: body,
|
||||
method: "POST",
|
||||
});
|
||||
} catch (error: any) {
|
||||
const errorMessage = getMessageFromFetchError(error);
|
||||
if (errorMessage) enqueueSnackbar(errorMessage);
|
||||
const [_, sendFileError] = await sendFileRequest(ticketId, file);
|
||||
|
||||
if (sendFileError) {
|
||||
enqueueSnackbar(sendFileError);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
@ -2,7 +2,7 @@ import { useNavigate } from "react-router-dom";
|
||||
import { setCash } from "@root/cash";
|
||||
import { useUserStore } from "@root/user";
|
||||
|
||||
import { payCart } from "@api/cart";
|
||||
import { cartApi } from "@api/cart";
|
||||
import { currencyFormatter } from "../../pages/Tariffs/tariffsUtils/currencyFormatter";
|
||||
|
||||
const MINUTE = 1000 * 60;
|
||||
@ -36,7 +36,7 @@ export const useAfterpay = () => {
|
||||
async function tryPayCart() {
|
||||
tryCount += 1;
|
||||
|
||||
const [data, payCartError] = await payCart();
|
||||
const [data, payCartError] = await cartApi.pay();
|
||||
if (data !== null)
|
||||
setCash(
|
||||
currencyFormatter.format(Number(data.wallet.cash) / 100),
|
||||
|
59
src/utils/hooks/useUserAccountFetcher.ts
Normal file
59
src/utils/hooks/useUserAccountFetcher.ts
Normal file
@ -0,0 +1,59 @@
|
||||
import { useEffect, useLayoutEffect, useRef } from "react";
|
||||
import { createUserAccount, devlog } from "@frontend/kitui";
|
||||
import { isAxiosError } from "axios";
|
||||
|
||||
import { makeRequest } from "@api/makeRequest";
|
||||
|
||||
import type { UserAccount } from "@frontend/kitui";
|
||||
|
||||
export const useUserAccountFetcher = <T = UserAccount>({
|
||||
onError,
|
||||
onNewUserAccount,
|
||||
url,
|
||||
userId,
|
||||
}: {
|
||||
url: string;
|
||||
userId: string | null;
|
||||
onNewUserAccount: (response: T) => void;
|
||||
onError?: (error: any) => void;
|
||||
}) => {
|
||||
const onNewUserAccountRef = useRef(onNewUserAccount);
|
||||
const onErrorRef = useRef(onError);
|
||||
useLayoutEffect(() => {
|
||||
onNewUserAccountRef.current = onNewUserAccount;
|
||||
onErrorRef.current = onError;
|
||||
}, [onError, onNewUserAccount]);
|
||||
useEffect(() => {
|
||||
if (!userId) return;
|
||||
const controller = new AbortController();
|
||||
makeRequest<never, T>({
|
||||
url,
|
||||
contentType: true,
|
||||
method: "GET",
|
||||
useToken: true,
|
||||
withCredentials: false,
|
||||
signal: controller.signal,
|
||||
})
|
||||
.then((result) => {
|
||||
devlog("User account", result);
|
||||
onNewUserAccountRef.current(result);
|
||||
})
|
||||
.catch((error) => {
|
||||
devlog("Error fetching user account", error);
|
||||
if (isAxiosError(error) && error.response?.status === 404) {
|
||||
createUserAccount(controller.signal, url.replace("get", "create"))
|
||||
.then((result) => {
|
||||
devlog("Created user account", result);
|
||||
onNewUserAccountRef.current(result as T);
|
||||
})
|
||||
.catch((error) => {
|
||||
devlog("Error creating user account", error);
|
||||
onErrorRef.current?.(error);
|
||||
});
|
||||
} else {
|
||||
onErrorRef.current?.(error);
|
||||
}
|
||||
});
|
||||
return () => controller.abort();
|
||||
}, [url, userId]);
|
||||
};
|
Loading…
Reference in New Issue
Block a user