Files
encoach_frontend/src/components/ExamEditor/SettingsEditor/Shared/Generate.ts
Carlos-Mesquita ccbbf30058 ENCOA-311
2025-01-13 01:18:19 +00:00

137 lines
5.1 KiB
TypeScript

import axios from "axios";
import { playSound } from "@/utils/sound";
import { toast } from "react-toastify";
import { Generating } from "@/stores/examEditor/types";
import useExamEditorStore from "@/stores/examEditor";
import { Module } from "@/interfaces";
interface GeneratorConfig {
method: 'GET' | 'POST';
queryParams?: Record<string, string | string[]>;
files?: Record<string, string>;
body?: Record<string, any>;
}
export function generate(
sectionId: number,
module: Module,
type: Generating,
config: GeneratorConfig,
mapData: (data: any) => Record<string, any>[],
levelSectionId?: number,
level: boolean = false
) {
const setGenerating = (sectionId: number, generating: Generating, level: boolean, remove?: boolean) => {
const state = useExamEditorStore.getState();
const dispatch = state.dispatch;
let generatingUpdate;
if (level) {
if (remove) {
generatingUpdate = state.modules["level"].sections.find((s) => s.sectionId === levelSectionId)!.levelGenerating.filter(g => g === generating)
}
else {
generatingUpdate = [...state.modules["level"].sections.find((s) => s.sectionId === levelSectionId)!.levelGenerating, generating];
}
} else {
generatingUpdate = generating;
}
dispatch({
type: "UPDATE_SECTION_SINGLE_FIELD",
payload: { sectionId, module: level ? "level" : module, field: level ? "levelGenerating" : "generating", value: generatingUpdate }
});
};
const setGeneratedResult = (sectionId: number, generating: Generating, result: Record<string, any>[] | undefined, level: boolean) => {
const state = useExamEditorStore.getState();
const dispatch = state.dispatch;
let genResults;
if (level) {
genResults = [...state.modules["level"].sections.find((s) => s.sectionId === levelSectionId)!.levelGenResults, { generating, result, module }];
} else {
genResults = { generating, result, module };
}
dispatch({
type: "UPDATE_SECTION_SINGLE_FIELD",
payload: { sectionId: level ? levelSectionId! : sectionId, module: level ? "level" : module, field: level ? "levelGenResults" : "genResult", value: genResults }
});
};
setGenerating(level ? levelSectionId! : sectionId, type, level);
function buildQueryString(params: Record<string, string | string[]>): string {
const searchParams = new URLSearchParams();
Object.entries(params).forEach(([key, value]) => {
if (Array.isArray(value)) {
value.forEach(v => searchParams.append(key, v));
} else {
searchParams.append(key, value);
}
});
return searchParams.toString();
}
const queryString = config.queryParams ? buildQueryString(config.queryParams) : '';
const url = `/api/exam/generate/${module}/${sectionId}${queryString ? `?${queryString}` : ''}`;
let body = null;
if (config.files && Object.keys(config.files).length > 0 && config.method === 'POST') {
const formData = new FormData();
const buildForm = async () => {
await Promise.all(
Object.entries(config.files ?? {}).map(async ([key, blobUrl]) => {
const response = await fetch(blobUrl);
const blob = await response.blob();
const file = new File([blob], key, { type: blob.type });
formData.append(key, file);
})
);
if (config.body) {
Object.entries(config.body).forEach(([key, value]) => {
formData.append(key, value as string);
});
}
return formData;
};
buildForm().then(form => {
body = form;
const request = axios.post(url, body, { headers: { 'Content-Type': 'multipart/form-data' } });
request
.then((result) => {
playSound("check");
setGeneratedResult(level ? levelSectionId! : sectionId, type, mapData(result.data), level);
})
.catch((error) => {
setGenerating(sectionId, undefined, level, true);
playSound("error");
toast.error("Something went wrong! Try to generate again.");
});
});
} else {
body = config.body;
const request = config.method === 'POST'
? axios.post(url, body, { headers: { 'Content-Type': 'application/json' } })
: axios.get(url);
request
.then((result) => {
playSound("check");
setGeneratedResult(level ? levelSectionId! : sectionId, type, mapData(result.data), level);
})
.catch((error) => {
setGenerating(sectionId, undefined, level, true);
playSound("error");
toast.error("Something went wrong! Try to generate again.");
});
}
}