2026-01-20 09:02:26 -06:00

181 lines
5.8 KiB
TypeScript

import { define } from "../../../utils.ts";
import { SessionCookie } from "../../auth/callback.ts";
import { cloneObjectExcept, KvObj, QuizConfig } from "../../../utils/types.ts";
import {
getAllKvSessionConfigs,
setKvSessionConfigAny,
} from "../../../utils/database.ts";
import { setKvQuizAny, trasKvQuizAny } from "../../../utils/QuizDataClient.ts";
export const handler = define.handlers({
async POST(ctx) {
const req = ctx.req;
const state = ctx.state;
const stateData: SessionCookie = state.data ??
{
started_on: 0,
user_name: "",
user_id: "",
role: "",
user_encrypted: false,
};
try {
const form = await req.formData();
const quizDataString = form.get("pageConfigData") as string;
if (
quizDataString
) {
const data: {
quiz: QuizConfig;
index: number;
action: string;
userId: string;
iQuestion: number;
quizKey: string[];
props: KvObj<QuizConfig>[];
question: {
id: string;
quiz_id: string;
owner_id: string;
language_1: string;
language_2: string;
text_1: string;
audio_file_1: string;
text_2: string;
audio_file_2: string;
order_num: number;
background_file: string;
background_image_data: string;
video_file: string;
video_file_data: string;
};
} = JSON.parse(quizDataString);
const index = data.index;
const iQuestion = data.iQuestion;
const imageFileChecks: {
index: number;
iQuestion: number;
file: string;
}[] = [];
if (data.action === "image") {
const quizKvObj = data.props[index];
const question = data.question;
if (
quizKvObj.value && index >= 0 && iQuestion >= 0 && question &&
question.background_file &&
question.background_image_data.length > 0 &&
(
question.background_image_data.startsWith("http") ||
question.background_image_data.startsWith("/")
)
) {
const existingQuestions = Array.isArray(quizKvObj.value.questions)
? [...quizKvObj.value.questions]
: [];
const cloneKvObjValue: QuizConfig = cloneObjectExcept(
quizKvObj.value,
["questions"],
[existingQuestions],
) as QuizConfig;
if (
cloneKvObjValue.questions.length > 0 &&
cloneKvObjValue.questions.length ===
quizKvObj.value.questions.length
) {
cloneKvObjValue.questions[iQuestion] = question;
const cloneKvObj = cloneObjectExcept(quizKvObj, ["value"], [
cloneKvObjValue,
]);
const result = await setKvQuizAny(cloneKvObj);
if (result.ok) {
quizKvObj.value.questions[iQuestion] = question;
quizKvObj.versionstamp = result.versionstamp;
imageFileChecks.push({
index,
iQuestion,
file: question.background_image_data,
});
}
}
} else {
console.log(
"image bad",
question.background_image_data.substring(0, 100),
);
}
} else if (data.action === "delete") {
const allMySessions = await getAllKvSessionConfigs(
stateData.user_id,
);
const session = allMySessions.find((config) =>
config.key[1] == stateData.user_id &&
config.key[2] == state.stateId
);
if (session && session.ok && session.value) {
const removeQuizConfig = data.props[data.index];
const deleteIndexs: Array<number>[] = [];
let hasDelete = false;
allMySessions.map((old, oI) => {
deleteIndexs.push([]);
if (old.value) {
old.value.quiz_configs.map((keyItem, index) => {
if (
keyItem[1] == removeQuizConfig.key[1] &&
keyItem[2] == removeQuizConfig.key[2]
) {
deleteIndexs[oI].push(index);
hasDelete = true;
}
});
}
});
if (hasDelete) {
await Promise.all(deleteIndexs.map(async (qIonIndexs, sI) => {
if (qIonIndexs.length > 0) {
qIonIndexs.forEach((qIndex) => {
allMySessions[sI].value?.quiz_configs.splice(qIndex, 1);
});
await setKvSessionConfigAny(allMySessions[sI]);
}
if (removeQuizConfig.key[1] == stateData.user_id) {
await trasKvQuizAny(removeQuizConfig);
}
}));
if (data.props.length > 1) {
data.props.splice(data.index, 1);
} else {
console.log("no props");
data.props = [];
}
}
}
}
return new Response(JSON.stringify({ success: true }), {
status: 200,
headers: { "Content-Type": "application/json" },
});
} else {
return new Response(JSON.stringify({ error: "Missing quiz data" }), {
status: 400,
headers: { "Content-Type": "application/json" },
});
}
} catch (e) {
console.log("List post error ", e);
return new Response(JSON.stringify({ error: "Internal server error" }), {
status: 500,
headers: { "Content-Type": "application/json" },
});
}
},
});