diff --git a/lib/components/ViewPublicationPage/questions/Varimg/OwnVarimgImage.tsx b/lib/components/ViewPublicationPage/questions/Varimg/OwnVarimgImage.tsx index 9446c24..2858920 100644 --- a/lib/components/ViewPublicationPage/questions/Varimg/OwnVarimgImage.tsx +++ b/lib/components/ViewPublicationPage/questions/Varimg/OwnVarimgImage.tsx @@ -1,5 +1,10 @@ -import React, { forwardRef } from "react"; +import React, { forwardRef, useState } from "react"; 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 { questionId: string; @@ -7,14 +12,58 @@ interface OwnVarimgImageProps { } export const OwnVarimgImage = forwardRef(({ 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) => { const file = event.target.files?.[0]; if (file) { - // @ts-ignore - updateOwnVariantWithFile(variantId, file); - updateAnswer(questionId, variantId, 0); + uploadImage(file); event.target.value = ""; } }; @@ -24,8 +73,9 @@ export const OwnVarimgImage = forwardRef( type="file" ref={ref} style={{ display: "none" }} - accept="image/*" + accept={ACCEPT_SEND_FILE_TYPES_MAP.picture.join(",")} onChange={handleFileChange} + disabled={isUploading} /> ); }); diff --git a/lib/components/ViewPublicationPage/questions/Varimg/index.tsx b/lib/components/ViewPublicationPage/questions/Varimg/index.tsx index c90a7fc..b6a9793 100644 --- a/lib/components/ViewPublicationPage/questions/Varimg/index.tsx +++ b/lib/components/ViewPublicationPage/questions/Varimg/index.tsx @@ -37,9 +37,7 @@ export const Varimg = ({ currentQuestion }: VarimgProps) => { ); const ownVariantData = ownVariants.find((v) => v.id === answer); const ownImageUrl = useMemo(() => { - return ownVariantData?.variant.file - ? URL.createObjectURL(ownVariantData.variant.file) - : ownVariantData?.variant.localImageUrl; + return ownVariantData?.variant.localImageUrl; }, [ownVariantData]); const inputRef = useRef(null); diff --git a/lib/model/questionTypes/shared.ts b/lib/model/questionTypes/shared.ts index 7f14c4e..c058608 100644 --- a/lib/model/questionTypes/shared.ts +++ b/lib/model/questionTypes/shared.ts @@ -54,7 +54,7 @@ export type QuestionVariant = { /** Локальный URL для предпросмотра */ localImageUrl?: string; points?: number; - file?: File; + fileId?: string; }; export interface QuestionVariantWithEditedImages extends QuestionVariant { editedUrlImagesList?: EditedUrlImagesList | null; diff --git a/lib/stores/quizView.ts b/lib/stores/quizView.ts index 2533acc..3238ce5 100644 --- a/lib/stores/quizView.ts +++ b/lib/stores/quizView.ts @@ -37,7 +37,6 @@ interface QuizViewActions { originalImageUrl?: string, localImageUrl?: string ) => void; - updateOwnVariantWithFile: (variantId: string, file: File) => void; deleteOwnVariant: (id: string) => 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) { set( (state) => { diff --git a/lib/utils/sendQuestionAnswer.ts b/lib/utils/sendQuestionAnswer.ts index 939e2a8..623d986 100644 --- a/lib/utils/sendQuestionAnswer.ts +++ b/lib/utils/sendQuestionAnswer.ts @@ -267,9 +267,24 @@ export async function sendQuestionAnswer( 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}`); + + 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 = { - Image: variant.extendedText, - Description: question.content.own ? ownAnswer : variant.answer, + Image: imageValue, + Description: variant.isOwn ? ownAnswer : variant.answer, }; if (!body) throw new Error(`Body of answer in question ${question.id} is undefined`);