From dc23829a4982b6d2139c07bae4765d6da7a77a19 Mon Sep 17 00:00:00 2001 From: IlyaDoronin Date: Tue, 21 May 2024 17:10:02 +0300 Subject: [PATCH 1/3] refactor: requests decomposed --- src/api/account.ts | 21 +++++++++- src/api/quiz.ts | 26 ++++++++++++ src/api/roles.ts | 2 +- src/api/tickets.ts | 41 ++++++++++++++++++- .../dashboard/Content/Support/Chat/Chat.tsx | 23 ++++------- .../Support/TicketList/CloseTicketModal.tsx | 29 +++---------- src/pages/dashboard/ModalUser/QuizTab.tsx | 15 +------ .../dashboard/ModalUser/VerificationTab.tsx | 12 ++---- 8 files changed, 106 insertions(+), 63 deletions(-) create mode 100644 src/api/quiz.ts diff --git a/src/api/account.ts b/src/api/account.ts index e9f4ba3..3548446 100644 --- a/src/api/account.ts +++ b/src/api/account.ts @@ -30,12 +30,12 @@ export type Account = { wallet: Wallet; }; -const baseUrl = process.env.REACT_APP_DOMAIN + "/customer"; +const API_URL = process.env.REACT_APP_DOMAIN + "/customer"; export const getAccountInfo = async (id: string): Promise<[Account | null, string?]> => { try { const accountInfoResponse = await makeRequest({ - url: `${baseUrl}/account/${id}`, + url: `${API_URL}/account/${id}`, method: "GET", useToken: true, }); @@ -47,3 +47,20 @@ export const getAccountInfo = async (id: string): Promise<[Account | null, strin return [null, `Не удалось получить информацию об аккаунте. ${error}`]; } }; + +export const editAccount = async (userId: string, status: "org" | "nko"): Promise<[unknown | null, string?]> => { + try { + const editResponse = await makeRequest<{ status: "org" | "nko" }, unknown>({ + method: "patch", + useToken: true, + url: `${API_URL}/account/${userId}`, + body: { status }, + }); + + return [editResponse]; + } catch (nativeError) { + const [error] = parseAxiosError(nativeError); + + return [null, `Не удалось отредактировать информацию. ${error}`]; + } +}; diff --git a/src/api/quiz.ts b/src/api/quiz.ts new file mode 100644 index 0000000..b4064a3 --- /dev/null +++ b/src/api/quiz.ts @@ -0,0 +1,26 @@ +import makeRequest from "@root/api/makeRequest"; + +import { parseAxiosError } from "@root/utils/parse-error"; + +const API_URL = `${process.env.REACT_APP_DOMAIN}/squiz/quiz`; + +type MoveQuizBody = { + Qid: string; + AccountID: string; +}; + +export const moveQuiz = async (quizId: string, userId: string): Promise<[unknown | null, string?]> => { + try { + const moveResponse = await makeRequest({ + method: "post", + url: `${API_URL}/move`, + body: { Qid: quizId, AccountID: userId }, + }); + + return [moveResponse]; + } catch (nativeError) { + const [error] = parseAxiosError(nativeError); + + return [null, `Ошибка перемещения квиза. ${error}`]; + } +}; diff --git a/src/api/roles.ts b/src/api/roles.ts index d0470f5..a99c242 100644 --- a/src/api/roles.ts +++ b/src/api/roles.ts @@ -47,7 +47,7 @@ export const getRoles_mock = (): Promise => { export const deleteRole = async (id: string): Promise<[unknown, string?]> => { try { - const deleteRoleResponse = await makeRequest({ + const deleteRoleResponse = await makeRequest({ url: `${baseUrl}/${id}`, method: "delete", }); diff --git a/src/api/tickets.ts b/src/api/tickets.ts index d0befdc..d7ca441 100644 --- a/src/api/tickets.ts +++ b/src/api/tickets.ts @@ -4,12 +4,12 @@ import { parseAxiosError } from "@root/utils/parse-error"; import type { SendTicketMessageRequest } from "@root/model/ticket"; -const baseUrl = process.env.REACT_APP_DOMAIN + "/heruvym"; +const API_URL = process.env.REACT_APP_DOMAIN + "/heruvym"; export const sendTicketMessage = async (body: SendTicketMessageRequest): Promise<[unknown, string?]> => { try { const sendTicketMessageResponse = await makeRequest({ - url: `${baseUrl}/send`, + url: `${API_URL}/send`, method: "POST", useToken: true, body, @@ -22,3 +22,40 @@ export const sendTicketMessage = async (body: SendTicketMessageRequest): Promise return [null, `Ошибка отправки сообщения. ${error}`]; } }; + +export const closeTicket = async (ticketId: string): Promise<[unknown, string?]> => { + try { + const ticketCloseResponse = await makeRequest({ + url: `${API_URL}/close`, + method: "post", + useToken: true, + body: { ticket: ticketId }, + }); + + return [ticketCloseResponse]; + } catch (nativeError) { + const [error] = parseAxiosError(nativeError); + + return [null, `Не удалось закрыть тикет. ${error}`]; + } +}; + +export const sendFile = async (file: File, ticketId: string): Promise<[unknown | null, string?]> => { + try { + const body = new FormData(); + body.append(file.name, file); + body.append("ticket", ticketId); + + const sendFileRespose = await makeRequest({ + method: "POST", + url: `${API_URL}/sendFiles`, + body, + }); + + return [sendFileRespose]; + } catch (nativeError) { + const [error] = parseAxiosError(nativeError); + + return [null, `Не удалось отправить файл. ${error}`]; + } +}; diff --git a/src/pages/dashboard/Content/Support/Chat/Chat.tsx b/src/pages/dashboard/Content/Support/Chat/Chat.tsx index 0585ca9..9f124d5 100644 --- a/src/pages/dashboard/Content/Support/Chat/Chat.tsx +++ b/src/pages/dashboard/Content/Support/Chat/Chat.tsx @@ -30,6 +30,7 @@ import ChatDocument from "./ChatDocument"; import ChatVideo from "./ChatVideo"; import ChatMessage from "./ChatMessage"; import { ACCEPT_SEND_MEDIA_TYPES_MAP, MAX_FILE_SIZE, MAX_PHOTO_SIZE, MAX_VIDEO_SIZE } from "./fileUpload"; +import { sendFile as sendFileRequest } from "@root/api/tickets"; const tooLarge = "Файл слишком большой"; const checkAcceptableMediaType = (file: File) => { @@ -164,24 +165,18 @@ export default function Chat() { const sendFile = async (file: File) => { if (file === undefined) return true; - let data; - const ticketId = ticket?.id; if (ticketId !== undefined) { - try { - const body = new FormData(); + const [_, sendFileError] = await sendFileRequest(file, ticketId); - 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); + if (sendFileError) { + const errorMessage = getMessageFromFetchError(sendFileError); + + if (errorMessage) { + enqueueSnackbar(errorMessage); + } } + return true; } }; diff --git a/src/pages/dashboard/Content/Support/TicketList/CloseTicketModal.tsx b/src/pages/dashboard/Content/Support/TicketList/CloseTicketModal.tsx index daafdcc..f258885 100644 --- a/src/pages/dashboard/Content/Support/TicketList/CloseTicketModal.tsx +++ b/src/pages/dashboard/Content/Support/TicketList/CloseTicketModal.tsx @@ -5,6 +5,7 @@ import Typography from "@mui/material/Typography"; import Button from "@mui/material/Button"; import makeRequest from "@root/api/makeRequest"; import { parseAxiosError } from "@root/utils/parse-error"; +import { closeTicket } from "@root/api/tickets"; interface Props { ticketId: string | undefined; openModal: boolean; @@ -12,22 +13,10 @@ interface Props { } export default function CloseTicketModal({ ticketId, openModal, setOpenModal }: Props) { - const CloseTicket = async () => { - try { - const ticketCloseResponse = await makeRequest({ - url: process.env.REACT_APP_DOMAIN + "/heruvym/close", - method: "post", - useToken: true, - body: { - ticket: ticketId, - }, - }); - - return [ticketCloseResponse]; - } catch (nativeError) { - const [error] = parseAxiosError(nativeError); - - return [null, `Не удалось закрыть тикет. ${error}`]; + const onCloseTicket = async () => { + if (ticketId) { + await closeTicket(ticketId); + setOpenModal(false); } }; @@ -64,13 +53,7 @@ export default function CloseTicketModal({ ticketId, openModal, setOpenModal }: alignItems: "center", }} > - diff --git a/src/pages/dashboard/ModalUser/VerificationTab.tsx b/src/pages/dashboard/ModalUser/VerificationTab.tsx index 1779153..d8b6b55 100644 --- a/src/pages/dashboard/ModalUser/VerificationTab.tsx +++ b/src/pages/dashboard/ModalUser/VerificationTab.tsx @@ -6,7 +6,7 @@ import { useDebouncedCallback } from "use-debounce"; import type { ChangeEvent } from "react"; import type { Verification } from "@root/api/verification"; -import makeRequest from "@root/api/makeRequest"; +import { editAccount } from "@root/api/account"; type VerificationTabProps = { userId: string; @@ -66,13 +66,9 @@ export const VerificationTab = ({ userId }: VerificationTabProps) => { status: verificationInfo.status, }); - if (accepted && _ === "OK") - await makeRequest({ - method: "patch", - useToken: true, - url: process.env.REACT_APP_DOMAIN + `/customer/account/${userId}`, - body: { status: verificationInfo.status }, - }); + if (accepted && _ === "OK") { + await editAccount(userId, verificationInfo.status); + } if (patchVerificationError) { return console.error("Error verifying:", patchVerificationError); From 2264fef8aabe3796f658db4321e88b15124492f2 Mon Sep 17 00:00:00 2001 From: IlyaDoronin Date: Wed, 22 May 2024 16:48:38 +0300 Subject: [PATCH 2/3] refactor: requests --- src/api/account.ts | 12 +- src/api/auth.ts | 12 +- src/api/discounts.ts | 32 ++--- src/api/history/requests.ts | 4 +- src/api/privilegies.ts | 24 ++-- src/api/promocode/requests.ts | 114 +++++++++--------- src/api/quiz.ts | 6 +- src/api/quizStatistics/index.ts | 28 +++-- src/api/roles.ts | 6 +- src/api/tariffs.ts | 26 ++-- src/api/tickets.ts | 30 +++-- src/api/user/requests.ts | 16 +-- src/api/verification.ts | 16 +-- .../dashboard/ModalUser/VerificationTab.tsx | 2 +- src/utils/hooks/usePromocodeStatistics.ts | 4 +- 15 files changed, 173 insertions(+), 159 deletions(-) diff --git a/src/api/account.ts b/src/api/account.ts index 3548446..05e9c9a 100644 --- a/src/api/account.ts +++ b/src/api/account.ts @@ -30,13 +30,13 @@ export type Account = { wallet: Wallet; }; -const API_URL = process.env.REACT_APP_DOMAIN + "/customer"; +const API_URL = `${process.env.REACT_APP_DOMAIN}/customer`; export const getAccountInfo = async (id: string): Promise<[Account | null, string?]> => { try { const accountInfoResponse = await makeRequest({ - url: `${API_URL}/account/${id}`, method: "GET", + url: `${API_URL}/account/${id}`, useToken: true, }); @@ -48,13 +48,13 @@ export const getAccountInfo = async (id: string): Promise<[Account | null, strin } }; -export const editAccount = async (userId: string, status: "org" | "nko"): Promise<[unknown | null, string?]> => { +export const editAccount = async (userId: string, status: "org" | "nko"): Promise<[Account | null, string?]> => { try { - const editResponse = await makeRequest<{ status: "org" | "nko" }, unknown>({ - method: "patch", - useToken: true, + const editResponse = await makeRequest<{ status: "org" | "nko" }, Account>({ + method: "PATCH", url: `${API_URL}/account/${userId}`, body: { status }, + useToken: true, }); return [editResponse]; diff --git a/src/api/auth.ts b/src/api/auth.ts index 7612c99..a5d129a 100644 --- a/src/api/auth.ts +++ b/src/api/auth.ts @@ -4,12 +4,12 @@ import { parseAxiosError } from "@root/utils/parse-error"; import type { LoginRequest, RegisterRequest, RegisterResponse } from "@frontend/kitui"; -const baseUrl = process.env.REACT_APP_DOMAIN + "/auth"; +const API_URL = `${process.env.REACT_APP_DOMAIN}/auth`; export const signin = async (login: string, password: string): Promise<[RegisterResponse | null, string?]> => { try { const signinResponse = await makeRequest({ - url: baseUrl + "/login", + url: `${API_URL}/login`, body: { login, password }, useToken: false, }); @@ -29,7 +29,7 @@ export const register = async ( ): Promise<[RegisterResponse | null, string?]> => { try { const registerResponse = await makeRequest({ - url: baseUrl + "/register", + url: `${API_URL}/register`, body: { login, password, phoneNumber }, useToken: false, }); @@ -42,11 +42,11 @@ export const register = async ( } }; -export const logout = async (): Promise<[unknown, string?]> => { +export const logout = async (): Promise<[unknown | null, string?]> => { try { const logoutResponse = await makeRequest({ - url: baseUrl + "/logout", - method: "post", + method: "POST", + url: `${API_URL}/logout`, contentType: true, }); diff --git a/src/api/discounts.ts b/src/api/discounts.ts index 2f4e00d..902f0c4 100644 --- a/src/api/discounts.ts +++ b/src/api/discounts.ts @@ -7,7 +7,7 @@ import type { CreateDiscountBody, DiscountType, GetDiscountResponse } from "@roo import useSWR from "swr"; import { enqueueSnackbar } from "notistack"; -const baseUrl = process.env.REACT_APP_DOMAIN + "/price"; +const API_URL = `${process.env.REACT_APP_DOMAIN}/price`; interface CreateDiscountParams { purchasesAmount: number; @@ -108,10 +108,10 @@ export function createDiscountObject({ export const changeDiscount = async (discountId: string, discount: Discount): Promise<[unknown, string?]> => { try { const changeDiscountResponse = await makeRequest({ - url: baseUrl + "/discount/" + discountId, - method: "patch", - useToken: true, + method: "PATCH", + url: `${API_URL}/discount/${discountId}`, body: discount, + useToken: true, }); return [changeDiscountResponse]; @@ -127,10 +127,10 @@ export const createDiscount = async (discountParams: CreateDiscountParams): Prom try { const createdDiscountResponse = await makeRequest({ - url: baseUrl + "/discount", - method: "post", - useToken: true, + method: "POST", + url: `${API_URL}/discount`, body: discount, + useToken: true, }); return [createdDiscountResponse]; @@ -144,8 +144,8 @@ export const createDiscount = async (discountParams: CreateDiscountParams): Prom export const deleteDiscount = async (discountId: string): Promise<[Discount | null, string?]> => { try { const deleteDiscountResponse = await makeRequest({ - url: baseUrl + "/discount/" + discountId, - method: "delete", + method: "DELETE", + url: `${API_URL}/discount/${discountId}`, useToken: true, }); @@ -165,10 +165,10 @@ export const patchDiscount = async ( try { const patchDiscountResponse = await makeRequest({ - url: baseUrl + "/discount/" + discountId, - method: "patch", - useToken: true, + method: "PATCH", + url: `${API_URL}/discount/${discountId}`, body: discount, + useToken: true, }); return [patchDiscountResponse]; @@ -182,8 +182,8 @@ export const patchDiscount = async ( export const requestDiscounts = async (): Promise<[GetDiscountResponse | null, string?]> => { try { const discountsResponse = await makeRequest({ - url: baseUrl + "/discounts", - method: "get", + method: "GET", + url: `${API_URL}/discounts`, useToken: true, }); @@ -198,8 +198,8 @@ export const requestDiscounts = async (): Promise<[GetDiscountResponse | null, s async function getDiscounts() { try { const discountsResponse = await makeRequest({ - url: baseUrl + "/discounts", - method: "get", + method: "GET", + url: `${API_URL}/discounts`, useToken: true, }); diff --git a/src/api/history/requests.ts b/src/api/history/requests.ts index c3ed448..bd9ecae 100644 --- a/src/api/history/requests.ts +++ b/src/api/history/requests.ts @@ -23,13 +23,13 @@ type HistoryResponse = { totalPages: number; }; -const baseUrl = process.env.REACT_APP_DOMAIN + "/customer"; +const API_URL = `${process.env.REACT_APP_DOMAIN}/customer`; const getUserHistory = async (accountId: string, page: number): Promise<[HistoryResponse | null, string?]> => { try { const historyResponse = await makeRequest({ method: "GET", - url: baseUrl + `/history?page=${page}&limit=${100}&accountID=${accountId}&type=payCart`, + url: `${API_URL}/history?page=${page}&limit=${100}&accountID=${accountId}&type=payCart`, }); return [historyResponse]; diff --git a/src/api/privilegies.ts b/src/api/privilegies.ts index c67df33..a8817d6 100644 --- a/src/api/privilegies.ts +++ b/src/api/privilegies.ts @@ -11,13 +11,13 @@ type SeverPrivilegesResponse = { squiz: CustomPrivilege[]; }; -const baseUrl = process.env.REACT_APP_DOMAIN + "/strator"; +const API_URL = `${process.env.REACT_APP_DOMAIN}/strator`; export const getRoles = async (): Promise<[TMockData | null, string?]> => { try { const rolesResponse = await makeRequest({ - method: "get", - url: baseUrl + "/role", + method: "GET", + url: `${API_URL}/role`, }); return [rolesResponse]; @@ -28,11 +28,13 @@ export const getRoles = async (): Promise<[TMockData | null, string?]> => { } }; -export const putPrivilege = async (body: Omit): Promise<[unknown, string?]> => { +export const putPrivilege = async ( + body: Omit +): Promise<[CustomPrivilege | null, string?]> => { try { - const putedPrivilege = await makeRequest, unknown>({ - url: baseUrl + "/privilege", - method: "put", + const putedPrivilege = await makeRequest, CustomPrivilege>({ + method: "PUT", + url: `${API_URL}/privilege`, body, }); @@ -47,8 +49,8 @@ export const putPrivilege = async (body: Omit): export const requestServicePrivileges = async (): Promise<[SeverPrivilegesResponse | null, string?]> => { try { const privilegesResponse = await makeRequest({ - url: baseUrl + "/privilege/service", - method: "get", + method: "GET", + url: `${API_URL}/privilege/service`, }); return [privilegesResponse]; @@ -62,8 +64,8 @@ export const requestServicePrivileges = async (): Promise<[SeverPrivilegesRespon export const requestPrivileges = async (signal: AbortSignal | undefined): Promise<[CustomPrivilege[], string?]> => { try { const privilegesResponse = await makeRequest({ - url: baseUrl + "/privilege", - method: "get", + method: "GET", + url: `${API_URL}/privilege`, useToken: true, signal, }); diff --git a/src/api/promocode/requests.ts b/src/api/promocode/requests.ts index 2be9e07..11afbc7 100644 --- a/src/api/promocode/requests.ts +++ b/src/api/promocode/requests.ts @@ -1,24 +1,30 @@ import makeRequest from "@root/api/makeRequest"; import type { - CreatePromocodeBody, + CreatePromocodeBody, EditPromocodeBody, - GetPromocodeListBody, - Promocode, - PromocodeList, - PromocodeStatistics, + GetPromocodeListBody, + Promocode, + PromocodeList, + PromocodeStatistics, } from "@root/model/promocodes"; import { parseAxiosError } from "@root/utils/parse-error"; import { isAxiosError } from "axios"; -const baseUrl = process.env.REACT_APP_DOMAIN + "/codeword/promocode"; +type PromocodeStatisticsBody = { + id: string; + from: number; + to: number; +}; + +const API_URL = `${process.env.REACT_APP_DOMAIN}/codeword/promocode`; const getPromocodeList = async (body: GetPromocodeListBody) => { try { const promocodeListResponse = await makeRequest({ - url: baseUrl + "/getList", method: "POST", + url: `${API_URL}/getList`, body, useToken: false, }); @@ -32,7 +38,7 @@ const getPromocodeList = async (body: GetPromocodeListBody) => { const createFastlink = async (id: string) => { try { return await makeRequest<{ id: string }, { fastlink: string }>({ - url: baseUrl + "/fastlink", + url: `${API_URL}/fastlink`, method: "POST", body: { id }, }); @@ -70,37 +76,37 @@ export const getAllPromocodes = async () => { }; export const getNotActivePromocodes = async () => { - try { - const promocodes: Promocode[] = []; + try { + const promocodes: Promocode[] = []; - let page = 0; - while (true) { - const promocodeList = await getPromocodeList({ - limit: 100, - filter: { - active: false, - }, - page, - }); + let page = 0; + while (true) { + const promocodeList = await getPromocodeList({ + limit: 100, + filter: { + active: false, + }, + page, + }); - if (promocodeList.items.length === 0) break; + if (promocodeList.items.length === 0) break; - promocodes.push(...promocodeList.items); - page++; - } + promocodes.push(...promocodeList.items); + page++; + } - return promocodes; - } catch (nativeError) { - const [error] = parseAxiosError(nativeError); - throw new Error(`Ошибка при получении списка промокодов. ${error}`); - } + return promocodes; + } catch (nativeError) { + const [error] = parseAxiosError(nativeError); + throw new Error(`Ошибка при получении списка промокодов. ${error}`); + } }; const createPromocode = async (body: CreatePromocodeBody) => { try { const createPromocodeResponse = await makeRequest({ - url: baseUrl + "/create", method: "POST", + url: `${API_URL}/create`, body, useToken: false, }); @@ -117,24 +123,24 @@ const createPromocode = async (body: CreatePromocodeBody) => { }; const editPromocode = async (body: EditPromocodeBody) => { - try { - const editPromocodeResponse = await makeRequest({ - url: process.env.REACT_APP_DOMAIN + "/codeword/promocode" + "/edit", - method: "PUT", - body, - }); - return [editPromocodeResponse]; - } catch (nativeError) { - const [error] = parseAxiosError(nativeError); - return [null, `Ошибка редактирования промокода. ${error}`]; - } + try { + const editPromocodeResponse = await makeRequest({ + method: "PUT", + url: `${API_URL}/codeword/promocode/edit`, + body, + }); + return [editPromocodeResponse]; + } catch (nativeError) { + const [error] = parseAxiosError(nativeError); + return [null, `Ошибка редактирования промокода. ${error}`]; + } }; const deletePromocode = async (id: string): Promise => { try { await makeRequest({ - url: `${baseUrl}/${id}`, method: "DELETE", + url: `${API_URL}/${id}`, useToken: false, }); } catch (nativeError) { @@ -145,14 +151,10 @@ const deletePromocode = async (id: string): Promise => { const getPromocodeStatistics = async (id: string, from: number, to: number) => { try { - const promocodeStatisticsResponse = await makeRequest({ - url: baseUrl + `/stats`, - body: { - id: id, - from: from, - to: to, - }, + const promocodeStatisticsResponse = await makeRequest({ method: "POST", + url: `${API_URL}/stats`, + body: { id, from, to }, useToken: false, }); return promocodeStatisticsResponse; @@ -163,12 +165,12 @@ const getPromocodeStatistics = async (id: string, from: number, to: number) => { }; export const promocodeApi = { - getPromocodeList, - createPromocode, - editPromocode, - deletePromocode, - getAllPromocodes, - getNotActivePromocodes, - getPromocodeStatistics, - createFastlink, + getPromocodeList, + createPromocode, + editPromocode, + deletePromocode, + getAllPromocodes, + getNotActivePromocodes, + getPromocodeStatistics, + createFastlink, }; diff --git a/src/api/quiz.ts b/src/api/quiz.ts index b4064a3..8f88959 100644 --- a/src/api/quiz.ts +++ b/src/api/quiz.ts @@ -9,10 +9,10 @@ type MoveQuizBody = { AccountID: string; }; -export const moveQuiz = async (quizId: string, userId: string): Promise<[unknown | null, string?]> => { +export const moveQuiz = async (quizId: string, userId: string): Promise<[string | null, string?]> => { try { - const moveResponse = await makeRequest({ - method: "post", + const moveResponse = await makeRequest({ + method: "POST", url: `${API_URL}/move`, body: { Qid: quizId, AccountID: userId }, }); diff --git a/src/api/quizStatistics/index.ts b/src/api/quizStatistics/index.ts index 13cec85..c2d1d04 100644 --- a/src/api/quizStatistics/index.ts +++ b/src/api/quizStatistics/index.ts @@ -18,10 +18,12 @@ type TRequest = { from: number; }; +const API_URL = process.env.REACT_APP_DOMAIN; + export const getStatistic = async (to: number, from: number): Promise => { try { const generalResponse = await makeRequest({ - url: `${process.env.REACT_APP_DOMAIN}/squiz/statistic`, + url: `${API_URL}/squiz/statistic`, body: { to, from }, }); return generalResponse; @@ -32,18 +34,18 @@ export const getStatistic = async (to: number, from: number): Promise => { try { - const StatisticResponse = await makeRequest({ - url: process.env.REACT_APP_DOMAIN + "/customer/quizlogo/stat", - method: "post", - useToken: true, + const statisticResponse = await makeRequest({ + method: "POST", + url: `${API_URL}/customer/quizlogo/stat`, body: { to, from, page: 0, limit: 100 }, + useToken: true, }); - if (!StatisticResponse) { + if (!statisticResponse) { throw new Error("Статистика не найдена"); } - return StatisticResponse; + return statisticResponse; } catch (nativeError) { return [ { @@ -56,19 +58,19 @@ export const getStatisticSchild = async (from: number, to: number): Promise> => { try { - const StatisticPromo = await makeRequest>({ - url: process.env.REACT_APP_DOMAIN + "/customer/promocode/ltv", - method: "post", - useToken: true, + const statisticsPromocode = await makeRequest>({ + method: "POST", + url: `${API_URL}/customer/promocode/ltv`, body: { to, from }, + useToken: true, }); - return StatisticPromo; + return statisticsPromocode; } catch (nativeError) { console.log(nativeError); diff --git a/src/api/roles.ts b/src/api/roles.ts index a99c242..e79dc51 100644 --- a/src/api/roles.ts +++ b/src/api/roles.ts @@ -35,7 +35,7 @@ export type UserType = { updatedAt: string; }; -const baseUrl = process.env.REACT_APP_DOMAIN + "/role"; +const API_URL = `${process.env.REACT_APP_DOMAIN}/role`; export const getRoles_mock = (): Promise => { return new Promise((resolve) => { @@ -48,8 +48,8 @@ export const getRoles_mock = (): Promise => { export const deleteRole = async (id: string): Promise<[unknown, string?]> => { try { const deleteRoleResponse = await makeRequest({ - url: `${baseUrl}/${id}`, - method: "delete", + method: "DELETE", + url: `${API_URL}/${id}`, }); return [deleteRoleResponse]; diff --git a/src/api/tariffs.ts b/src/api/tariffs.ts index a8a0926..7411736 100644 --- a/src/api/tariffs.ts +++ b/src/api/tariffs.ts @@ -20,13 +20,13 @@ type GetTariffsResponse = { tariffs: Tariff[]; }; -const baseUrl = process.env.REACT_APP_DOMAIN + "/strator"; +const API_URL = `${process.env.REACT_APP_DOMAIN}/strator`; -export const createTariff = async (body: CreateTariffBackendRequest): Promise<[unknown, string?]> => { +export const createTariff = async (body: CreateTariffBackendRequest): Promise<[Tariff | null, string?]> => { try { - const createdTariffResponse = await makeRequest({ - url: baseUrl + "/tariff/", - method: "post", + const createdTariffResponse = await makeRequest({ + method: "POST", + url: `${API_URL}/tariff/`, body, }); @@ -38,11 +38,11 @@ export const createTariff = async (body: CreateTariffBackendRequest): Promise<[u } }; -export const putTariff = async (tariff: Tariff): Promise<[null, string?]> => { +export const putTariff = async (tariff: Tariff): Promise<[Tariff | null, string?]> => { try { - const putedTariffResponse = await makeRequest({ - method: "put", - url: baseUrl + `/tariff/${tariff._id}`, + const putedTariffResponse = await makeRequest({ + method: "PUT", + url: `${API_URL}/tariff/${tariff._id}`, body: { name: tariff.name, price: tariff.price ?? 0, @@ -64,8 +64,8 @@ export const putTariff = async (tariff: Tariff): Promise<[null, string?]> => { export const deleteTariff = async (tariffId: string): Promise<[Tariff | null, string?]> => { try { const deletedTariffResponse = await makeRequest<{ id: string }, Tariff>({ - method: "delete", - url: baseUrl + "/tariff", + method: "DELETE", + url: `${API_URL}/tariff`, body: { id: tariffId }, }); @@ -80,8 +80,8 @@ export const deleteTariff = async (tariffId: string): Promise<[Tariff | null, st export const requestTariffs = async (page: number): Promise<[GetTariffsResponse | null, string?]> => { try { const tariffsResponse = await makeRequest({ - url: baseUrl + `/tariff/?page=${page}&limit=${100}`, - method: "get", + method: "GET", + url: `${API_URL}/tariff/?page=${page}&limit=${100}`, }); return [tariffsResponse]; diff --git a/src/api/tickets.ts b/src/api/tickets.ts index d7ca441..95dfbc3 100644 --- a/src/api/tickets.ts +++ b/src/api/tickets.ts @@ -4,15 +4,23 @@ import { parseAxiosError } from "@root/utils/parse-error"; import type { SendTicketMessageRequest } from "@root/model/ticket"; -const API_URL = process.env.REACT_APP_DOMAIN + "/heruvym"; +const API_URL = `${process.env.REACT_APP_DOMAIN}/heruvym`; -export const sendTicketMessage = async (body: SendTicketMessageRequest): Promise<[unknown, string?]> => { +type CloseTicketBody = { + ticket: string; +}; + +type SendFileResponse = { + message: string; +}; + +export const sendTicketMessage = async (body: SendTicketMessageRequest): Promise<[null, string?]> => { try { - const sendTicketMessageResponse = await makeRequest({ - url: `${API_URL}/send`, + const sendTicketMessageResponse = await makeRequest({ method: "POST", - useToken: true, + url: `${API_URL}/send`, body, + useToken: true, }); return [sendTicketMessageResponse]; @@ -23,13 +31,13 @@ export const sendTicketMessage = async (body: SendTicketMessageRequest): Promise } }; -export const closeTicket = async (ticketId: string): Promise<[unknown, string?]> => { +export const closeTicket = async (ticketId: string): Promise<[CloseTicketBody | null, string?]> => { try { - const ticketCloseResponse = await makeRequest({ + const ticketCloseResponse = await makeRequest({ + method: "POST", url: `${API_URL}/close`, - method: "post", - useToken: true, body: { ticket: ticketId }, + useToken: true, }); return [ticketCloseResponse]; @@ -40,13 +48,13 @@ export const closeTicket = async (ticketId: string): Promise<[unknown, string?]> } }; -export const sendFile = async (file: File, ticketId: string): Promise<[unknown | null, string?]> => { +export const sendFile = async (file: File, ticketId: string): Promise<[SendFileResponse | null, string?]> => { try { const body = new FormData(); body.append(file.name, file); body.append("ticket", ticketId); - const sendFileRespose = await makeRequest({ + const sendFileRespose = await makeRequest({ method: "POST", url: `${API_URL}/sendFiles`, body, diff --git a/src/api/user/requests.ts b/src/api/user/requests.ts index 42a2a33..408256b 100644 --- a/src/api/user/requests.ts +++ b/src/api/user/requests.ts @@ -9,13 +9,13 @@ export type UsersListResponse = { users: UserType[]; }; -const baseUrl = process.env.REACT_APP_DOMAIN + "/user"; +const API_URL = `${process.env.REACT_APP_DOMAIN}/user`; const getUserInfo = async (id: string): Promise<[UserType | null, string?]> => { try { const userInfoResponse = await makeRequest({ - url: `${baseUrl}/${id}`, method: "GET", + url: `${API_URL}/${id}`, useToken: true, }); @@ -30,8 +30,8 @@ const getUserInfo = async (id: string): Promise<[UserType | null, string?]> => { const getUserList = async (page = 1, limit = 10): Promise<[UsersListResponse | null, string?]> => { try { const userResponse = await makeRequest({ - method: "get", - url: baseUrl + `/?page=${page}&limit=${limit}`, + method: "GET", + url: `${API_URL}/?page=${page}&limit=${limit}`, }); return [userResponse]; @@ -45,8 +45,8 @@ const getUserList = async (page = 1, limit = 10): Promise<[UsersListResponse | n const getManagerList = async (page = 1, limit = 10): Promise<[UsersListResponse | null, string?]> => { try { const managerResponse = await makeRequest({ - method: "get", - url: baseUrl + `/?page=${page}&limit=${limit}`, + method: "GET", + url: `${API_URL}/?page=${page}&limit=${limit}`, }); return [managerResponse]; @@ -60,8 +60,8 @@ const getManagerList = async (page = 1, limit = 10): Promise<[UsersListResponse const getAdminList = async (page = 1, limit = 10): Promise<[UsersListResponse | null, string?]> => { try { const adminResponse = await makeRequest({ - method: "get", - url: baseUrl + `/?page=${page}&limit=${limit}`, + method: "GET", + url: `${API_URL}/?page=${page}&limit=${limit}`, }); return [adminResponse]; diff --git a/src/api/verification.ts b/src/api/verification.ts index b1c39d8..7771059 100644 --- a/src/api/verification.ts +++ b/src/api/verification.ts @@ -25,13 +25,13 @@ type PatchVerificationBody = { taxnumber?: string; }; -const baseUrl = process.env.REACT_APP_DOMAIN + "/verification"; +const API_URL = `${process.env.REACT_APP_DOMAIN}/verification`; export const verification = async (userId: string): Promise<[Verification | null, string?]> => { try { const verificationResponse = await makeRequest({ - method: "get", - url: baseUrl + `/verification/${userId}`, + method: "GET", + url: `${API_URL}/verification/${userId}`, }); return [verificationResponse]; @@ -42,13 +42,13 @@ export const verification = async (userId: string): Promise<[Verification | null } }; -export const patchVerification = async (body: PatchVerificationBody): Promise<[unknown, string?]> => { +export const patchVerification = async (body: PatchVerificationBody): Promise<[string | null, string?]> => { try { - const patchedVerificationResponse = await makeRequest({ - method: "patch", - useToken: true, - url: baseUrl + `/verification`, + const patchedVerificationResponse = await makeRequest({ + method: "PATCH", + url: `${API_URL}/verification`, body, + useToken: true, }); return [patchedVerificationResponse]; diff --git a/src/pages/dashboard/ModalUser/VerificationTab.tsx b/src/pages/dashboard/ModalUser/VerificationTab.tsx index d8b6b55..789ca7a 100644 --- a/src/pages/dashboard/ModalUser/VerificationTab.tsx +++ b/src/pages/dashboard/ModalUser/VerificationTab.tsx @@ -54,7 +54,7 @@ export const VerificationTab = ({ userId }: VerificationTabProps) => { }, []); const verify = async (accepted: boolean) => { - if (!verificationInfo) { + if (!verificationInfo) { return; } diff --git a/src/utils/hooks/usePromocodeStatistics.ts b/src/utils/hooks/usePromocodeStatistics.ts index 52f81cd..b8a0f6b 100644 --- a/src/utils/hooks/usePromocodeStatistics.ts +++ b/src/utils/hooks/usePromocodeStatistics.ts @@ -1,5 +1,5 @@ import { useEffect, useState } from "react"; -import { getStatisticPromocode } from "@root/api/quizStatistics"; +import { getStatisticsPromocode } from "@root/api/quizStatistics"; import type { Moment } from "moment"; import type { AllPromocodeStatistics } from "@root/api/quizStatistics/types"; @@ -18,7 +18,7 @@ export function usePromocodeStatistics({ to, from }: useStatisticProps) { useEffect(() => { const requestStatistics = async () => { - const gottenData = await getStatisticPromocode(Number(formatFrom), Number(formatTo)); + const gottenData = await getStatisticsPromocode(Number(formatFrom), Number(formatTo)); setPromocodeStatistics(gottenData); }; From e1817672789ae46b1fee1264c909b1e03bd385a5 Mon Sep 17 00:00:00 2001 From: IlyaDoronin Date: Thu, 23 May 2024 15:01:51 +0300 Subject: [PATCH 3/3] refactor: requests --- src/api/auth.ts | 2 +- .../{discounts.ts => discounts/requests.ts} | 24 +- src/api/discounts/swr.ts | 30 ++ src/api/promocode/requests.ts | 84 +++--- src/api/promocode/swr.ts | 230 +++++++++------- src/api/quizStatistics/index.ts | 41 +-- src/kitUI/Cart/Cart.tsx | 2 +- .../DiscountManagement/ControlPanel.tsx | 2 +- .../DiscountManagement/CreateDiscount.tsx | 2 +- .../DiscountManagement/DiscountDataGrid.tsx | 2 +- .../DiscountManagement/EditDiscountDialog.tsx | 2 +- .../Content/PromocodeManagement/index.tsx | 259 +++++++++--------- src/pages/dashboard/Header/index.tsx | 4 +- .../dashboard/ModalUser/VerificationTab.tsx | 6 +- src/services/discounts.service.ts | 2 +- src/utils/hooks/usePromocodeStatistics.ts | 6 +- src/utils/hooks/useQuizStatistic.ts | 9 +- src/utils/hooks/useSchildStatistics.ts | 6 +- 18 files changed, 400 insertions(+), 313 deletions(-) rename src/api/{discounts.ts => discounts/requests.ts} (89%) create mode 100644 src/api/discounts/swr.ts diff --git a/src/api/auth.ts b/src/api/auth.ts index a5d129a..82e90d0 100644 --- a/src/api/auth.ts +++ b/src/api/auth.ts @@ -17,7 +17,7 @@ export const signin = async (login: string, password: string): Promise<[Register return [signinResponse]; } catch (nativeError) { const [error] = parseAxiosError(nativeError); - console.error(error); + return [null, `Ошибка авторизации. ${error}`]; } }; diff --git a/src/api/discounts.ts b/src/api/discounts/requests.ts similarity index 89% rename from src/api/discounts.ts rename to src/api/discounts/requests.ts index 902f0c4..2a1c8ec 100644 --- a/src/api/discounts.ts +++ b/src/api/discounts/requests.ts @@ -4,8 +4,6 @@ import { parseAxiosError } from "@root/utils/parse-error"; import type { Discount } from "@frontend/kitui"; import type { CreateDiscountBody, DiscountType, GetDiscountResponse } from "@root/model/discount"; -import useSWR from "swr"; -import { enqueueSnackbar } from "notistack"; const API_URL = `${process.env.REACT_APP_DOMAIN}/price`; @@ -195,7 +193,7 @@ export const requestDiscounts = async (): Promise<[GetDiscountResponse | null, s } }; -async function getDiscounts() { +export const getDiscounts = async (): Promise<[Discount[] | null, string?]> => { try { const discountsResponse = await makeRequest({ method: "GET", @@ -203,24 +201,10 @@ async function getDiscounts() { useToken: true, }); - return discountsResponse.Discounts.filter((discount) => !discount.Deprecated); + return [discountsResponse.Discounts.filter((discount) => !discount.Deprecated)]; } catch (nativeError) { const [error] = parseAxiosError(nativeError); - throw new Error(`Ошибка получения списка скидок. ${error}`); + return [null, `Ошибка получения списка скидок. ${error}`]; } -} - -export function useDiscounts() { - const { data } = useSWR("discounts", getDiscounts, { - keepPreviousData: true, - suspense: true, - onError: (error) => { - if (!(error instanceof Error)) return; - - enqueueSnackbar(error.message, { variant: "error" }); - }, - }); - - return data; -} +}; diff --git a/src/api/discounts/swr.ts b/src/api/discounts/swr.ts new file mode 100644 index 0000000..78dacd6 --- /dev/null +++ b/src/api/discounts/swr.ts @@ -0,0 +1,30 @@ +import useSWR from "swr"; +import { enqueueSnackbar } from "notistack"; + +import { getDiscounts } from "./requests"; + +export function useDiscounts() { + const { data } = useSWR( + "discounts", + async () => { + const [discounts, discountsError] = await getDiscounts(); + + if (discountsError || !discounts) { + throw new Error(discountsError); + } + + return discounts; + }, + { + keepPreviousData: true, + suspense: true, + onError: (error) => { + if (!(error instanceof Error)) return; + + enqueueSnackbar(error.message, { variant: "error" }); + }, + } + ); + + return data; +} diff --git a/src/api/promocode/requests.ts b/src/api/promocode/requests.ts index 11afbc7..c080076 100644 --- a/src/api/promocode/requests.ts +++ b/src/api/promocode/requests.ts @@ -20,7 +20,7 @@ type PromocodeStatisticsBody = { const API_URL = `${process.env.REACT_APP_DOMAIN}/codeword/promocode`; -const getPromocodeList = async (body: GetPromocodeListBody) => { +const getPromocodeList = async (body: GetPromocodeListBody): Promise<[PromocodeList | null, string?]> => { try { const promocodeListResponse = await makeRequest({ method: "POST", @@ -29,32 +29,36 @@ const getPromocodeList = async (body: GetPromocodeListBody) => { useToken: false, }); - return promocodeListResponse; + return [promocodeListResponse]; } catch (nativeError) { const [error] = parseAxiosError(nativeError); - throw new Error(`Ошибка при получении списка промокодов. ${error}`); + + return [null, `Ошибка при получении списка промокодов. ${error}`]; } }; -const createFastlink = async (id: string) => { +const createFastlink = async (id: string): Promise<[{ fastlink: string } | null, string?]> => { try { - return await makeRequest<{ id: string }, { fastlink: string }>({ + const createFastLinkResponse = await makeRequest<{ id: string }, { fastlink: string }>({ url: `${API_URL}/fastlink`, method: "POST", body: { id }, }); + + return [createFastLinkResponse]; } catch (nativeError) { const [error] = parseAxiosError(nativeError); - throw new Error(`Ошибка при создании фастлинка. ${error}`); + + return [null, `Ошибка при создании фастлинка. ${error}`]; } }; -export const getAllPromocodes = async () => { +export const getAllPromocodes = async (): Promise<[Promocode[] | null, string?]> => { try { const promocodes: Promocode[] = []; let page = 0; while (true) { - const promocodeList = await getPromocodeList({ + const [promocodeList] = await getPromocodeList({ limit: 100, filter: { active: true, @@ -62,26 +66,29 @@ export const getAllPromocodes = async () => { page, }); - if (promocodeList.items.length === 0) break; + if (promocodeList) { + if (promocodeList.items.length === 0) break; - promocodes.push(...promocodeList.items); - page++; + promocodes.push(...promocodeList.items); + page++; + } } - return promocodes; + return [promocodes]; } catch (nativeError) { const [error] = parseAxiosError(nativeError); - throw new Error(`Ошибка при получении списка промокодов. ${error}`); + + return [null, `Ошибка при получении списка промокодов. ${error}`]; } }; -export const getNotActivePromocodes = async () => { +export const getNotActivePromocodes = async (): Promise<[Promocode[] | null, string?]> => { try { const promocodes: Promocode[] = []; let page = 0; while (true) { - const promocodeList = await getPromocodeList({ + const [promocodeList] = await getPromocodeList({ limit: 100, filter: { active: false, @@ -89,20 +96,23 @@ export const getNotActivePromocodes = async () => { page, }); - if (promocodeList.items.length === 0) break; + if (promocodeList) { + if (promocodeList.items.length === 0) break; - promocodes.push(...promocodeList.items); - page++; + promocodes.push(...promocodeList.items); + page++; + } } - return promocodes; + return [promocodes]; } catch (nativeError) { const [error] = parseAxiosError(nativeError); - throw new Error(`Ошибка при получении списка промокодов. ${error}`); + + return [null, `Ошибка при получении списка промокодов. ${error}`]; } }; -const createPromocode = async (body: CreatePromocodeBody) => { +const createPromocode = async (body: CreatePromocodeBody): Promise<[Promocode | null, string?]> => { try { const createPromocodeResponse = await makeRequest({ method: "POST", @@ -111,45 +121,55 @@ const createPromocode = async (body: CreatePromocodeBody) => { useToken: false, }); - return createPromocodeResponse; + return [createPromocodeResponse]; } catch (nativeError) { + const [error] = parseAxiosError(nativeError); + if (isAxiosError(nativeError) && nativeError.response?.data.error === "Duplicate Codeword") { - throw new Error(`Промокод уже существует`); + return [null, `Промокод уже существует`]; } - const [error] = parseAxiosError(nativeError); - throw new Error(`Ошибка создания промокода. ${error}`); + return [null, `Ошибка создания промокода. ${error}`]; } }; -const editPromocode = async (body: EditPromocodeBody) => { +const editPromocode = async (body: EditPromocodeBody): Promise<[Promocode | null, string?]> => { try { const editPromocodeResponse = await makeRequest({ method: "PUT", url: `${API_URL}/codeword/promocode/edit`, body, }); + return [editPromocodeResponse]; } catch (nativeError) { const [error] = parseAxiosError(nativeError); + return [null, `Ошибка редактирования промокода. ${error}`]; } }; -const deletePromocode = async (id: string): Promise => { +const deletePromocode = async (id: string): Promise<[null, string?]> => { try { await makeRequest({ method: "DELETE", url: `${API_URL}/${id}`, useToken: false, }); + + return [null]; } catch (nativeError) { const [error] = parseAxiosError(nativeError); - throw new Error(`Ошибка удаления промокода. ${error}`); + + return [null, `Ошибка удаления промокода. ${error}`]; } }; -const getPromocodeStatistics = async (id: string, from: number, to: number) => { +const getPromocodeStatistics = async ( + id: string, + from: number, + to: number +): Promise<[PromocodeStatistics | null, string?]> => { try { const promocodeStatisticsResponse = await makeRequest({ method: "POST", @@ -157,10 +177,12 @@ const getPromocodeStatistics = async (id: string, from: number, to: number) => { body: { id, from, to }, useToken: false, }); - return promocodeStatisticsResponse; + + return [promocodeStatisticsResponse]; } catch (nativeError) { const [error] = parseAxiosError(nativeError); - throw new Error(`Ошибка при получении статистики промокода. ${error}`); + + return [null, `Ошибка при получении статистики промокода. ${error}`]; } }; diff --git a/src/api/promocode/swr.ts b/src/api/promocode/swr.ts index d2d5ca1..230113a 100644 --- a/src/api/promocode/swr.ts +++ b/src/api/promocode/swr.ts @@ -3,33 +3,34 @@ import useSwr, { mutate } from "swr"; import { enqueueSnackbar } from "notistack"; import { promocodeApi } from "./requests"; -import type { - CreatePromocodeBody, EditPromocodeBody, - PromocodeList, -} from "@root/model/promocodes"; +import type { CreatePromocodeBody, EditPromocodeBody, PromocodeList } from "@root/model/promocodes"; export function usePromocodes( - page: number, - pageSize: number, - promocodeId: string, - to: number, - from: number, - active: boolean + page: number, + pageSize: number, + promocodeId: string, + to: number, + from: number, + active: boolean ) { - const promocodesCountRef = useRef(0); - const swrResponse = useSwr( - ["promocodes", page, pageSize, active], - async (key) => { - const result = await promocodeApi.getPromocodeList({ - limit: key[2], - filter: { - active: key[3], - }, - page: key[1], - }); + const promocodesCountRef = useRef(0); + const swrResponse = useSwr( + ["promocodes", page, pageSize, active], + async (key) => { + const [promocodeList, promocodeListError] = await promocodeApi.getPromocodeList({ + limit: key[2], + filter: { + active: key[3], + }, + page: key[1], + }); - promocodesCountRef.current = result.count; - return result; + if (promocodeListError || !promocodeList) { + throw new Error(promocodeListError); + } + + promocodesCountRef.current = promocodeList.count; + return promocodeList; }, { onError(err) { @@ -43,49 +44,60 @@ export function usePromocodes( const createPromocode = useCallback( async function (body: CreatePromocodeBody) { - try { - await promocodeApi.createPromocode(body); - mutate(["promocodes", page, pageSize]); - } catch (error) { - console.error("Error creating promocode", error); - if (error instanceof Error) enqueueSnackbar(error.message, { variant: "error" }); + const [, createError] = await promocodeApi.createPromocode(body); + + if (createError) { + enqueueSnackbar(createError, { variant: "error" }); + + return; + } + + mutate(["promocodes", page, pageSize]); + }, + [page, pageSize] + ); + + const editPromocode = useCallback( + async function (body: EditPromocodeBody) { + const [, editError] = await promocodeApi.editPromocode(body); + + if (editError) { + enqueueSnackbar(editError, { variant: "error" }); + + return; + } + + mutate(["promocodes", page, pageSize, active]); + const [, getPromocodesError] = await promocodeApi.getPromocodeList({ + limit: pageSize, + filter: { + active: active, + }, + page: page, + }); + + if (getPromocodesError) { + enqueueSnackbar(getPromocodesError, { variant: "error" }); } }, [page, pageSize] ); - const editPromocode = useCallback( - async function (body: EditPromocodeBody) { - try { - await promocodeApi.editPromocode(body); - mutate( - ["promocodes", page, pageSize, active], - ); - await promocodeApi.getPromocodeList({ - limit: pageSize, - filter: { - active: active, - }, - page: page, - }); - } catch (error) { - console.error("Error editing promocode", error); - if (error instanceof Error) - enqueueSnackbar(error.message, { variant: "error" }); - } - }, - [page, pageSize,] - ); + const deletePromocode = useCallback( + async function (id: string) { + try { + await mutate( + ["promocodes", page, pageSize], + async () => { + const [_, deleteError] = await promocodeApi.deletePromocode(id); - const deletePromocode = useCallback( - async function (id: string) { - try { - await mutate( - ["promocodes", page, pageSize], - promocodeApi.deletePromocode(id), - { - optimisticData(currentData, displayedData) { - if (!displayedData) return; + if (deleteError) { + throw new Error(deleteError); + } + }, + { + optimisticData(currentData, displayedData) { + if (!displayedData) return; return { count: displayedData.count - 1, @@ -118,7 +130,15 @@ export function usePromocodes( return null; } - const promocodeStatisticsResponse = await promocodeApi.getPromocodeStatistics(id, from, to); + const [promocodeStatisticsResponse, promocodeStatisticsError] = await promocodeApi.getPromocodeStatistics( + id, + from, + to + ); + + if (promocodeStatisticsError) { + throw new Error(promocodeStatisticsError); + } return promocodeStatisticsResponse; }, @@ -134,50 +154,76 @@ export function usePromocodes( const createFastLink = useCallback( async function (id: string) { - try { - await promocodeApi.createFastlink(id); - mutate(["promocodes", page, pageSize]); - } catch (error) { - console.error("Error creating fast link", error); - if (error instanceof Error) enqueueSnackbar(error.message, { variant: "error" }); + const [, createError] = await promocodeApi.createFastlink(id); + + if (createError) { + enqueueSnackbar(createError, { variant: "error" }); + + return; } + + mutate(["promocodes", page, pageSize]); }, [page, pageSize] ); - return { - ...swrResponse, - createPromocode, - deletePromocode, - editPromocode, - createFastLink, - promocodeStatistics: promocodeStatistics.data, - promocodesCount: promocodesCountRef.current, - }; + return { + ...swrResponse, + createPromocode, + deletePromocode, + editPromocode, + createFastLink, + promocodeStatistics: promocodeStatistics.data, + promocodesCount: promocodesCountRef.current, + }; } export function useAllPromocodes() { - const { data } = useSwr("allPromocodes", promocodeApi.getAllPromocodes, { - keepPreviousData: true, - suspense: true, - onError(err) { - console.error("Error fetching all promocodes", err); - enqueueSnackbar(err.message, { variant: "error" }); + const { data } = useSwr( + "allPromocodes", + async () => { + const [promocodes, promocodesError] = await promocodeApi.getAllPromocodes(); + + if (promocodesError || !promocodes) { + throw new Error(promocodesError); + } + + return promocodes; }, - }); + { + keepPreviousData: true, + suspense: true, + onError(err) { + console.error("Error fetching all promocodes", err); + enqueueSnackbar(err.message, { variant: "error" }); + }, + } + ); return data; } export function useNotActivePromocodes() { - const { data } = useSwr("notActivePromocodes", promocodeApi.getNotActivePromocodes, { - keepPreviousData: true, - suspense: true, - onError(err) { - console.error("Error fetching all promocodes", err); - enqueueSnackbar(err.message, { variant: "error" }); - }, - }); + const { data } = useSwr( + "notActivePromocodes", + async () => { + const [promocodes, promocodesError] = await promocodeApi.getNotActivePromocodes(); - return data; + if (promocodesError || !promocodes) { + throw new Error(promocodesError); + } + + return promocodes; + }, + { + keepPreviousData: true, + suspense: true, + onError(err) { + console.error("Error fetching all promocodes", err); + enqueueSnackbar(err.message, { variant: "error" }); + }, + } + ); + + return data; } diff --git a/src/api/quizStatistics/index.ts b/src/api/quizStatistics/index.ts index c2d1d04..865d918 100644 --- a/src/api/quizStatistics/index.ts +++ b/src/api/quizStatistics/index.ts @@ -1,4 +1,5 @@ import makeRequest from "@root/api/makeRequest"; +import { parseAxiosError } from "@root/utils/parse-error"; import type { GetStatisticSchildBody, @@ -20,19 +21,22 @@ type TRequest = { const API_URL = process.env.REACT_APP_DOMAIN; -export const getStatistic = async (to: number, from: number): Promise => { +export const getStatistic = async (to: number, from: number): Promise<[QuizStatisticResponse | null, string?]> => { try { const generalResponse = await makeRequest({ url: `${API_URL}/squiz/statistic`, body: { to, from }, }); - return generalResponse; + + return [generalResponse]; } catch (nativeError) { - return { Registrations: 0, Quizes: 0, Results: 0 }; + const [error] = parseAxiosError(nativeError); + + return [null, `Не удалось получить статистику ${error}`]; } }; -export const getStatisticSchild = async (from: number, to: number): Promise => { +export const getStatisticSchild = async (from: number, to: number): Promise<[QuizStatisticsItem[] | null, string?]> => { try { const statisticResponse = await makeRequest({ method: "POST", @@ -42,18 +46,23 @@ export const getStatisticSchild = async (from: number, to: number): Promise> => { +): Promise<[Record | null, string?]> => { try { const statisticsPromocode = await makeRequest>({ method: "POST", @@ -70,10 +79,10 @@ export const getStatisticsPromocode = async ( useToken: true, }); - return statisticsPromocode; + return [statisticsPromocode]; } catch (nativeError) { - console.log(nativeError); + const error = parseAxiosError(nativeError); - return {}; + return [null, `Не удалось получить статистику промокода ${error}`]; } }; diff --git a/src/kitUI/Cart/Cart.tsx b/src/kitUI/Cart/Cart.tsx index faa23c9..360cf72 100644 --- a/src/kitUI/Cart/Cart.tsx +++ b/src/kitUI/Cart/Cart.tsx @@ -16,7 +16,7 @@ import { useMediaQuery, useTheme, } from "@mui/material"; -import { useDiscounts } from "@root/api/discounts"; +import { useDiscounts } from "@root/api/discounts/swr"; import { useAllPromocodes } from "@root/api/promocode/swr"; import { requestDiscounts } from "@root/services/discounts.service"; import { requestPrivileges } from "@root/services/privilegies.service"; diff --git a/src/pages/dashboard/Content/DiscountManagement/ControlPanel.tsx b/src/pages/dashboard/Content/DiscountManagement/ControlPanel.tsx index 7d35e7b..951e1d0 100644 --- a/src/pages/dashboard/Content/DiscountManagement/ControlPanel.tsx +++ b/src/pages/dashboard/Content/DiscountManagement/ControlPanel.tsx @@ -2,7 +2,7 @@ import { enqueueSnackbar } from "notistack"; import { GridSelectionModel } from "@mui/x-data-grid"; import { Box, Button, useMediaQuery, useTheme } from "@mui/material"; -import { changeDiscount } from "@root/api/discounts"; +import { changeDiscount } from "@root/api/discounts/requests"; import { findDiscountsById } from "@root/stores/discounts"; import { requestDiscounts } from "@root/services/discounts.service"; diff --git a/src/pages/dashboard/Content/DiscountManagement/CreateDiscount.tsx b/src/pages/dashboard/Content/DiscountManagement/CreateDiscount.tsx index 3a26fd5..a4c4bcc 100644 --- a/src/pages/dashboard/Content/DiscountManagement/CreateDiscount.tsx +++ b/src/pages/dashboard/Content/DiscountManagement/CreateDiscount.tsx @@ -18,7 +18,7 @@ import { resetPrivilegeArray, usePrivilegeStore } from "@root/stores/privilegesS import { addDiscount } from "@root/stores/discounts"; import { enqueueSnackbar } from "notistack"; import { DiscountType, discountTypes } from "@root/model/discount"; -import { createDiscount } from "@root/api/discounts"; +import { createDiscount } from "@root/api/discounts/requests"; import usePrivileges from "@root/utils/hooks/usePrivileges"; import { Formik, Field, Form, FormikHelpers } from "formik"; import { mutate } from "swr"; diff --git a/src/pages/dashboard/Content/DiscountManagement/DiscountDataGrid.tsx b/src/pages/dashboard/Content/DiscountManagement/DiscountDataGrid.tsx index 971283c..413f736 100644 --- a/src/pages/dashboard/Content/DiscountManagement/DiscountDataGrid.tsx +++ b/src/pages/dashboard/Content/DiscountManagement/DiscountDataGrid.tsx @@ -9,7 +9,7 @@ import { } from "@root/stores/discounts"; import DeleteIcon from "@mui/icons-material/Delete"; import EditIcon from "@mui/icons-material/Edit"; -import { deleteDiscount } from "@root/api/discounts"; +import { deleteDiscount } from "@root/api/discounts/requests"; import { GridSelectionModel } from "@mui/x-data-grid"; import { requestDiscounts } from "@root/services/discounts.service"; import AutorenewIcon from "@mui/icons-material/Autorenew"; diff --git a/src/pages/dashboard/Content/DiscountManagement/EditDiscountDialog.tsx b/src/pages/dashboard/Content/DiscountManagement/EditDiscountDialog.tsx index f491ddc..3833f86 100644 --- a/src/pages/dashboard/Content/DiscountManagement/EditDiscountDialog.tsx +++ b/src/pages/dashboard/Content/DiscountManagement/EditDiscountDialog.tsx @@ -14,7 +14,7 @@ import { Typography, useTheme, } from "@mui/material"; -import { patchDiscount } from "@root/api/discounts"; +import { patchDiscount } from "@root/api/discounts/requests"; import { CustomTextField } from "@root/kitUI/CustomTextField"; import { DiscountType, discountTypes } from "@root/model/discount"; import { ServiceType, SERVICE_LIST } from "@root/model/tariff"; diff --git a/src/pages/dashboard/Content/PromocodeManagement/index.tsx b/src/pages/dashboard/Content/PromocodeManagement/index.tsx index f405285..6970661 100644 --- a/src/pages/dashboard/Content/PromocodeManagement/index.tsx +++ b/src/pages/dashboard/Content/PromocodeManagement/index.tsx @@ -1,5 +1,5 @@ import { useState } from "react"; -import {Box, Button, FormControl, InputLabel, MenuItem, Select, Typography, useTheme} from "@mui/material"; +import { Box, Button, FormControl, InputLabel, MenuItem, Select, Typography, useTheme } from "@mui/material"; import { DataGrid, GridLoadingOverlay, GridToolbar } from "@mui/x-data-grid"; import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; @@ -9,9 +9,9 @@ import { CreatePromocodeForm } from "./CreatePromocodeForm"; import { usePromocodeGridColDef } from "./usePromocodeGridColDef"; import { StatisticsModal } from "./StatisticsModal"; import DeleteModal from "./DeleteModal"; -import {promocodeApi} from "@root/api/promocode/requests"; -import {SelectChangeEvent} from "@mui/material/Select"; -import {EditModal} from "@pages/dashboard/Content/PromocodeManagement/EditModal"; +import { promocodeApi } from "@root/api/promocode/requests"; +import { SelectChangeEvent } from "@mui/material/Select"; +import { EditModal } from "@pages/dashboard/Content/PromocodeManagement/EditModal"; export const PromocodeManagement = () => { const theme = useTheme(); @@ -19,135 +19,126 @@ export const PromocodeManagement = () => { const [deleteModal, setDeleteModal] = useState(""); const deleteModalHC = (id: string) => setDeleteModal(id); - const [showStatisticsModalId, setShowStatisticsModalId] = - useState(""); - const [showEditModalId, setShowEditModalId] = - useState(""); - const [page, setPage] = useState(0); - const [to, setTo] = useState(0); - const [from, setFrom] = useState(0); - const [pageSize, setPageSize] = useState(10); - const [active, setActive] = useState(true); - const { - data, - error, - isValidating, - promocodesCount, - promocodeStatistics, - deletePromocode, - createPromocode, - editPromocode, - createFastLink, - } = usePromocodes(page, pageSize, showStatisticsModalId, to, from, active); - const columns = usePromocodeGridColDef( - setShowEditModalId, - setShowStatisticsModalId, - deleteModalHC - ); - if (error) return Ошибка загрузки промокодов; + const [showStatisticsModalId, setShowStatisticsModalId] = useState(""); + const [showEditModalId, setShowEditModalId] = useState(""); + const [page, setPage] = useState(0); + const [to, setTo] = useState(0); + const [from, setFrom] = useState(0); + const [pageSize, setPageSize] = useState(10); + const [active, setActive] = useState(true); + const { + data, + error, + isValidating, + promocodesCount, + promocodeStatistics, + deletePromocode, + createPromocode, + editPromocode, + createFastLink, + } = usePromocodes(page, pageSize, showStatisticsModalId, to, from, active); + const columns = usePromocodeGridColDef(setShowEditModalId, setShowStatisticsModalId, deleteModalHC); + if (error) return Ошибка загрузки промокодов; - return ( - - - Создание промокода - - - - - - - - - - - - - - - ); + return ( + + + Создание промокода + + + + + + + + + + + + + + + ); }; diff --git a/src/pages/dashboard/Header/index.tsx b/src/pages/dashboard/Header/index.tsx index d0e5d53..f259679 100644 --- a/src/pages/dashboard/Header/index.tsx +++ b/src/pages/dashboard/Header/index.tsx @@ -51,9 +51,7 @@ const Header: React.FC = () => { { - logout().then(clearAuthToken); - }} + onClick={() => logout().then(clearAuthToken)} sx={{ display: "flex", flexDirection: "column", diff --git a/src/pages/dashboard/ModalUser/VerificationTab.tsx b/src/pages/dashboard/ModalUser/VerificationTab.tsx index 789ca7a..b8b4dcd 100644 --- a/src/pages/dashboard/ModalUser/VerificationTab.tsx +++ b/src/pages/dashboard/ModalUser/VerificationTab.tsx @@ -54,11 +54,11 @@ export const VerificationTab = ({ userId }: VerificationTabProps) => { }, []); const verify = async (accepted: boolean) => { - if (!verificationInfo) { + if (!verificationInfo) { return; } - const [_, patchVerificationError] = await patchVerification({ + const [patchResponse, patchVerificationError] = await patchVerification({ accepted, comment, id: verificationInfo._id, @@ -66,7 +66,7 @@ export const VerificationTab = ({ userId }: VerificationTabProps) => { status: verificationInfo.status, }); - if (accepted && _ === "OK") { + if (accepted && patchResponse === "OK") { await editAccount(userId, verificationInfo.status); } diff --git a/src/services/discounts.service.ts b/src/services/discounts.service.ts index 36ce0b3..8e9c19f 100644 --- a/src/services/discounts.service.ts +++ b/src/services/discounts.service.ts @@ -1,6 +1,6 @@ import { setDiscounts } from "@root/stores/discounts"; -import { requestDiscounts as requestDiscountsRequest } from "@root/api/discounts"; +import { requestDiscounts as requestDiscountsRequest } from "@root/api/discounts/requests"; import type { Discount } from "@frontend/kitui"; const filterDiscounts = (discounts: Discount[]) => { diff --git a/src/utils/hooks/usePromocodeStatistics.ts b/src/utils/hooks/usePromocodeStatistics.ts index b8a0f6b..b22280d 100644 --- a/src/utils/hooks/usePromocodeStatistics.ts +++ b/src/utils/hooks/usePromocodeStatistics.ts @@ -18,9 +18,11 @@ export function usePromocodeStatistics({ to, from }: useStatisticProps) { useEffect(() => { const requestStatistics = async () => { - const gottenData = await getStatisticsPromocode(Number(formatFrom), Number(formatTo)); + const [gottenData] = await getStatisticsPromocode(Number(formatFrom), Number(formatTo)); - setPromocodeStatistics(gottenData); + if (gottenData) { + setPromocodeStatistics(gottenData); + } }; requestStatistics(); diff --git a/src/utils/hooks/useQuizStatistic.ts b/src/utils/hooks/useQuizStatistic.ts index 3af2db0..fde593b 100644 --- a/src/utils/hooks/useQuizStatistic.ts +++ b/src/utils/hooks/useQuizStatistic.ts @@ -12,7 +12,7 @@ export function useQuizStatistic({ to, from }: useQuizStatisticProps) { const formatTo = to?.unix(); const formatFrom = from?.unix(); - const [data, setData] = useState({ + const [data, setData] = useState({ Registrations: 0, Quizes: 0, Results: 0, @@ -20,8 +20,11 @@ export function useQuizStatistic({ to, from }: useQuizStatisticProps) { useEffect(() => { const requestStatistics = async () => { - const gottenData = await getStatistic(Number(formatTo), Number(formatFrom)); - setData(gottenData); + const [gottenData] = await getStatistic(Number(formatTo), Number(formatFrom)); + + if (gottenData) { + setData(gottenData); + } }; requestStatistics(); diff --git a/src/utils/hooks/useSchildStatistics.ts b/src/utils/hooks/useSchildStatistics.ts index b982602..3855eb3 100644 --- a/src/utils/hooks/useSchildStatistics.ts +++ b/src/utils/hooks/useSchildStatistics.ts @@ -13,9 +13,11 @@ export const useSchildStatistics = (from: Moment | null, to: Moment | null) => { useEffect(() => { const StatisticsShild = async () => { - const gottenData = await getStatisticSchild(Number(formatFrom), Number(formatTo)); + const [gottenData] = await getStatisticSchild(Number(formatFrom), Number(formatTo)); - setStatistics(gottenData); + if (gottenData) { + setStatistics(gottenData); + } }; StatisticsShild();