- create MediaSelectionAndDisplay
This commit is contained in:
parent
25bdf1ba87
commit
494d750534
@ -1,18 +1,13 @@
|
|||||||
import { VideofileIcon } from "@icons/questionsPage/VideofileIcon";
|
import { Box, useMediaQuery, useTheme } from "@mui/material";
|
||||||
import { Box, Button, Typography, useMediaQuery, useTheme } from "@mui/material";
|
import { updateQuestion } from "@root/questions/actions";
|
||||||
import { updateQuestion, uploadQuestionImage } from "@root/questions/actions";
|
|
||||||
import { useCurrentQuiz } from "@root/quizes/hooks";
|
|
||||||
import AddOrEditImageButton from "@ui_kit/AddOrEditImageButton";
|
|
||||||
import CustomTextField from "@ui_kit/CustomTextField";
|
import CustomTextField from "@ui_kit/CustomTextField";
|
||||||
import { CropModal, useCropModalState } from "@ui_kit/Modal/CropModal";
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useDebouncedCallback } from "use-debounce";
|
import { useDebouncedCallback } from "use-debounce";
|
||||||
import type { QuizQuestionPage } from "../../../model/questionTypes/page";
|
import type { QuizQuestionPage } from "../../../model/questionTypes/page";
|
||||||
import ButtonsOptions from "../ButtonsOptions";
|
import ButtonsOptions from "../ButtonsOptions";
|
||||||
import { UploadImageModal } from "../UploadImage/UploadImageModal";
|
|
||||||
import { UploadVideoModal } from "../UploadVideoModal";
|
|
||||||
import SwitchPageOptions from "./switchPageOptions";
|
import SwitchPageOptions from "./switchPageOptions";
|
||||||
import { useDisclosure } from "../../../utils/useDisclosure";
|
import { MediaSelectionAndDisplay } from "@ui_kit/MediaSelectionAndDisplay";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
disableInput?: boolean;
|
disableInput?: boolean;
|
||||||
@ -20,16 +15,11 @@ type Props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export default function PageOptions({ disableInput, question }: Props) {
|
export default function PageOptions({ disableInput, question }: Props) {
|
||||||
const [openVideoModal, setOpenVideoModal] = useState<boolean>(false);
|
|
||||||
const [switchState, setSwitchState] = useState("setting");
|
const [switchState, setSwitchState] = useState("setting");
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isTablet = useMediaQuery(theme.breakpoints.down(980));
|
const isTablet = useMediaQuery(theme.breakpoints.down(980));
|
||||||
const isFigmaTablet = useMediaQuery(theme.breakpoints.down(990));
|
const isFigmaTablet = useMediaQuery(theme.breakpoints.down(990));
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down(780));
|
const isMobile = useMediaQuery(theme.breakpoints.down(780));
|
||||||
const quizQid = useCurrentQuiz()?.qid;
|
|
||||||
const { isCropModalOpen, openCropModal, closeCropModal, imageBlob, originalImageUrl, setCropModalImageBlob } =
|
|
||||||
useCropModalState();
|
|
||||||
const [isImageUploadOpen, openImageUploadModal, closeImageUploadModal] = useDisclosure();
|
|
||||||
|
|
||||||
const setText = useDebouncedCallback((value) => {
|
const setText = useDebouncedCallback((value) => {
|
||||||
updateQuestion(question.id, (question) => {
|
updateQuestion(question.id, (question) => {
|
||||||
@ -43,27 +33,6 @@ export default function PageOptions({ disableInput, question }: Props) {
|
|||||||
setSwitchState(data);
|
setSwitchState(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
async function handleImageUpload(file: File) {
|
|
||||||
const url = await uploadQuestionImage(question.id, quizQid, file, (question, url) => {
|
|
||||||
if (question.type !== "page") return;
|
|
||||||
|
|
||||||
question.content.picture = url;
|
|
||||||
question.content.originalPicture = url;
|
|
||||||
});
|
|
||||||
closeImageUploadModal();
|
|
||||||
openCropModal(file, url);
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleCropModalSaveClick(imageBlob: Blob) {
|
|
||||||
uploadQuestionImage(question.id, quizQid, imageBlob, (question, url) => {
|
|
||||||
if (question.type !== "page") return;
|
|
||||||
|
|
||||||
question.content.picture = url;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(question.content.useImage);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Box
|
<Box
|
||||||
@ -73,7 +42,6 @@ export default function PageOptions({ disableInput, question }: Props) {
|
|||||||
display: "flex",
|
display: "flex",
|
||||||
px: "20px",
|
px: "20px",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
gap: isMobile ? "25px" : "20px",
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box sx={{ display: disableInput ? "none" : "", mt: isMobile ? "15px" : "0px" }}>
|
<Box sx={{ display: disableInput ? "none" : "", mt: isMobile ? "15px" : "0px" }}>
|
||||||
@ -84,179 +52,7 @@ export default function PageOptions({ disableInput, question }: Props) {
|
|||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box
|
<MediaSelectionAndDisplay resultData={question} />
|
||||||
sx={{
|
|
||||||
mb: "20px",
|
|
||||||
ml: isTablet ? "0px" : "60px",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
gap: "28px",
|
|
||||||
justifyContent: isMobile ? "space-between" : null,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
cursor: "pointer",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
gap: "20px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<AddOrEditImageButton
|
|
||||||
imageSrc={question.content.picture}
|
|
||||||
onImageClick={() => {
|
|
||||||
if (question.content.picture) {
|
|
||||||
return openCropModal(question.content.picture, question.content.originalPicture);
|
|
||||||
}
|
|
||||||
|
|
||||||
openImageUploadModal();
|
|
||||||
}}
|
|
||||||
onPlusClick={() => {
|
|
||||||
openImageUploadModal();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Typography
|
|
||||||
sx={{
|
|
||||||
display: isMobile ? "none" : "block",
|
|
||||||
fontWeight: 400,
|
|
||||||
fontSize: "16px",
|
|
||||||
lineHeight: "18.96px",
|
|
||||||
color: question.content.useImage ? "#7E2AEA" : "#9A9AAF",
|
|
||||||
}}
|
|
||||||
onClick={() =>
|
|
||||||
updateQuestion(question.id, (question) => ((question as QuizQuestionPage).content.useImage = true))
|
|
||||||
}
|
|
||||||
>
|
|
||||||
Изображение
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
<UploadImageModal
|
|
||||||
isOpen={isImageUploadOpen}
|
|
||||||
onClose={closeImageUploadModal}
|
|
||||||
handleImageChange={handleImageUpload}
|
|
||||||
/>
|
|
||||||
<CropModal
|
|
||||||
isOpen={isCropModalOpen}
|
|
||||||
imageBlob={imageBlob}
|
|
||||||
originalImageUrl={originalImageUrl}
|
|
||||||
setCropModalImageBlob={setCropModalImageBlob}
|
|
||||||
onClose={closeCropModal}
|
|
||||||
onSaveImageClick={handleCropModalSaveClick}
|
|
||||||
/>
|
|
||||||
<Typography> или</Typography>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
cursor: "pointer",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
gap: "10px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{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",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<VideofileIcon
|
|
||||||
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",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box sx={{ display: "flex", alignItems: "center", justifyContent: "center", width: "100%" }}>
|
|
||||||
<VideofileIcon fontSize="22px" color="#7E2AEA" />
|
|
||||||
</Box>
|
|
||||||
<span
|
|
||||||
onClick={() => setOpenVideoModal(true)}
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
background: "#7E2AEA",
|
|
||||||
height: "100%",
|
|
||||||
width: "25px",
|
|
||||||
color: "white",
|
|
||||||
fontSize: "15px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
+
|
|
||||||
</span>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<Typography
|
|
||||||
sx={{
|
|
||||||
display: isMobile ? "none" : "block",
|
|
||||||
fontWeight: 400,
|
|
||||||
fontSize: "16px",
|
|
||||||
lineHeight: "18.96px",
|
|
||||||
color: question.content.useImage ? "#9A9AAF" : "#7E2AEA",
|
|
||||||
}}
|
|
||||||
onClick={() =>
|
|
||||||
updateQuestion(question.id, (question) => ((question as QuizQuestionPage).content.useImage = false))
|
|
||||||
}
|
|
||||||
>
|
|
||||||
Видео
|
|
||||||
</Typography>
|
|
||||||
</Box>
|
|
||||||
<UploadVideoModal
|
|
||||||
open={openVideoModal}
|
|
||||||
onClose={() => setOpenVideoModal(false)}
|
|
||||||
video={question.content.video}
|
|
||||||
onUpload={(url) => {
|
|
||||||
updateQuestion(question.id, (question) => {
|
|
||||||
if (question.type !== "page") return;
|
|
||||||
|
|
||||||
question.content.video = url;
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
</Box>
|
||||||
<ButtonsOptions switchState={switchState} SSHC={SSHC} question={question} />
|
<ButtonsOptions switchState={switchState} SSHC={SSHC} question={question} />
|
||||||
<SwitchPageOptions switchState={switchState} question={question} />
|
<SwitchPageOptions switchState={switchState} question={question} />
|
||||||
|
|||||||
@ -1,14 +1,8 @@
|
|||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
|
||||||
import { getQuestionByContentId, updateQuestion, uploadQuestionImage } from "@root/questions/actions"
|
import { getQuestionByContentId, updateQuestion } from "@root/questions/actions";
|
||||||
import { useCurrentQuiz } from "@root/quizes/hooks"
|
|
||||||
|
|
||||||
|
|
||||||
import CustomTextField from "@ui_kit/CustomTextField";
|
import CustomTextField from "@ui_kit/CustomTextField";
|
||||||
import { CropModal, useCropModalState } from "@ui_kit/Modal/CropModal";
|
|
||||||
import { UploadImageModal } from "../../Questions/UploadImage/UploadImageModal";
|
|
||||||
import { useDisclosure } from "../../../utils/useDisclosure";
|
|
||||||
import AddOrEditImageButton from "@ui_kit/AddOrEditImageButton";
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
@ -20,7 +14,7 @@ import {
|
|||||||
useMediaQuery,
|
useMediaQuery,
|
||||||
useTheme,
|
useTheme,
|
||||||
FormControl,
|
FormControl,
|
||||||
Popover
|
Popover,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import MiniButtonSetting from "@ui_kit/MiniButtonSetting";
|
import MiniButtonSetting from "@ui_kit/MiniButtonSetting";
|
||||||
|
|
||||||
@ -30,7 +24,7 @@ import Trash from "@icons/trash";
|
|||||||
import Info from "@icons/Info";
|
import Info from "@icons/Info";
|
||||||
import SettingIcon from "@icons/questionsPage/settingIcon";
|
import SettingIcon from "@icons/questionsPage/settingIcon";
|
||||||
import { QuizQuestionResult } from "@model/questionTypes/result";
|
import { QuizQuestionResult } from "@model/questionTypes/result";
|
||||||
import { MutableRefObject } from "react";
|
import { MediaSelectionAndDisplay } from "@ui_kit/MediaSelectionAndDisplay";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
resultContract: boolean;
|
resultContract: boolean;
|
||||||
@ -38,7 +32,7 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const checkEmptyData = ({ resultData }: { resultData: QuizQuestionResult }) => {
|
export const checkEmptyData = ({ resultData }: { resultData: QuizQuestionResult }) => {
|
||||||
let check = true
|
let check = true;
|
||||||
if (
|
if (
|
||||||
resultData.title.length > 0 ||
|
resultData.title.length > 0 ||
|
||||||
resultData.description.length > 0 ||
|
resultData.description.length > 0 ||
|
||||||
@ -47,14 +41,15 @@ export const checkEmptyData = ({ resultData }: { resultData: QuizQuestionResult
|
|||||||
resultData.content.innerName.length > 0 ||
|
resultData.content.innerName.length > 0 ||
|
||||||
resultData.content.text.length > 0 ||
|
resultData.content.text.length > 0 ||
|
||||||
resultData.content.video.length > 0 ||
|
resultData.content.video.length > 0 ||
|
||||||
resultData.content.hint.text.length > 0
|
resultData.content.hint.text.length > 0
|
||||||
) check = false
|
)
|
||||||
return check
|
check = false;
|
||||||
}
|
return check;
|
||||||
|
};
|
||||||
|
|
||||||
const InfoView = ({ resultData }: { resultData: QuizQuestionResult }) => {
|
const InfoView = ({ resultData }: { resultData: QuizQuestionResult }) => {
|
||||||
const checkEmpty = checkEmptyData({ resultData })
|
const checkEmpty = checkEmptyData({ resultData });
|
||||||
const question = getQuestionByContentId(resultData.content.rule.parentId)
|
const question = getQuestionByContentId(resultData.content.rule.parentId);
|
||||||
const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null);
|
const [anchorEl, setAnchorEl] = React.useState<HTMLButtonElement | null>(null);
|
||||||
|
|
||||||
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
||||||
@ -66,20 +61,18 @@ const InfoView = ({ resultData }: { resultData: QuizQuestionResult }) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const open = Boolean(anchorEl);
|
const open = Boolean(anchorEl);
|
||||||
const id = open ? 'simple-popover' : undefined;
|
const id = open ? "simple-popover" : undefined;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Info
|
<Info
|
||||||
sx={{
|
sx={{
|
||||||
"MuiIconButton-root": {
|
"MuiIconButton-root": {
|
||||||
|
boxShadow: "0 0 10px 10px red",
|
||||||
boxShadow: "0 0 10px 10px red"
|
},
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
className={checkEmpty ? "blink" : ""}
|
className={checkEmpty ? "blink" : ""}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
|
|
||||||
/>
|
/>
|
||||||
<Popover
|
<Popover
|
||||||
id={id}
|
id={id}
|
||||||
@ -87,85 +80,44 @@ const InfoView = ({ resultData }: { resultData: QuizQuestionResult }) => {
|
|||||||
anchorEl={anchorEl}
|
anchorEl={anchorEl}
|
||||||
onClose={handleClose}
|
onClose={handleClose}
|
||||||
anchorOrigin={{
|
anchorOrigin={{
|
||||||
vertical: 'bottom',
|
vertical: "bottom",
|
||||||
horizontal: 'left',
|
horizontal: "left",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Paper
|
<Paper
|
||||||
sx={{
|
sx={{
|
||||||
p: '20px',
|
p: "20px",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
flexDirection: "column"
|
flexDirection: "column",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography>
|
<Typography>
|
||||||
{resultData?.content.rule.parentId === "line" ? "Единый результат в конце прохождения опросника без ветвления"
|
{resultData?.content.rule.parentId === "line"
|
||||||
:
|
? "Единый результат в конце прохождения опросника без ветвления"
|
||||||
`Заголовок вопроса, после которого появится результат: "${question?.title || "нет заголовка"}"`
|
: `Заголовок вопроса, после которого появится результат: "${question?.title || "нет заголовка"}"`}
|
||||||
}
|
|
||||||
|
|
||||||
</Typography>
|
</Typography>
|
||||||
{checkEmpty &&
|
{checkEmpty && <Typography color="red">Вы не заполнили этот результат никакими данными</Typography>}
|
||||||
<Typography color="red">
|
|
||||||
Вы не заполнили этот результат никакими данными
|
|
||||||
</Typography>
|
|
||||||
}
|
|
||||||
|
|
||||||
</Paper>
|
</Paper>
|
||||||
</Popover>
|
</Popover>
|
||||||
</>
|
</>
|
||||||
)
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export const ResultCard = ({ resultContract, resultData }: Props) => {
|
export const ResultCard = ({ resultContract, resultData }: Props) => {
|
||||||
|
|
||||||
const quizQid = useCurrentQuiz()?.qid;
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down(790));
|
const isMobile = useMediaQuery(theme.breakpoints.down(790));
|
||||||
const isTablet = useMediaQuery(theme.breakpoints.down(800));
|
const isTablet = useMediaQuery(theme.breakpoints.down(800));
|
||||||
|
|
||||||
const [expand, setExpand] = React.useState(true)
|
const [expand, setExpand] = React.useState(true);
|
||||||
const [resultCardSettings, setResultCardSettings] = React.useState(false)
|
const [resultCardSettings, setResultCardSettings] = React.useState(false);
|
||||||
const [buttonPlus, setButtonPlus] = React.useState(true)
|
const [buttonPlus, setButtonPlus] = React.useState(true);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
setExpand(true)
|
setExpand(true);
|
||||||
}, [resultContract])
|
}, [resultContract]);
|
||||||
|
|
||||||
|
|
||||||
const {
|
|
||||||
isCropModalOpen,
|
|
||||||
openCropModal,
|
|
||||||
closeCropModal,
|
|
||||||
imageBlob,
|
|
||||||
originalImageUrl,
|
|
||||||
setCropModalImageBlob,
|
|
||||||
} = useCropModalState();
|
|
||||||
const [isImageUploadOpen, openImageUploadModal, closeImageUploadModal] = useDisclosure();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async function handleImageUpload(file: File) {
|
|
||||||
const url = await uploadQuestionImage(resultData.id, quizQid, file, (question, url) => {
|
|
||||||
|
|
||||||
question.content.back = url;
|
|
||||||
question.content.originalBack = url;
|
|
||||||
});
|
|
||||||
closeImageUploadModal();
|
|
||||||
openCropModal(file, url);
|
|
||||||
}
|
|
||||||
|
|
||||||
function handleCropModalSaveClick(imageBlob: Blob) {
|
|
||||||
uploadQuestionImage(resultData.id, quizQid, imageBlob, (question, url) => {
|
|
||||||
question.content.back = url;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Paper
|
<Paper
|
||||||
@ -177,7 +129,7 @@ export const ResultCard = ({ resultContract, resultData }: Props) => {
|
|||||||
backgroundColor: expand ? "white" : "#EEE4FC",
|
backgroundColor: expand ? "white" : "#EEE4FC",
|
||||||
border: expand ? "none" : "1px solid #9A9AAF",
|
border: expand ? "none" : "1px solid #9A9AAF",
|
||||||
boxShadow: "0px 10px 30px #e7e7e7",
|
boxShadow: "0px 10px 30px #e7e7e7",
|
||||||
m: "20px 0"
|
m: "20px 0",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box
|
<Box
|
||||||
@ -188,7 +140,6 @@ export const ResultCard = ({ resultContract, resultData }: Props) => {
|
|||||||
flexDirection: isMobile ? "column" : null,
|
flexDirection: isMobile ? "column" : null,
|
||||||
justifyContent: "space-between",
|
justifyContent: "space-between",
|
||||||
minHeight: "40px",
|
minHeight: "40px",
|
||||||
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<FormControl
|
<FormControl
|
||||||
@ -203,14 +154,14 @@ export const ResultCard = ({ resultContract, resultData }: Props) => {
|
|||||||
<TextField
|
<TextField
|
||||||
value={resultData.title}
|
value={resultData.title}
|
||||||
placeholder={"Заголовок результата"}
|
placeholder={"Заголовок результата"}
|
||||||
onChange={({ target }: { target: HTMLInputElement; }) => updateQuestion(resultData.id, question => question.title = target.value)}
|
onChange={({ target }: { target: HTMLInputElement }) =>
|
||||||
|
updateQuestion(resultData.id, (question) => (question.title = target.value))
|
||||||
|
}
|
||||||
sx={{
|
sx={{
|
||||||
margin: isMobile ? "10px 0" : 0,
|
margin: isMobile ? "10px 0" : 0,
|
||||||
"& .MuiInputBase-root": {
|
"& .MuiInputBase-root": {
|
||||||
color: "#000000",
|
color: "#000000",
|
||||||
backgroundColor: expand
|
backgroundColor: expand ? theme.palette.background.default : "transparent",
|
||||||
? theme.palette.background.default
|
|
||||||
: "transparent",
|
|
||||||
height: "48px",
|
height: "48px",
|
||||||
borderRadius: "10px",
|
borderRadius: "10px",
|
||||||
".MuiOutlinedInput-notchedOutline": {
|
".MuiOutlinedInput-notchedOutline": {
|
||||||
@ -291,7 +242,10 @@ export const ResultCard = ({ resultContract, resultData }: Props) => {
|
|||||||
<CustomTextField
|
<CustomTextField
|
||||||
value={resultData.title}
|
value={resultData.title}
|
||||||
placeholder={"Заголовок результата"}
|
placeholder={"Заголовок результата"}
|
||||||
onChange={({ target }: { target: HTMLInputElement; }) => updateQuestion(resultData.id, question => question.title = target.value)} />
|
onChange={({ target }: { target: HTMLInputElement }) =>
|
||||||
|
updateQuestion(resultData.id, (question) => (question.title = target.value))
|
||||||
|
}
|
||||||
|
/>
|
||||||
<IconButton
|
<IconButton
|
||||||
sx={{ padding: "0", margin: "5px" }}
|
sx={{ padding: "0", margin: "5px" }}
|
||||||
disableRipple
|
disableRipple
|
||||||
@ -301,18 +255,18 @@ export const ResultCard = ({ resultContract, resultData }: Props) => {
|
|||||||
<ExpandLessIconBG />
|
<ExpandLessIconBG />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<InfoView resultData={resultData} />
|
<InfoView resultData={resultData} />
|
||||||
|
|
||||||
|
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
margin: "20px 0"
|
margin: "20px 0",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<CustomTextField
|
<CustomTextField
|
||||||
value={resultData.description}
|
value={resultData.description}
|
||||||
onChange={({ target }: { target: HTMLInputElement; }) => updateQuestion(resultData.id, (question) => question.description = target.value)}
|
onChange={({ target }: { target: HTMLInputElement }) =>
|
||||||
|
updateQuestion(resultData.id, (question) => (question.description = target.value))
|
||||||
|
}
|
||||||
placeholder={"Заголовок пожирнее"}
|
placeholder={"Заголовок пожирнее"}
|
||||||
sx={{
|
sx={{
|
||||||
borderRadius: "8px",
|
borderRadius: "8px",
|
||||||
@ -323,9 +277,10 @@ export const ResultCard = ({ resultContract, resultData }: Props) => {
|
|||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<TextField
|
<TextField
|
||||||
|
|
||||||
value={resultData.content.text}
|
value={resultData.content.text}
|
||||||
onChange={({ target }: { target: HTMLInputElement; }) => updateQuestion(resultData.id, (question) => question.content.text = target.value)}
|
onChange={({ target }: { target: HTMLInputElement }) =>
|
||||||
|
updateQuestion(resultData.id, (question) => (question.content.text = target.value))
|
||||||
|
}
|
||||||
fullWidth
|
fullWidth
|
||||||
placeholder="Описание"
|
placeholder="Описание"
|
||||||
multiline
|
multiline
|
||||||
@ -349,198 +304,77 @@ export const ResultCard = ({ resultContract, resultData }: Props) => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<MediaSelectionAndDisplay resultData={resultData} />
|
||||||
|
|
||||||
|
{buttonPlus ? (
|
||||||
<Box
|
<Button
|
||||||
sx={{
|
onClick={() => {
|
||||||
mt: "20px",
|
setButtonPlus(false);
|
||||||
display: "flex",
|
}}
|
||||||
gap: "10px",
|
|
||||||
flexDirection: "column"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box
|
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "inline flex",
|
||||||
|
height: "48px",
|
||||||
|
padding: "10px 20px",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: "8px",
|
||||||
|
flexShrink: 0,
|
||||||
|
borderRadius: "8px",
|
||||||
|
border: "1px solid #9A9AAF",
|
||||||
|
background: " #F2F3F7",
|
||||||
|
color: "#9A9AAF",
|
||||||
|
mb: "30px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Button
|
Кнопка +
|
||||||
sx={{
|
</Button>
|
||||||
color: resultData.content.useImage ? "#7E2AEA" : "#9A9AAF",
|
) : (
|
||||||
fontSize: "16px",
|
|
||||||
"&:hover": {
|
|
||||||
background: "none",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
variant="text"
|
|
||||||
onClick={() => updateQuestion(resultData.id, (question) => question.content.useImage = true)}
|
|
||||||
>
|
|
||||||
Изображение
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
sx={{
|
|
||||||
color: resultData.content.useImage ? "#9A9AAF" : "#7E2AEA",
|
|
||||||
fontSize: "16px",
|
|
||||||
"&:hover": {
|
|
||||||
background: "none",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
variant="text"
|
|
||||||
onClick={() => updateQuestion(resultData.id, (question) => question.content.useImage = false)}
|
|
||||||
>
|
|
||||||
Видео
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
mb: "30px",
|
||||||
flexDirection: "column",
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<UploadImageModal
|
<Box>
|
||||||
isOpen={isImageUploadOpen}
|
<Typography component={"span"} sx={{ weight: "500", fontSize: "18px", mb: "10px" }}>
|
||||||
onClose={closeImageUploadModal}
|
Призыв к действию
|
||||||
handleImageChange={handleImageUpload}
|
</Typography>
|
||||||
/>
|
<IconButton
|
||||||
<CropModal
|
onClick={() => {
|
||||||
isOpen={isCropModalOpen}
|
setButtonPlus(true);
|
||||||
imageBlob={imageBlob}
|
updateQuestion(resultData.id, (q) => (q.content.hint.text = ""));
|
||||||
originalImageUrl={originalImageUrl}
|
}}
|
||||||
setCropModalImageBlob={setCropModalImageBlob}
|
>
|
||||||
onClose={closeCropModal}
|
<Trash />
|
||||||
onSaveImageClick={handleCropModalSaveClick}
|
</IconButton>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<TextField
|
||||||
|
value={resultData.content.hint.text}
|
||||||
|
onChange={({ target }: { target: HTMLInputElement }) =>
|
||||||
|
updateQuestion(resultData.id, (question) => (question.content.hint.text = target.value))
|
||||||
|
}
|
||||||
|
fullWidth
|
||||||
|
placeholder="Например: узнать подробнее"
|
||||||
|
sx={{
|
||||||
|
"& .MuiInputBase-root": {
|
||||||
|
backgroundColor: "#F2F3F7",
|
||||||
|
width: "409px",
|
||||||
|
height: "48px",
|
||||||
|
borderRadius: "8px",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
inputProps={{
|
||||||
|
sx: {
|
||||||
|
height: "85px",
|
||||||
|
borderRadius: "10px",
|
||||||
|
fontSize: "18px",
|
||||||
|
lineHeight: "21px",
|
||||||
|
py: 0,
|
||||||
|
},
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
)}
|
||||||
{
|
|
||||||
resultData.content.useImage &&
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
cursor: "pointer",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
gap: "20px",
|
|
||||||
mb: "30px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<AddOrEditImageButton
|
|
||||||
imageSrc={resultData.content.back}
|
|
||||||
onImageClick={() => {
|
|
||||||
if (resultData.content.back) {
|
|
||||||
return openCropModal(
|
|
||||||
resultData.content.back,
|
|
||||||
resultData.content.originalBack
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
openImageUploadModal();
|
|
||||||
}}
|
|
||||||
onPlusClick={() => {
|
|
||||||
openImageUploadModal();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
}
|
|
||||||
{
|
|
||||||
!resultData.content.useImage &&
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
cursor: "pointer",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
gap: "20px",
|
|
||||||
mb: "30px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<CustomTextField
|
|
||||||
placeholder="URL видео"
|
|
||||||
text={resultData.content.video ?? ""}
|
|
||||||
onChange={e => updateQuestion(resultData.id, q => {
|
|
||||||
q.content.video = e.target.value;
|
|
||||||
})}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
}
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
{
|
|
||||||
buttonPlus ?
|
|
||||||
<Button
|
|
||||||
onClick={() => {
|
|
||||||
setButtonPlus(false)
|
|
||||||
}}
|
|
||||||
sx={{
|
|
||||||
display: "inline flex",
|
|
||||||
height: "48px",
|
|
||||||
padding: "10px 20px",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
gap: "8px",
|
|
||||||
flexShrink: 0,
|
|
||||||
borderRadius: "8px",
|
|
||||||
border: "1px solid #9A9AAF",
|
|
||||||
background: " #F2F3F7",
|
|
||||||
color: "#9A9AAF",
|
|
||||||
mb: "30px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Кнопка +
|
|
||||||
</Button>
|
|
||||||
:
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
mb: "30px"
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box>
|
|
||||||
<Typography component={"span"} sx={{ weight: "500", fontSize: "18px", mb: "10px" }}>
|
|
||||||
Призыв к действию
|
|
||||||
</Typography>
|
|
||||||
<IconButton
|
|
||||||
onClick={() => {
|
|
||||||
setButtonPlus(true)
|
|
||||||
updateQuestion(resultData.id, (q) => q.content.hint.text = "")
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Trash />
|
|
||||||
</IconButton>
|
|
||||||
</Box>
|
|
||||||
|
|
||||||
<TextField
|
|
||||||
value={resultData.content.hint.text}
|
|
||||||
onChange={({ target }: { target: HTMLInputElement; }) => updateQuestion(resultData.id, (question) => question.content.hint.text = target.value)}
|
|
||||||
fullWidth
|
|
||||||
placeholder="Например: узнать подробнее"
|
|
||||||
sx={{
|
|
||||||
"& .MuiInputBase-root": {
|
|
||||||
backgroundColor: "#F2F3F7",
|
|
||||||
width: "409px",
|
|
||||||
height: "48px",
|
|
||||||
borderRadius: "8px",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
inputProps={{
|
|
||||||
sx: {
|
|
||||||
height: "85px",
|
|
||||||
borderRadius: "10px",
|
|
||||||
fontSize: "18px",
|
|
||||||
lineHeight: "21px",
|
|
||||||
py: 0,
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</Box>
|
</Box>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
@ -560,50 +394,42 @@ export const ResultCard = ({ resultContract, resultData }: Props) => {
|
|||||||
>
|
>
|
||||||
<MiniButtonSetting
|
<MiniButtonSetting
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setResultCardSettings(!resultCardSettings)
|
setResultCardSettings(!resultCardSettings);
|
||||||
}}
|
}}
|
||||||
sx={{
|
sx={{
|
||||||
backgroundColor:
|
backgroundColor: resultCardSettings ? theme.palette.brightPurple.main : "transparent",
|
||||||
resultCardSettings
|
color: resultCardSettings ? "#ffffff" : theme.palette.grey3.main,
|
||||||
? theme.palette.brightPurple.main
|
|
||||||
: "transparent",
|
|
||||||
color:
|
|
||||||
resultCardSettings ? "#ffffff" : theme.palette.grey3.main,
|
|
||||||
"&:hover": {
|
"&:hover": {
|
||||||
backgroundColor: resultCardSettings ? "#581CA7" : "#7E2AEA",
|
backgroundColor: resultCardSettings ? "#581CA7" : "#7E2AEA",
|
||||||
color: "white"
|
color: "white",
|
||||||
}
|
},
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<SettingIcon
|
<SettingIcon color={resultCardSettings ? "#ffffff" : theme.palette.grey3.main} />
|
||||||
color={
|
|
||||||
resultCardSettings ? "#ffffff" : theme.palette.grey3.main
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
{!isTablet && "Настройки"}
|
{!isTablet && "Настройки"}
|
||||||
</MiniButtonSetting>
|
</MiniButtonSetting>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
{
|
{resultCardSettings && (
|
||||||
resultCardSettings &&
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
backgroundColor: "white",
|
backgroundColor: "white",
|
||||||
p: "20px",
|
p: "20px",
|
||||||
borderRadius: "0 0 12px 12px"
|
borderRadius: "0 0 12px 12px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<CustomTextField
|
<CustomTextField
|
||||||
placeholder={"Внутреннее описание вопроса"}
|
placeholder={"Внутреннее описание вопроса"}
|
||||||
value={resultData.innerName}
|
value={resultData.innerName}
|
||||||
onChange={({ target }: { target: HTMLInputElement; }) => updateQuestion(resultData.id, (question) => question.content.innerName = target.value)}
|
onChange={({ target }: { target: HTMLInputElement }) =>
|
||||||
|
updateQuestion(resultData.id, (question) => (question.content.innerName = target.value))
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
}
|
)}
|
||||||
</>
|
</>
|
||||||
)
|
)}
|
||||||
}
|
</Paper>
|
||||||
</Paper >
|
);
|
||||||
)
|
};
|
||||||
}
|
|
||||||
|
|||||||
149
src/ui_kit/MediaSelectionAndDisplay.tsx
Normal file
149
src/ui_kit/MediaSelectionAndDisplay.tsx
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
import { FC } from "react";
|
||||||
|
import { Box, Button } from "@mui/material";
|
||||||
|
import CustomTextField from "./CustomTextField";
|
||||||
|
import { updateQuestion, uploadQuestionImage } from "@root/questions/actions";
|
||||||
|
import { CropModal, useCropModalState } from "@ui_kit/Modal/CropModal";
|
||||||
|
|
||||||
|
import AddOrEditImageButton from "@ui_kit/AddOrEditImageButton";
|
||||||
|
import { UploadImageModal } from "../pages/Questions/UploadImage/UploadImageModal";
|
||||||
|
import { useDisclosure } from "../utils/useDisclosure";
|
||||||
|
import { useCurrentQuiz } from "../stores/quizes/hooks";
|
||||||
|
import { AnyTypedQuizQuestion } from "@model/questionTypes/shared";
|
||||||
|
|
||||||
|
interface Iprops {
|
||||||
|
resultData: AnyTypedQuizQuestion;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const MediaSelectionAndDisplay: FC<Iprops> = ({ resultData }) => {
|
||||||
|
const quizQid = useCurrentQuiz()?.qid;
|
||||||
|
const { isCropModalOpen, openCropModal, closeCropModal, imageBlob, originalImageUrl, setCropModalImageBlob } =
|
||||||
|
useCropModalState();
|
||||||
|
const [isImageUploadOpen, openImageUploadModal, closeImageUploadModal] = useDisclosure();
|
||||||
|
|
||||||
|
async function handleImageUpload(file: File) {
|
||||||
|
const url = await uploadQuestionImage(resultData.id, quizQid, file, (question, url) => {
|
||||||
|
question.content.back = url;
|
||||||
|
question.content.originalBack = url;
|
||||||
|
});
|
||||||
|
closeImageUploadModal();
|
||||||
|
openCropModal(file, url);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleCropModalSaveClick(imageBlob: Blob) {
|
||||||
|
uploadQuestionImage(resultData.id, quizQid, imageBlob, (question, url) => {
|
||||||
|
question.content.back = url;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
mt: "20px",
|
||||||
|
display: "flex",
|
||||||
|
gap: "10px",
|
||||||
|
flexDirection: "column",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
sx={{
|
||||||
|
color: resultData.content.useImage ? "#7E2AEA" : "#9A9AAF",
|
||||||
|
fontSize: "16px",
|
||||||
|
"&:hover": {
|
||||||
|
background: "none",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
variant="text"
|
||||||
|
onClick={() => updateQuestion(resultData.id, (question) => (question.content.useImage = true))}
|
||||||
|
>
|
||||||
|
Изображение
|
||||||
|
</Button>
|
||||||
|
<Button
|
||||||
|
sx={{
|
||||||
|
color: resultData.content.useImage ? "#9A9AAF" : "#7E2AEA",
|
||||||
|
fontSize: "16px",
|
||||||
|
"&:hover": {
|
||||||
|
background: "none",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
variant="text"
|
||||||
|
onClick={() => updateQuestion(resultData.id, (question) => (question.content.useImage = false))}
|
||||||
|
>
|
||||||
|
Видео
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<UploadImageModal
|
||||||
|
isOpen={isImageUploadOpen}
|
||||||
|
onClose={closeImageUploadModal}
|
||||||
|
handleImageChange={handleImageUpload}
|
||||||
|
/>
|
||||||
|
<CropModal
|
||||||
|
isOpen={isCropModalOpen}
|
||||||
|
imageBlob={imageBlob}
|
||||||
|
originalImageUrl={originalImageUrl}
|
||||||
|
setCropModalImageBlob={setCropModalImageBlob}
|
||||||
|
onClose={closeCropModal}
|
||||||
|
onSaveImageClick={handleCropModalSaveClick}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{resultData.content.useImage && (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
cursor: "pointer",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: "20px",
|
||||||
|
mb: "30px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<AddOrEditImageButton
|
||||||
|
imageSrc={resultData.content.back}
|
||||||
|
onImageClick={() => {
|
||||||
|
if (resultData.content.back) {
|
||||||
|
return openCropModal(resultData.content.back, resultData.content.originalBack);
|
||||||
|
}
|
||||||
|
|
||||||
|
openImageUploadModal();
|
||||||
|
}}
|
||||||
|
onPlusClick={() => {
|
||||||
|
openImageUploadModal();
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
{!resultData.content.useImage && (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
cursor: "pointer",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: "20px",
|
||||||
|
mb: "30px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CustomTextField
|
||||||
|
placeholder="URL видео"
|
||||||
|
text={resultData.content.video ?? ""}
|
||||||
|
onChange={(e) =>
|
||||||
|
updateQuestion(resultData.id, (q) => {
|
||||||
|
q.content.video = e.target.value;
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue
Block a user