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