frontPanel/src/pages/Questions/BranchingModal/Settings.tsx

516 lines
19 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Box, MenuItem, FormControl, Checkbox, FormControlLabel, Radio, RadioGroup, Typography, useTheme, Select, Chip, IconButton, TextField } from "@mui/material"
import RadioCheck from "@ui_kit/RadioCheck"
import RadioIcon from "@ui_kit/RadioIcon"
import { QuizQuestionBase } from "model/questionTypes/shared"
import { useState, useRef, useEffect } from "react";
import { useParams } from "react-router-dom";
import { useQuestionsStore } from "@root/questions/store";
import { updateQuestion, getQuestionById } from "@root/questions/actions";
import { AnyQuizQuestion } from "../../../model/questionTypes/shared"
import { SelectChangeEvent } from '@mui/material/Select';
import InfoIcon from "@icons/Info";
import { DeleteIcon } from "@icons/questionsPage/deleteIcon";
const CONDITIONS = [
"Все условия обязательны",
"Обязательно хотя бы одно условие",
];
interface Props {
parentQuestion: AnyQuizQuestion;
targetQuestion: AnyQuizQuestion;
ruleIndex: number;
}
//Этот компонент вызывается 1 раз на каждое условие родителя для перехода к этому вопросу. Поэтому для изменения стора мы знаем индекс
export const TypeSwitch = ({ parentQuestion, targetQuestion, ruleIndex }: Props) => {
switch (parentQuestion.type) {
// case 'nonselected':
// return <BlockRule text={"Не выбран тип родительского вопроса"} />
// break;
case "variant":
case "images":
case "varimg":
case "emoji":
case "select":
return (parentQuestion.content.variants === undefined ? <BlockRule text={"У родителя нет вариантов"} /> :
<SelectorType targetQuestion={targetQuestion} parentQuestion={parentQuestion} ruleIndex={ruleIndex} />
//Реализован
)
break;
case "date":
// return <DateInputsType targetQuestion={targetQuestion} parentQuestion={parentQuestion} ruleIndex={ruleIndex} />
return <></>
break;
case "number":
return <NumberInputsType targetQuestion={targetQuestion} parentQuestion={parentQuestion} ruleIndex={ruleIndex} />
//Реализован
break;
case "page":
case "date":
return <BlockRule text={"У такого родителя может быть только один потомок"} />
break;
case "text":
return <TextInputsType targetQuestion={targetQuestion} parentQuestion={parentQuestion} ruleIndex={ruleIndex} />
//Реализован
break;
case "file":
return <FileInputsType targetQuestion={targetQuestion} parentQuestion={parentQuestion} ruleIndex={ruleIndex} />
//Реализован
break;
case "rating":
return <RatingInputsType targetQuestion={targetQuestion} parentQuestion={parentQuestion} ruleIndex={ruleIndex} />
//Реализован
break;
default:
return <BlockRule text={"Не распознан тип родительского вопроса"} />
break;
}
}
export const BlockRule = ({ text }: { text: string }) => {
return (
<Typography
sx={{
margin: "100px 0",
textAlign: "center"
}}
>{text}</Typography>
)
}
const SelectorType = ({ parentQuestion, targetQuestion, ruleIndex }: { parentQuestion: any, targetQuestion: any, ruleIndex: number }) => {
const theme = useTheme();
const quizId = Number(useParams().quizId);
return (
<Box
sx={{
padding: "20px",
margin: "20px",
borderRadius: "8px",
bgcolor: "#F2F3F7",
height: "280px",
overflow: "auto"
}}
>
<Box
sx={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
pb: "5px",
}}
>
<Typography sx={{ color: "#4D4D4D", fontWeight: "500" }}>
Новое условие
</Typography>
<IconButton
sx={{ borderRadius: "6px", padding: "2px" }}
onClick={() => {
const newParentQuestion = { ...parentQuestion }
newParentQuestion.content.rule.main.splice(ruleIndex, 1)
//updateQuestionsList(quizId, parentQuestion.index, parentQuestion);
}}
>
<DeleteIcon color={"#4D4D4D"} />
</IconButton>
</Box>
<Box
sx={{
display: "flex",
alignItems: "center",
pb: "10px",
}}
>
<Typography sx={{ color: "#4D4D4D", fontWeight: "500" }}>
Дан ответ
</Typography>
<Typography sx={{ color: "#7E2AEA", pl: "10px" }}>
(Укажите один или несколько вариантов)
</Typography>
</Box>
<Select
multiple
value={parentQuestion.content.rule.main[ruleIndex].rules[0].answers}
onChange={(event: SelectChangeEvent) => {
const newParentQuestion = { ...parentQuestion }
parentQuestion.content.rule.main[ruleIndex].rules[0].answers = (event.target as HTMLSelectElement).value
//updateQuestionsList(quizId, parentQuestion.index, parentQuestion);
}}
sx={{
width: "100%",
height: "48px",
borderRadius: "8px",
"& .MuiOutlinedInput-notchedOutline": {
border: `1px solid ${theme.palette.brightPurple.main} !important`,
height: "48px",
borderRadius: "10px",
},
}}
>
{parentQuestion.content.variants.map((e: any) => {
return <MenuItem value={e.id}>
{e.answer}
</MenuItem>
})}
</Select>
<FormControl>
<RadioGroup
aria-labelledby="demo-controlled-radio-buttons-group"
value={parentQuestion.content.rule.main[ruleIndex].or}
onChange={(_, value) => {
const newParentQuestion = { ...parentQuestion }
parentQuestion.content.rule.main[ruleIndex].or = value
//updateQuestionsList(quizId, parentQuestion.index, parentQuestion);
}}
>
{CONDITIONS.map((condition, totalIndex) => (
<FormControlLabel
key={totalIndex}
sx={{ color: theme.palette.grey2.main }}
value={Boolean(Number(totalIndex))}
control={
<Radio
checkedIcon={<RadioCheck />}
icon={<RadioIcon />}
/>
}
label={condition}
/>
))}
</RadioGroup>
</FormControl>
</Box >
)
}
const DateInputsType = ({ parentQuestion, targetQuestion, ruleIndex }: { parentQuestion: any, targetQuestion: any, ruleIndex: number }) => {
return <></>
}
const NumberInputsType = ({ parentQuestion, targetQuestion, ruleIndex }: { parentQuestion: any, targetQuestion: any, ruleIndex: number }) => {
const theme = useTheme();
const quizId = Number(useParams().quizId);
return (
<Box
sx={{
padding: "20px",
margin: "20px",
borderRadius: "8px",
bgcolor: "#F2F3F7",
height: "280px",
overflow: "auto"
}}
>
<Box
sx={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
pb: "5px",
}}
>
<Typography sx={{ color: "#4D4D4D", fontWeight: "500" }}>
Новое условие
</Typography>
<IconButton
sx={{ borderRadius: "6px", padding: "2px" }}
onClick={() => {
const newParentQuestion = { ...parentQuestion }
newParentQuestion.content.rule.main.splice(ruleIndex, 1)
//updateQuestionsList(quizId, parentQuestion.index, parentQuestion);
}}
>
<DeleteIcon color={"#4D4D4D"} />
</IconButton>
</Box>
<Box
sx={{
display: "flex",
alignItems: "center",
pb: "10px",
}}
>
<Typography sx={{ color: "#4D4D4D", fontWeight: "500" }}>
Дан ответ
</Typography>
<Typography sx={{ color: "#7E2AEA", pl: "10px" }}>
(Укажите один или несколько вариантов)
</Typography>
</Box>
{/* <TextField
sx={{
marginTop: "20px",
width: "100%"
}}
value={parentQuestion.content.rule.main[ruleIndex].rules[0].answers[0]}
onChange={(event: React.FormEvent<HTMLInputElement>) => {
const newParentQuestion = { ...parentQuestion }
parentQuestion.content.rule.main[ruleIndex].rules[0].answers = [(event.target as HTMLInputElement).value.replace(/[^0-9,\s]/g, "")]
//updateQuestionsList(quizId, parentQuestion.index, parentQuestion);
}}
/> */}
</Box >
)
}
const TextInputsType = ({ parentQuestion, targetQuestion, ruleIndex }: { parentQuestion: any, targetQuestion: any, ruleIndex: number }) => {
const theme = useTheme();
const quizId = Number(useParams().quizId);
return (
<Box
sx={{
padding: "20px",
margin: "20px",
borderRadius: "8px",
bgcolor: "#F2F3F7",
height: "280px",
overflow: "auto"
}}
>
<Box
sx={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
pb: "5px",
}}
>
<Typography sx={{ color: "#4D4D4D", fontWeight: "500" }}>
Новое условие
</Typography>
<IconButton
sx={{ borderRadius: "6px", padding: "2px" }}
onClick={() => {
const newParentQuestion = { ...parentQuestion }
newParentQuestion.content.rule.main.splice(ruleIndex, 1)
//updateQuestionsList(quizId, parentQuestion.index, parentQuestion);
}}
>
<DeleteIcon color={"#4D4D4D"} />
</IconButton>
</Box>
<Box
sx={{
display: "inline",
alignItems: "center",
pb: "10px",
}}
>
<Typography sx={{ color: "#4D4D4D", fontWeight: "500" }}>
Дан ответ
</Typography>
<Typography sx={{ color: "#7E2AEA", pl: "10px", fontSize: "12px" }}>
(Укажите текст, при совпадении с которым пользователь попадёт на этот вопрос)
</Typography>
</Box>
{/* <TextField
sx={{
marginTop: "20px",
width: "100%"
}}
value={parentQuestion.content.rule.main[ruleIndex].rules[0].answers[0]}
onChange={(event: React.FormEvent<HTMLInputElement>) => {
const newParentQuestion = { ...parentQuestion }
newParentQuestion.content.rule.main[ruleIndex].rules[0].answers = [(event.target as HTMLInputElement).value]
//updateQuestionsList(quizId, parentQuestion.index, parentQuestion);
}}
/> */}
</Box >
)
}
const FileInputsType = ({ parentQuestion, targetQuestion, ruleIndex }: { parentQuestion: any, targetQuestion: any, ruleIndex: number }) => {
const theme = useTheme();
const quizId = Number(useParams().quizId);
return (
<Box
sx={{
padding: "20px",
margin: "20px",
borderRadius: "8px",
bgcolor: "#F2F3F7",
height: "280px",
overflow: "auto"
}}
>
<Box
sx={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
pb: "5px",
}}
>
<Typography sx={{ color: "#4D4D4D", fontWeight: "500" }}>
Новое условие
</Typography>
<IconButton
sx={{ borderRadius: "6px", padding: "2px" }}
onClick={() => {
const newParentQuestion = { ...parentQuestion }
newParentQuestion.content.rule.main.splice(ruleIndex, 1)
//updateQuestionsList(quizId, parentQuestion.index, parentQuestion);
}}
>
<DeleteIcon color={"#4D4D4D"} />
</IconButton>
</Box>
<Box
sx={{
display: "inline",
alignItems: "center",
pb: "10px",
}}
>
<Typography sx={{ color: "#4D4D4D", fontWeight: "500" }}>
Перевести на этот вопрос если пользователь загрузил файл
</Typography>
</Box>
<FormControlLabel control={<Checkbox
sx={{
margin: 0
}}
checked={parentQuestion.content.rule.main[ruleIndex].rules[0].answers[0]}
onChange={(event: React.FormEvent<HTMLInputElement>) => {
const newParentQuestion = { ...parentQuestion }
parentQuestion.content.rule.main[ruleIndex].rules[0].answers = [(event.target as HTMLInputElement).checked]
//updateQuestionsList(quizId, parentQuestion.index, parentQuestion);
}}
/>} label="да" />
</Box >
)
}
const RatingInputsType = ({ parentQuestion, targetQuestion, ruleIndex }: { parentQuestion: any, targetQuestion: any, ruleIndex: number }) => {
const theme = useTheme();
const quizId = Number(useParams().quizId);
return (
<Box
sx={{
padding: "20px",
margin: "20px",
borderRadius: "8px",
bgcolor: "#F2F3F7",
height: "280px",
overflow: "auto"
}}
>
<Box
sx={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
pb: "5px",
}}
>
<Typography sx={{ color: "#4D4D4D", fontWeight: "500" }}>
Новое условие
</Typography>
<IconButton
sx={{ borderRadius: "6px", padding: "2px" }}
onClick={() => {
const newParentQuestion = { ...parentQuestion }
newParentQuestion.content.rule.main.splice(ruleIndex, 1)
//updateQuestionsList(quizId, parentQuestion.index, parentQuestion);
}}
>
<DeleteIcon color={"#4D4D4D"} />
</IconButton>
</Box>
<Box
sx={{
display: "inline",
alignItems: "center",
pb: "10px",
}}
>
<Typography sx={{ color: "#7E2AEA", pl: "10px", fontSize: "12px" }}>
(Ожидаемое количество ячеек)
</Typography>
</Box>
{/* <TextField
sx={{
marginTop: "20px",
width: "100%"
}}
value={parentQuestion.content.rule.main[ruleIndex].rules[0].answers[0]}
onChange={(event: React.FormEvent<HTMLInputElement>) => {
const newParentQuestion = { ...parentQuestion }
parentQuestion.content.rule.main[ruleIndex].rules[0].answers = [(event.target as HTMLInputElement).value.replace(/[^0-9,\s]/g, "")]
//updateQuestionsList(quizId, parentQuestion.index, parentQuestion);
}}
/> */}
</Box >
)
}
// {
// content: {
// rule: {
// main: [
// {
// next: "id of next question", // 2 string
// or: true // 3 boolean
// rules: [
// {
// question: "question id", string
// answers: [] // ответы на вопросы. для вариантов выбора - конкретные айдишники, для полей ввода текста - текст по полному совпадению, для ввода файла ии ещё какой подобной дичи - просто факт того что файл ввели, т.е. boolean
// }
// ]
// }
// ],
// default: ID string
// }
// }
// }