2024-05-13 13:24:41 +00:00
|
|
|
|
import { makeRequest } from "@api/makeRequest";
|
2023-11-14 13:09:17 +00:00
|
|
|
|
import { defaultQuizConfig } from "@model/quizSettings";
|
2024-05-16 13:40:52 +00:00
|
|
|
|
|
2024-05-13 13:24:41 +00:00
|
|
|
|
import { parseAxiosError } from "@utils/parse-error";
|
2023-11-02 16:45:28 +00:00
|
|
|
|
|
2024-05-16 13:40:52 +00:00
|
|
|
|
import type { RawQuiz } from "model/quiz/quiz";
|
|
|
|
|
import type { CopyQuizRequest, CopyQuizResponse } from "model/quiz/copy";
|
|
|
|
|
import type { CreateQuizRequest } from "model/quiz/create";
|
|
|
|
|
import type { DeleteQuizRequest, DeleteQuizResponse } from "model/quiz/delete";
|
|
|
|
|
import type { EditQuizRequest, EditQuizResponse } from "model/quiz/edit";
|
|
|
|
|
import type { GetQuizRequest, GetQuizResponse } from "model/quiz/get";
|
2024-08-28 22:30:06 +00:00
|
|
|
|
import { transliterate } from 'transliteration';
|
2024-05-16 13:40:52 +00:00
|
|
|
|
import type {
|
|
|
|
|
GetQuizListRequest,
|
|
|
|
|
GetQuizListResponse,
|
|
|
|
|
} from "model/quiz/getList";
|
|
|
|
|
|
2024-05-13 13:24:41 +00:00
|
|
|
|
type AddedQuizImagesResponse = {
|
|
|
|
|
[key: string]: string;
|
|
|
|
|
};
|
|
|
|
|
|
2024-05-15 11:44:10 +00:00
|
|
|
|
const API_URL = `${process.env.REACT_APP_DOMAIN}/squiz`;
|
2024-05-29 11:29:54 +00:00
|
|
|
|
const IMAGES_URL = `${process.env.REACT_APP_DOMAIN}/squizstorer/v1.0.0`;
|
2024-05-13 13:24:41 +00:00
|
|
|
|
|
|
|
|
|
export const createQuiz = async (
|
|
|
|
|
body?: Partial<CreateQuizRequest>,
|
|
|
|
|
): Promise<[RawQuiz | null, string?]> => {
|
|
|
|
|
try {
|
|
|
|
|
const createdQuiz = await makeRequest<CreateQuizRequest, RawQuiz>({
|
|
|
|
|
method: "POST",
|
|
|
|
|
url: `${API_URL}/quiz/create`,
|
|
|
|
|
body: { ...defaultCreateQuizBody, ...body },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return [createdQuiz];
|
|
|
|
|
} catch (nativeError) {
|
|
|
|
|
const [error] = parseAxiosError(nativeError);
|
|
|
|
|
|
2024-05-15 12:37:42 +00:00
|
|
|
|
return [null, `Не удалось создать квиз. ${error}`];
|
2024-05-13 13:24:41 +00:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const getQuizList = async (
|
|
|
|
|
body?: Partial<CreateQuizRequest>,
|
|
|
|
|
): Promise<[RawQuiz[] | null, string?]> => {
|
|
|
|
|
try {
|
|
|
|
|
const { items } = await makeRequest<
|
|
|
|
|
GetQuizListRequest,
|
|
|
|
|
GetQuizListResponse
|
|
|
|
|
>({
|
|
|
|
|
method: "POST",
|
|
|
|
|
url: `${API_URL}/quiz/getList`,
|
|
|
|
|
body: { ...defaultGetQuizListBody, ...body },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return [items];
|
|
|
|
|
} catch (nativeError) {
|
|
|
|
|
const [error] = parseAxiosError(nativeError);
|
|
|
|
|
|
2024-05-15 12:37:42 +00:00
|
|
|
|
return [null, `Не удалось получить список квизов. ${error}`];
|
2024-05-13 13:24:41 +00:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const getQuiz = async (
|
|
|
|
|
body?: Partial<GetQuizRequest>,
|
|
|
|
|
): Promise<[GetQuizResponse | null, string?]> => {
|
|
|
|
|
try {
|
|
|
|
|
const quiz = await makeRequest<GetQuizRequest, GetQuizResponse>({
|
|
|
|
|
method: "GET",
|
|
|
|
|
url: `${API_URL}/quiz/get`,
|
|
|
|
|
body: { ...defaultGetQuizBody, ...body },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return [quiz];
|
|
|
|
|
} catch (nativeError) {
|
|
|
|
|
const [error] = parseAxiosError(nativeError);
|
|
|
|
|
|
2024-05-15 12:37:42 +00:00
|
|
|
|
return [null, `Не удалось получить квиз. ${error}`];
|
2024-05-13 13:24:41 +00:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const editQuiz = async (
|
|
|
|
|
body: EditQuizRequest,
|
|
|
|
|
signal?: AbortSignal,
|
|
|
|
|
): Promise<[EditQuizResponse | null, string?]> => {
|
|
|
|
|
try {
|
|
|
|
|
const editedQuiz = await makeRequest<EditQuizRequest, EditQuizResponse>({
|
|
|
|
|
method: "PATCH",
|
|
|
|
|
url: `${API_URL}/quiz/edit`,
|
|
|
|
|
body,
|
|
|
|
|
signal,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return [editedQuiz];
|
|
|
|
|
} catch (nativeError) {
|
|
|
|
|
const [error] = parseAxiosError(nativeError);
|
|
|
|
|
|
2024-05-15 12:37:42 +00:00
|
|
|
|
return [null, `Не удалось изменить квиз. ${error}`];
|
2024-05-13 13:24:41 +00:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const copyQuiz = async (
|
|
|
|
|
id: number,
|
|
|
|
|
): Promise<[EditQuizResponse | null, string?]> => {
|
|
|
|
|
try {
|
|
|
|
|
const copiedQuiz = await makeRequest<CopyQuizRequest, CopyQuizResponse>({
|
|
|
|
|
method: "POST",
|
|
|
|
|
url: `${API_URL}/quiz/copy`,
|
|
|
|
|
body: { id },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return [copiedQuiz];
|
|
|
|
|
} catch (nativeError) {
|
|
|
|
|
const [error] = parseAxiosError(nativeError);
|
|
|
|
|
|
2024-05-15 12:37:42 +00:00
|
|
|
|
return [null, `Не удалось скопировать квиз. ${error}`];
|
2024-05-13 13:24:41 +00:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const deleteQuiz = async (
|
|
|
|
|
id: number,
|
|
|
|
|
): Promise<[DeleteQuizResponse | null, string?]> => {
|
|
|
|
|
try {
|
|
|
|
|
const deletedQuiz = await makeRequest<
|
|
|
|
|
DeleteQuizRequest,
|
|
|
|
|
DeleteQuizResponse
|
|
|
|
|
>({
|
|
|
|
|
method: "DELETE",
|
|
|
|
|
url: `${API_URL}/quiz/delete`,
|
|
|
|
|
body: { id },
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return [deletedQuiz];
|
|
|
|
|
} catch (nativeError) {
|
|
|
|
|
const [error] = parseAxiosError(nativeError);
|
|
|
|
|
|
2024-05-15 12:37:42 +00:00
|
|
|
|
return [null, `Не удалось удалить квиз. ${error}`];
|
2024-05-13 13:24:41 +00:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const addQuizImages = async (
|
|
|
|
|
quizId: number,
|
|
|
|
|
image: Blob,
|
|
|
|
|
): Promise<[AddedQuizImagesResponse | null, string?]> => {
|
|
|
|
|
try {
|
|
|
|
|
const formData = new FormData();
|
|
|
|
|
|
2024-08-28 22:30:06 +00:00
|
|
|
|
const name = image?.name ? transliterate(image?.name.replace(/\s/g, '_')) : "blob"
|
2024-08-28 00:02:17 +00:00
|
|
|
|
|
|
|
|
|
//Замена всех побелов на _
|
2025-06-01 14:05:41 +00:00
|
|
|
|
const renamedImage = new File([image], name)
|
|
|
|
|
|
2024-08-28 00:02:17 +00:00
|
|
|
|
|
2024-05-13 13:24:41 +00:00
|
|
|
|
formData.append("quiz", quizId.toString());
|
2024-08-28 00:02:17 +00:00
|
|
|
|
formData.append("image", renamedImage);
|
2024-05-13 13:24:41 +00:00
|
|
|
|
|
|
|
|
|
const addedQuizImages = await makeRequest<
|
|
|
|
|
FormData,
|
|
|
|
|
AddedQuizImagesResponse
|
|
|
|
|
>({
|
|
|
|
|
url: `${IMAGES_URL}/quiz/putImages`,
|
|
|
|
|
body: formData,
|
|
|
|
|
method: "PUT",
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
return [addedQuizImages];
|
|
|
|
|
} catch (nativeError) {
|
|
|
|
|
const [error] = parseAxiosError(nativeError);
|
|
|
|
|
|
2024-05-15 13:51:41 +00:00
|
|
|
|
return [null, `Не удалось добавить изображение. ${error}`];
|
2024-05-13 13:24:41 +00:00
|
|
|
|
}
|
|
|
|
|
};
|
2023-11-02 16:45:28 +00:00
|
|
|
|
|
2024-05-17 14:13:05 +00:00
|
|
|
|
export const copyQuizTemplate = async (
|
|
|
|
|
qid: string,
|
2024-05-17 14:14:34 +00:00
|
|
|
|
): Promise<[number | null, string?]> => {
|
2024-05-17 14:13:05 +00:00
|
|
|
|
try {
|
2024-05-17 14:14:34 +00:00
|
|
|
|
const { id } = await makeRequest<{ Qid: string }, { id: number }>({
|
2024-05-17 14:13:05 +00:00
|
|
|
|
method: "POST",
|
|
|
|
|
url: `${API_URL}/quiz/template`,
|
|
|
|
|
body: { Qid: qid },
|
|
|
|
|
});
|
|
|
|
|
|
2024-05-17 14:14:34 +00:00
|
|
|
|
if (!id) {
|
|
|
|
|
return [null, `Не удалось скопировать шаблон квиза.`];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return [id];
|
2024-05-17 14:13:05 +00:00
|
|
|
|
} catch (nativeError) {
|
|
|
|
|
const [error] = parseAxiosError(nativeError);
|
|
|
|
|
|
|
|
|
|
return [null, `Не удалось скопировать шаблон квиза. ${error}`];
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2023-11-02 16:45:28 +00:00
|
|
|
|
export const quizApi = {
|
2023-12-31 02:53:25 +00:00
|
|
|
|
create: createQuiz,
|
|
|
|
|
getList: getQuizList,
|
|
|
|
|
get: getQuiz,
|
|
|
|
|
edit: editQuiz,
|
|
|
|
|
copy: copyQuiz,
|
|
|
|
|
delete: deleteQuiz,
|
|
|
|
|
addImages: addQuizImages,
|
2024-05-17 14:13:05 +00:00
|
|
|
|
copyTemplate: copyQuizTemplate,
|
2023-11-02 16:45:28 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const defaultCreateQuizBody: CreateQuizRequest = {
|
2023-12-31 02:53:25 +00:00
|
|
|
|
fingerprinting: true,
|
|
|
|
|
repeatable: true,
|
|
|
|
|
note_prevented: true,
|
|
|
|
|
mail_notifications: false,
|
|
|
|
|
unique_answers: true,
|
|
|
|
|
name: "",
|
|
|
|
|
description: "",
|
|
|
|
|
config: JSON.stringify(defaultQuizConfig),
|
|
|
|
|
status: "stop",
|
|
|
|
|
limit: 0,
|
|
|
|
|
due_to: 0,
|
|
|
|
|
time_of_passing: 0,
|
|
|
|
|
pausable: false,
|
|
|
|
|
super: false,
|
|
|
|
|
group_id: 0,
|
2023-11-02 16:45:28 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const defaultGetQuizBody: GetQuizRequest = {
|
2023-12-31 02:53:25 +00:00
|
|
|
|
quiz_id: "string",
|
|
|
|
|
limit: 0,
|
|
|
|
|
page: 0,
|
|
|
|
|
need_config: true,
|
2023-11-02 16:45:28 +00:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const defaultGetQuizListBody: GetQuizListRequest = {
|
2023-12-31 02:53:25 +00:00
|
|
|
|
limit: 100,
|
|
|
|
|
offset: 0,
|
2023-11-02 16:45:28 +00:00
|
|
|
|
};
|