add image crop modal to page question settings
This commit is contained in:
parent
66b39f63de
commit
fe616ecf3a
@ -11,6 +11,7 @@ export const QUIZ_QUESTION_PAGE: Omit<QuizQuestionPage, "id"> = {
|
||||
innerName: "",
|
||||
text: "",
|
||||
picture: "",
|
||||
originalPicture: "",
|
||||
video: "",
|
||||
},
|
||||
};
|
||||
|
@ -13,6 +13,7 @@ export interface QuizQuestionPage extends QuizQuestionBase {
|
||||
innerName: string;
|
||||
text: string;
|
||||
picture: string;
|
||||
originalPicture: string;
|
||||
video: string;
|
||||
hint: QuestionHint;
|
||||
rule: QuestionBranchingRule;
|
||||
|
@ -1,9 +1,8 @@
|
||||
import { ImageAddIcons } from "@icons/ImageAddIcons";
|
||||
import { VideofileIcon } from "@icons/questionsPage/VideofileIcon";
|
||||
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
|
||||
import { questionStore, updateQuestionsList } from "@root/questions";
|
||||
import { questionStore, setPageQuestionOriginalPicture, setPageQuestionPicture, updateQuestionsList } from "@root/questions";
|
||||
import CustomTextField from "@ui_kit/CustomTextField";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useState } from "react";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useDebouncedCallback } from "use-debounce";
|
||||
import ButtonsOptions from "../ButtonsOptions";
|
||||
@ -11,6 +10,9 @@ import { UploadImageModal } from "../UploadImage/UploadImageModal";
|
||||
import { UploadVideoModal } from "../UploadVideoModal";
|
||||
import SwitchPageOptions from "./switchPageOptions";
|
||||
|
||||
import { openCropModal } from "@root/cropModal";
|
||||
import AddOrEditImageButton from "@ui_kit/AddOrEditImageButton";
|
||||
import { CropModal } from "@ui_kit/Modal/CropModal";
|
||||
import type { QuizQuestionPage } from "../../../model/questionTypes/page";
|
||||
|
||||
type Props = {
|
||||
@ -39,6 +41,21 @@ export default function PageOptions({ disableInput, totalIndex }: Props) {
|
||||
setSwitchState(data);
|
||||
};
|
||||
|
||||
function handleImageUpload(fileList: FileList | null) {
|
||||
if (!fileList?.length) return;
|
||||
|
||||
const url = URL.createObjectURL(fileList[0]);
|
||||
|
||||
setPageQuestionPicture(quizId, totalIndex, url);
|
||||
setPageQuestionOriginalPicture(quizId, totalIndex, url);
|
||||
setOpenImageModal(false);
|
||||
openCropModal(url, url);
|
||||
}
|
||||
|
||||
function handleCropModalSaveClick(url: string) {
|
||||
setPageQuestionPicture(quizId, totalIndex, url);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box
|
||||
@ -70,7 +87,6 @@ export default function PageOptions({ disableInput, totalIndex }: Props) {
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
onClick={() => setOpenImageModal(true)}
|
||||
sx={{
|
||||
cursor: "pointer",
|
||||
display: "flex",
|
||||
@ -78,101 +94,22 @@ export default function PageOptions({ disableInput, totalIndex }: Props) {
|
||||
gap: "20px",
|
||||
}}
|
||||
>
|
||||
{isMobile ? (
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
width: "120px",
|
||||
position: "relative",
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
sx={{
|
||||
width: "100%",
|
||||
background: "#EEE4FC",
|
||||
height: "40px",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
borderTopLeftRadius: "4px",
|
||||
borderBottomLeftRadius: "4px",
|
||||
}}
|
||||
>
|
||||
{question.content.picture ? (
|
||||
<Box sx={{ display: "flex", width: "40px" }}>
|
||||
<img
|
||||
src={question.content.picture}
|
||||
alt=""
|
||||
style={{ width: "100%" }}
|
||||
/>
|
||||
</Box>
|
||||
) : (
|
||||
<ImageAddIcons
|
||||
style={{
|
||||
color: "#7E2AEA",
|
||||
fontSize: "20px",
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
width: "20px",
|
||||
background: "#EEE4FC",
|
||||
height: "40px",
|
||||
color: "white",
|
||||
backgroundColor: "#7E2AEA",
|
||||
borderTopRightRadius: "4px",
|
||||
borderBottomRightRadius: "4px",
|
||||
}}
|
||||
>
|
||||
+
|
||||
</Box>
|
||||
</Box>
|
||||
) : (
|
||||
<Box
|
||||
sx={{
|
||||
width: "60px",
|
||||
height: "40px",
|
||||
background: "#EEE4FC",
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
{question.content.picture ? (
|
||||
<Box sx={{ display: "flex", width: "40px" }}>
|
||||
<img
|
||||
src={question.content.picture}
|
||||
alt=""
|
||||
style={{ width: "100%" }}
|
||||
/>
|
||||
</Box>
|
||||
) : (
|
||||
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "center", width: "100%" }}>
|
||||
<ImageAddIcons fontSize="22px" color="#7E2AEA" />
|
||||
</Box>
|
||||
)}
|
||||
<span
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
background: "#7E2AEA",
|
||||
height: "100%",
|
||||
width: "25px",
|
||||
color: "white",
|
||||
fontSize: "15px",
|
||||
}}
|
||||
>
|
||||
+
|
||||
</span>
|
||||
</Box>
|
||||
)}
|
||||
<AddOrEditImageButton
|
||||
imageSrc={question.content.picture}
|
||||
onImageClick={() => {
|
||||
if (question.content.picture) {
|
||||
return openCropModal(
|
||||
question.content.picture,
|
||||
question.content.originalPicture
|
||||
);
|
||||
}
|
||||
|
||||
setOpenImageModal(true);
|
||||
}}
|
||||
onPlusClick={() => {
|
||||
setOpenImageModal(true);
|
||||
}}
|
||||
/>
|
||||
|
||||
<Typography
|
||||
sx={{
|
||||
@ -189,18 +126,9 @@ export default function PageOptions({ disableInput, totalIndex }: Props) {
|
||||
<UploadImageModal
|
||||
open={openImageModal}
|
||||
onClose={() => setOpenImageModal(false)}
|
||||
imgHC={(fileList) => {
|
||||
if (fileList?.length) {
|
||||
updateQuestionsList<QuizQuestionPage>(quizId, totalIndex, {
|
||||
content: {
|
||||
...question.content,
|
||||
picture: URL.createObjectURL(fileList[0]),
|
||||
},
|
||||
});
|
||||
}
|
||||
}}
|
||||
// onClick={() => setOpenVideoModal(true)}
|
||||
imgHC={handleImageUpload}
|
||||
/>
|
||||
<CropModal onSaveImageClick={handleCropModalSaveClick} />
|
||||
<Typography> или</Typography>
|
||||
<Box
|
||||
sx={{
|
||||
|
@ -120,6 +120,21 @@ export const updateQuestionsList = <T = AnyQuizQuestion>(
|
||||
questionStore.setState({ listQuestions: questionListClone });
|
||||
};
|
||||
|
||||
export const updateQuestion = <T extends AnyQuizQuestion>(
|
||||
quizId: number,
|
||||
questionIndex: number,
|
||||
recipe: (question: T) => void,
|
||||
) => setProducedState(state => {
|
||||
const question = state.listQuestions[quizId][questionIndex] as T;
|
||||
|
||||
recipe(question);
|
||||
}, {
|
||||
type: "updateQuestion",
|
||||
quizId,
|
||||
questionIndex,
|
||||
recipe,
|
||||
});
|
||||
|
||||
export const removeQuestionsByQuizId = (quizId: number) => setProducedState(state => {
|
||||
delete state.listQuestions[quizId];
|
||||
}, "removeQuestionsByQuizId");
|
||||
@ -172,6 +187,36 @@ export const setVariantOriginalImageUrl = (
|
||||
url,
|
||||
});
|
||||
|
||||
export const setPageQuestionPicture = (
|
||||
quizId: number,
|
||||
questionIndex: number,
|
||||
url: string,
|
||||
) => setProducedState(state => {
|
||||
const question = state.listQuestions[quizId][questionIndex];
|
||||
if (question.type !== "page") return;
|
||||
|
||||
if (question.content.picture === url) return;
|
||||
|
||||
if (
|
||||
question.content.picture !== question.content.originalPicture
|
||||
) URL.revokeObjectURL(question.content.picture);
|
||||
question.content.picture = url;
|
||||
});
|
||||
|
||||
export const setPageQuestionOriginalPicture = (
|
||||
quizId: number,
|
||||
questionIndex: number,
|
||||
url: string,
|
||||
) => setProducedState(state => {
|
||||
const question = state.listQuestions[quizId][questionIndex];
|
||||
if (question.type !== "page") return;
|
||||
|
||||
if (question.content.originalPicture === url) return;
|
||||
|
||||
URL.revokeObjectURL(question.content.originalPicture);
|
||||
question.content.originalPicture = url;
|
||||
});
|
||||
|
||||
export const updateQuestionsListDragAndDrop = (
|
||||
quizId: number,
|
||||
updatedQuestions: AnyQuizQuestion[]
|
||||
|
Loading…
Reference in New Issue
Block a user