commit
6cf187703e
@ -3,7 +3,7 @@ import type { QuizQuestionInitial } from "../model/questionTypes/shared";
|
|||||||
export const QUIZ_QUESTION_BASE: Omit<QuizQuestionInitial, "id"> = {
|
export const QUIZ_QUESTION_BASE: Omit<QuizQuestionInitial, "id"> = {
|
||||||
title: "",
|
title: "",
|
||||||
type: "nonselected",
|
type: "nonselected",
|
||||||
expanded: false,
|
expanded: true,
|
||||||
required: false,
|
required: false,
|
||||||
deleted: false,
|
deleted: false,
|
||||||
deleteTimeoutId: 0,
|
deleteTimeoutId: 0,
|
||||||
|
|||||||
@ -15,7 +15,6 @@ export const QUIZ_QUESTION_EMOJI: Omit<QuizQuestionEmoji, "id"> = {
|
|||||||
variants: [
|
variants: [
|
||||||
{
|
{
|
||||||
answer: "",
|
answer: "",
|
||||||
hints: "",
|
|
||||||
extendedText: "",
|
extendedText: "",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@ -18,7 +18,6 @@ export const QUIZ_QUESTION_IMAGES: Omit<QuizQuestionImages, "id"> = {
|
|||||||
variants: [
|
variants: [
|
||||||
{
|
{
|
||||||
answer: "",
|
answer: "",
|
||||||
hints: "",
|
|
||||||
extendedText: "",
|
extendedText: "",
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
@ -12,6 +12,6 @@ export const QUIZ_QUESTION_SELECT: Omit<QuizQuestionSelect, "id"> = {
|
|||||||
innerNameCheck: false,
|
innerNameCheck: false,
|
||||||
innerName: "",
|
innerName: "",
|
||||||
default: "",
|
default: "",
|
||||||
variants: [{ answer: "", hints: "", extendedText: "" }],
|
variants: [{ answer: "", extendedText: "" }],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -13,6 +13,6 @@ export const QUIZ_QUESTION_VARIANT: Omit<QuizQuestionVariant, "id"> = {
|
|||||||
innerNameCheck: false,
|
innerNameCheck: false,
|
||||||
required: false,
|
required: false,
|
||||||
innerName: "",
|
innerName: "",
|
||||||
variants: [{ answer: "", hints: "", extendedText: "" }],
|
variants: [{ answer: "", extendedText: "" }],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -11,7 +11,7 @@ export const QUIZ_QUESTION_VARIMG: Omit<QuizQuestionVarImg, "id"> = {
|
|||||||
innerNameCheck: false,
|
innerNameCheck: false,
|
||||||
innerName: "",
|
innerName: "",
|
||||||
required: false,
|
required: false,
|
||||||
variants: [{ answer: "", hints: "", extendedText: "" }],
|
variants: [{ answer: "", extendedText: "" }],
|
||||||
largeCheck: false,
|
largeCheck: false,
|
||||||
replText: "",
|
replText: "",
|
||||||
},
|
},
|
||||||
|
|||||||
@ -32,8 +32,6 @@ export interface QuestionHint {
|
|||||||
export type QuestionVariant = {
|
export type QuestionVariant = {
|
||||||
/** Текст */
|
/** Текст */
|
||||||
answer: string;
|
answer: string;
|
||||||
/** Текст подсказки */
|
|
||||||
hints: string;
|
|
||||||
/** Дополнительное поле для текста, emoji, ссылки на картинку */
|
/** Дополнительное поле для текста, emoji, ссылки на картинку */
|
||||||
extendedText: string;
|
extendedText: string;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import {
|
|||||||
FormControl,
|
FormControl,
|
||||||
InputAdornment,
|
InputAdornment,
|
||||||
IconButton,
|
IconButton,
|
||||||
Popover,
|
|
||||||
useTheme,
|
useTheme,
|
||||||
useMediaQuery,
|
useMediaQuery,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
@ -17,10 +16,9 @@ import { questionStore, updateQuestionsList } from "@root/questions";
|
|||||||
|
|
||||||
import { PointsIcon } from "@icons/questionsPage/PointsIcon";
|
import { PointsIcon } from "@icons/questionsPage/PointsIcon";
|
||||||
import { DeleteIcon } from "@icons/questionsPage/deleteIcon";
|
import { DeleteIcon } from "@icons/questionsPage/deleteIcon";
|
||||||
import { MessageIcon } from "@icons/messagIcon";
|
|
||||||
import TextareaAutosize from "@mui/base/TextareaAutosize";
|
|
||||||
|
|
||||||
import type { ChangeEvent, KeyboardEvent, ReactNode } from "react";
|
import type { KeyboardEvent, ReactNode } from "react";
|
||||||
|
import type { DroppableProvided } from "react-beautiful-dnd";
|
||||||
import type { QuizQuestionVariant } from "../../../model/questionTypes/variant";
|
import type { QuizQuestionVariant } from "../../../model/questionTypes/variant";
|
||||||
import type { QuestionVariant } from "../../../model/questionTypes/shared";
|
import type { QuestionVariant } from "../../../model/questionTypes/shared";
|
||||||
|
|
||||||
@ -29,9 +27,9 @@ type AnswerItemProps = {
|
|||||||
totalIndex: number;
|
totalIndex: number;
|
||||||
variants: QuestionVariant[];
|
variants: QuestionVariant[];
|
||||||
variant: QuestionVariant;
|
variant: QuestionVariant;
|
||||||
|
provided: DroppableProvided;
|
||||||
additionalContent?: ReactNode;
|
additionalContent?: ReactNode;
|
||||||
additionalMobile?: ReactNode;
|
additionalMobile?: ReactNode;
|
||||||
icon?: ReactNode;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const AnswerItem = ({
|
export const AnswerItem = ({
|
||||||
@ -39,6 +37,7 @@ export const AnswerItem = ({
|
|||||||
totalIndex,
|
totalIndex,
|
||||||
variants,
|
variants,
|
||||||
variant,
|
variant,
|
||||||
|
provided,
|
||||||
additionalContent,
|
additionalContent,
|
||||||
additionalMobile,
|
additionalMobile,
|
||||||
}: AnswerItemProps) => {
|
}: AnswerItemProps) => {
|
||||||
@ -59,21 +58,9 @@ export const AnswerItem = ({
|
|||||||
});
|
});
|
||||||
}, 1000);
|
}, 1000);
|
||||||
|
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
|
||||||
const [anchorEl, setAnchorEl] = useState<HTMLButtonElement | null>(null);
|
|
||||||
|
|
||||||
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
|
|
||||||
setAnchorEl(event.currentTarget);
|
|
||||||
setIsOpen(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleClose = () => {
|
|
||||||
setIsOpen(false);
|
|
||||||
};
|
|
||||||
|
|
||||||
const addNewAnswer = () => {
|
const addNewAnswer = () => {
|
||||||
const answerNew = variants.slice();
|
const answerNew = variants.slice();
|
||||||
answerNew.push({ answer: "", hints: "", extendedText: "" });
|
answerNew.push({ answer: "", extendedText: "" });
|
||||||
|
|
||||||
updateQuestionsList<QuizQuestionVariant>(quizId, totalIndex, {
|
updateQuestionsList<QuizQuestionVariant>(quizId, totalIndex, {
|
||||||
content: { ...question.content, variants: answerNew },
|
content: { ...question.content, variants: answerNew },
|
||||||
@ -89,123 +76,79 @@ export const AnswerItem = ({
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const changeAnswerHint = (event: ChangeEvent<HTMLTextAreaElement>) => {
|
|
||||||
const answerNew = variants.slice();
|
|
||||||
answerNew[index].hints = event.target.value;
|
|
||||||
|
|
||||||
updateQuestionsList<QuizQuestionVariant>(quizId, totalIndex, {
|
|
||||||
content: { ...question.content, variants: answerNew },
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Draggable draggableId={String(index)} index={index}>
|
<Box>
|
||||||
{(provided) => (
|
<FormControl
|
||||||
<Box ref={provided.innerRef} {...provided.draggableProps}>
|
key={index}
|
||||||
<FormControl
|
fullWidth
|
||||||
key={index}
|
variant="standard"
|
||||||
fullWidth
|
sx={{
|
||||||
variant="standard"
|
margin: isTablet ? " 15px 0 20px 0" : "0 0 20px 0",
|
||||||
sx={{
|
borderRadius: "10px",
|
||||||
margin: isTablet ? " 15px 0 20px 0" : "0 0 20px 0",
|
border: "1px solid rgba(0, 0, 0, 0.23)",
|
||||||
|
background: "white",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<TextField
|
||||||
|
defaultValue={variant.answer}
|
||||||
|
fullWidth
|
||||||
|
focused={false}
|
||||||
|
placeholder={"Добавьте ответ"}
|
||||||
|
multiline={question.content.largeCheck}
|
||||||
|
onChange={({ target }) => debounced(target.value)}
|
||||||
|
onKeyDown={(event: KeyboardEvent<HTMLInputElement>) => {
|
||||||
|
if (event.code === "Enter" && !question.content.largeCheck) {
|
||||||
|
addNewAnswer();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
InputProps={{
|
||||||
|
startAdornment: (
|
||||||
|
<>
|
||||||
|
<InputAdornment {...provided.droppableProps} position="start">
|
||||||
|
<PointsIcon style={{ color: "#9A9AAF", fontSize: "30px" }} />
|
||||||
|
</InputAdornment>
|
||||||
|
{additionalContent}
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
endAdornment: (
|
||||||
|
<InputAdornment position="end">
|
||||||
|
<IconButton sx={{ padding: "0" }} onClick={deleteAnswer}>
|
||||||
|
<DeleteIcon
|
||||||
|
style={{
|
||||||
|
color: theme.palette.grey2.main,
|
||||||
|
marginRight: "-1px",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</IconButton>
|
||||||
|
</InputAdornment>
|
||||||
|
),
|
||||||
|
}}
|
||||||
|
sx={{
|
||||||
|
"& .MuiInputBase-root": {
|
||||||
|
padding: additionalContent
|
||||||
|
? isTablet
|
||||||
|
? "13px"
|
||||||
|
: "5px 13px"
|
||||||
|
: "13px",
|
||||||
borderRadius: "10px",
|
borderRadius: "10px",
|
||||||
border: "1px solid rgba(0, 0, 0, 0.23)",
|
background: "#ffffff",
|
||||||
background: "white",
|
"& input.MuiInputBase-input": {
|
||||||
}}
|
height: "22px",
|
||||||
>
|
},
|
||||||
<TextField
|
"& textarea.MuiInputBase-input": {
|
||||||
defaultValue={variant.answer}
|
marginTop: "1px",
|
||||||
fullWidth
|
},
|
||||||
focused={false}
|
"& .MuiOutlinedInput-notchedOutline": {
|
||||||
placeholder={"Добавьте ответ"}
|
border: "none",
|
||||||
multiline={question.content.largeCheck}
|
},
|
||||||
onChange={({ target }) => debounced(target.value)}
|
},
|
||||||
onKeyDown={(event: KeyboardEvent<HTMLInputElement>) => {
|
}}
|
||||||
if (event.code === "Enter" && !question.content.largeCheck) {
|
inputProps={{
|
||||||
addNewAnswer();
|
sx: { fontSize: "18px", lineHeight: "21px", py: 0, ml: "13px" },
|
||||||
}
|
}}
|
||||||
}}
|
/>
|
||||||
InputProps={{
|
{additionalMobile}
|
||||||
startAdornment: (
|
</FormControl>
|
||||||
<>
|
</Box>
|
||||||
<InputAdornment
|
|
||||||
{...provided.dragHandleProps}
|
|
||||||
position="start"
|
|
||||||
>
|
|
||||||
<PointsIcon
|
|
||||||
style={{ color: "#9A9AAF", fontSize: "30px" }}
|
|
||||||
/>
|
|
||||||
</InputAdornment>
|
|
||||||
{additionalContent}
|
|
||||||
</>
|
|
||||||
),
|
|
||||||
endAdornment: (
|
|
||||||
<InputAdornment position="end">
|
|
||||||
<IconButton
|
|
||||||
sx={{ padding: "0" }}
|
|
||||||
aria-describedby="my-popover-id"
|
|
||||||
onClick={handleClick}
|
|
||||||
>
|
|
||||||
<MessageIcon
|
|
||||||
style={{
|
|
||||||
color: "#9A9AAF",
|
|
||||||
fontSize: "30px",
|
|
||||||
marginRight: "6.5px",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</IconButton>
|
|
||||||
<Popover
|
|
||||||
id="my-popover-id"
|
|
||||||
open={isOpen}
|
|
||||||
anchorEl={anchorEl}
|
|
||||||
onClose={handleClose}
|
|
||||||
anchorOrigin={{ vertical: "bottom", horizontal: "left" }}
|
|
||||||
>
|
|
||||||
<TextareaAutosize
|
|
||||||
style={{ margin: "10px" }}
|
|
||||||
placeholder="Подсказка для этого ответа"
|
|
||||||
value={variant.hints}
|
|
||||||
onChange={changeAnswerHint}
|
|
||||||
onKeyDown={(
|
|
||||||
event: KeyboardEvent<HTMLTextAreaElement>
|
|
||||||
) => event.stopPropagation()}
|
|
||||||
/>
|
|
||||||
</Popover>
|
|
||||||
<IconButton sx={{ padding: "0" }} onClick={deleteAnswer}>
|
|
||||||
<DeleteIcon
|
|
||||||
style={{
|
|
||||||
color: theme.palette.grey2.main,
|
|
||||||
marginRight: "-1px",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</IconButton>
|
|
||||||
</InputAdornment>
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
sx={{
|
|
||||||
"& .MuiInputBase-root": {
|
|
||||||
padding: additionalContent ? "5px 13px" : "13px",
|
|
||||||
borderRadius: "10px",
|
|
||||||
background: "#ffffff",
|
|
||||||
"& input.MuiInputBase-input": {
|
|
||||||
height: "22px",
|
|
||||||
},
|
|
||||||
"& textarea.MuiInputBase-input": {
|
|
||||||
marginTop: "1px",
|
|
||||||
},
|
|
||||||
"& .MuiOutlinedInput-notchedOutline": {
|
|
||||||
border: "none",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
inputProps={{
|
|
||||||
sx: { fontSize: "18px", lineHeight: "21px", py: 0, ml: "13px" },
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{additionalMobile}
|
|
||||||
</FormControl>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
</Draggable>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -47,6 +47,7 @@ export const AnswerDraggableList = ({
|
|||||||
totalIndex={totalIndex}
|
totalIndex={totalIndex}
|
||||||
variants={variants}
|
variants={variants}
|
||||||
variant={variant}
|
variant={variant}
|
||||||
|
provided={provided}
|
||||||
additionalContent={additionalContent?.(variant, index)}
|
additionalContent={additionalContent?.(variant, index)}
|
||||||
additionalMobile={additionalMobile?.(variant, index)}
|
additionalMobile={additionalMobile?.(variant, index)}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -225,7 +225,7 @@ export default function QuestionsPageCard({
|
|||||||
sx={{
|
sx={{
|
||||||
margin: isMobile ? "10px 0" : 0,
|
margin: isMobile ? "10px 0" : 0,
|
||||||
"& .MuiInputBase-root": {
|
"& .MuiInputBase-root": {
|
||||||
color: question.expanded ? "#9A9AAF" : "#4D4D4D",
|
color: question.expanded ? "#000000" : "#4D4D4D",
|
||||||
backgroundColor: question.expanded
|
backgroundColor: question.expanded
|
||||||
? theme.palette.background.default
|
? theme.palette.background.default
|
||||||
: "transparent",
|
: "transparent",
|
||||||
|
|||||||
@ -29,7 +29,7 @@ export default function DropDown({ totalIndex }: Props) {
|
|||||||
|
|
||||||
const addNewAnswer = () => {
|
const addNewAnswer = () => {
|
||||||
const answerNew = question.content.variants.slice();
|
const answerNew = question.content.variants.slice();
|
||||||
answerNew.push({ answer: "", hints: "", extendedText: "" });
|
answerNew.push({ answer: "", extendedText: "" });
|
||||||
|
|
||||||
updateQuestionsList<QuizQuestionSelect>(quizId, totalIndex, {
|
updateQuestionsList<QuizQuestionSelect>(quizId, totalIndex, {
|
||||||
content: { ...question.content, variants: answerNew },
|
content: { ...question.content, variants: answerNew },
|
||||||
@ -94,12 +94,22 @@ export default function DropDown({ totalIndex }: Props) {
|
|||||||
>
|
>
|
||||||
или нажмите Enter
|
или нажмите Enter
|
||||||
</Typography>
|
</Typography>
|
||||||
<EnterIcon style={{ color: "#7E2AEA", fontSize: "24px", marginLeft: "6px" }} />
|
<EnterIcon
|
||||||
|
style={{
|
||||||
|
color: "#7E2AEA",
|
||||||
|
fontSize: "24px",
|
||||||
|
marginLeft: "6px",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
<ButtonsOptions switchState={switchState} SSHC={SSHC} totalIndex={totalIndex} />
|
<ButtonsOptions
|
||||||
|
switchState={switchState}
|
||||||
|
SSHC={SSHC}
|
||||||
|
totalIndex={totalIndex}
|
||||||
|
/>
|
||||||
<SwitchDropDown switchState={switchState} totalIndex={totalIndex} />
|
<SwitchDropDown switchState={switchState} totalIndex={totalIndex} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -28,7 +28,9 @@ interface Props {
|
|||||||
export default function Emoji({ totalIndex }: Props) {
|
export default function Emoji({ totalIndex }: Props) {
|
||||||
const [switchState, setSwitchState] = useState<string>("setting");
|
const [switchState, setSwitchState] = useState<string>("setting");
|
||||||
const [open, setOpen] = useState<boolean>(false);
|
const [open, setOpen] = useState<boolean>(false);
|
||||||
const [anchorElement, setAnchorElement] = useState<HTMLDivElement | null>(null);
|
const [anchorElement, setAnchorElement] = useState<HTMLDivElement | null>(
|
||||||
|
null
|
||||||
|
);
|
||||||
const [currentIndex, setCurrentIndex] = useState<number>(0);
|
const [currentIndex, setCurrentIndex] = useState<number>(0);
|
||||||
const { listQuestions } = questionStore();
|
const { listQuestions } = questionStore();
|
||||||
const quizId = Number(useParams().quizId);
|
const quizId = Number(useParams().quizId);
|
||||||
@ -37,7 +39,6 @@ export default function Emoji({ totalIndex }: Props) {
|
|||||||
const isMobile = useMediaQuery(theme.breakpoints.down(790));
|
const isMobile = useMediaQuery(theme.breakpoints.down(790));
|
||||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||||
|
|
||||||
|
|
||||||
const SSHC = (data: string) => {
|
const SSHC = (data: string) => {
|
||||||
setSwitchState(data);
|
setSwitchState(data);
|
||||||
};
|
};
|
||||||
@ -198,14 +199,21 @@ export default function Emoji({ totalIndex }: Props) {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Popover>
|
</Popover>
|
||||||
<Box sx={{ display: "flex", alignItems: "center", gap: "10px", marginBottom: isMobile ? "17px" : "20px" }}>
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
gap: "10px",
|
||||||
|
marginBottom: isMobile ? "17px" : "20px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
<Link
|
<Link
|
||||||
component="button"
|
component="button"
|
||||||
variant="body2"
|
variant="body2"
|
||||||
sx={{ color: theme.palette.brightPurple.main }}
|
sx={{ color: theme.palette.brightPurple.main }}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const answerNew = question.content.variants.slice();
|
const answerNew = question.content.variants.slice();
|
||||||
answerNew.push({ answer: "", hints: "", extendedText: "" });
|
answerNew.push({ answer: "", extendedText: "" });
|
||||||
|
|
||||||
updateQuestionsList<QuizQuestionEmoji>(quizId, totalIndex, {
|
updateQuestionsList<QuizQuestionEmoji>(quizId, totalIndex, {
|
||||||
content: { ...question.content, variants: answerNew },
|
content: { ...question.content, variants: answerNew },
|
||||||
@ -237,7 +245,11 @@ export default function Emoji({ totalIndex }: Props) {
|
|||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
<ButtonsOptions switchState={switchState} SSHC={SSHC} totalIndex={totalIndex} />
|
<ButtonsOptions
|
||||||
|
switchState={switchState}
|
||||||
|
SSHC={SSHC}
|
||||||
|
totalIndex={totalIndex}
|
||||||
|
/>
|
||||||
<SwitchEmoji switchState={switchState} totalIndex={totalIndex} />
|
<SwitchEmoji switchState={switchState} totalIndex={totalIndex} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -27,7 +27,7 @@ export default memo(
|
|||||||
{(provided) => (
|
{(provided) => (
|
||||||
<ListItem
|
<ListItem
|
||||||
ref={provided.innerRef}
|
ref={provided.innerRef}
|
||||||
{...provided.draggableProps}
|
{...(index !== 0 ? provided.draggableProps : {})}
|
||||||
sx={{ userSelect: "none", padding: 0 }}
|
sx={{ userSelect: "none", padding: 0 }}
|
||||||
>
|
>
|
||||||
{questionData.deleted ? (
|
{questionData.deleted ? (
|
||||||
|
|||||||
@ -147,11 +147,13 @@ export default function QuestionsPageCard({
|
|||||||
),
|
),
|
||||||
endAdornment: (
|
endAdornment: (
|
||||||
<>
|
<>
|
||||||
<InputAdornment {...draggableProps} position="start">
|
{totalIndex !== 0 && (
|
||||||
<PointsIcon
|
<InputAdornment {...draggableProps} position="start">
|
||||||
style={{ color: "#9A9AAF", fontSize: "30px" }}
|
<PointsIcon
|
||||||
/>
|
style={{ color: "#9A9AAF", fontSize: "30px" }}
|
||||||
</InputAdornment>
|
/>
|
||||||
|
</InputAdornment>
|
||||||
|
)}
|
||||||
</>
|
</>
|
||||||
),
|
),
|
||||||
}}
|
}}
|
||||||
|
|||||||
@ -15,6 +15,10 @@ export const FormDraggableList = () => {
|
|||||||
const { listQuestions } = questionStore();
|
const { listQuestions } = questionStore();
|
||||||
|
|
||||||
const onDragEnd = ({ destination, source }: DropResult) => {
|
const onDragEnd = ({ destination, source }: DropResult) => {
|
||||||
|
if (destination?.index === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (destination) {
|
if (destination) {
|
||||||
const newItems = reorder(
|
const newItems = reorder(
|
||||||
listQuestions[quizId],
|
listQuestions[quizId],
|
||||||
|
|||||||
@ -93,13 +93,6 @@ export default function FormQuestionsPage() {
|
|||||||
}}
|
}}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
createQuestion(quizId);
|
createQuestion(quizId);
|
||||||
updateQuestionsList<QuizQuestionBase>(
|
|
||||||
quizId,
|
|
||||||
listQuestions[quizId].length - 1 || 0,
|
|
||||||
{
|
|
||||||
expanded: true,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<AddAnswer color="#EEE4FC" />
|
<AddAnswer color="#EEE4FC" />
|
||||||
|
|||||||
@ -5,18 +5,14 @@ import { Box } from "@mui/material";
|
|||||||
import QuestionsMiniButton from "@ui_kit/QuestionsMiniButton";
|
import QuestionsMiniButton from "@ui_kit/QuestionsMiniButton";
|
||||||
import ButtonsOptions from "../ButtonsOptions";
|
import ButtonsOptions from "../ButtonsOptions";
|
||||||
import SwitchAnswerOptions from "../answerOptions/switchAnswerOptions";
|
import SwitchAnswerOptions from "../answerOptions/switchAnswerOptions";
|
||||||
|
import { BUTTON_TYPE_QUESTIONS } from "../TypeQuestions";
|
||||||
|
|
||||||
import Answer from "../../../assets/icons/questionsPage/answer";
|
import Answer from "../../../assets/icons/questionsPage/answer";
|
||||||
import OptionsPict from "../../../assets/icons/questionsPage/options_pict";
|
|
||||||
import OptionsAndPict from "../../../assets/icons/questionsPage/options_and_pict";
|
|
||||||
import Emoji from "../../../assets/icons/questionsPage/emoji";
|
|
||||||
import Input from "../../../assets/icons/questionsPage/input";
|
import Input from "../../../assets/icons/questionsPage/input";
|
||||||
import DropDown from "../../../assets/icons/questionsPage/drop_down";
|
import DropDown from "../../../assets/icons/questionsPage/drop_down";
|
||||||
import Date from "../../../assets/icons/questionsPage/date";
|
import Date from "../../../assets/icons/questionsPage/date";
|
||||||
import Slider from "../../../assets/icons/questionsPage/slider";
|
import Slider from "../../../assets/icons/questionsPage/slider";
|
||||||
import Download from "../../../assets/icons/questionsPage/download";
|
import Download from "../../../assets/icons/questionsPage/download";
|
||||||
import Page from "../../../assets/icons/questionsPage/page";
|
|
||||||
import RatingIcon from "../../../assets/icons/questionsPage/rating";
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
questionStore,
|
questionStore,
|
||||||
@ -40,27 +36,12 @@ type ButtonTypeQuestion = {
|
|||||||
value: QuizQuestionType;
|
value: QuizQuestionType;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const BUTTON_TYPE_QUESTIONS: ButtonTypeQuestion[] = [
|
const BUTTON_TYPE_SHORT_QUESTIONS: ButtonTypeQuestion[] = [
|
||||||
{
|
{
|
||||||
icon: <Answer color="#9A9AAF" />,
|
icon: <Answer color="#9A9AAF" />,
|
||||||
title: "Варианты ответов",
|
title: "Варианты ответов",
|
||||||
value: "variant",
|
value: "variant",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
icon: <OptionsPict color="#9A9AAF" />,
|
|
||||||
title: "Варианты с картинками",
|
|
||||||
value: "images",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: <OptionsAndPict color="#9A9AAF" />,
|
|
||||||
title: "Варианты и картинка",
|
|
||||||
value: "varimg",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: <Emoji color="#9A9AAF" />,
|
|
||||||
title: "Эмоджи",
|
|
||||||
value: "emoji",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
icon: <Input color="#9A9AAF" />,
|
icon: <Input color="#9A9AAF" />,
|
||||||
title: "Своё поле для ввода",
|
title: "Своё поле для ввода",
|
||||||
@ -86,16 +67,6 @@ export const BUTTON_TYPE_QUESTIONS: ButtonTypeQuestion[] = [
|
|||||||
title: "Загрузка файла",
|
title: "Загрузка файла",
|
||||||
value: "file",
|
value: "file",
|
||||||
},
|
},
|
||||||
{
|
|
||||||
icon: <Page color="#9A9AAF" />,
|
|
||||||
title: "Страница",
|
|
||||||
value: "page",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
icon: <RatingIcon color="#9A9AAF" />,
|
|
||||||
title: "Рейтинг",
|
|
||||||
value: "rating",
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function FormTypeQuestions({ totalIndex }: Props) {
|
export default function FormTypeQuestions({ totalIndex }: Props) {
|
||||||
@ -114,7 +85,10 @@ export default function FormTypeQuestions({ totalIndex }: Props) {
|
|||||||
margin: "20px",
|
margin: "20px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{BUTTON_TYPE_QUESTIONS.map(({ icon, title, value }) => (
|
{(totalIndex === 0
|
||||||
|
? BUTTON_TYPE_QUESTIONS
|
||||||
|
: BUTTON_TYPE_SHORT_QUESTIONS
|
||||||
|
).map(({ icon, title, value }) => (
|
||||||
<QuestionsMiniButton
|
<QuestionsMiniButton
|
||||||
key={title}
|
key={title}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
|
|||||||
@ -1,16 +1,16 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Link,
|
Link,
|
||||||
Typography,
|
Typography,
|
||||||
useTheme,
|
useTheme,
|
||||||
useMediaQuery,
|
useMediaQuery,
|
||||||
InputAdornment,
|
InputAdornment,
|
||||||
IconButton,
|
IconButton,
|
||||||
Button,
|
Button,
|
||||||
Popover,
|
Popover,
|
||||||
TextareaAutosize,
|
TextareaAutosize,
|
||||||
TextField,
|
TextField,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
|
|
||||||
@ -35,423 +35,247 @@ import type { QuizQuestionVarImg } from "../../../model/questionTypes/varimg";
|
|||||||
import { produce } from "immer";
|
import { produce } from "immer";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
totalIndex: number;
|
totalIndex: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function OptionsAndPicture({ totalIndex }: Props) {
|
export default function OptionsAndPicture({ totalIndex }: Props) {
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const [opened, setOpened] = useState<boolean>(false);
|
const [opened, setOpened] = useState<boolean>(false);
|
||||||
const [switchState, setSwitchState] = useState("setting");
|
const [switchState, setSwitchState] = useState("setting");
|
||||||
const [currentIndex, setCurrentIndex] = useState<number>(0);
|
const [currentIndex, setCurrentIndex] = useState<number>(0);
|
||||||
const quizId = Number(useParams().quizId);
|
const quizId = Number(useParams().quizId);
|
||||||
const { listQuestions } = questionStore();
|
const { listQuestions } = questionStore();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down(790));
|
const isMobile = useMediaQuery(theme.breakpoints.down(790));
|
||||||
const question = listQuestions[quizId][totalIndex] as QuizQuestionVarImg;
|
const question = listQuestions[quizId][totalIndex] as QuizQuestionVarImg;
|
||||||
|
|
||||||
const SSHC = (data: string) => {
|
const SSHC = (data: string) => {
|
||||||
setSwitchState(data);
|
setSwitchState(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
const uploadImage = (files: FileList | null) => {
|
const uploadImage = (files: FileList | null) => {
|
||||||
if (files?.length) {
|
if (files?.length) {
|
||||||
const [file] = Array.from(files);
|
const [file] = Array.from(files);
|
||||||
|
|
||||||
const clonedContent = { ...question.content };
|
const clonedContent = { ...question.content };
|
||||||
clonedContent.variants[currentIndex].extendedText =
|
clonedContent.variants[currentIndex].extendedText =
|
||||||
URL.createObjectURL(file);
|
URL.createObjectURL(file);
|
||||||
updateQuestionsList<QuizQuestionVarImg>(quizId, totalIndex, {
|
updateQuestionsList<QuizQuestionVarImg>(quizId, totalIndex, {
|
||||||
content: clonedContent,
|
content: clonedContent,
|
||||||
});
|
});
|
||||||
|
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
setOpened(true);
|
setOpened(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Box sx={{ pl: "20px", pr: "20px" }}>
|
<Box sx={{ pl: "20px", pr: "20px" }}>
|
||||||
<AnswerDraggableList
|
<AnswerDraggableList
|
||||||
variants={question.content.variants}
|
variants={question.content.variants}
|
||||||
totalIndex={totalIndex}
|
totalIndex={totalIndex}
|
||||||
additionalContent={(variant, index) => (
|
additionalContent={(variant, index) => (
|
||||||
<>
|
<>
|
||||||
{!isMobile && (
|
{!isMobile && (
|
||||||
<Box
|
|
||||||
sx={{ cursor: "pointer" }}
|
|
||||||
onClick={() => {
|
|
||||||
setCurrentIndex(index);
|
|
||||||
setOpen(true);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{variant.extendedText ? (
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
overflow: "hidden",
|
|
||||||
width: "60px",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
background: "#EEE4FC",
|
|
||||||
borderRadius: "3px",
|
|
||||||
margin: "0 10px",
|
|
||||||
height: "40px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box sx={{ display: "flex", width: "40px" }}>
|
|
||||||
<img
|
|
||||||
src={variant.extendedText}
|
|
||||||
alt=""
|
|
||||||
style={{ width: "100%" }}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
<PlusImage />
|
|
||||||
</Box>
|
|
||||||
) : (
|
|
||||||
<Button component="label" sx={{ padding: "0px" }}>
|
|
||||||
<AddImage
|
|
||||||
sx={{
|
|
||||||
height: "40px",
|
|
||||||
width: "60px",
|
|
||||||
margin: "0 10px",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
additionalMobile={(variant, index) => (
|
|
||||||
<>
|
|
||||||
{isMobile && (
|
|
||||||
<Box
|
|
||||||
onClick={() => {
|
|
||||||
setCurrentIndex(index);
|
|
||||||
setOpen(true);
|
|
||||||
}}
|
|
||||||
sx={{
|
|
||||||
overflow: "hidden",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
m: "8px",
|
|
||||||
position: "relative",
|
|
||||||
borderRadius: "3px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
width: "100%",
|
|
||||||
background: "#EEE4FC",
|
|
||||||
height: "40px",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{variant.extendedText ? (
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
overflow: "hidden",
|
|
||||||
width: "40px",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
background: "#EEE4FC",
|
|
||||||
height: "30px",
|
|
||||||
borderRadius: "3px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
src={variant.extendedText}
|
|
||||||
alt=""
|
|
||||||
style={{ width: "100%" }}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
) : (
|
|
||||||
<Button component="label" sx={{ padding: "0px" }}>
|
|
||||||
<Image
|
|
||||||
sx={{
|
|
||||||
height: "40px",
|
|
||||||
width: "60px",
|
|
||||||
margin: "0 10px",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</Box>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
width: "20px",
|
|
||||||
background: "#EEE4FC",
|
|
||||||
height: "40px",
|
|
||||||
color: "white",
|
|
||||||
backgroundColor: "#7E2AEA",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
+
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<UploadImageModal
|
|
||||||
open={open}
|
|
||||||
onClose={() => setOpen(false)}
|
|
||||||
imgHC={uploadImage}
|
|
||||||
/>
|
|
||||||
<CropModal
|
|
||||||
opened={opened}
|
|
||||||
onClose={() => setOpened(false)}
|
|
||||||
picture={question.content.variants[currentIndex]?.extendedText}
|
|
||||||
onCropPress={url => {
|
|
||||||
const content = produce(question.content, draft => {
|
|
||||||
draft.variants[currentIndex].extendedText = url;
|
|
||||||
});
|
|
||||||
updateQuestionsList<QuizQuestionVarImg>(quizId, totalIndex, {
|
|
||||||
content,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{ cursor: "pointer" }}
|
||||||
width: "100%",
|
onClick={() => {
|
||||||
border: "1px solid #9A9AAF",
|
setCurrentIndex(index);
|
||||||
borderRadius: "8px",
|
setOpen(true);
|
||||||
display: isTablet ? "block" : "none",
|
}}
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
<TextField
|
{variant.extendedText ? (
|
||||||
fullWidth
|
<Box
|
||||||
focused={false}
|
sx={{
|
||||||
placeholder={"Добавьте ответ"}
|
overflow: "hidden",
|
||||||
multiline={question.content.largeCheck}
|
width: "60px",
|
||||||
InputProps={{
|
|
||||||
startAdornment: (
|
|
||||||
<>
|
|
||||||
<InputAdornment position="start">
|
|
||||||
<PointsIcon
|
|
||||||
style={{ color: "#9A9AAF", fontSize: "30px" }}
|
|
||||||
/>
|
|
||||||
</InputAdornment>
|
|
||||||
{!isMobile && (
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
width: "60px",
|
|
||||||
height: "40px",
|
|
||||||
background: "#EEE4FC",
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "space-between",
|
|
||||||
marginRight: "20px",
|
|
||||||
marginLeft: "12px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<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>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
),
|
|
||||||
endAdornment: (
|
|
||||||
<InputAdornment position="end">
|
|
||||||
<IconButton
|
|
||||||
sx={{ padding: "0" }}
|
|
||||||
aria-describedby="my-popover-id"
|
|
||||||
>
|
|
||||||
<MessageIcon
|
|
||||||
style={{
|
|
||||||
color: "#9A9AAF",
|
|
||||||
fontSize: "30px",
|
|
||||||
marginRight: "6.5px",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</IconButton>
|
|
||||||
<Popover
|
|
||||||
id="my-popover-id"
|
|
||||||
anchorOrigin={{ vertical: "bottom", horizontal: "left" }}
|
|
||||||
open={false}
|
|
||||||
>
|
|
||||||
<TextareaAutosize
|
|
||||||
style={{ margin: "10px" }}
|
|
||||||
placeholder="Подсказка для этого ответа"
|
|
||||||
/>
|
|
||||||
</Popover>
|
|
||||||
<IconButton sx={{ padding: "0" }}>
|
|
||||||
<DeleteIcon
|
|
||||||
style={{
|
|
||||||
color: theme.palette.grey2.main,
|
|
||||||
marginRight: "-1px",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</IconButton>
|
|
||||||
</InputAdornment>
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
sx={{
|
|
||||||
"& .MuiInputBase-root": {
|
|
||||||
padding: "13.5px",
|
|
||||||
borderRadius: "10px",
|
|
||||||
background: "#ffffff",
|
|
||||||
height: "48px",
|
|
||||||
},
|
|
||||||
"& .MuiOutlinedInput-notchedOutline": {
|
|
||||||
border: "none",
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
inputProps={{
|
|
||||||
sx: { fontSize: "18px", lineHeight: "21px", py: 0 },
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{isMobile && (
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
m: "8px",
|
|
||||||
position: "relative",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box
|
|
||||||
sx={{ width: "100%", background: "#EEE4FC", height: "40px" }}
|
|
||||||
/>
|
|
||||||
<ImageAddIcons
|
|
||||||
style={{
|
|
||||||
position: "absolute",
|
|
||||||
color: "#7E2AEA",
|
|
||||||
fontSize: "20px",
|
|
||||||
left: "45%",
|
|
||||||
right: "55%",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
width: "20px",
|
|
||||||
background: "#EEE4FC",
|
|
||||||
height: "40px",
|
|
||||||
color: "white",
|
|
||||||
backgroundColor: "#7E2AEA",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box
|
|
||||||
sx={{ width: "100%", background: "#EEE4FC", height: "40px" }}
|
|
||||||
/>
|
|
||||||
<ImageAddIcons
|
|
||||||
style={{
|
|
||||||
position: "absolute",
|
|
||||||
color: "#7E2AEA",
|
|
||||||
fontSize: "20px",
|
|
||||||
left: "45%",
|
|
||||||
right: "55%",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
width: "20px",
|
|
||||||
background: "#EEE4FC",
|
|
||||||
height: "40px",
|
|
||||||
color: "white",
|
|
||||||
backgroundColor: "#7E2AEA",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
+
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
</Box>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
marginBottom: "17px",
|
background: "#EEE4FC",
|
||||||
}}
|
borderRadius: "3px",
|
||||||
>
|
margin: "0 10px",
|
||||||
<Link
|
height: "40px",
|
||||||
component="button"
|
}}
|
||||||
variant="body2"
|
|
||||||
sx={{
|
|
||||||
color: theme.palette.brightPurple.main,
|
|
||||||
fontWeight: "400",
|
|
||||||
fontSize: "16px",
|
|
||||||
mr: "4px",
|
|
||||||
height: "19px",
|
|
||||||
}}
|
|
||||||
onClick={() => {
|
|
||||||
const clonedContent = { ...question.content };
|
|
||||||
clonedContent.variants.push({
|
|
||||||
answer: "",
|
|
||||||
hints: "",
|
|
||||||
extendedText: "",
|
|
||||||
});
|
|
||||||
updateQuestionsList<QuizQuestionVarImg>(quizId, totalIndex, {
|
|
||||||
content: clonedContent,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
Добавьте ответ
|
<Box sx={{ display: "flex", width: "40px" }}>
|
||||||
</Link>
|
<img
|
||||||
{isMobile ? null : (
|
src={variant.extendedText}
|
||||||
<>
|
alt=""
|
||||||
<Typography
|
style={{ width: "100%" }}
|
||||||
sx={{
|
/>
|
||||||
fontWeight: 400,
|
</Box>
|
||||||
lineHeight: "21.33px",
|
<PlusImage />
|
||||||
color: theme.palette.grey2.main,
|
</Box>
|
||||||
fontSize: "16px",
|
) : (
|
||||||
}}
|
<Button component="label" sx={{ padding: "0px" }}>
|
||||||
>
|
<AddImage
|
||||||
или нажмите Enter
|
sx={{
|
||||||
</Typography>
|
height: "40px",
|
||||||
<EnterIcon
|
width: "60px",
|
||||||
style={{
|
margin: "0 10px",
|
||||||
color: "#7E2AEA",
|
}}
|
||||||
fontSize: "24px",
|
/>
|
||||||
marginLeft: "6px",
|
</Button>
|
||||||
}}
|
)}
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
)}
|
||||||
<ButtonsOptionsAndPict
|
</>
|
||||||
switchState={switchState}
|
)}
|
||||||
SSHC={SSHC}
|
additionalMobile={(variant, index) => (
|
||||||
totalIndex={totalIndex}
|
<>
|
||||||
/>
|
{isMobile && (
|
||||||
<SwitchOptionsAndPict switchState={switchState} totalIndex={totalIndex} />
|
<Box
|
||||||
</>
|
onClick={() => {
|
||||||
);
|
setCurrentIndex(index);
|
||||||
|
setOpen(true);
|
||||||
|
}}
|
||||||
|
sx={{
|
||||||
|
overflow: "hidden",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
m: "8px",
|
||||||
|
position: "relative",
|
||||||
|
borderRadius: "3px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
width: "100%",
|
||||||
|
background: "#EEE4FC",
|
||||||
|
height: "40px",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{variant.extendedText ? (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
overflow: "hidden",
|
||||||
|
width: "40px",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
background: "#EEE4FC",
|
||||||
|
height: "30px",
|
||||||
|
borderRadius: "3px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={variant.extendedText}
|
||||||
|
alt=""
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
) : (
|
||||||
|
<Button component="label" sx={{ padding: "0px" }}>
|
||||||
|
<Image
|
||||||
|
sx={{
|
||||||
|
height: "40px",
|
||||||
|
width: "60px",
|
||||||
|
margin: "0 10px",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
width: "20px",
|
||||||
|
background: "#EEE4FC",
|
||||||
|
height: "40px",
|
||||||
|
color: "white",
|
||||||
|
backgroundColor: "#7E2AEA",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
+
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<UploadImageModal
|
||||||
|
open={open}
|
||||||
|
onClose={() => setOpen(false)}
|
||||||
|
imgHC={uploadImage}
|
||||||
|
/>
|
||||||
|
<CropModal
|
||||||
|
opened={opened}
|
||||||
|
onClose={() => setOpened(false)}
|
||||||
|
picture={question.content.variants[currentIndex]?.extendedText}
|
||||||
|
onCropPress={(url) => {
|
||||||
|
const content = produce(question.content, (draft) => {
|
||||||
|
draft.variants[currentIndex].extendedText = url;
|
||||||
|
});
|
||||||
|
updateQuestionsList<QuizQuestionVarImg>(quizId, totalIndex, {
|
||||||
|
content,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
marginBottom: "17px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Link
|
||||||
|
component="button"
|
||||||
|
variant="body2"
|
||||||
|
sx={{
|
||||||
|
color: theme.palette.brightPurple.main,
|
||||||
|
fontWeight: "400",
|
||||||
|
fontSize: "16px",
|
||||||
|
mr: "4px",
|
||||||
|
height: "19px",
|
||||||
|
}}
|
||||||
|
onClick={() => {
|
||||||
|
const clonedContent = { ...question.content };
|
||||||
|
clonedContent.variants.push({
|
||||||
|
answer: "",
|
||||||
|
extendedText: "",
|
||||||
|
});
|
||||||
|
updateQuestionsList<QuizQuestionVarImg>(quizId, totalIndex, {
|
||||||
|
content: clonedContent,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Добавьте ответ
|
||||||
|
</Link>
|
||||||
|
{isMobile ? null : (
|
||||||
|
<>
|
||||||
|
<Typography
|
||||||
|
sx={{
|
||||||
|
fontWeight: 400,
|
||||||
|
lineHeight: "21.33px",
|
||||||
|
color: theme.palette.grey2.main,
|
||||||
|
fontSize: "16px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
или нажмите Enter
|
||||||
|
</Typography>
|
||||||
|
<EnterIcon
|
||||||
|
style={{
|
||||||
|
color: "#7E2AEA",
|
||||||
|
fontSize: "24px",
|
||||||
|
marginLeft: "6px",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<ButtonsOptionsAndPict
|
||||||
|
switchState={switchState}
|
||||||
|
SSHC={SSHC}
|
||||||
|
totalIndex={totalIndex}
|
||||||
|
/>
|
||||||
|
<SwitchOptionsAndPict switchState={switchState} totalIndex={totalIndex} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Link,
|
Link,
|
||||||
Typography,
|
Typography,
|
||||||
Button,
|
Button,
|
||||||
useTheme,
|
useTheme,
|
||||||
useMediaQuery
|
useMediaQuery,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
|
|
||||||
import ButtonsOptions from "../ButtonsOptions";
|
import ButtonsOptions from "../ButtonsOptions";
|
||||||
@ -25,227 +25,234 @@ import type { QuizQuestionImages } from "../../../model/questionTypes/images";
|
|||||||
import { produce } from "immer";
|
import { produce } from "immer";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
totalIndex: number;
|
totalIndex: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function OptionsPicture({ totalIndex }: Props) {
|
export default function OptionsPicture({ totalIndex }: Props) {
|
||||||
const [open, setOpen] = useState(false);
|
const [open, setOpen] = useState(false);
|
||||||
const [opened, setOpened] = useState<boolean>(false);
|
const [opened, setOpened] = useState<boolean>(false);
|
||||||
const [currentIndex, setCurrentIndex] = useState<number>(0);
|
const [currentIndex, setCurrentIndex] = useState<number>(0);
|
||||||
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(790));
|
const isTablet = useMediaQuery(theme.breakpoints.down(790));
|
||||||
const quizId = Number(useParams().quizId);
|
const quizId = Number(useParams().quizId);
|
||||||
const [switchState, setSwitchState] = useState("setting");
|
const [switchState, setSwitchState] = useState("setting");
|
||||||
const { listQuestions } = questionStore();
|
const { listQuestions } = questionStore();
|
||||||
const question = listQuestions[quizId][totalIndex] as QuizQuestionImages;
|
const question = listQuestions[quizId][totalIndex] as QuizQuestionImages;
|
||||||
|
|
||||||
const SSHC = (data: string) => {
|
const SSHC = (data: string) => {
|
||||||
setSwitchState(data);
|
setSwitchState(data);
|
||||||
};
|
};
|
||||||
|
|
||||||
const uploadImage = (files: FileList | null) => {
|
const uploadImage = (files: FileList | null) => {
|
||||||
if (files?.length) {
|
if (files?.length) {
|
||||||
const [file] = Array.from(files);
|
const [file] = Array.from(files);
|
||||||
|
|
||||||
const clonedContent = { ...question.content };
|
const clonedContent = { ...question.content };
|
||||||
clonedContent.variants[currentIndex].extendedText =
|
clonedContent.variants[currentIndex].extendedText =
|
||||||
URL.createObjectURL(file);
|
URL.createObjectURL(file);
|
||||||
updateQuestionsList<QuizQuestionImages>(quizId, totalIndex, {
|
updateQuestionsList<QuizQuestionImages>(quizId, totalIndex, {
|
||||||
content: clonedContent,
|
content: clonedContent,
|
||||||
});
|
});
|
||||||
|
|
||||||
setOpen(false);
|
setOpen(false);
|
||||||
setOpened(true);
|
setOpened(true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const addNewAnswer = () => {
|
const addNewAnswer = () => {
|
||||||
const answerNew = question.content.variants.slice();
|
const answerNew = question.content.variants.slice();
|
||||||
answerNew.push({ answer: "", hints: "", extendedText: "" });
|
answerNew.push({ answer: "", extendedText: "" });
|
||||||
|
|
||||||
updateQuestionsList<QuizQuestionImages>(quizId, totalIndex, {
|
updateQuestionsList<QuizQuestionImages>(quizId, totalIndex, {
|
||||||
content: { ...question.content, variants: answerNew },
|
content: { ...question.content, variants: answerNew },
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Box sx={{ padding: "20px" }}>
|
<Box sx={{ padding: "20px" }}>
|
||||||
<AnswerDraggableList
|
<AnswerDraggableList
|
||||||
variants={question.content.variants}
|
variants={question.content.variants}
|
||||||
totalIndex={totalIndex}
|
totalIndex={totalIndex}
|
||||||
additionalContent={(variant, index) => (
|
additionalContent={(variant, index) => (
|
||||||
<>
|
<>
|
||||||
{!isMobile && (
|
{!isMobile && (
|
||||||
<Box
|
<Box
|
||||||
sx={{ cursor: "pointer" }}
|
sx={{ cursor: "pointer" }}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
setCurrentIndex(index);
|
setCurrentIndex(index);
|
||||||
setOpen(true);
|
setOpen(true);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{variant.extendedText ? (
|
{variant.extendedText ? (
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
overflow: "hidden",
|
overflow: "hidden",
|
||||||
width: "60px",
|
width: "60px",
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
background: "#EEE4FC",
|
background: "#EEE4FC",
|
||||||
borderRadius: "3px",
|
borderRadius: "3px",
|
||||||
margin: "0 10px",
|
margin: "0 10px",
|
||||||
height: "40px",
|
height: "40px",
|
||||||
}}
|
}}
|
||||||
>
|
|
||||||
<Box sx={{ display: "flex", width: "40px" }}>
|
|
||||||
<img
|
|
||||||
src={variant.extendedText}
|
|
||||||
alt=""
|
|
||||||
style={{ width: "100%" }}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
<PlusImage />
|
|
||||||
</Box>
|
|
||||||
) : (
|
|
||||||
<Button component="label" sx={{ padding: "0px" }}>
|
|
||||||
<AddImage
|
|
||||||
sx={{ height: "40px", width: "60px", margin: "0 10px" }}
|
|
||||||
/>
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
additionalMobile={(variant, index) => (
|
|
||||||
<>
|
|
||||||
{isMobile && (
|
|
||||||
<Box
|
|
||||||
onClick={() => {
|
|
||||||
setCurrentIndex(index);
|
|
||||||
setOpen(true);
|
|
||||||
}}
|
|
||||||
sx={{
|
|
||||||
overflow: "hidden",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
m: "8px",
|
|
||||||
position: "relative",
|
|
||||||
borderRadius: "3px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
width: "100%",
|
|
||||||
background: "#EEE4FC",
|
|
||||||
height: "40px",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
justifyContent: "center",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{variant.extendedText ? (
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
overflow: "hidden",
|
|
||||||
width: "40px",
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
background: "#EEE4FC",
|
|
||||||
height: "30px",
|
|
||||||
borderRadius: "3px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img
|
|
||||||
src={variant.extendedText}
|
|
||||||
alt=""
|
|
||||||
style={{ width: "100%" }}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
) : (
|
|
||||||
<Button component="label" sx={{ padding: "0px" }}>
|
|
||||||
<Image
|
|
||||||
sx={{
|
|
||||||
height: "40px",
|
|
||||||
width: "60px",
|
|
||||||
margin: "0 10px",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Button>
|
|
||||||
)}
|
|
||||||
</Box>
|
|
||||||
<Box
|
|
||||||
sx={{
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
width: "20px",
|
|
||||||
background: "#EEE4FC",
|
|
||||||
height: "40px",
|
|
||||||
color: "white",
|
|
||||||
backgroundColor: "#7E2AEA",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
+
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
/>
|
|
||||||
<UploadImageModal
|
|
||||||
open={open}
|
|
||||||
onClose={() => setOpen(false)}
|
|
||||||
imgHC={uploadImage}
|
|
||||||
/>
|
|
||||||
<CropModal
|
|
||||||
opened={opened}
|
|
||||||
onClose={() => setOpened(false)}
|
|
||||||
picture={question.content.variants[currentIndex]?.extendedText}
|
|
||||||
onCropPress={url => {
|
|
||||||
const content = produce(question.content, draft => {
|
|
||||||
draft.variants[currentIndex].extendedText = url;
|
|
||||||
});
|
|
||||||
updateQuestionsList<QuizQuestionImages>(quizId, totalIndex, {
|
|
||||||
content,
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<Box sx={{ display: "flex", alignItems: "center", gap: "10px" }}>
|
|
||||||
<Link
|
|
||||||
component="button"
|
|
||||||
variant="body2"
|
|
||||||
sx={{ color: theme.palette.brightPurple.main }}
|
|
||||||
onClick={addNewAnswer}
|
|
||||||
>
|
>
|
||||||
Добавьте ответ
|
<Box sx={{ display: "flex", width: "40px" }}>
|
||||||
</Link>
|
<img
|
||||||
{isMobile ? null : (
|
src={variant.extendedText}
|
||||||
<>
|
alt=""
|
||||||
<Typography
|
style={{ width: "100%" }}
|
||||||
sx={{
|
/>
|
||||||
fontWeight: 400,
|
</Box>
|
||||||
lineHeight: "21.33px",
|
<PlusImage />
|
||||||
color: theme.palette.grey2.main,
|
</Box>
|
||||||
fontSize: "16px",
|
) : (
|
||||||
}}
|
<Button component="label" sx={{ padding: "0px" }}>
|
||||||
>
|
<AddImage
|
||||||
или нажмите Enter
|
sx={{ height: "40px", width: "60px", margin: "0 10px" }}
|
||||||
</Typography>
|
/>
|
||||||
<EnterIcon
|
</Button>
|
||||||
style={{
|
)}
|
||||||
color: "#7E2AEA",
|
|
||||||
fontSize: "24px",
|
|
||||||
marginLeft: "6px",
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
)}
|
||||||
<ButtonsOptions switchState={switchState} SSHC={SSHC} totalIndex={totalIndex} />
|
</>
|
||||||
<SwitchAnswerOptionsPict switchState={switchState} totalIndex={totalIndex} />
|
)}
|
||||||
</>
|
additionalMobile={(variant, index) => (
|
||||||
);
|
<>
|
||||||
|
{isMobile && (
|
||||||
|
<Box
|
||||||
|
onClick={() => {
|
||||||
|
setCurrentIndex(index);
|
||||||
|
setOpen(true);
|
||||||
|
}}
|
||||||
|
sx={{
|
||||||
|
overflow: "hidden",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
m: "8px",
|
||||||
|
position: "relative",
|
||||||
|
borderRadius: "3px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
width: "100%",
|
||||||
|
background: "#EEE4FC",
|
||||||
|
height: "40px",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
justifyContent: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{variant.extendedText ? (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
overflow: "hidden",
|
||||||
|
width: "40px",
|
||||||
|
display: "flex",
|
||||||
|
alignItems: "center",
|
||||||
|
background: "#EEE4FC",
|
||||||
|
height: "30px",
|
||||||
|
borderRadius: "3px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
src={variant.extendedText}
|
||||||
|
alt=""
|
||||||
|
style={{ width: "100%" }}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
) : (
|
||||||
|
<Button component="label" sx={{ padding: "0px" }}>
|
||||||
|
<Image
|
||||||
|
sx={{
|
||||||
|
height: "40px",
|
||||||
|
width: "60px",
|
||||||
|
margin: "0 10px",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Button>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
width: "20px",
|
||||||
|
background: "#EEE4FC",
|
||||||
|
height: "40px",
|
||||||
|
color: "white",
|
||||||
|
backgroundColor: "#7E2AEA",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
+
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
<UploadImageModal
|
||||||
|
open={open}
|
||||||
|
onClose={() => setOpen(false)}
|
||||||
|
imgHC={uploadImage}
|
||||||
|
/>
|
||||||
|
<CropModal
|
||||||
|
opened={opened}
|
||||||
|
onClose={() => setOpened(false)}
|
||||||
|
picture={question.content.variants[currentIndex]?.extendedText}
|
||||||
|
onCropPress={(url) => {
|
||||||
|
const content = produce(question.content, (draft) => {
|
||||||
|
draft.variants[currentIndex].extendedText = url;
|
||||||
|
});
|
||||||
|
updateQuestionsList<QuizQuestionImages>(quizId, totalIndex, {
|
||||||
|
content,
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Box sx={{ display: "flex", alignItems: "center", gap: "10px" }}>
|
||||||
|
<Link
|
||||||
|
component="button"
|
||||||
|
variant="body2"
|
||||||
|
sx={{ color: theme.palette.brightPurple.main }}
|
||||||
|
onClick={addNewAnswer}
|
||||||
|
>
|
||||||
|
Добавьте ответ
|
||||||
|
</Link>
|
||||||
|
{isMobile ? null : (
|
||||||
|
<>
|
||||||
|
<Typography
|
||||||
|
sx={{
|
||||||
|
fontWeight: 400,
|
||||||
|
lineHeight: "21.33px",
|
||||||
|
color: theme.palette.grey2.main,
|
||||||
|
fontSize: "16px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
или нажмите Enter
|
||||||
|
</Typography>
|
||||||
|
<EnterIcon
|
||||||
|
style={{
|
||||||
|
color: "#7E2AEA",
|
||||||
|
fontSize: "24px",
|
||||||
|
marginLeft: "6px",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
<ButtonsOptions
|
||||||
|
switchState={switchState}
|
||||||
|
SSHC={SSHC}
|
||||||
|
totalIndex={totalIndex}
|
||||||
|
/>
|
||||||
|
<SwitchAnswerOptionsPict
|
||||||
|
switchState={switchState}
|
||||||
|
totalIndex={totalIndex}
|
||||||
|
/>
|
||||||
|
</>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,19 +1,19 @@
|
|||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
Button,
|
Button,
|
||||||
IconButton,
|
IconButton,
|
||||||
Typography,
|
Typography,
|
||||||
useMediaQuery,
|
useMediaQuery,
|
||||||
useTheme,
|
useTheme,
|
||||||
} from "@mui/material";
|
} from "@mui/material";
|
||||||
import AddPlus from "../../assets/icons/questionsPage/addPlus";
|
import AddPlus from "../../assets/icons/questionsPage/addPlus";
|
||||||
import ArrowLeft from "../../assets/icons/questionsPage/arrowLeft";
|
import ArrowLeft from "../../assets/icons/questionsPage/arrowLeft";
|
||||||
import { quizStore } from "@root/quizes";
|
import { quizStore } from "@root/quizes";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
import {
|
import {
|
||||||
questionStore,
|
questionStore,
|
||||||
createQuestion,
|
createQuestion,
|
||||||
updateQuestionsList,
|
updateQuestionsList,
|
||||||
} from "@root/questions";
|
} from "@root/questions";
|
||||||
import { DraggableList } from "./DraggableList";
|
import { DraggableList } from "./DraggableList";
|
||||||
|
|
||||||
@ -22,17 +22,17 @@ import QuizPreview from "@ui_kit/QuizPreview/QuizPreview";
|
|||||||
import { createPortal } from "react-dom";
|
import { createPortal } from "react-dom";
|
||||||
|
|
||||||
export default function QuestionsPage() {
|
export default function QuestionsPage() {
|
||||||
const { listQuizes, updateQuizesList } = quizStore();
|
const { listQuizes, updateQuizesList } = quizStore();
|
||||||
const quizId = Number(useParams().quizId);
|
const quizId = Number(useParams().quizId);
|
||||||
const { listQuestions } = questionStore();
|
const { listQuestions } = questionStore();
|
||||||
const handleNext = () => {
|
const handleNext = () => {
|
||||||
updateQuizesList(quizId, { step: listQuizes[quizId].step + 1 });
|
updateQuizesList(quizId, { step: listQuizes[quizId].step + 1 });
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBack = () => {
|
const handleBack = () => {
|
||||||
let result = listQuizes[quizId].step - 1;
|
let result = listQuizes[quizId].step - 1;
|
||||||
updateQuizesList(quizId, { step: result ? result : 1 });
|
updateQuizesList(quizId, { step: result ? result : 1 });
|
||||||
};
|
};
|
||||||
|
|
||||||
const collapseEverything = () => {
|
const collapseEverything = () => {
|
||||||
listQuestions[quizId].forEach((item, index) => {
|
listQuestions[quizId].forEach((item, index) => {
|
||||||
@ -43,12 +43,11 @@ export default function QuestionsPage() {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const isTablet = useMediaQuery(theme.breakpoints.up(1000));
|
const isMobile = useMediaQuery(theme.breakpoints.down(660));
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{/* <Stepper activeStep={activeStep} desc={"Задайте вопросы"} /> */}
|
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
maxWidth: "796px",
|
maxWidth: "796px",
|
||||||
@ -85,10 +84,15 @@ export default function QuestionsPage() {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
createQuestion(quizId);
|
createQuestion(quizId);
|
||||||
}}
|
}}
|
||||||
|
sx={{
|
||||||
|
position: "fixed",
|
||||||
|
left: isMobile ? "20px" : "250px",
|
||||||
|
bottom: "20px",
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<AddPlus />
|
<AddPlus />
|
||||||
</IconButton>
|
</IconButton>
|
||||||
<Box sx={{ display: "flex", gap: "8px" }}>
|
<Box sx={{ display: "flex", gap: "8px", marginLeft: "auto" }}>
|
||||||
<Button
|
<Button
|
||||||
variant="outlined"
|
variant="outlined"
|
||||||
sx={{ padding: "10px 20px", borderRadius: "8px", height: "44px" }}
|
sx={{ padding: "10px 20px", borderRadius: "8px", height: "44px" }}
|
||||||
|
|||||||
@ -27,7 +27,7 @@ export default function AnswerOptions({ totalIndex }: Props) {
|
|||||||
|
|
||||||
const addNewAnswer = () => {
|
const addNewAnswer = () => {
|
||||||
const answerNew = question.content.variants.slice();
|
const answerNew = question.content.variants.slice();
|
||||||
answerNew.push({ answer: "", hints: "", extendedText: "" });
|
answerNew.push({ answer: "", extendedText: "" });
|
||||||
|
|
||||||
updateQuestionsList<QuizQuestionVariant>(quizId, totalIndex, {
|
updateQuestionsList<QuizQuestionVariant>(quizId, totalIndex, {
|
||||||
content: { ...question.content, variants: answerNew },
|
content: { ...question.content, variants: answerNew },
|
||||||
@ -89,12 +89,22 @@ export default function AnswerOptions({ totalIndex }: Props) {
|
|||||||
>
|
>
|
||||||
или нажмите Enter
|
или нажмите Enter
|
||||||
</Typography>
|
</Typography>
|
||||||
<EnterIcon style={{ color: "#7E2AEA", fontSize: "24px", marginLeft: "6px" }} />
|
<EnterIcon
|
||||||
|
style={{
|
||||||
|
color: "#7E2AEA",
|
||||||
|
fontSize: "24px",
|
||||||
|
marginLeft: "6px",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
<ButtonsOptionsAndPict switchState={switchState} SSHC={SSHC} totalIndex={totalIndex} />
|
<ButtonsOptionsAndPict
|
||||||
|
switchState={switchState}
|
||||||
|
SSHC={SSHC}
|
||||||
|
totalIndex={totalIndex}
|
||||||
|
/>
|
||||||
<SwitchAnswerOptions switchState={switchState} totalIndex={totalIndex} />
|
<SwitchAnswerOptions switchState={switchState} totalIndex={totalIndex} />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -126,7 +126,7 @@ export const quizStore = create<QuizStore>()(
|
|||||||
"logo": "hub.pena.digital/img/logo",
|
"logo": "hub.pena.digital/img/logo",
|
||||||
"startpage": {
|
"startpage": {
|
||||||
"description": "",// приветственный текст опроса
|
"description": "",// приветственный текст опроса
|
||||||
"button": "Начать", // текст на кнопке начала опроса
|
"button": "", // текст на кнопке начала опроса
|
||||||
"position": "ltr", // ltr или rtl. отображение элементов поверх фона
|
"position": "ltr", // ltr или rtl. отображение элементов поверх фона
|
||||||
"background": {
|
"background": {
|
||||||
"type": "image", //image или video
|
"type": "image", //image или video
|
||||||
@ -137,11 +137,11 @@ export const quizStore = create<QuizStore>()(
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"info": {
|
"info": {
|
||||||
"phonenumber": "+79885895677",
|
"phonenumber": "",
|
||||||
"clickable": true,
|
"clickable": true,
|
||||||
"orgname": "ООО \"Пена\"",
|
"orgname": "",
|
||||||
"site": "hub.pena.digital",
|
"site": "",
|
||||||
"law": "юридическая информация"
|
"law": ""
|
||||||
},
|
},
|
||||||
"meta": "что-то"
|
"meta": "что-то"
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,130 +1,132 @@
|
|||||||
import { PointsIcon } from "@icons/questionsPage/PointsIcon";
|
|
||||||
import { Box, IconButton } from "@mui/material";
|
import { Box, IconButton } from "@mui/material";
|
||||||
import { toggleQuizPreview, useQuizPreviewStore } from "@root/quizPreview";
|
import { toggleQuizPreview, useQuizPreviewStore } from "@root/quizPreview";
|
||||||
import { useLayoutEffect, useRef } from "react";
|
import { useLayoutEffect, useRef } from "react";
|
||||||
import { Rnd } from "react-rnd";
|
import { Rnd } from "react-rnd";
|
||||||
import QuizPreviewLayout from "./QuizPreviewLayout";
|
import QuizPreviewLayout from "./QuizPreviewLayout";
|
||||||
import ResizeIcon from "./ResizeIcon";
|
import ResizeIcon from "./ResizeIcon";
|
||||||
import VisibilityIcon from '@mui/icons-material/Visibility';
|
import VisibilityIcon from "@mui/icons-material/Visibility";
|
||||||
|
|
||||||
|
const DRAG_PARENT_MARGIN = 0;
|
||||||
const DRAG_PARENT_MARGIN = 25;
|
const NAVBAR_HEIGHT = 0;
|
||||||
const NAVBAR_HEIGHT = 81;
|
const DRAG_PARENT_BOTTOM_MARGIN = 0;
|
||||||
const DRAG_PARENT_BOTTOM_MARGIN = 65;
|
|
||||||
|
|
||||||
interface RndPositionAndSize {
|
interface RndPositionAndSize {
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
width: string;
|
width: string;
|
||||||
height: string;
|
height: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function QuizPreview() {
|
export default function QuizPreview() {
|
||||||
const isPreviewShown = useQuizPreviewStore(state => state.isPreviewShown);
|
const isPreviewShown = useQuizPreviewStore((state) => state.isPreviewShown);
|
||||||
const rndParentRef = useRef<HTMLDivElement>(null);
|
const rndParentRef = useRef<HTMLDivElement>(null);
|
||||||
const rndRef = useRef<Rnd | null>(null);
|
const rndRef = useRef<Rnd | null>(null);
|
||||||
const rndPositionAndSizeRef = useRef<RndPositionAndSize>({ x: 0, y: 0, width: "340", height: "480" });
|
const rndPositionAndSizeRef = useRef<RndPositionAndSize>({
|
||||||
const isFirstShowRef = useRef<boolean>(true);
|
x: 0,
|
||||||
|
y: 0,
|
||||||
|
width: "340",
|
||||||
|
height: "480",
|
||||||
|
});
|
||||||
|
const isFirstShowRef = useRef<boolean>(true);
|
||||||
|
|
||||||
useLayoutEffect(function stickPreviewToBottomRight() {
|
useLayoutEffect(
|
||||||
const rnd = rndRef.current;
|
function stickPreviewToBottomRight() {
|
||||||
const rndSelfElement = rnd?.getSelfElement();
|
const rnd = rndRef.current;
|
||||||
if (!rnd || !rndSelfElement || !rndParentRef.current || !isFirstShowRef.current) return;
|
const rndSelfElement = rnd?.getSelfElement();
|
||||||
|
if (
|
||||||
|
!rnd ||
|
||||||
|
!rndSelfElement ||
|
||||||
|
!rndParentRef.current ||
|
||||||
|
!isFirstShowRef.current
|
||||||
|
)
|
||||||
|
return;
|
||||||
|
|
||||||
const rndParentRect = rndParentRef.current.getBoundingClientRect();
|
const rndParentRect = rndParentRef.current.getBoundingClientRect();
|
||||||
const rndRect = rndSelfElement.getBoundingClientRect();
|
const rndRect = rndSelfElement.getBoundingClientRect();
|
||||||
|
|
||||||
const x = rndParentRect.width - rndRect.width;
|
const x = rndParentRect.width - rndRect.width;
|
||||||
const y = rndParentRect.height - rndRect.height;
|
const y = rndParentRect.height - rndRect.height;
|
||||||
|
|
||||||
rnd.updatePosition({ x, y });
|
rnd.updatePosition({ x, y });
|
||||||
rndPositionAndSizeRef.current.x = x;
|
rndPositionAndSizeRef.current.x = x;
|
||||||
rndPositionAndSizeRef.current.y = y;
|
rndPositionAndSizeRef.current.y = y;
|
||||||
|
|
||||||
isFirstShowRef.current = false;
|
isFirstShowRef.current = false;
|
||||||
}, [isPreviewShown]);
|
},
|
||||||
|
[isPreviewShown]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
ref={rndParentRef}
|
ref={rndParentRef}
|
||||||
sx={{
|
sx={{
|
||||||
position: "fixed",
|
position: "fixed",
|
||||||
top: NAVBAR_HEIGHT + DRAG_PARENT_MARGIN,
|
top: NAVBAR_HEIGHT + DRAG_PARENT_MARGIN,
|
||||||
left: DRAG_PARENT_MARGIN,
|
left: DRAG_PARENT_MARGIN,
|
||||||
bottom: DRAG_PARENT_BOTTOM_MARGIN,
|
bottom: DRAG_PARENT_BOTTOM_MARGIN,
|
||||||
right: DRAG_PARENT_MARGIN,
|
right: DRAG_PARENT_MARGIN,
|
||||||
// backgroundColor: "rgba(0, 100, 0, 0.2)",
|
// backgroundColor: "rgba(0, 100, 0, 0.2)",
|
||||||
pointerEvents: "none",
|
pointerEvents: "none",
|
||||||
zIndex: 100,
|
zIndex: 100,
|
||||||
}}
|
}}
|
||||||
|
>
|
||||||
|
{isPreviewShown && (
|
||||||
|
<Rnd
|
||||||
|
minHeight={20}
|
||||||
|
minWidth={20}
|
||||||
|
bounds="parent"
|
||||||
|
ref={rndRef}
|
||||||
|
dragHandleClassName="quiz-preview-draghandle"
|
||||||
|
default={{
|
||||||
|
x: rndPositionAndSizeRef.current.x,
|
||||||
|
y: rndPositionAndSizeRef.current.y,
|
||||||
|
width: rndPositionAndSizeRef.current.width,
|
||||||
|
height: rndPositionAndSizeRef.current.height,
|
||||||
|
}}
|
||||||
|
onResizeStop={(e, direction, ref, delta, position) => {
|
||||||
|
rndPositionAndSizeRef.current.x = position.x;
|
||||||
|
rndPositionAndSizeRef.current.y = position.y;
|
||||||
|
rndPositionAndSizeRef.current.width = ref.style.width;
|
||||||
|
rndPositionAndSizeRef.current.height = ref.style.height;
|
||||||
|
}}
|
||||||
|
onDragStop={(e, d) => {
|
||||||
|
rndPositionAndSizeRef.current.x = d.x;
|
||||||
|
rndPositionAndSizeRef.current.y = d.y;
|
||||||
|
}}
|
||||||
|
onDragStart={(e, d) => {
|
||||||
|
e.preventDefault();
|
||||||
|
}}
|
||||||
|
enableResizing={{
|
||||||
|
topLeft: isPreviewShown,
|
||||||
|
}}
|
||||||
|
resizeHandleComponent={{
|
||||||
|
topLeft: <ResizeIcon />,
|
||||||
|
}}
|
||||||
|
resizeHandleStyles={{
|
||||||
|
topLeft: {
|
||||||
|
top: "-1px",
|
||||||
|
left: "-1px",
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
style={{
|
||||||
|
overflow: "hidden",
|
||||||
|
pointerEvents: "auto",
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
{isPreviewShown &&
|
<QuizPreviewLayout />
|
||||||
<Rnd
|
</Rnd>
|
||||||
minHeight={300}
|
)}
|
||||||
minWidth={340}
|
<IconButton
|
||||||
bounds="parent"
|
onClick={toggleQuizPreview}
|
||||||
ref={rndRef}
|
sx={{
|
||||||
dragHandleClassName="quiz-preview-draghandle"
|
position: "absolute",
|
||||||
default={{
|
right: 0,
|
||||||
x: rndPositionAndSizeRef.current.x,
|
bottom: -54,
|
||||||
y: rndPositionAndSizeRef.current.y,
|
pointerEvents: "auto",
|
||||||
width: rndPositionAndSizeRef.current.width,
|
}}
|
||||||
height: rndPositionAndSizeRef.current.height
|
>
|
||||||
}}
|
<VisibilityIcon sx={{ height: "30px", width: "30px" }} />
|
||||||
onResizeStop={(e, direction, ref, delta, position) => {
|
</IconButton>
|
||||||
rndPositionAndSizeRef.current.x = position.x;
|
</Box>
|
||||||
rndPositionAndSizeRef.current.y = position.y;
|
);
|
||||||
rndPositionAndSizeRef.current.width = ref.style.width;
|
|
||||||
rndPositionAndSizeRef.current.height = ref.style.height;
|
|
||||||
}}
|
|
||||||
onDragStop={(e, d) => {
|
|
||||||
rndPositionAndSizeRef.current.x = d.x;
|
|
||||||
rndPositionAndSizeRef.current.y = d.y;
|
|
||||||
}}
|
|
||||||
onDragStart={(e, d) => {
|
|
||||||
e.preventDefault();
|
|
||||||
}}
|
|
||||||
enableResizing={{
|
|
||||||
topLeft: isPreviewShown,
|
|
||||||
}}
|
|
||||||
resizeHandleComponent={{
|
|
||||||
topLeft: <ResizeIcon />
|
|
||||||
}}
|
|
||||||
resizeHandleStyles={{
|
|
||||||
topLeft: {
|
|
||||||
top: "-1px",
|
|
||||||
left: "-1px",
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
style={{
|
|
||||||
pointerEvents: "auto",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<QuizPreviewLayout />
|
|
||||||
<IconButton
|
|
||||||
className="quiz-preview-draghandle"
|
|
||||||
sx={{
|
|
||||||
position: "absolute",
|
|
||||||
bottom: -54,
|
|
||||||
right: 46,
|
|
||||||
cursor: "move",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<PointsIcon style={{ color: "#4D4D4D", fontSize: "30px" }} />
|
|
||||||
</IconButton>
|
|
||||||
</Rnd>
|
|
||||||
}
|
|
||||||
<IconButton
|
|
||||||
onClick={toggleQuizPreview}
|
|
||||||
sx={{
|
|
||||||
position: "absolute",
|
|
||||||
right: 0,
|
|
||||||
bottom: -54,
|
|
||||||
pointerEvents: "auto",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<VisibilityIcon sx={{ height: "30px", width: "30px" }} />
|
|
||||||
</IconButton>
|
|
||||||
</Box>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
import { Box, Button, LinearProgress, Paper, Typography } from "@mui/material";
|
import { Box, Button, LinearProgress, Paper, Typography } from "@mui/material";
|
||||||
import { questionStore } from "@root/questions";
|
import { questionStore } from "@root/questions";
|
||||||
import { decrementCurrentQuestionIndex, incrementCurrentQuestionIndex, useQuizPreviewStore } from "@root/quizPreview";
|
import {
|
||||||
|
decrementCurrentQuestionIndex,
|
||||||
|
incrementCurrentQuestionIndex,
|
||||||
|
useQuizPreviewStore,
|
||||||
|
} from "@root/quizPreview";
|
||||||
import { DefiniteQuestionType } from "model/questionTypes/shared";
|
import { DefiniteQuestionType } from "model/questionTypes/shared";
|
||||||
import { FC, useEffect } from "react";
|
import { FC, useEffect } from "react";
|
||||||
import { useParams } from "react-router-dom";
|
import { useParams } from "react-router-dom";
|
||||||
@ -17,117 +21,143 @@ import Text from "./QuizPreviewQuestionTypes/Text";
|
|||||||
import Variant from "./QuizPreviewQuestionTypes/Variant";
|
import Variant from "./QuizPreviewQuestionTypes/Variant";
|
||||||
import Varimg from "./QuizPreviewQuestionTypes/Varimg";
|
import Varimg from "./QuizPreviewQuestionTypes/Varimg";
|
||||||
|
|
||||||
|
|
||||||
const QuestionPreviewComponentByType: Record<DefiniteQuestionType, FC<any>> = {
|
const QuestionPreviewComponentByType: Record<DefiniteQuestionType, FC<any>> = {
|
||||||
variant: Variant,
|
variant: Variant,
|
||||||
images: Images,
|
images: Images,
|
||||||
varimg: Varimg,
|
varimg: Varimg,
|
||||||
emoji: Emoji,
|
emoji: Emoji,
|
||||||
text: Text,
|
text: Text,
|
||||||
select: Select,
|
select: Select,
|
||||||
date: Date,
|
date: Date,
|
||||||
number: Number,
|
number: Number,
|
||||||
file: File,
|
file: File,
|
||||||
page: Page,
|
page: Page,
|
||||||
rating: Rating,
|
rating: Rating,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function QuizPreviewLayout() {
|
export default function QuizPreviewLayout() {
|
||||||
const quizId = useParams().quizId ?? 0;
|
const quizId = useParams().quizId ?? 0;
|
||||||
const listQuestions = questionStore(state => state.listQuestions);
|
const listQuestions = questionStore((state) => state.listQuestions);
|
||||||
const currentQuizStep = useQuizPreviewStore(state => state.currentQuestionIndex);
|
const currentQuizStep = useQuizPreviewStore(
|
||||||
|
(state) => state.currentQuestionIndex
|
||||||
|
);
|
||||||
|
|
||||||
const quizQuestions = listQuestions[quizId] ?? [];
|
const quizQuestions = listQuestions[quizId] ?? [];
|
||||||
const nonDeletedQuizQuestions = quizQuestions.filter(question => !question.deleted);
|
const nonDeletedQuizQuestions = quizQuestions.filter(
|
||||||
const maxCurrentQuizStep = nonDeletedQuizQuestions.length > 0 ? nonDeletedQuizQuestions.length - 1 : 0;
|
(question) => !question.deleted
|
||||||
const currentProgress = Math.floor((currentQuizStep / maxCurrentQuizStep) * 100);
|
);
|
||||||
|
const maxCurrentQuizStep =
|
||||||
|
nonDeletedQuizQuestions.length > 0 ? nonDeletedQuizQuestions.length - 1 : 0;
|
||||||
|
const currentProgress = Math.floor(
|
||||||
|
(currentQuizStep / maxCurrentQuizStep) * 100
|
||||||
|
);
|
||||||
|
|
||||||
const currentQuestion = nonDeletedQuizQuestions[currentQuizStep];
|
const currentQuestion = nonDeletedQuizQuestions[currentQuizStep];
|
||||||
const QuestionComponent = currentQuestion
|
const QuestionComponent = currentQuestion
|
||||||
? QuestionPreviewComponentByType[currentQuestion.type as DefiniteQuestionType]
|
? QuestionPreviewComponentByType[
|
||||||
: null;
|
currentQuestion.type as DefiniteQuestionType
|
||||||
|
]
|
||||||
|
: null;
|
||||||
|
|
||||||
const questionElement = QuestionComponent
|
const questionElement = QuestionComponent ? (
|
||||||
? <QuestionComponent key={currentQuestion.id} question={currentQuestion} />
|
<QuestionComponent key={currentQuestion.id} question={currentQuestion} />
|
||||||
: null;
|
) : null;
|
||||||
|
|
||||||
useEffect(function resetCurrentQuizStep() {
|
useEffect(
|
||||||
if (currentQuizStep > maxCurrentQuizStep) {
|
function resetCurrentQuizStep() {
|
||||||
decrementCurrentQuestionIndex();
|
if (currentQuizStep > maxCurrentQuizStep) {
|
||||||
}
|
decrementCurrentQuestionIndex();
|
||||||
}, [currentQuizStep, maxCurrentQuizStep]);
|
}
|
||||||
|
},
|
||||||
|
[currentQuizStep, maxCurrentQuizStep]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Paper sx={{
|
<Paper
|
||||||
height: "100%",
|
className="quiz-preview-draghandle"
|
||||||
|
sx={{
|
||||||
|
height: "100%",
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "column",
|
||||||
|
flexGrow: 1,
|
||||||
|
borderRadius: "12px",
|
||||||
|
pointerEvents: "auto",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
p: "16px",
|
||||||
|
whiteSpace: "break-spaces",
|
||||||
|
overflowY: "auto",
|
||||||
|
flexGrow: 1,
|
||||||
|
"&::-webkit-scrollbar": { width: 0 },
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{questionElement}
|
||||||
|
</Box>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
mt: "auto",
|
||||||
|
p: "16px",
|
||||||
|
display: "flex",
|
||||||
|
borderTop: "1px solid #E3E3E3",
|
||||||
|
alignItems: "center",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
flexGrow: 1,
|
||||||
display: "flex",
|
display: "flex",
|
||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
flexGrow: 1,
|
gap: 1,
|
||||||
borderRadius: "12px",
|
}}
|
||||||
pointerEvents: "auto",
|
>
|
||||||
}}>
|
<Typography>
|
||||||
<Box sx={{
|
{nonDeletedQuizQuestions.length > 0
|
||||||
p: "16px",
|
? `Вопрос ${currentQuizStep + 1} из ${
|
||||||
whiteSpace: "break-spaces",
|
nonDeletedQuizQuestions.length
|
||||||
overflowY: "auto",
|
}`
|
||||||
flexGrow: 1,
|
: "Нет вопросов"}
|
||||||
}}>
|
</Typography>
|
||||||
{questionElement}
|
{nonDeletedQuizQuestions.length > 0 && (
|
||||||
</Box>
|
<LinearProgress
|
||||||
<Box sx={{
|
variant="determinate"
|
||||||
mt: "auto",
|
value={currentProgress}
|
||||||
p: "16px",
|
sx={{
|
||||||
display: "flex",
|
"&.MuiLinearProgress-colorPrimary": {
|
||||||
borderTop: "1px solid #E3E3E3",
|
backgroundColor: "fadePurple.main",
|
||||||
alignItems: "center",
|
},
|
||||||
}}>
|
"& .MuiLinearProgress-barColorPrimary": {
|
||||||
<Box sx={{
|
backgroundColor: "brightPurple.main",
|
||||||
flexGrow: 1,
|
},
|
||||||
display: "flex",
|
}}
|
||||||
flexDirection: "column",
|
/>
|
||||||
gap: 1,
|
)}
|
||||||
}}>
|
</Box>
|
||||||
<Typography>
|
<Box
|
||||||
{nonDeletedQuizQuestions.length > 0
|
sx={{
|
||||||
? `Вопрос ${currentQuizStep + 1} из ${nonDeletedQuizQuestions.length}`
|
ml: 2,
|
||||||
: "Нет вопросов"
|
display: "flex",
|
||||||
}
|
gap: 1,
|
||||||
</Typography>
|
}}
|
||||||
{nonDeletedQuizQuestions.length > 0 &&
|
>
|
||||||
<LinearProgress
|
<Button
|
||||||
variant="determinate"
|
variant="outlined"
|
||||||
value={currentProgress}
|
onClick={decrementCurrentQuestionIndex}
|
||||||
sx={{
|
disabled={currentQuizStep === 0}
|
||||||
"&.MuiLinearProgress-colorPrimary": {
|
sx={{ px: 1, minWidth: 0 }}
|
||||||
backgroundColor: "fadePurple.main",
|
>
|
||||||
},
|
<ArrowLeft />
|
||||||
"& .MuiLinearProgress-barColorPrimary": {
|
</Button>
|
||||||
backgroundColor: "brightPurple.main",
|
<Button
|
||||||
},
|
variant="contained"
|
||||||
}}
|
onClick={() => incrementCurrentQuestionIndex(maxCurrentQuizStep)}
|
||||||
/>
|
disabled={currentQuizStep >= maxCurrentQuizStep}
|
||||||
}
|
>
|
||||||
</Box>
|
Далее
|
||||||
<Box sx={{
|
</Button>
|
||||||
ml: 2,
|
</Box>
|
||||||
display: "flex",
|
</Box>
|
||||||
gap: 1,
|
</Paper>
|
||||||
}}>
|
);
|
||||||
<Button
|
|
||||||
variant="outlined"
|
|
||||||
onClick={decrementCurrentQuestionIndex}
|
|
||||||
disabled={currentQuizStep === 0}
|
|
||||||
sx={{ px: 1, minWidth: 0 }}
|
|
||||||
>
|
|
||||||
<ArrowLeft />
|
|
||||||
</Button>
|
|
||||||
<Button
|
|
||||||
variant="contained"
|
|
||||||
onClick={() => incrementCurrentQuestionIndex(maxCurrentQuizStep)}
|
|
||||||
disabled={currentQuizStep >= maxCurrentQuizStep}
|
|
||||||
>Далее</Button>
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
</Paper>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,39 +1,54 @@
|
|||||||
import InfoIcon from "@icons/InfoIcon";
|
import InfoIcon from "@icons/InfoIcon";
|
||||||
import { Box, FormControl, FormControlLabel, FormLabel, Radio, RadioGroup, Tooltip, Typography } from "@mui/material";
|
import {
|
||||||
|
Box,
|
||||||
|
FormControl,
|
||||||
|
FormControlLabel,
|
||||||
|
FormLabel,
|
||||||
|
Radio,
|
||||||
|
RadioGroup,
|
||||||
|
Tooltip,
|
||||||
|
Typography,
|
||||||
|
} from "@mui/material";
|
||||||
import { QuizQuestionEmoji } from "model/questionTypes/emoji";
|
import { QuizQuestionEmoji } from "model/questionTypes/emoji";
|
||||||
import { useState, ChangeEvent } from "react";
|
import { useState, ChangeEvent } from "react";
|
||||||
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
question: QuizQuestionEmoji;
|
question: QuizQuestionEmoji;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Emoji({ question }: Props) {
|
export default function Emoji({ question }: Props) {
|
||||||
const [value, setValue] = useState<string | null>(null);
|
const [value, setValue] = useState<string | null>(null);
|
||||||
|
|
||||||
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
|
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
|
||||||
setValue((event.target as HTMLInputElement).value);
|
setValue((event.target as HTMLInputElement).value);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormControl fullWidth>
|
<FormControl fullWidth>
|
||||||
<FormLabel id="quiz-question-radio-group">{question.title}</FormLabel>
|
<FormLabel id="quiz-question-radio-group">{question.title}</FormLabel>
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
aria-labelledby="quiz-question-radio-group"
|
aria-labelledby="quiz-question-radio-group"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
>
|
>
|
||||||
{question.content.variants.map((variant, index) => (
|
{question.content.variants.map((variant, index) => (
|
||||||
<FormControlLabel key={index} value={variant.answer} control={<Radio />} label={
|
<FormControlLabel
|
||||||
<Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
|
key={index}
|
||||||
<Typography>{`${variant.extendedText} ${variant.answer}`}</Typography>
|
value={variant.answer}
|
||||||
<Tooltip title={variant.hints} placement="right">
|
control={<Radio />}
|
||||||
<Box><InfoIcon /></Box>
|
label={
|
||||||
</Tooltip>
|
<Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
|
||||||
</Box>
|
<Typography>{`${variant.extendedText} ${variant.answer}`}</Typography>
|
||||||
} />
|
<Tooltip title="Подсказка" placement="right">
|
||||||
))}
|
<Box>
|
||||||
</RadioGroup>
|
<InfoIcon />
|
||||||
</FormControl>
|
</Box>
|
||||||
);
|
</Tooltip>
|
||||||
|
</Box>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</RadioGroup>
|
||||||
|
</FormControl>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,90 +1,107 @@
|
|||||||
import InfoIcon from "@icons/InfoIcon";
|
import InfoIcon from "@icons/InfoIcon";
|
||||||
import { Box, ButtonBase, Divider, Tooltip, Typography, useTheme } from "@mui/material";
|
import {
|
||||||
|
Box,
|
||||||
|
ButtonBase,
|
||||||
|
Divider,
|
||||||
|
Tooltip,
|
||||||
|
Typography,
|
||||||
|
useTheme,
|
||||||
|
} from "@mui/material";
|
||||||
import { QuizQuestionImages } from "model/questionTypes/images";
|
import { QuizQuestionImages } from "model/questionTypes/images";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
question: QuizQuestionImages;
|
question: QuizQuestionImages;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Images({ question }: Props) {
|
export default function Images({ question }: Props) {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const [selectedVariants, setSelectedVariants] = useState<number[]>([]);
|
const [selectedVariants, setSelectedVariants] = useState<number[]>([]);
|
||||||
|
|
||||||
function handleVariantClick(index: number) {
|
function handleVariantClick(index: number) {
|
||||||
if (!question.content.multi) return setSelectedVariants([index]);
|
if (!question.content.multi) return setSelectedVariants([index]);
|
||||||
|
|
||||||
const newSelectedVariants = [...selectedVariants];
|
const newSelectedVariants = [...selectedVariants];
|
||||||
if (newSelectedVariants.includes(index)) {
|
if (newSelectedVariants.includes(index)) {
|
||||||
newSelectedVariants.splice(newSelectedVariants.indexOf(index), 1);
|
newSelectedVariants.splice(newSelectedVariants.indexOf(index), 1);
|
||||||
} else {
|
} else {
|
||||||
newSelectedVariants.push(index);
|
newSelectedVariants.push(index);
|
||||||
}
|
|
||||||
setSelectedVariants(newSelectedVariants);
|
|
||||||
}
|
}
|
||||||
|
setSelectedVariants(newSelectedVariants);
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(function resetSelectedVariants() {
|
useEffect(
|
||||||
setSelectedVariants([]);
|
function resetSelectedVariants() {
|
||||||
}, [question.content.multi]);
|
setSelectedVariants([]);
|
||||||
|
},
|
||||||
|
[question.content.multi]
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box sx={{
|
<Box
|
||||||
display: "flex",
|
sx={{
|
||||||
flexDirection: "column",
|
display: "flex",
|
||||||
gap: 1,
|
flexDirection: "column",
|
||||||
}}>
|
gap: 1,
|
||||||
<Typography variant="h6">{question.title}</Typography>
|
}}
|
||||||
<Box sx={{
|
>
|
||||||
display: "grid",
|
<Typography variant="h6">{question.title}</Typography>
|
||||||
gridTemplateColumns: "repeat(auto-fit, minmax(160px, 1fr))",
|
<Box
|
||||||
gap: 1,
|
sx={{
|
||||||
}}>
|
display: "grid",
|
||||||
{question.content.variants.map((variant, index) => (
|
gridTemplateColumns: "repeat(auto-fit, minmax(160px, 1fr))",
|
||||||
<ButtonBase
|
gap: 1,
|
||||||
key={index}
|
}}
|
||||||
onClick={() => handleVariantClick(index)}
|
>
|
||||||
sx={{
|
{question.content.variants.map((variant, index) => (
|
||||||
display: "flex",
|
<ButtonBase
|
||||||
flexDirection: "column",
|
key={index}
|
||||||
borderRadius: "8px",
|
onClick={() => handleVariantClick(index)}
|
||||||
overflow: "hidden",
|
sx={{
|
||||||
border: "1px solid",
|
display: "flex",
|
||||||
borderColor: selectedVariants.includes(index) ? theme.palette.brightPurple.main : "#E3E3E3",
|
flexDirection: "column",
|
||||||
}}
|
borderRadius: "8px",
|
||||||
>
|
overflow: "hidden",
|
||||||
{variant.extendedText ?
|
border: "1px solid",
|
||||||
<img
|
borderColor: selectedVariants.includes(index)
|
||||||
src={variant.extendedText}
|
? theme.palette.brightPurple.main
|
||||||
alt="question variant"
|
: "#E3E3E3",
|
||||||
style={{
|
}}
|
||||||
width: "100%",
|
>
|
||||||
display: "block",
|
{variant.extendedText ? (
|
||||||
objectFit: "scale-down",
|
<img
|
||||||
flexGrow: 1,
|
src={variant.extendedText}
|
||||||
}}
|
alt="question variant"
|
||||||
/>
|
style={{
|
||||||
:
|
width: "100%",
|
||||||
<Typography p={2}>Картинка отсутствует</Typography>
|
display: "block",
|
||||||
}
|
objectFit: "scale-down",
|
||||||
<Divider sx={{ width: "100%" }} />
|
flexGrow: 1,
|
||||||
<Box sx={{
|
}}
|
||||||
display: "flex",
|
/>
|
||||||
alignItems: "center",
|
) : (
|
||||||
justifyContent: "space-between",
|
<Typography p={2}>Картинка отсутствует</Typography>
|
||||||
gap: 2,
|
)}
|
||||||
p: 1,
|
<Divider sx={{ width: "100%" }} />
|
||||||
}}>
|
<Box
|
||||||
<Typography>{variant.answer}</Typography>
|
sx={{
|
||||||
<Tooltip title={variant.hints} placement="right">
|
display: "flex",
|
||||||
<Box>
|
alignItems: "center",
|
||||||
<InfoIcon />
|
justifyContent: "space-between",
|
||||||
</Box>
|
gap: 2,
|
||||||
</Tooltip>
|
p: 1,
|
||||||
</Box>
|
}}
|
||||||
</ButtonBase>
|
>
|
||||||
))}
|
<Typography>{variant.answer}</Typography>
|
||||||
|
<Tooltip title="Подсказка" placement="right">
|
||||||
|
<Box>
|
||||||
|
<InfoIcon />
|
||||||
|
</Box>
|
||||||
|
</Tooltip>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</ButtonBase>
|
||||||
);
|
))}
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,41 +1,54 @@
|
|||||||
import InfoIcon from "@icons/InfoIcon";
|
import InfoIcon from "@icons/InfoIcon";
|
||||||
import { Box, FormControl, FormControlLabel, FormLabel, Radio, RadioGroup, Tooltip, Typography } from "@mui/material";
|
import {
|
||||||
|
Box,
|
||||||
|
FormControl,
|
||||||
|
FormControlLabel,
|
||||||
|
FormLabel,
|
||||||
|
Radio,
|
||||||
|
RadioGroup,
|
||||||
|
Tooltip,
|
||||||
|
Typography,
|
||||||
|
} from "@mui/material";
|
||||||
import { QuizQuestionVariant } from "model/questionTypes/variant";
|
import { QuizQuestionVariant } from "model/questionTypes/variant";
|
||||||
import { ChangeEvent, useState } from "react";
|
import { ChangeEvent, useState } from "react";
|
||||||
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
question: QuizQuestionVariant;
|
question: QuizQuestionVariant;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Variant({ question }: Props) {
|
export default function Variant({ question }: Props) {
|
||||||
const [value, setValue] = useState<string | null>(null);
|
const [value, setValue] = useState<string | null>(null);
|
||||||
|
|
||||||
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
|
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
|
||||||
setValue((event.target as HTMLInputElement).value);
|
setValue((event.target as HTMLInputElement).value);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FormControl fullWidth>
|
<FormControl fullWidth>
|
||||||
<FormLabel id="quiz-question-radio-group">{question.title}</FormLabel>
|
<FormLabel id="quiz-question-radio-group">{question.title}</FormLabel>
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
aria-labelledby="quiz-question-radio-group"
|
aria-labelledby="quiz-question-radio-group"
|
||||||
value={value}
|
value={value}
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
>
|
>
|
||||||
{question.content.variants.map((variant, index) => (
|
{question.content.variants.map((variant, index) => (
|
||||||
<FormControlLabel key={index} value={variant.answer} control={<Radio />} label={
|
<FormControlLabel
|
||||||
<Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
|
key={index}
|
||||||
<Typography>{variant.answer}</Typography>
|
value={variant.answer}
|
||||||
<Tooltip title={variant.hints} placement="right">
|
control={<Radio />}
|
||||||
<Box>
|
label={
|
||||||
<InfoIcon />
|
<Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
|
||||||
</Box>
|
<Typography>{variant.answer}</Typography>
|
||||||
</Tooltip>
|
<Tooltip title="Подсказка" placement="right">
|
||||||
</Box>
|
<Box>
|
||||||
} />
|
<InfoIcon />
|
||||||
))}
|
</Box>
|
||||||
</RadioGroup>
|
</Tooltip>
|
||||||
</FormControl>
|
</Box>
|
||||||
);
|
}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</RadioGroup>
|
||||||
|
</FormControl>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,80 +1,99 @@
|
|||||||
import InfoIcon from "@icons/InfoIcon";
|
import InfoIcon from "@icons/InfoIcon";
|
||||||
import { Box, FormControl, FormControlLabel, FormLabel, Radio, RadioGroup, Tooltip, Typography } from "@mui/material";
|
import {
|
||||||
|
Box,
|
||||||
|
FormControl,
|
||||||
|
FormControlLabel,
|
||||||
|
FormLabel,
|
||||||
|
Radio,
|
||||||
|
RadioGroup,
|
||||||
|
Tooltip,
|
||||||
|
Typography,
|
||||||
|
} from "@mui/material";
|
||||||
import { QuestionVariant } from "model/questionTypes/shared";
|
import { QuestionVariant } from "model/questionTypes/shared";
|
||||||
import { QuizQuestionVarImg } from "model/questionTypes/varimg";
|
import { QuizQuestionVarImg } from "model/questionTypes/varimg";
|
||||||
import { useState, ChangeEvent } from "react";
|
import { useState, ChangeEvent } from "react";
|
||||||
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
question: QuizQuestionVarImg;
|
question: QuizQuestionVarImg;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function Varimg({ question }: Props) {
|
export default function Varimg({ question }: Props) {
|
||||||
const [selectedVariantIndex, setSelectedVariantIndex] = useState<number>(-1);
|
const [selectedVariantIndex, setSelectedVariantIndex] = useState<number>(-1);
|
||||||
|
|
||||||
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
|
const handleChange = (event: ChangeEvent<HTMLInputElement>) => {
|
||||||
setSelectedVariantIndex(question.content.variants.findIndex(
|
setSelectedVariantIndex(
|
||||||
variant => variant.answer === event.target.value
|
question.content.variants.findIndex(
|
||||||
));
|
(variant) => variant.answer === event.target.value
|
||||||
};
|
)
|
||||||
|
|
||||||
const currentVariant: QuestionVariant | undefined = question.content.variants[selectedVariantIndex];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Box sx={{
|
|
||||||
display: "flex",
|
|
||||||
flexWrap: "wrap",
|
|
||||||
gap: 2,
|
|
||||||
}}>
|
|
||||||
<FormControl>
|
|
||||||
<FormLabel id="quiz-question-radio-group">{question.title}</FormLabel>
|
|
||||||
<RadioGroup
|
|
||||||
aria-labelledby="quiz-question-radio-group"
|
|
||||||
value={currentVariant?.answer ?? ""}
|
|
||||||
onChange={handleChange}
|
|
||||||
>
|
|
||||||
{question.content.variants.map((variant, index) => (
|
|
||||||
<FormControlLabel
|
|
||||||
key={index}
|
|
||||||
value={variant.answer}
|
|
||||||
control={<Radio />}
|
|
||||||
label={
|
|
||||||
<Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
|
|
||||||
<Typography>{variant.answer}</Typography>
|
|
||||||
<Tooltip title={variant.hints} placement="right">
|
|
||||||
<Box>
|
|
||||||
<InfoIcon />
|
|
||||||
</Box>
|
|
||||||
</Tooltip>
|
|
||||||
</Box>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</RadioGroup>
|
|
||||||
</FormControl>
|
|
||||||
<Box sx={{
|
|
||||||
border: "1px solid #E3E3E3",
|
|
||||||
maxWidth: "400px",
|
|
||||||
display: "flex",
|
|
||||||
justifyContent: "center",
|
|
||||||
alignItems: "center",
|
|
||||||
borderRadius: "8px",
|
|
||||||
}}>
|
|
||||||
{currentVariant?.extendedText ?
|
|
||||||
<img
|
|
||||||
src={currentVariant.extendedText}
|
|
||||||
alt="question variant"
|
|
||||||
style={{
|
|
||||||
width: "100%",
|
|
||||||
display: "block",
|
|
||||||
objectFit: "scale-down",
|
|
||||||
flexGrow: 1,
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
:
|
|
||||||
<Typography p={2}>{selectedVariantIndex === -1 ? "Выберите вариант" : "Картинка отсутствует"}</Typography>
|
|
||||||
}
|
|
||||||
</Box>
|
|
||||||
</Box>
|
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const currentVariant: QuestionVariant | undefined =
|
||||||
|
question.content.variants[selectedVariantIndex];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
display: "flex",
|
||||||
|
flexWrap: "wrap",
|
||||||
|
gap: 2,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FormControl>
|
||||||
|
<FormLabel id="quiz-question-radio-group">{question.title}</FormLabel>
|
||||||
|
<RadioGroup
|
||||||
|
aria-labelledby="quiz-question-radio-group"
|
||||||
|
value={currentVariant?.answer ?? ""}
|
||||||
|
onChange={handleChange}
|
||||||
|
>
|
||||||
|
{question.content.variants.map((variant, index) => (
|
||||||
|
<FormControlLabel
|
||||||
|
key={index}
|
||||||
|
value={variant.answer}
|
||||||
|
control={<Radio />}
|
||||||
|
label={
|
||||||
|
<Box sx={{ display: "flex", alignItems: "center", gap: 2 }}>
|
||||||
|
<Typography>{variant.answer}</Typography>
|
||||||
|
<Tooltip title="Подсказка" placement="right">
|
||||||
|
<Box>
|
||||||
|
<InfoIcon />
|
||||||
|
</Box>
|
||||||
|
</Tooltip>
|
||||||
|
</Box>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</RadioGroup>
|
||||||
|
</FormControl>
|
||||||
|
<Box
|
||||||
|
sx={{
|
||||||
|
border: "1px solid #E3E3E3",
|
||||||
|
maxWidth: "400px",
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
borderRadius: "8px",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{currentVariant?.extendedText ? (
|
||||||
|
<img
|
||||||
|
src={currentVariant.extendedText}
|
||||||
|
alt="question variant"
|
||||||
|
style={{
|
||||||
|
width: "100%",
|
||||||
|
display: "block",
|
||||||
|
objectFit: "scale-down",
|
||||||
|
flexGrow: 1,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Typography p={2}>
|
||||||
|
{selectedVariantIndex === -1
|
||||||
|
? "Выберите вариант"
|
||||||
|
: "Картинка отсутствует"}
|
||||||
|
</Typography>
|
||||||
|
)}
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user