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: "",
|
innerName: "",
|
||||||
text: "",
|
text: "",
|
||||||
picture: "",
|
picture: "",
|
||||||
|
originalPicture: "",
|
||||||
video: "",
|
video: "",
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -13,6 +13,7 @@ export interface QuizQuestionPage extends QuizQuestionBase {
|
|||||||
innerName: string;
|
innerName: string;
|
||||||
text: string;
|
text: string;
|
||||||
picture: string;
|
picture: string;
|
||||||
|
originalPicture: string;
|
||||||
video: string;
|
video: string;
|
||||||
hint: QuestionHint;
|
hint: QuestionHint;
|
||||||
rule: QuestionBranchingRule;
|
rule: QuestionBranchingRule;
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
import { ImageAddIcons } from "@icons/ImageAddIcons";
|
|
||||||
import { VideofileIcon } from "@icons/questionsPage/VideofileIcon";
|
import { VideofileIcon } from "@icons/questionsPage/VideofileIcon";
|
||||||
import { Box, Typography, useMediaQuery, useTheme } from "@mui/material";
|
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 CustomTextField from "@ui_kit/CustomTextField";
|
||||||
import { useEffect, useState } from "react";
|
import { useState } from "react";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import { useDebouncedCallback } from "use-debounce";
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
import ButtonsOptions from "../ButtonsOptions";
|
import ButtonsOptions from "../ButtonsOptions";
|
||||||
@ -11,6 +10,9 @@ import { UploadImageModal } from "../UploadImage/UploadImageModal";
|
|||||||
import { UploadVideoModal } from "../UploadVideoModal";
|
import { UploadVideoModal } from "../UploadVideoModal";
|
||||||
import SwitchPageOptions from "./switchPageOptions";
|
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";
|
import type { QuizQuestionPage } from "../../../model/questionTypes/page";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
@ -39,6 +41,21 @@ export default function PageOptions({ disableInput, totalIndex }: Props) {
|
|||||||
setSwitchState(data);
|
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 (
|
return (
|
||||||
<>
|
<>
|
||||||
<Box
|
<Box
|
||||||
@ -70,7 +87,6 @@ export default function PageOptions({ disableInput, totalIndex }: Props) {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
onClick={() => setOpenImageModal(true)}
|
|
||||||
sx={{
|
sx={{
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@ -78,101 +94,22 @@ export default function PageOptions({ disableInput, totalIndex }: Props) {
|
|||||||
gap: "20px",
|
gap: "20px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{isMobile ? (
|
<AddOrEditImageButton
|
||||||
<Box
|
imageSrc={question.content.picture}
|
||||||
sx={{
|
onImageClick={() => {
|
||||||
display: "flex",
|
if (question.content.picture) {
|
||||||
alignItems: "center",
|
return openCropModal(
|
||||||
width: "120px",
|
question.content.picture,
|
||||||
position: "relative",
|
question.content.originalPicture
|
||||||
}}
|
);
|
||||||
>
|
}
|
||||||
<Box
|
|
||||||
sx={{
|
setOpenImageModal(true);
|
||||||
width: "100%",
|
}}
|
||||||
background: "#EEE4FC",
|
onPlusClick={() => {
|
||||||
height: "40px",
|
setOpenImageModal(true);
|
||||||
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>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Typography
|
<Typography
|
||||||
sx={{
|
sx={{
|
||||||
@ -189,18 +126,9 @@ export default function PageOptions({ disableInput, totalIndex }: Props) {
|
|||||||
<UploadImageModal
|
<UploadImageModal
|
||||||
open={openImageModal}
|
open={openImageModal}
|
||||||
onClose={() => setOpenImageModal(false)}
|
onClose={() => setOpenImageModal(false)}
|
||||||
imgHC={(fileList) => {
|
imgHC={handleImageUpload}
|
||||||
if (fileList?.length) {
|
|
||||||
updateQuestionsList<QuizQuestionPage>(quizId, totalIndex, {
|
|
||||||
content: {
|
|
||||||
...question.content,
|
|
||||||
picture: URL.createObjectURL(fileList[0]),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
// onClick={() => setOpenVideoModal(true)}
|
|
||||||
/>
|
/>
|
||||||
|
<CropModal onSaveImageClick={handleCropModalSaveClick} />
|
||||||
<Typography> или</Typography>
|
<Typography> или</Typography>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
|
@ -120,6 +120,21 @@ export const updateQuestionsList = <T = AnyQuizQuestion>(
|
|||||||
questionStore.setState({ listQuestions: questionListClone });
|
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 => {
|
export const removeQuestionsByQuizId = (quizId: number) => setProducedState(state => {
|
||||||
delete state.listQuestions[quizId];
|
delete state.listQuestions[quizId];
|
||||||
}, "removeQuestionsByQuizId");
|
}, "removeQuestionsByQuizId");
|
||||||
@ -172,6 +187,36 @@ export const setVariantOriginalImageUrl = (
|
|||||||
url,
|
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 = (
|
export const updateQuestionsListDragAndDrop = (
|
||||||
quizId: number,
|
quizId: number,
|
||||||
updatedQuestions: AnyQuizQuestion[]
|
updatedQuestions: AnyQuizQuestion[]
|
||||||
|
Loading…
Reference in New Issue
Block a user