корректная отправка ответа
This commit is contained in:
parent
b8b30a352b
commit
6a1f015ff8
@ -1,5 +1,10 @@
|
|||||||
import React, { forwardRef } from "react";
|
import React, { forwardRef, useState } from "react";
|
||||||
import { useQuizViewStore } from "@stores/quizView";
|
import { useQuizViewStore } from "@stores/quizView";
|
||||||
|
import { useQuizStore } from "@/stores/useQuizStore";
|
||||||
|
import { useSnackbar } from "notistack";
|
||||||
|
import { useTranslation } from "react-i18next";
|
||||||
|
import { sendFile } from "@/api/quizRelase";
|
||||||
|
import { ACCEPT_SEND_FILE_TYPES_MAP, MAX_FILE_SIZE } from "../../tools/fileUpload";
|
||||||
|
|
||||||
interface OwnVarimgImageProps {
|
interface OwnVarimgImageProps {
|
||||||
questionId: string;
|
questionId: string;
|
||||||
@ -7,14 +12,58 @@ interface OwnVarimgImageProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const OwnVarimgImage = forwardRef<HTMLInputElement, OwnVarimgImageProps>(({ questionId, variantId }, ref) => {
|
export const OwnVarimgImage = forwardRef<HTMLInputElement, OwnVarimgImageProps>(({ questionId, variantId }, ref) => {
|
||||||
const { updateAnswer, updateOwnVariantWithFile } = useQuizViewStore((state) => state);
|
const { updateAnswer, updateOwnVariant } = useQuizViewStore((state) => state);
|
||||||
|
const { quizId, preview } = useQuizStore();
|
||||||
|
const { enqueueSnackbar } = useSnackbar();
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const [isUploading, setIsUploading] = useState(false);
|
||||||
|
|
||||||
|
const uploadImage = async (file: File) => {
|
||||||
|
if (isUploading) return;
|
||||||
|
if (!file) return;
|
||||||
|
|
||||||
|
// Валидация размера файла
|
||||||
|
if (file.size > MAX_FILE_SIZE) {
|
||||||
|
enqueueSnackbar(t("file is too big"), { variant: "warning" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Валидация типа файла
|
||||||
|
const isFileTypeAccepted = ACCEPT_SEND_FILE_TYPES_MAP.picture.some((fileType) =>
|
||||||
|
file.name.toLowerCase().endsWith(fileType)
|
||||||
|
);
|
||||||
|
if (!isFileTypeAccepted) {
|
||||||
|
enqueueSnackbar(t("file type is not supported"), { variant: "warning" });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsUploading(true);
|
||||||
|
try {
|
||||||
|
const data = await sendFile({
|
||||||
|
questionId,
|
||||||
|
body: { file, name: file.name, preview },
|
||||||
|
qid: quizId,
|
||||||
|
});
|
||||||
|
|
||||||
|
const fileId = data?.data.fileIDMap[questionId];
|
||||||
|
const localImageUrl = URL.createObjectURL(file);
|
||||||
|
|
||||||
|
updateOwnVariant(variantId, "", "", fileId, localImageUrl);
|
||||||
|
// Автоматически выбираем "own" вариант при загрузке файла
|
||||||
|
updateAnswer(questionId, variantId, 0);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error uploading image:", error);
|
||||||
|
enqueueSnackbar(t("The answer was not counted"));
|
||||||
|
} finally {
|
||||||
|
setIsUploading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
const file = event.target.files?.[0];
|
const file = event.target.files?.[0];
|
||||||
if (file) {
|
if (file) {
|
||||||
// @ts-ignore
|
uploadImage(file);
|
||||||
updateOwnVariantWithFile(variantId, file);
|
|
||||||
updateAnswer(questionId, variantId, 0);
|
|
||||||
event.target.value = "";
|
event.target.value = "";
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -24,8 +73,9 @@ export const OwnVarimgImage = forwardRef<HTMLInputElement, OwnVarimgImageProps>(
|
|||||||
type="file"
|
type="file"
|
||||||
ref={ref}
|
ref={ref}
|
||||||
style={{ display: "none" }}
|
style={{ display: "none" }}
|
||||||
accept="image/*"
|
accept={ACCEPT_SEND_FILE_TYPES_MAP.picture.join(",")}
|
||||||
onChange={handleFileChange}
|
onChange={handleFileChange}
|
||||||
|
disabled={isUploading}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -37,9 +37,7 @@ export const Varimg = ({ currentQuestion }: VarimgProps) => {
|
|||||||
);
|
);
|
||||||
const ownVariantData = ownVariants.find((v) => v.id === answer);
|
const ownVariantData = ownVariants.find((v) => v.id === answer);
|
||||||
const ownImageUrl = useMemo(() => {
|
const ownImageUrl = useMemo(() => {
|
||||||
return ownVariantData?.variant.file
|
return ownVariantData?.variant.localImageUrl;
|
||||||
? URL.createObjectURL(ownVariantData.variant.file)
|
|
||||||
: ownVariantData?.variant.localImageUrl;
|
|
||||||
}, [ownVariantData]);
|
}, [ownVariantData]);
|
||||||
|
|
||||||
const inputRef = useRef<HTMLInputElement>(null);
|
const inputRef = useRef<HTMLInputElement>(null);
|
||||||
|
@ -54,7 +54,7 @@ export type QuestionVariant = {
|
|||||||
/** Локальный URL для предпросмотра */
|
/** Локальный URL для предпросмотра */
|
||||||
localImageUrl?: string;
|
localImageUrl?: string;
|
||||||
points?: number;
|
points?: number;
|
||||||
file?: File;
|
fileId?: string;
|
||||||
};
|
};
|
||||||
export interface QuestionVariantWithEditedImages extends QuestionVariant {
|
export interface QuestionVariantWithEditedImages extends QuestionVariant {
|
||||||
editedUrlImagesList?: EditedUrlImagesList | null;
|
editedUrlImagesList?: EditedUrlImagesList | null;
|
||||||
|
@ -37,7 +37,6 @@ interface QuizViewActions {
|
|||||||
originalImageUrl?: string,
|
originalImageUrl?: string,
|
||||||
localImageUrl?: string
|
localImageUrl?: string
|
||||||
) => void;
|
) => void;
|
||||||
updateOwnVariantWithFile: (variantId: string, file: File) => void;
|
|
||||||
deleteOwnVariant: (id: string) => void;
|
deleteOwnVariant: (id: string) => void;
|
||||||
setCurrentQuizStep: (step: QuizStep) => void;
|
setCurrentQuizStep: (step: QuizStep) => void;
|
||||||
}
|
}
|
||||||
@ -135,35 +134,6 @@ export const createQuizViewStore = () =>
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
updateOwnVariantWithFile(variantId, file) {
|
|
||||||
set(
|
|
||||||
(state) => {
|
|
||||||
const index = state.ownVariants.findIndex((v) => v.id === variantId);
|
|
||||||
|
|
||||||
if (index < 0) {
|
|
||||||
state.ownVariants.push({
|
|
||||||
id: variantId,
|
|
||||||
variant: {
|
|
||||||
id: variantId,
|
|
||||||
answer: "",
|
|
||||||
extendedText: "",
|
|
||||||
hints: "",
|
|
||||||
originalImageUrl: "",
|
|
||||||
file: file,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
state.ownVariants[index].variant.file = file;
|
|
||||||
state.ownVariants[index].variant.localImageUrl = undefined;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
false,
|
|
||||||
{
|
|
||||||
type: "updateOwnVariantWithFile",
|
|
||||||
variantId,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
},
|
|
||||||
deleteOwnVariant(id) {
|
deleteOwnVariant(id) {
|
||||||
set(
|
set(
|
||||||
(state) => {
|
(state) => {
|
||||||
|
@ -267,9 +267,24 @@ export async function sendQuestionAnswer(
|
|||||||
ownVariants[ownVariants.findIndex((variant) => variant.id === questionAnswer.answer)]?.variant?.answer || "";
|
ownVariants[ownVariants.findIndex((variant) => variant.id === questionAnswer.answer)]?.variant?.answer || "";
|
||||||
|
|
||||||
if (!variant) throw new Error(`Cannot find variant with id ${questionAnswer.answer} in question ${question.id}`);
|
if (!variant) throw new Error(`Cannot find variant with id ${questionAnswer.answer} in question ${question.id}`);
|
||||||
|
|
||||||
|
let imageValue = variant.extendedText;
|
||||||
|
if (variant.isOwn) {
|
||||||
|
// Берем fileId из ownVariants для own вариантов
|
||||||
|
const ownVariantData = ownVariants.find((v) => v.id === variant.id)?.variant;
|
||||||
|
if (ownVariantData?.originalImageUrl) {
|
||||||
|
// Конструируем полный URL для own вариантов
|
||||||
|
const baseUrl =
|
||||||
|
"https://s3.timeweb.cloud/3c580be9-cf31f296-d055-49cf-b39e-30c7959dc17b/squizimages/55c25eb9-4533-4d51-9da5-54e63e8aeace/";
|
||||||
|
// Убираем расширение файла из fileId
|
||||||
|
const fileIdWithoutExtension = ownVariantData.originalImageUrl.replace(/\.(jpg|jpeg|png|gif|webp)$/i, "");
|
||||||
|
imageValue = baseUrl + fileIdWithoutExtension;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const body = {
|
const body = {
|
||||||
Image: variant.extendedText,
|
Image: imageValue,
|
||||||
Description: question.content.own ? ownAnswer : variant.answer,
|
Description: variant.isOwn ? ownAnswer : variant.answer,
|
||||||
};
|
};
|
||||||
if (!body) throw new Error(`Body of answer in question ${question.id} is undefined`);
|
if (!body) throw new Error(`Body of answer in question ${question.id} is undefined`);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user