refactor: requests
This commit is contained in:
parent
2264fef8aa
commit
e181767278
@ -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}`];
|
||||
}
|
||||
};
|
||||
|
@ -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<never, GetDiscountResponse>({
|
||||
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;
|
||||
}
|
||||
};
|
30
src/api/discounts/swr.ts
Normal file
30
src/api/discounts/swr.ts
Normal file
@ -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;
|
||||
}
|
@ -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<GetPromocodeListBody, PromocodeList>({
|
||||
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<CreatePromocodeBody, Promocode>({
|
||||
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<EditPromocodeBody, Promocode>({
|
||||
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<void> => {
|
||||
const deletePromocode = async (id: string): Promise<[null, string?]> => {
|
||||
try {
|
||||
await makeRequest<never, never>({
|
||||
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<PromocodeStatisticsBody, PromocodeStatistics>({
|
||||
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}`];
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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<number>(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<number>(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<PromocodeList | undefined, void>(["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<PromocodeList | undefined, void>(
|
||||
["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<PromocodeList | undefined, void>(
|
||||
["promocodes", page, pageSize],
|
||||
async () => {
|
||||
const [_, deleteError] = await promocodeApi.deletePromocode(id);
|
||||
|
||||
const deletePromocode = useCallback(
|
||||
async function (id: string) {
|
||||
try {
|
||||
await mutate<PromocodeList | undefined, void>(
|
||||
["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;
|
||||
}
|
||||
|
@ -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<QuizStatisticResponse> => {
|
||||
export const getStatistic = async (to: number, from: number): Promise<[QuizStatisticResponse | null, string?]> => {
|
||||
try {
|
||||
const generalResponse = await makeRequest<TRequest, QuizStatisticResponse>({
|
||||
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<QuizStatisticsItem[]> => {
|
||||
export const getStatisticSchild = async (from: number, to: number): Promise<[QuizStatisticsItem[] | null, string?]> => {
|
||||
try {
|
||||
const statisticResponse = await makeRequest<GetStatisticSchildBody, QuizStatisticsItem[]>({
|
||||
method: "POST",
|
||||
@ -42,18 +46,23 @@ export const getStatisticSchild = async (from: number, to: number): Promise<Quiz
|
||||
});
|
||||
|
||||
if (!statisticResponse) {
|
||||
throw new Error("Статистика не найдена");
|
||||
return [null, "Статистика не найдена"];
|
||||
}
|
||||
|
||||
return statisticResponse;
|
||||
return [statisticResponse];
|
||||
} catch (nativeError) {
|
||||
const [error] = parseAxiosError(nativeError);
|
||||
|
||||
return [
|
||||
{
|
||||
ID: "0",
|
||||
Regs: 0,
|
||||
Money: 0,
|
||||
Quizes: [{ QuizID: "0", Regs: 0, Money: 0 }],
|
||||
},
|
||||
[
|
||||
{
|
||||
ID: "0",
|
||||
Regs: 0,
|
||||
Money: 0,
|
||||
Quizes: [{ QuizID: "0", Regs: 0, Money: 0 }],
|
||||
},
|
||||
],
|
||||
`Не удалось получить статистику ${error}`,
|
||||
];
|
||||
}
|
||||
};
|
||||
@ -61,7 +70,7 @@ export const getStatisticSchild = async (from: number, to: number): Promise<Quiz
|
||||
export const getStatisticsPromocode = async (
|
||||
from: number,
|
||||
to: number
|
||||
): Promise<Record<string, AllPromocodeStatistics>> => {
|
||||
): Promise<[Record<string, AllPromocodeStatistics> | null, string?]> => {
|
||||
try {
|
||||
const statisticsPromocode = await makeRequest<GetPromocodeStatisticsBody, Record<string, AllPromocodeStatistics>>({
|
||||
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}`];
|
||||
}
|
||||
};
|
||||
|
@ -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";
|
||||
|
@ -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";
|
||||
|
@ -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";
|
||||
|
@ -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";
|
||||
|
@ -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";
|
||||
|
@ -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<string>("");
|
||||
const deleteModalHC = (id: string) => setDeleteModal(id);
|
||||
|
||||
const [showStatisticsModalId, setShowStatisticsModalId] =
|
||||
useState<string>("");
|
||||
const [showEditModalId, setShowEditModalId] =
|
||||
useState<string>("");
|
||||
const [page, setPage] = useState<number>(0);
|
||||
const [to, setTo] = useState(0);
|
||||
const [from, setFrom] = useState(0);
|
||||
const [pageSize, setPageSize] = useState<number>(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 <Typography>Ошибка загрузки промокодов</Typography>;
|
||||
const [showStatisticsModalId, setShowStatisticsModalId] = useState<string>("");
|
||||
const [showEditModalId, setShowEditModalId] = useState<string>("");
|
||||
const [page, setPage] = useState<number>(0);
|
||||
const [to, setTo] = useState(0);
|
||||
const [from, setFrom] = useState(0);
|
||||
const [pageSize, setPageSize] = useState<number>(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 <Typography>Ошибка загрузки промокодов</Typography>;
|
||||
|
||||
return (
|
||||
<LocalizationProvider dateAdapter={AdapterDayjs}>
|
||||
<Typography
|
||||
variant="subtitle1"
|
||||
sx={{
|
||||
width: "90%",
|
||||
height: "60px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
textTransform: "uppercase",
|
||||
color: theme.palette.secondary.main,
|
||||
}}
|
||||
>
|
||||
Создание промокода
|
||||
</Typography>
|
||||
<CreatePromocodeForm createPromocode={createPromocode} />
|
||||
<Box sx={{marginTop: "55px", width: "80%", display: "flex"}}>
|
||||
<FormControl variant="standard" sx={{ m: 1, minWidth: 120 }}>
|
||||
<Select
|
||||
labelId="demo-simple-select-standard-label"
|
||||
id="demo-simple-select-standard"
|
||||
sx={{color: "white",
|
||||
backgroundColor: "transparent",
|
||||
padding: "5px",
|
||||
border: "1px solid white",
|
||||
borderRadius: "4px",
|
||||
".MuiSelect-icon": {
|
||||
color: "white"
|
||||
}
|
||||
}}
|
||||
value={active? "true" : "false"}
|
||||
onChange={(event: SelectChangeEvent) => {
|
||||
setActive((event.target.value) === "true" ? true : false);
|
||||
}}
|
||||
label="Age"
|
||||
>
|
||||
<MenuItem value={"true"}>Активные</MenuItem>
|
||||
<MenuItem value={"false"}>Неактивные</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Box>
|
||||
<Box style={{ width: "80%", marginTop: "25px" }}>
|
||||
<DataGrid
|
||||
disableSelectionOnClick={true}
|
||||
rows={data?.items ?? []}
|
||||
columns={columns}
|
||||
sx={{
|
||||
color: theme.palette.secondary.main,
|
||||
"& .MuiDataGrid-iconSeparator": { display: "none" },
|
||||
"& .css-levciy-MuiTablePagination-displayedRows": {
|
||||
color: theme.palette.secondary.main,
|
||||
},
|
||||
"& .MuiSvgIcon-root": { color: theme.palette.secondary.main },
|
||||
"& .MuiTablePagination-selectLabel": {
|
||||
color: theme.palette.secondary.main,
|
||||
},
|
||||
"& .MuiInputBase-root": { color: theme.palette.secondary.main },
|
||||
"& .MuiButton-text": { color: theme.palette.secondary.main },
|
||||
"& .MuiDataGrid-overlay": {
|
||||
backgroundColor: "rgba(255, 255, 255, 0.1)",
|
||||
animation: `${fadeIn} 0.5s ease-out`,
|
||||
},
|
||||
}}
|
||||
components={{
|
||||
Toolbar: GridToolbar,
|
||||
LoadingOverlay: GridLoadingOverlay,
|
||||
}}
|
||||
loading={isValidating}
|
||||
paginationMode="server"
|
||||
page={page}
|
||||
onPageChange={setPage}
|
||||
rowCount={promocodesCount}
|
||||
pageSize={pageSize}
|
||||
onPageSizeChange={setPageSize}
|
||||
rowsPerPageOptions={[10, 25, 50, 100]}
|
||||
autoHeight
|
||||
/>
|
||||
</Box>
|
||||
<EditModal
|
||||
id={showEditModalId}
|
||||
setId={setShowEditModalId}
|
||||
promocodes={data?.items ?? []}
|
||||
editPromocode={editPromocode}
|
||||
/>
|
||||
<StatisticsModal
|
||||
id={showStatisticsModalId}
|
||||
setId={setShowStatisticsModalId}
|
||||
promocodeStatistics={promocodeStatistics}
|
||||
to={to}
|
||||
setTo={setTo}
|
||||
from={from}
|
||||
setFrom={setFrom}
|
||||
promocodes={data?.items ?? []}
|
||||
createFastLink={createFastLink}
|
||||
/>
|
||||
<DeleteModal
|
||||
id={deleteModal}
|
||||
setModal={setDeleteModal}
|
||||
deletePromocode={deletePromocode}
|
||||
/>
|
||||
</LocalizationProvider>
|
||||
);
|
||||
return (
|
||||
<LocalizationProvider dateAdapter={AdapterDayjs}>
|
||||
<Typography
|
||||
variant="subtitle1"
|
||||
sx={{
|
||||
width: "90%",
|
||||
height: "60px",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
textTransform: "uppercase",
|
||||
color: theme.palette.secondary.main,
|
||||
}}
|
||||
>
|
||||
Создание промокода
|
||||
</Typography>
|
||||
<CreatePromocodeForm createPromocode={createPromocode} />
|
||||
<Box sx={{ marginTop: "55px", width: "80%", display: "flex" }}>
|
||||
<FormControl variant="standard" sx={{ m: 1, minWidth: 120 }}>
|
||||
<Select
|
||||
labelId="demo-simple-select-standard-label"
|
||||
id="demo-simple-select-standard"
|
||||
sx={{
|
||||
color: "white",
|
||||
backgroundColor: "transparent",
|
||||
padding: "5px",
|
||||
border: "1px solid white",
|
||||
borderRadius: "4px",
|
||||
".MuiSelect-icon": {
|
||||
color: "white",
|
||||
},
|
||||
}}
|
||||
value={active ? "true" : "false"}
|
||||
onChange={(event: SelectChangeEvent) => {
|
||||
setActive(event.target.value === "true" ? true : false);
|
||||
}}
|
||||
label="Age"
|
||||
>
|
||||
<MenuItem value={"true"}>Активные</MenuItem>
|
||||
<MenuItem value={"false"}>Неактивные</MenuItem>
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Box>
|
||||
<Box style={{ width: "80%", marginTop: "25px" }}>
|
||||
<DataGrid
|
||||
disableSelectionOnClick={true}
|
||||
rows={data?.items ?? []}
|
||||
columns={columns}
|
||||
sx={{
|
||||
color: theme.palette.secondary.main,
|
||||
"& .MuiDataGrid-iconSeparator": { display: "none" },
|
||||
"& .css-levciy-MuiTablePagination-displayedRows": {
|
||||
color: theme.palette.secondary.main,
|
||||
},
|
||||
"& .MuiSvgIcon-root": { color: theme.palette.secondary.main },
|
||||
"& .MuiTablePagination-selectLabel": {
|
||||
color: theme.palette.secondary.main,
|
||||
},
|
||||
"& .MuiInputBase-root": { color: theme.palette.secondary.main },
|
||||
"& .MuiButton-text": { color: theme.palette.secondary.main },
|
||||
"& .MuiDataGrid-overlay": {
|
||||
backgroundColor: "rgba(255, 255, 255, 0.1)",
|
||||
animation: `${fadeIn} 0.5s ease-out`,
|
||||
},
|
||||
}}
|
||||
components={{
|
||||
Toolbar: GridToolbar,
|
||||
LoadingOverlay: GridLoadingOverlay,
|
||||
}}
|
||||
loading={isValidating}
|
||||
paginationMode="server"
|
||||
page={page}
|
||||
onPageChange={setPage}
|
||||
rowCount={promocodesCount}
|
||||
pageSize={pageSize}
|
||||
onPageSizeChange={setPageSize}
|
||||
rowsPerPageOptions={[10, 25, 50, 100]}
|
||||
autoHeight
|
||||
/>
|
||||
</Box>
|
||||
<EditModal
|
||||
id={showEditModalId}
|
||||
setId={setShowEditModalId}
|
||||
promocodes={data?.items ?? []}
|
||||
editPromocode={editPromocode}
|
||||
/>
|
||||
<StatisticsModal
|
||||
id={showStatisticsModalId}
|
||||
setId={setShowStatisticsModalId}
|
||||
promocodeStatistics={promocodeStatistics}
|
||||
to={to}
|
||||
setTo={setTo}
|
||||
from={from}
|
||||
setFrom={setFrom}
|
||||
promocodes={data?.items ?? []}
|
||||
createFastLink={createFastLink}
|
||||
/>
|
||||
<DeleteModal id={deleteModal} setModal={setDeleteModal} deletePromocode={deletePromocode} />
|
||||
</LocalizationProvider>
|
||||
);
|
||||
};
|
||||
|
@ -51,9 +51,7 @@ const Header: React.FC = () => {
|
||||
</Typography>
|
||||
|
||||
<IconButton
|
||||
onClick={() => {
|
||||
logout().then(clearAuthToken);
|
||||
}}
|
||||
onClick={() => logout().then(clearAuthToken)}
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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[]) => {
|
||||
|
@ -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();
|
||||
|
@ -12,7 +12,7 @@ export function useQuizStatistic({ to, from }: useQuizStatisticProps) {
|
||||
const formatTo = to?.unix();
|
||||
const formatFrom = from?.unix();
|
||||
|
||||
const [data, setData] = useState<QuizStatisticResponse | null>({
|
||||
const [data, setData] = useState<QuizStatisticResponse>({
|
||||
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();
|
||||
|
@ -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();
|
||||
|
Loading…
Reference in New Issue
Block a user