import { CrossedEyeIcon } from "@icons/CrossedEyeIcon"; import { ArrowDownIcon } from "@icons/questionsPage/ArrowDownIcon"; import { CopyIcon } from "@icons/questionsPage/CopyIcon"; import { OneIcon } from "@icons/questionsPage/OneIcon"; import { PointsIcon } from "@icons/questionsPage/PointsIcon"; import Answer from "@icons/questionsPage/answer"; import Date from "@icons/questionsPage/date"; import { DeleteIcon } from "@icons/questionsPage/deleteIcon"; import Download from "@icons/questionsPage/download"; import DropDown from "@icons/questionsPage/drop_down"; import Emoji from "@icons/questionsPage/emoji"; import { HideIcon } from "@icons/questionsPage/hideIcon"; import Input from "@icons/questionsPage/input"; import OptionsAndPict from "@icons/questionsPage/options_and_pict"; import OptionsPict from "@icons/questionsPage/options_pict"; import Page from "@icons/questionsPage/page"; import RatingIcon from "@icons/questionsPage/rating"; import Slider from "@icons/questionsPage/slider"; import ExpandLessIcon from "@mui/icons-material/ExpandLess"; import { Box, Button, Checkbox, FormControl, FormControlLabel, IconButton, InputAdornment, Modal, Paper, TextField, Typography, useMediaQuery, useTheme, } from "@mui/material"; import { copyQuestion, createUntypedQuestion, deleteQuestion, clearRuleForAll, toggleExpandQuestion, updateQuestion, updateUntypedQuestion, getQuestionByContentId, deleteQuestionWithTimeout } from "@root/questions/actions"; import { updateRootContentId } from "@root/quizes/actions"; import { useRef, useState } from "react"; import type { DraggableProvidedDragHandleProps } from "react-beautiful-dnd"; import { useDebouncedCallback } from "use-debounce"; import { ReactComponent as PlusIcon } from "../../../assets/icons/plus.svg"; import type { AnyTypedQuizQuestion, UntypedQuizQuestion } from "../../../model/questionTypes/shared"; import SwitchQuestionsPage from "../SwitchQuestionsPage"; import { ChooseAnswerModal } from "./ChooseAnswerModal"; import TypeQuestions from "../TypeQuestions"; import { QuestionType } from "@model/question/question"; import { useCurrentQuiz } from "@root/quizes/hooks"; import { useQuestionsStore } from "@root/questions/store"; interface Props { question: AnyTypedQuizQuestion | UntypedQuizQuestion; draggableProps: DraggableProvidedDragHandleProps | null | undefined; isDragging: boolean; index: number; } export default function QuestionsPageCard({ question, draggableProps, isDragging, index }: Props) { const { questions } = useQuestionsStore(); const [plusVisible, setPlusVisible] = useState(false); const [open, setOpen] = useState(false); const [openDelete, setOpenDelete] = useState(false); const theme = useTheme(); const isTablet = useMediaQuery(theme.breakpoints.down(1000)); const isMobile = useMediaQuery(theme.breakpoints.down(790)); const anchorRef = useRef(null); const quiz = useCurrentQuiz(); const setTitle = useDebouncedCallback((title) => { const updateQuestionFn = question.type === null ? updateUntypedQuestion : updateQuestion; updateQuestionFn(question.id, question => { question.title = title; }); }, 200); const deleteFn = () => { if (question.type !== null) { if (question.content.rule.parentId === "root") { //удалить из стора root и очистить rule всем вопросам updateRootContentId(quiz.id, ""); clearRuleForAll(); deleteQuestion(question.id); questions.forEach(q => { if (q.type === "result") { deleteQuestion(q.id); } }); } else if (question.content.rule.parentId.length > 0) { //удалить из стора вопрос из дерева и очистить его потомков const clearQuestions = [] as string[]; //записываем потомков , а их результаты удаляем const getChildren = (parentQuestion: AnyTypedQuizQuestion) => { questions.forEach((targetQuestion) => { if (targetQuestion.content.rule.parentId === parentQuestion.content.id) {//если у вопроса совпал родитель с родителем => он потомок, в кучу его if (targetQuestion.type === "result") { deleteQuestion(targetQuestion.id); } else { if (!clearQuestions.includes(targetQuestion.content.id)) clearQuestions.push(targetQuestion.content.id); getChildren(targetQuestion); //и ищем его потомков } } }); }; getChildren(question); //чистим потомков от инфы ветвления clearQuestions.forEach((id) => { updateQuestion(id, question => { question.content.rule.parentId = ""; question.content.rule.main = []; question.content.rule.default = ""; }); }); //чистим rule родителя const parentQuestion = getQuestionByContentId(question.content.rule.parentId); const newRule = {}; newRule.main = parentQuestion.content.rule.main.filter((data) => data.next !== question.content.id); //удаляем условия перехода от родителя к этому вопросу newRule.parentId = parentQuestion.content.rule.parentId; newRule.default = parentQuestion.content.rule.parentId === question.content.id ? "" : parentQuestion.content.rule.parentId; newRule.children = [...parentQuestion.content.rule.children].splice(parentQuestion.content.rule.children.indexOf(question.content.id), 1); updateQuestion(question.content.rule.parentId, (PQ) => { PQ.content.rule = newRule; }); deleteQuestion(question.id); } deleteQuestion(question.id); } else { console.log("удаляю безтипогово"); deleteQuestion(question.id); } }; return ( <> setTitle(target.value || " ")} InputProps={{ startAdornment: ( setOpen((isOpened) => !isOpened)} > {IconAndrom(question.expanded, question.type)} setOpen(false)} anchorRef={anchorRef} question={question} questionType={question.type} /> ), }} sx={{ margin: isMobile ? "10px 0" : 0, "& .MuiInputBase-root": { color: "#000000", backgroundColor: question.expanded ? theme.palette.background.default : "transparent", height: "48px", borderRadius: "10px", ".MuiOutlinedInput-notchedOutline": { borderWidth: "1px !important", border: !question.expanded ? "none" : null, }, "& .MuiInputBase-input::placeholder": { color: "#4D4D4D", opacity: 0.8, }, }, }} inputProps={{ sx: { fontSize: "18px", lineHeight: "21px", py: 0, paddingLeft: question.type === null ? 0 : "18px", }, "data-cy": "quiz-question-title", }} /> toggleExpandQuestion(question.id)} > {question.expanded ? ( ) : ( )} {question.expanded ? ( <> ) : ( } checkedIcon={} /> } label={""} sx={{ color: theme.palette.grey2.main, ml: "-9px", mr: 0, userSelect: "none", }} /> copyQuestion(question.id, question.quizId)} > { if(question.content.rule.parentId.length !== 0) { setOpenDelete(true) } else { deleteQuestionWithTimeout(question.id, deleteFn); } }} data-cy="delete-question" > setOpenDelete(false)}> Вы удаляете вопрос, участвующий в ветвлении. Все его потомки потеряют данные ветвления. Вы уверены, что хотите удалить вопрос? )} {question.type !== null && {question.page + 1} } {question.expanded && ( {question.type === null ? ( ) : ( )} )} setPlusVisible(true)} onMouseLeave={() => setPlusVisible(false)} sx={{ maxWidth: "825px", display: "flex", alignItems: "center", height: "40px", cursor: "pointer", }} > createUntypedQuestion(question.quizId, question.id)} sx={{ display: plusVisible && !isDragging ? "flex" : "none", width: "100%", alignItems: "center", columnGap: "10px", }} data-cy="create-question" > ); } const IconAndrom = (isExpanded: boolean, questionType: QuestionType | null) => { switch (questionType) { case "variant": return ( ); case "images": return ( ); case "varimg": return ( ); case "emoji": return ( ); case "text": return ( ); case "select": return ( ); case "date": return ( ); case "number": return ( ); case "file": return ( ); case "page": return ( ); case "rating": return ( ); default: return <>; } };