feat: questions store new logic

This commit is contained in:
IlyaDoronin 2023-09-06 16:20:12 +03:00
parent 015717cc0c
commit 4a58ef2bfc
34 changed files with 470 additions and 332 deletions

@ -6,17 +6,14 @@ import "./index.css";
import { BrowserRouter, Route, Routes } from "react-router-dom"; import { BrowserRouter, Route, Routes } from "react-router-dom";
import lightTheme from "./utils/themes/light"; import lightTheme from "./utils/themes/light";
import { ThemeProvider } from "@mui/material"; import { ThemeProvider } from "@mui/material";
import HorizontalLinearStepper from "./ui_kit/Stepper";
import StartPage from "./pages/startPage/StartPage"; import StartPage from "./pages/startPage/StartPage";
import Main from "./pages/main"; import Main from "./pages/main";
import FirstQuiz from "./pages/createQuize/FirstQuiz";
import QuestionsPage from "./pages/Questions/QuestionsPage"; import QuestionsPage from "./pages/Questions/QuestionsPage";
import ContactFormPage from "./pages/ContactFormPage/ContactFormPage"; import ContactFormPage from "./pages/ContactFormPage/ContactFormPage";
import InstallQuiz from "./pages/InstallQuiz/InstallQuiz"; import InstallQuiz from "./pages/InstallQuiz/InstallQuiz";
import { Result } from "./pages/Result/Result"; import { Result } from "./pages/Result/Result";
import { Setting } from "./pages/Result/Setting"; import { Setting } from "./pages/Result/Setting";
import MyQuizzes from "./pages/createQuize/MyQuizzes";
import MyQuizzesFull from "./pages/createQuize/MyQuizzesFull"; import MyQuizzesFull from "./pages/createQuize/MyQuizzesFull";
import ImageCrop from "@ui_kit/Modal/ImageCrop"; import ImageCrop from "@ui_kit/Modal/ImageCrop";

@ -1,4 +1,5 @@
import { useState } from "react"; import { useState } from "react";
import { useParams } from "react-router-dom";
import { Draggable } from "react-beautiful-dnd"; import { Draggable } from "react-beautiful-dnd";
import { import {
Box, Box,
@ -36,6 +37,7 @@ export const AnswerItem = ({
variant, variant,
icon, icon,
}: AnswerItemProps) => { }: AnswerItemProps) => {
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
const theme = useTheme(); const theme = useTheme();
@ -55,8 +57,11 @@ export const AnswerItem = ({
const answerNew = variants.slice(); const answerNew = variants.slice();
answerNew[index].answer = event.target.value; answerNew[index].answer = event.target.value;
updateQuestionsList(totalIndex, { updateQuestionsList(quizId, totalIndex, {
content: { ...listQuestions[totalIndex].content, variants: answerNew }, content: {
...listQuestions[quizId][totalIndex].content,
variants: answerNew,
},
}); });
}; };
@ -64,8 +69,11 @@ export const AnswerItem = ({
const answerNew = variants.slice(); const answerNew = variants.slice();
answerNew.push({ answer: "", answerLong: "", hints: "" }); answerNew.push({ answer: "", answerLong: "", hints: "" });
updateQuestionsList(totalIndex, { updateQuestionsList(quizId, totalIndex, {
content: { ...listQuestions[totalIndex].content, variants: answerNew }, content: {
...listQuestions[quizId][totalIndex].content,
variants: answerNew,
},
}); });
}; };
@ -73,8 +81,11 @@ export const AnswerItem = ({
const answerNew = variants.slice(); const answerNew = variants.slice();
answerNew.splice(index, 1); answerNew.splice(index, 1);
updateQuestionsList(totalIndex, { updateQuestionsList(quizId, totalIndex, {
content: { ...listQuestions[totalIndex].content, variants: answerNew }, content: {
...listQuestions[quizId][totalIndex].content,
variants: answerNew,
},
}); });
}; };
@ -82,8 +93,11 @@ export const AnswerItem = ({
const answerNew = variants.slice(); const answerNew = variants.slice();
answerNew[index].hints = event.target.value; answerNew[index].hints = event.target.value;
updateQuestionsList(totalIndex, { updateQuestionsList(quizId, totalIndex, {
content: { ...listQuestions[totalIndex].content, variants: answerNew }, content: {
...listQuestions[quizId][totalIndex].content,
variants: answerNew,
},
}); });
}; };

@ -1,3 +1,4 @@
import { useParams } from "react-router-dom";
import { Box } from "@mui/material"; import { Box } from "@mui/material";
import { DragDropContext, Droppable } from "react-beautiful-dnd"; import { DragDropContext, Droppable } from "react-beautiful-dnd";
@ -22,11 +23,13 @@ export const AnswerDraggableList = ({
totalIndex, totalIndex,
icon, icon,
}: AnswerDraggableListProps) => { }: AnswerDraggableListProps) => {
const quizId = Number(useParams().quizId);
const onDragEnd = ({ destination, source }: DropResult) => { const onDragEnd = ({ destination, source }: DropResult) => {
if (destination) { if (destination) {
const newItems = reorder(variants, source.index, destination.index); const newItems = reorder(variants, source.index, destination.index);
updateVariants(totalIndex, newItems); updateVariants(quizId, totalIndex, newItems);
} }
}; };

@ -17,7 +17,7 @@ interface Props {
} }
export default function ButtonsOptions({ SSHC, switchState, totalIndex }: Props) { export default function ButtonsOptions({ SSHC, switchState, totalIndex }: Props) {
const params = Number(useParams().quizId); const quizId = Number(useParams().quizId);
const {openedModalSettings} = questionStore() const {openedModalSettings} = questionStore()
const openedModal = () => { const openedModal = () => {
resetSomeField({openedModalSettings: "open"}) resetSomeField({openedModalSettings: "open"})
@ -64,7 +64,7 @@ export default function ButtonsOptions({ SSHC, switchState, totalIndex }: Props)
key={title} key={title}
onClick={() => { onClick={() => {
SSHC(value); SSHC(value);
{myFunc()} myFunc()
}} }}
sx={{ sx={{
backgroundColor: switchState === value ? theme.palette.brightPurple.main : "transparent", backgroundColor: switchState === value ? theme.palette.brightPurple.main : "transparent",
@ -87,7 +87,7 @@ export default function ButtonsOptions({ SSHC, switchState, totalIndex }: Props)
<IconButton sx={{ borderRadius: "6px", padding: "2px" }}> <IconButton sx={{ borderRadius: "6px", padding: "2px" }}>
<CopyIcon color={"#4D4D4D"}/> <CopyIcon color={"#4D4D4D"}/>
</IconButton> </IconButton>
<IconButton sx={{ borderRadius: "6px", padding: "2px" }} onClick={() => removeQuestion(totalIndex)}> <IconButton sx={{ borderRadius: "6px", padding: "2px" }} onClick={() => removeQuestion(quizId, totalIndex)}>
<DeleteIcon color={"#4D4D4D"}/> <DeleteIcon color={"#4D4D4D"}/>
</IconButton> </IconButton>
</Box> </Box>

@ -24,7 +24,7 @@ export default function ButtonsOptionsAndPict({
switchState, switchState,
totalIndex, totalIndex,
}: Props) { }: Props) {
const params = Number(useParams().quizId); const quizId = Number(useParams().quizId);
const { openedModalSettings } = questionStore(); const { openedModalSettings } = questionStore();
const theme = useTheme(); const theme = useTheme();
@ -181,7 +181,7 @@ export default function ButtonsOptionsAndPict({
</IconButton> </IconButton>
<IconButton <IconButton
sx={{ borderRadius: "6px", padding: "2px" }} sx={{ borderRadius: "6px", padding: "2px" }}
onClick={() => removeQuestion(totalIndex)} onClick={() => removeQuestion(quizId, totalIndex)}
> >
<DeleteIcon color={"#4D4D4D"} /> <DeleteIcon color={"#4D4D4D"} />
</IconButton> </IconButton>

@ -1,3 +1,4 @@
import { useParams } from "react-router-dom";
import { Box, Typography, useTheme } from "@mui/material"; import { Box, Typography, useTheme } from "@mui/material";
import ButtonsOptions from "../ButtonsOptions"; import ButtonsOptions from "../ButtonsOptions";
import SwitchData from "./switchData"; import SwitchData from "./switchData";
@ -12,6 +13,7 @@ interface Props {
export default function DataOptions({ totalIndex }: Props) { export default function DataOptions({ totalIndex }: Props) {
const [switchState, setSwitchState] = useState("setting"); const [switchState, setSwitchState] = useState("setting");
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
const theme = useTheme(); const theme = useTheme();
@ -20,10 +22,10 @@ export default function DataOptions({ totalIndex }: Props) {
}; };
useEffect(() => { useEffect(() => {
if (listQuestions[totalIndex].content.type !== "mask") { if (listQuestions[quizId][totalIndex].content.type !== "mask") {
const clonContent = listQuestions[totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.type = "calendar"; clonContent.type = "calendar";
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
} }
}, []); }, []);
@ -41,21 +43,25 @@ export default function DataOptions({ totalIndex }: Props) {
> >
<Box sx={{ gap: "10px", display: "flex" }}> <Box sx={{ gap: "10px", display: "flex" }}>
<SelectableButton <SelectableButton
isSelected={listQuestions[totalIndex].content.type === "calendar"} isSelected={
listQuestions[quizId][totalIndex].content.type === "calendar"
}
onClick={() => { onClick={() => {
const clonContent = listQuestions[totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.type = "calendar"; clonContent.type = "calendar";
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}} }}
> >
Использовать календарь Использовать календарь
</SelectableButton> </SelectableButton>
<SelectableButton <SelectableButton
isSelected={listQuestions[totalIndex].content.type === "mask"} isSelected={
listQuestions[quizId][totalIndex].content.type === "mask"
}
onClick={() => { onClick={() => {
const clonContent = listQuestions[totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.type = "mask"; clonContent.type = "mask";
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}} }}
> >
Использовать маску Использовать маску

@ -1,3 +1,4 @@
import { useParams } from "react-router-dom";
import { Box, Typography } from "@mui/material"; import { Box, Typography } from "@mui/material";
import CustomCheckbox from "@ui_kit/CustomCheckbox"; import CustomCheckbox from "@ui_kit/CustomCheckbox";
import InfoIcon from "../../../assets/icons/InfoIcon"; import InfoIcon from "../../../assets/icons/InfoIcon";
@ -8,6 +9,7 @@ type SettingsDataProps = {
}; };
export default function SettingsData({ totalIndex }: SettingsDataProps) { export default function SettingsData({ totalIndex }: SettingsDataProps) {
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
return ( return (
@ -16,20 +18,20 @@ export default function SettingsData({ totalIndex }: SettingsDataProps) {
<Typography>Настройки календаря</Typography> <Typography>Настройки календаря</Typography>
<CustomCheckbox <CustomCheckbox
label={"Выбор диапозона дат"} label={"Выбор диапозона дат"}
checked={listQuestions[totalIndex].content.dateRange} checked={listQuestions[quizId][totalIndex].content.dateRange}
handleChange={({ target }) => { handleChange={({ target }) => {
const clonContent = listQuestions[totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.dateRange = target.checked; clonContent.dateRange = target.checked;
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}} }}
/> />
<CustomCheckbox <CustomCheckbox
label={"Выбор времени"} label={"Выбор времени"}
checked={listQuestions[totalIndex].content.time} checked={listQuestions[quizId][totalIndex].content.time}
handleChange={({ target }) => { handleChange={({ target }) => {
const clonContent = listQuestions[totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.time = target.checked; clonContent.time = target.checked;
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}} }}
/> />
</Box> </Box>

@ -1,3 +1,4 @@
import { useParams } from "react-router-dom";
import { import {
Box, Box,
Checkbox, Checkbox,
@ -133,9 +134,11 @@ export default function QuestionsPageCard({
totalIndex, totalIndex,
draggableProps, draggableProps,
}: Props) { }: Props) {
const quizId = Number(useParams().quizId);
const theme = useTheme(); const theme = useTheme();
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
const { type: switchState, expanded: isExpanded } = listQuestions[totalIndex]; const { type: switchState, expanded: isExpanded } =
listQuestions[quizId][totalIndex];
return ( return (
<Paper <Paper
@ -161,11 +164,13 @@ export default function QuestionsPageCard({
<FormControl fullWidth variant="standard" sx={{ p: 0 }}> <FormControl fullWidth variant="standard" sx={{ p: 0 }}>
<TextField <TextField
fullWidth fullWidth
value={listQuestions[totalIndex].title} value={listQuestions[quizId][totalIndex].title}
placeholder={"Заголовок вопроса"} placeholder={"Заголовок вопроса"}
onChange={(e) => { onChange={(e) => {
updateQuestionsList(totalIndex, { title: e.target.value }); updateQuestionsList(quizId, totalIndex, {
console.log(listQuestions[totalIndex].title); title: e.target.value,
});
console.log(listQuestions[quizId][totalIndex].title);
}} }}
InputProps={{ InputProps={{
startAdornment: ( startAdornment: (
@ -198,7 +203,7 @@ export default function QuestionsPageCard({
<IconButton <IconButton
onClick={() => onClick={() =>
updateQuestionsList(totalIndex, { expanded: !isExpanded }) updateQuestionsList(quizId, totalIndex, { expanded: !isExpanded })
} }
> >
{isExpanded ? <ExpandMoreIcon /> : <ExpandLessIcon fill="#7E2AEA" />} {isExpanded ? <ExpandMoreIcon /> : <ExpandLessIcon fill="#7E2AEA" />}
@ -222,12 +227,12 @@ export default function QuestionsPageCard({
userSelect: "none", userSelect: "none",
}} }}
/> />
<IconButton onClick={() => copyQuestion(totalIndex)}> <IconButton onClick={() => copyQuestion(quizId, totalIndex)}>
<CopyIcon color={"white"} /> <CopyIcon color={"white"} />
</IconButton> </IconButton>
<IconButton <IconButton
sx={{ cursor: "pointer", borderRadius: "6px", padding: "2px" }} sx={{ cursor: "pointer", borderRadius: "6px", padding: "2px" }}
onClick={() => removeQuestion(totalIndex)} onClick={() => removeQuestion(quizId, totalIndex)}
> >
<DeleteIcon color={"white"} /> <DeleteIcon color={"white"} />
</IconButton> </IconButton>

@ -1,4 +1,5 @@
import { useState } from "react"; import { useState } from "react";
import { useParams } from "react-router-dom";
import { Box } from "@mui/material"; import { Box } from "@mui/material";
import { DragDropContext, Droppable } from "react-beautiful-dnd"; import { DragDropContext, Droppable } from "react-beautiful-dnd";
@ -13,6 +14,7 @@ import type { DropResult } from "react-beautiful-dnd";
export const DraggableList = () => { export const DraggableList = () => {
const [draggableId, setDraggableId] = useState<number>(-1); const [draggableId, setDraggableId] = useState<number>(-1);
const [dropPlaceIndex, setDropPlaceIndex] = useState<number>(-1); const [dropPlaceIndex, setDropPlaceIndex] = useState<number>(-1);
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
const onDrop = () => { const onDrop = () => {
@ -22,9 +24,13 @@ export const DraggableList = () => {
const onDragEnd = ({ destination, source }: DropResult) => { const onDragEnd = ({ destination, source }: DropResult) => {
if (destination) { if (destination) {
const newItems = reorder(listQuestions, source.index, destination.index); const newItems = reorder(
listQuestions[quizId],
source.index,
destination.index
);
updateQuestionsListDragAndDrop(newItems); updateQuestionsListDragAndDrop(quizId, newItems);
} }
}; };
@ -43,7 +49,7 @@ export const DraggableList = () => {
{...provided.droppableProps} {...provided.droppableProps}
onMouseUp={onDrop} onMouseUp={onDrop}
> >
{listQuestions.map((_, index) => ( {listQuestions[quizId]?.map((_, index) => (
<DraggableListItem <DraggableListItem
key={index} key={index}
index={index} index={index}

@ -1,4 +1,5 @@
import { useState } from "react"; import { useState } from "react";
import { useParams } from "react-router-dom";
import { Box, Typography, Link, useTheme } from "@mui/material"; import { Box, Typography, Link, useTheme } from "@mui/material";
import { AnswerDraggableList } from "../AnswerDraggableList"; import { AnswerDraggableList } from "../AnswerDraggableList";
@ -14,9 +15,10 @@ interface Props {
export default function DropDown({ totalIndex }: Props) { export default function DropDown({ totalIndex }: Props) {
const [switchState, setSwitchState] = useState("setting"); const [switchState, setSwitchState] = useState("setting");
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
const theme = useTheme(); const theme = useTheme();
const variants = listQuestions[totalIndex].content.variants; const variants = listQuestions[quizId][totalIndex].content.variants;
const SSHC = (data: string) => { const SSHC = (data: string) => {
setSwitchState(data); setSwitchState(data);
@ -26,8 +28,11 @@ export default function DropDown({ totalIndex }: Props) {
const answerNew = variants.slice(); const answerNew = variants.slice();
answerNew.push({ answer: "", answerLong: "", hints: "" }); answerNew.push({ answer: "", answerLong: "", hints: "" });
updateQuestionsList(totalIndex, { updateQuestionsList(quizId, totalIndex, {
content: { ...listQuestions[totalIndex].content, variants: answerNew }, content: {
...listQuestions[quizId][totalIndex].content,
variants: answerNew,
},
}); });
}; };

@ -1,3 +1,4 @@
import { useParams } from "react-router-dom";
import { Box, Typography } from "@mui/material"; import { Box, Typography } from "@mui/material";
import CustomCheckbox from "@ui_kit/CustomCheckbox"; import CustomCheckbox from "@ui_kit/CustomCheckbox";
import CustomTextField from "@ui_kit/CustomTextField"; import CustomTextField from "@ui_kit/CustomTextField";
@ -11,6 +12,7 @@ type SettingDropDownProps = {
}; };
export default function SettingDropDown({ totalIndex }: SettingDropDownProps) { export default function SettingDropDown({ totalIndex }: SettingDropDownProps) {
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
return ( return (
@ -28,11 +30,11 @@ export default function SettingDropDown({ totalIndex }: SettingDropDownProps) {
</Typography> </Typography>
<CustomTextField <CustomTextField
placeholder={"Выберите вариант"} placeholder={"Выберите вариант"}
text={listQuestions[totalIndex].content.default} text={listQuestions[quizId][totalIndex].content.default}
onChange={({ target }) => { onChange={({ target }) => {
const clonContent = listQuestions[totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.default = target.value; clonContent.default = target.value;
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}} }}
/> />
</Box> </Box>

@ -1,3 +1,4 @@
import { useParams } from "react-router-dom";
import { Box, Link, Typography, useTheme } from "@mui/material"; import { Box, Link, Typography, useTheme } from "@mui/material";
import EnterIcon from "../../../assets/icons/questionsPage/enterIcon"; import EnterIcon from "../../../assets/icons/questionsPage/enterIcon";
import ButtonsOptions from "../ButtonsOptions"; import ButtonsOptions from "../ButtonsOptions";
@ -13,6 +14,7 @@ interface Props {
export default function Emoji({ totalIndex }: Props) { export default function Emoji({ totalIndex }: Props) {
const [switchState, setSwitchState] = React.useState("setting"); const [switchState, setSwitchState] = React.useState("setting");
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
const quizId = Number(useParams().quizId);
const theme = useTheme(); const theme = useTheme();
const SSHC = (data: string) => { const SSHC = (data: string) => {
@ -23,7 +25,7 @@ export default function Emoji({ totalIndex }: Props) {
<> <>
<Box sx={{ padding: "20px" }}> <Box sx={{ padding: "20px" }}>
<AnswerDraggableList <AnswerDraggableList
variants={listQuestions[totalIndex].content.variants} variants={listQuestions[quizId][totalIndex].content.variants}
totalIndex={totalIndex} totalIndex={totalIndex}
icon={ icon={
<Box sx={{ margin: "0 15px 0 5px" }}> <Box sx={{ margin: "0 15px 0 5px" }}>
@ -38,12 +40,12 @@ export default function Emoji({ totalIndex }: Props) {
sx={{ color: theme.palette.brightPurple.main }} sx={{ color: theme.palette.brightPurple.main }}
onClick={() => { onClick={() => {
const answerNew = const answerNew =
listQuestions[totalIndex].content.variants.slice(); listQuestions[quizId][totalIndex].content.variants.slice();
answerNew.push({ answer: "", answerLong: "", hints: "" }); answerNew.push({ answer: "", answerLong: "", hints: "" });
updateQuestionsList(totalIndex, { updateQuestionsList(quizId, totalIndex, {
content: { content: {
...listQuestions[totalIndex].content, ...listQuestions[quizId][totalIndex].content,
variants: answerNew, variants: answerNew,
}, },
}); });

@ -1,3 +1,4 @@
import { useParams } from "react-router-dom";
import { Box, Typography } from "@mui/material"; import { Box, Typography } from "@mui/material";
import CustomCheckbox from "@ui_kit/CustomCheckbox"; import CustomCheckbox from "@ui_kit/CustomCheckbox";
import InfoIcon from "../../../assets/icons/InfoIcon"; import InfoIcon from "../../../assets/icons/InfoIcon";
@ -8,6 +9,7 @@ type SettingEmojiProps = {
}; };
export default function SettingEmoji({ totalIndex }: SettingEmojiProps) { export default function SettingEmoji({ totalIndex }: SettingEmojiProps) {
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
return ( return (
@ -16,20 +18,20 @@ export default function SettingEmoji({ totalIndex }: SettingEmojiProps) {
<Typography>Настройки ответов</Typography> <Typography>Настройки ответов</Typography>
<CustomCheckbox <CustomCheckbox
label={"Можно несколько"} label={"Можно несколько"}
checked={listQuestions[totalIndex].content.multi} checked={listQuestions[quizId][totalIndex].content.multi}
handleChange={(e) => { handleChange={(e) => {
let clonContent = listQuestions[totalIndex].content; let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.multi = e.target.checked; clonContent.multi = e.target.checked;
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}} }}
/> />
<CustomCheckbox <CustomCheckbox
label={'Вариант "свой ответ"'} label={'Вариант "свой ответ"'}
checked={listQuestions[totalIndex].content.own} checked={listQuestions[quizId][totalIndex].content.own}
handleChange={(e) => { handleChange={(e) => {
let clonContent = listQuestions[totalIndex].content; let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.own = e.target.checked; clonContent.own = e.target.checked;
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}} }}
/> />
</Box> </Box>

@ -1,4 +1,5 @@
import { Box, Link, Typography, ButtonBase, useTheme } from "@mui/material"; import { Box, Link, Typography, ButtonBase, useTheme } from "@mui/material";
import { useParams } from "react-router-dom";
import AddImage from "../../../assets/icons/questionsPage/addImage"; import AddImage from "../../../assets/icons/questionsPage/addImage";
import EnterIcon from "../../../assets/icons/questionsPage/enterIcon"; import EnterIcon from "../../../assets/icons/questionsPage/enterIcon";
import ButtonsOptionsAndPict from "../ButtonsOptionsAndPict"; import ButtonsOptionsAndPict from "../ButtonsOptionsAndPict";
@ -13,6 +14,7 @@ interface Props {
export default function OptionsAndPicture({ totalIndex }: Props) { export default function OptionsAndPicture({ totalIndex }: Props) {
const [switchState, setSwitchState] = React.useState("setting"); const [switchState, setSwitchState] = React.useState("setting");
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
const quizId = Number(useParams().quizId);
const theme = useTheme(); const theme = useTheme();
const SSHC = (data: string) => { const SSHC = (data: string) => {
setSwitchState(data); setSwitchState(data);
@ -22,7 +24,8 @@ export default function OptionsAndPicture({ totalIndex }: Props) {
<> <>
<Box sx={{ padding: "20px" }}> <Box sx={{ padding: "20px" }}>
<Box sx={{ paddingBottom: "25px" }}> <Box sx={{ paddingBottom: "25px" }}>
{listQuestions[totalIndex].content.variants.map((_, index) => ( {listQuestions[quizId][totalIndex].content.variants.map(
(_, index) => (
<ButtonBase <ButtonBase
component="label" component="label"
sx={{ sx={{
@ -36,13 +39,16 @@ export default function OptionsAndPicture({ totalIndex }: Props) {
<input <input
onChange={({ target }) => { onChange={({ target }) => {
if (target.files?.length) { if (target.files?.length) {
const clonContent = listQuestions[totalIndex].content; const clonContent =
listQuestions[quizId][totalIndex].content;
clonContent.variants[index].answer = URL.createObjectURL( clonContent.variants[index].answer = URL.createObjectURL(
target.files[0] target.files[0]
); );
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, {
content: clonContent,
});
} }
}} }}
hidden hidden
@ -63,7 +69,8 @@ export default function OptionsAndPicture({ totalIndex }: Props) {
Добавьте ответ Добавьте ответ
</Typography> </Typography>
</ButtonBase> </ButtonBase>
))} )
)}
</Box> </Box>
<Box sx={{ display: "flex", alignItems: "center", gap: "10px" }}> <Box sx={{ display: "flex", alignItems: "center", gap: "10px" }}>
<Link <Link
@ -71,14 +78,14 @@ export default function OptionsAndPicture({ totalIndex }: Props) {
variant="body2" variant="body2"
sx={{ color: theme.palette.brightPurple.main }} sx={{ color: theme.palette.brightPurple.main }}
onClick={() => { onClick={() => {
const clonContent = listQuestions[totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.variants.push({ clonContent.variants.push({
answer: "", answer: "",
answerLong: "", answerLong: "",
hints: "", hints: "",
}); });
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}} }}
> >
Добавьте ответ Добавьте ответ

@ -1,4 +1,5 @@
import { useState } from "react"; import { useState } from "react";
import { useParams } from "react-router-dom";
import { Box, Link, Typography, Button, useTheme } from "@mui/material"; import { Box, Link, Typography, Button, useTheme } from "@mui/material";
import ButtonsOptions from "../ButtonsOptions"; import ButtonsOptions from "../ButtonsOptions";
@ -16,6 +17,7 @@ interface Props {
export default function OptionsPicture({ totalIndex }: Props) { export default function OptionsPicture({ totalIndex }: Props) {
const theme = useTheme(); const theme = useTheme();
const quizId = Number(useParams().quizId);
const [switchState, setSwitchState] = useState("setting"); const [switchState, setSwitchState] = useState("setting");
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
@ -25,11 +27,11 @@ export default function OptionsPicture({ totalIndex }: Props) {
const addImage = ({ target }: ChangeEvent<HTMLInputElement>) => { const addImage = ({ target }: ChangeEvent<HTMLInputElement>) => {
if (target.files?.length) { if (target.files?.length) {
const clonContent = listQuestions[totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.images.push(URL.createObjectURL(target.files[0])); clonContent.images.push(URL.createObjectURL(target.files[0]));
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
} }
}; };

@ -1,4 +1,5 @@
import { useEffect } from "react"; import { useEffect } from "react";
import { useParams } from "react-router-dom";
import { Box, Button, Typography, useTheme } from "@mui/material"; import { Box, Button, Typography, useTheme } from "@mui/material";
import CustomCheckbox from "@ui_kit/CustomCheckbox"; import CustomCheckbox from "@ui_kit/CustomCheckbox";
@ -70,18 +71,19 @@ export function SelectIconButton({ Icon, isActive = false, onClick }: Props) {
export default function SettingOpytionsPict({ export default function SettingOpytionsPict({
totalIndex, totalIndex,
}: SettingOpytionsPictProps) { }: SettingOpytionsPictProps) {
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
useEffect(() => { useEffect(() => {
if (!listQuestions[totalIndex].content.xy) { if (!listQuestions[quizId][totalIndex].content.xy) {
updateProportions("1:1"); updateProportions("1:1");
} }
}, []); }, []);
const updateProportions = (proportions: string) => { const updateProportions = (proportions: string) => {
const clonContent = listQuestions[totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.xy = proportions; clonContent.xy = proportions;
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}; };
return ( return (
@ -100,7 +102,9 @@ export default function SettingOpytionsPict({
<SelectIconButton <SelectIconButton
key={index} key={index}
onClick={() => updateProportions(value)} onClick={() => updateProportions(value)}
isActive={listQuestions[totalIndex].content.xy === value} isActive={
listQuestions[quizId][totalIndex].content.xy === value
}
Icon={icon} Icon={icon}
/> />
))} ))}
@ -111,24 +115,25 @@ export default function SettingOpytionsPict({
<CustomCheckbox <CustomCheckbox
label={"Можно несколько"} label={"Можно несколько"}
checked={listQuestions[totalIndex].content.multi} checked={listQuestions[quizId][totalIndex].content.multi}
handleChange={() => handleChange={() =>
updateQuestionsList(totalIndex, { updateQuestionsList(quizId, totalIndex, {
content: { content: {
...listQuestions[totalIndex].content, ...listQuestions[quizId][totalIndex].content,
multi: !listQuestions[totalIndex].content.multi, multi: !listQuestions[quizId][totalIndex].content.multi,
}, },
}) })
} }
/> />
<CustomCheckbox <CustomCheckbox
label={"Большие картинки"} label={"Большие картинки"}
checked={listQuestions[totalIndex].content.largeCheck} checked={listQuestions[quizId][totalIndex].content.largeCheck}
handleChange={() => handleChange={() =>
updateQuestionsList(totalIndex, { updateQuestionsList(quizId, totalIndex, {
content: { content: {
...listQuestions[totalIndex].content, ...listQuestions[quizId][totalIndex].content,
largeCheck: !listQuestions[totalIndex].content.largeCheck, largeCheck:
!listQuestions[quizId][totalIndex].content.largeCheck,
}, },
}) })
} }
@ -146,26 +151,30 @@ export default function SettingOpytionsPict({
> >
<SelectIconButton <SelectIconButton
onClick={() => onClick={() =>
updateQuestionsList(totalIndex, { updateQuestionsList(quizId, totalIndex, {
content: { content: {
...listQuestions[totalIndex].content, ...listQuestions[quizId][totalIndex].content,
format: "carousel", format: "carousel",
}, },
}) })
} }
isActive={listQuestions[totalIndex].content.format === "carousel"} isActive={
listQuestions[quizId][totalIndex].content.format === "carousel"
}
Icon={FormatIcon2} Icon={FormatIcon2}
/> />
<SelectIconButton <SelectIconButton
onClick={() => onClick={() =>
updateQuestionsList(totalIndex, { updateQuestionsList(quizId, totalIndex, {
content: { content: {
...listQuestions[totalIndex].content, ...listQuestions[quizId][totalIndex].content,
format: "masonry", format: "masonry",
}, },
}) })
} }
isActive={listQuestions[totalIndex].content.format === "masonry"} isActive={
listQuestions[quizId][totalIndex].content.format === "masonry"
}
Icon={FormatIcon1} Icon={FormatIcon1}
/> />
</Box> </Box>

@ -1,4 +1,5 @@
import { useState } from "react"; import { useState } from "react";
import { useParams } from "react-router-dom";
import { Box, Typography, useTheme } from "@mui/material"; import { Box, Typography, useTheme } from "@mui/material";
import CustomTextField from "@ui_kit/CustomTextField"; import CustomTextField from "@ui_kit/CustomTextField";
@ -16,6 +17,7 @@ interface Props {
} }
export default function OwnTextField({ totalIndex }: Props) { export default function OwnTextField({ totalIndex }: Props) {
const [switchState, setSwitchState] = useState("setting"); const [switchState, setSwitchState] = useState("setting");
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
const theme = useTheme(); const theme = useTheme();
@ -37,11 +39,11 @@ export default function OwnTextField({ totalIndex }: Props) {
> >
<CustomTextField <CustomTextField
placeholder={"Пример ответа"} placeholder={"Пример ответа"}
text={listQuestions[totalIndex].content.placeholder} text={listQuestions[quizId][totalIndex].content.placeholder}
onChange={({ target }: ChangeEvent<HTMLInputElement>) => { onChange={({ target }: ChangeEvent<HTMLInputElement>) => {
const clonContent = listQuestions[totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.placeholder = target.value; clonContent.placeholder = target.value;
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}} }}
/> />
<Box sx={{ display: "flex", alignItems: "center", gap: "12px" }}> <Box sx={{ display: "flex", alignItems: "center", gap: "12px" }}>

@ -1,3 +1,4 @@
import { useParams } from "react-router-dom";
import { import {
Box, Box,
FormControl, FormControl,
@ -32,6 +33,7 @@ export default function SettingTextField({
totalIndex, totalIndex,
}: SettingTextFieldProps) { }: SettingTextFieldProps) {
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
const quizId = Number(useParams().quizId);
const theme = useTheme(); const theme = useTheme();
return ( return (
@ -43,18 +45,18 @@ export default function SettingTextField({
aria-labelledby="demo-controlled-radio-buttons-group" aria-labelledby="demo-controlled-radio-buttons-group"
name="controlled-radio-buttons-group" name="controlled-radio-buttons-group"
value={ANSWER_TYPES.findIndex( value={ANSWER_TYPES.findIndex(
({ value }) => listQuestions[totalIndex].content[value] ({ value }) => listQuestions[quizId][totalIndex].content[value]
)} )}
onChange={({ target }: React.ChangeEvent<HTMLInputElement>) => { onChange={({ target }: React.ChangeEvent<HTMLInputElement>) => {
const clonContent = { const clonContent = {
...listQuestions[totalIndex].content, ...listQuestions[quizId][totalIndex].content,
single: false, single: false,
multi: false, multi: false,
number: false, number: false,
[ANSWER_TYPES[Number(target.value)].value]: true, [ANSWER_TYPES[Number(target.value)].value]: true,
}; };
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}} }}
> >
{ANSWER_TYPES.map(({ name }, index) => ( {ANSWER_TYPES.map(({ name }, index) => (

@ -1,4 +1,5 @@
import { useState } from "react"; import { useState } from "react";
import { useParams } from "react-router-dom";
import { Box, Typography, useTheme } from "@mui/material"; import { Box, Typography, useTheme } from "@mui/material";
import ButtonsOptions from "../ButtonsOptions"; import ButtonsOptions from "../ButtonsOptions";
import CustomTextField from "@ui_kit/CustomTextField"; import CustomTextField from "@ui_kit/CustomTextField";
@ -18,6 +19,7 @@ export default function PageOptions({ disableInput, totalIndex }: Props) {
const [openImageModal, setOpenImageModal] = useState<boolean>(false); const [openImageModal, setOpenImageModal] = useState<boolean>(false);
const [openVideoModal, setOpenVideoModal] = useState<boolean>(false); const [openVideoModal, setOpenVideoModal] = useState<boolean>(false);
const [switchState, setSwitchState] = useState("setting"); const [switchState, setSwitchState] = useState("setting");
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
const theme = useTheme(); const theme = useTheme();
@ -40,11 +42,11 @@ export default function PageOptions({ disableInput, totalIndex }: Props) {
<Box sx={{ display: disableInput ? "none" : "" }}> <Box sx={{ display: disableInput ? "none" : "" }}>
<CustomTextField <CustomTextField
placeholder={"Можно добавить текст"} placeholder={"Можно добавить текст"}
text={listQuestions[totalIndex].content.text} text={listQuestions[quizId][totalIndex].content.text}
onChange={({ target }) => { onChange={({ target }) => {
const clonContent = listQuestions[totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.text = target.value; clonContent.text = target.value;
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}} }}
/> />
</Box> </Box>
@ -75,9 +77,11 @@ export default function PageOptions({ disableInput, totalIndex }: Props) {
onClose={() => setOpenImageModal(false)} onClose={() => setOpenImageModal(false)}
imgHC={(fileList) => { imgHC={(fileList) => {
if (fileList?.length) { if (fileList?.length) {
const clonContent = listQuestions[totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.picture = URL.createObjectURL(fileList[0]); clonContent.picture = URL.createObjectURL(fileList[0]);
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, {
content: clonContent,
});
} }
}} }}
/> />
@ -106,11 +110,11 @@ export default function PageOptions({ disableInput, totalIndex }: Props) {
<UploadVideoModal <UploadVideoModal
open={openVideoModal} open={openVideoModal}
onClose={() => setOpenVideoModal(false)} onClose={() => setOpenVideoModal(false)}
video={listQuestions[totalIndex].content.video} video={listQuestions[quizId][totalIndex].content.video}
onUpload={(url) => { onUpload={(url) => {
const clonContent = listQuestions[totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.video = url; clonContent.video = url;
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}} }}
/> />
</Box> </Box>

@ -25,7 +25,7 @@ export default function QuestionsPage() {
const collapseEverything = () => { const collapseEverything = () => {
listQuestions[quizId].forEach((item, index) => { listQuestions[quizId].forEach((item, index) => {
updateQuestionsList(quizId, { ...item, expanded: false }); updateQuestionsList(quizId, index, { ...item, expanded: false });
}); });
}; };

@ -1,4 +1,5 @@
import { useState } from "react"; import { useState } from "react";
import { useParams } from "react-router-dom";
import { Box, Typography, useTheme } from "@mui/material"; import { Box, Typography, useTheme } from "@mui/material";
import ButtonsOptions from "../ButtonsOptions"; import ButtonsOptions from "../ButtonsOptions";
import Rating from "@mui/material/Rating"; import Rating from "@mui/material/Rating";
@ -12,6 +13,7 @@ interface Props {
export default function RatingOptions({ totalIndex }: Props) { export default function RatingOptions({ totalIndex }: Props) {
const [switchState, setSwitchState] = useState("setting"); const [switchState, setSwitchState] = useState("setting");
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
const theme = useTheme(); const theme = useTheme();
@ -33,7 +35,7 @@ export default function RatingOptions({ totalIndex }: Props) {
> >
<Rating <Rating
name="customized-color" name="customized-color"
defaultValue={listQuestions[totalIndex].content.starts} defaultValue={listQuestions[quizId][totalIndex].content.starts}
getLabelText={(value: number) => getLabelText={(value: number) =>
`${value} Heart${value !== 1 ? "s" : ""}` `${value} Heart${value !== 1 ? "s" : ""}`
} }
@ -42,9 +44,9 @@ export default function RatingOptions({ totalIndex }: Props) {
emptyIcon={<RatingStar color={"#9A9AAF"} />} emptyIcon={<RatingStar color={"#9A9AAF"} />}
sx={{ display: "flex", gap: "15px" }} sx={{ display: "flex", gap: "15px" }}
onChange={(_, value) => { onChange={(_, value) => {
const clonContent = listQuestions[totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.starts = value || 0; clonContent.starts = value || 0;
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}} }}
/> />
<Box <Box

@ -1,3 +1,4 @@
import { useParams } from "react-router-dom";
import { Box, ButtonBase, Slider, Typography, useTheme } from "@mui/material"; import { Box, ButtonBase, Slider, Typography, useTheme } from "@mui/material";
import CustomCheckbox from "@ui_kit/CustomCheckbox"; import CustomCheckbox from "@ui_kit/CustomCheckbox";
@ -22,6 +23,7 @@ type ButtonRatingFrom = {
}; };
export default function SettingSlider({ totalIndex }: SettingSliderProps) { export default function SettingSlider({ totalIndex }: SettingSliderProps) {
const quizId = Number(useParams().quizId);
const theme = useTheme(); const theme = useTheme();
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
@ -58,17 +60,19 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
<ButtonBase <ButtonBase
key={index} key={index}
onClick={() => { onClick={() => {
const clonContent = listQuestions[totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.form = name; clonContent.form = name;
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, {
content: clonContent,
});
}} }}
sx={{ sx={{
backgroundColor: backgroundColor:
listQuestions[totalIndex].content.form === name listQuestions[quizId][totalIndex].content.form === name
? theme.palette.brightPurple.main ? theme.palette.brightPurple.main
: "transparent", : "transparent",
color: color:
listQuestions[totalIndex].content.form === name listQuestions[quizId][totalIndex].content.form === name
? "#ffffff" ? "#ffffff"
: theme.palette.grey3.main, : theme.palette.grey3.main,
width: "40px", width: "40px",
@ -90,16 +94,16 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
Количество Количество
</Typography> </Typography>
<Slider <Slider
value={listQuestions[totalIndex].content.steps} value={listQuestions[quizId][totalIndex].content.steps}
min={1} min={1}
max={10} max={10}
aria-label="Default" aria-label="Default"
valueLabelDisplay="auto" valueLabelDisplay="auto"
sx={{ color: theme.palette.brightPurple.main }} sx={{ color: theme.palette.brightPurple.main }}
onChange={(_, value) => { onChange={(_, value) => {
const clonContent = listQuestions[totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.steps = Number(value) || 1; clonContent.steps = Number(value) || 1;
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}} }}
/> />
</Box> </Box>

@ -1,4 +1,5 @@
import { Box, Typography, useTheme } from "@mui/material"; import { useParams } from "react-router-dom";
import { Box, Typography } from "@mui/material";
import ButtonsOptions from "../ButtonsOptions"; import ButtonsOptions from "../ButtonsOptions";
import React from "react"; import React from "react";
import CustomTextField from "@ui_kit/CustomTextField"; import CustomTextField from "@ui_kit/CustomTextField";
@ -11,8 +12,9 @@ interface Props {
export default function SliderOptions({ totalIndex }: Props) { export default function SliderOptions({ totalIndex }: Props) {
const [switchState, setSwitchState] = React.useState("setting"); const [switchState, setSwitchState] = React.useState("setting");
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
const theme = useTheme();
const SSHC = (data: string) => { const SSHC = (data: string) => {
setSwitchState(data); setSwitchState(data);
}; };
@ -34,25 +36,33 @@ export default function SliderOptions({ totalIndex }: Props) {
<Box sx={{ display: "flex", alignItems: "center", gap: "20px" }}> <Box sx={{ display: "flex", alignItems: "center", gap: "20px" }}>
<CustomTextField <CustomTextField
placeholder={"0"} placeholder={"0"}
text={listQuestions[totalIndex].content.range.split("—")[0]} text={
listQuestions[quizId][totalIndex].content.range.split("—")[0]
}
onChange={({ target }) => { onChange={({ target }) => {
const clonContent = listQuestions[totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.range = `${target.value}${ clonContent.range = `${target.value}${
listQuestions[totalIndex].content.range.split("—")[1] listQuestions[quizId][totalIndex].content.range.split("—")[1]
}`; }`;
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, {
content: clonContent,
});
}} }}
/> />
<Typography></Typography> <Typography></Typography>
<CustomTextField <CustomTextField
placeholder={"100"} placeholder={"100"}
text={listQuestions[totalIndex].content.range.split("—")[1]} text={
listQuestions[quizId][totalIndex].content.range.split("—")[1]
}
onChange={({ target }) => { onChange={({ target }) => {
const clonContent = listQuestions[totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.range = `${ clonContent.range = `${
listQuestions[totalIndex].content.range.split("—")[0] listQuestions[quizId][totalIndex].content.range.split("—")[0]
}${target.value}`; }${target.value}`;
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, {
content: clonContent,
});
}} }}
/> />
</Box> </Box>
@ -68,11 +78,13 @@ export default function SliderOptions({ totalIndex }: Props) {
<Typography>Начальное значение</Typography> <Typography>Начальное значение</Typography>
<CustomTextField <CustomTextField
placeholder={"50"} placeholder={"50"}
text={String(listQuestions[totalIndex].content.start)} text={String(listQuestions[quizId][totalIndex].content.start)}
onChange={({ target }) => { onChange={({ target }) => {
const clonContent = listQuestions[totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.start = Number(target.value); clonContent.start = Number(target.value);
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, {
content: clonContent,
});
}} }}
/> />
</Box> </Box>
@ -80,11 +92,13 @@ export default function SliderOptions({ totalIndex }: Props) {
<Typography>Шаг</Typography> <Typography>Шаг</Typography>
<CustomTextField <CustomTextField
placeholder={"1"} placeholder={"1"}
text={String(listQuestions[totalIndex].content.step)} text={String(listQuestions[quizId][totalIndex].content.step)}
onChange={({ target }) => { onChange={({ target }) => {
const clonContent = listQuestions[totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.step = Number(target.value); clonContent.step = Number(target.value);
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, {
content: clonContent,
});
}} }}
/> />
</Box> </Box>

@ -1,3 +1,4 @@
import { useParams } from "react-router-dom";
import { Box, Typography } from "@mui/material"; import { Box, Typography } from "@mui/material";
import CustomCheckbox from "@ui_kit/CustomCheckbox"; import CustomCheckbox from "@ui_kit/CustomCheckbox";
import InfoIcon from "../../../assets/icons/InfoIcon"; import InfoIcon from "../../../assets/icons/InfoIcon";
@ -8,6 +9,7 @@ type SettingSliderProps = {
}; };
export default function SettingSlider({ totalIndex }: SettingSliderProps) { export default function SettingSlider({ totalIndex }: SettingSliderProps) {
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
return ( return (
@ -16,11 +18,11 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
<Typography>Настройки ползунка</Typography> <Typography>Настройки ползунка</Typography>
<CustomCheckbox <CustomCheckbox
label={"Выбор диапозона (два ползунка)"} label={"Выбор диапозона (два ползунка)"}
checked={listQuestions[totalIndex].content.chooseRange} checked={listQuestions[quizId][totalIndex].content.chooseRange}
handleChange={(e) => { handleChange={(e) => {
let clonContent = listQuestions[totalIndex].content; let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.chooseRange = e.target.checked; clonContent.chooseRange = e.target.checked;
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}} }}
/> />
</Box> </Box>

@ -19,9 +19,10 @@ interface Props {
} }
export default function SwitchQuestionsPage({ totalIndex }: Props) { export default function SwitchQuestionsPage({ totalIndex }: Props) {
const params = Number(useParams().quizId); const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
const switchState = listQuestions[totalIndex].type;
const switchState = listQuestions[quizId][totalIndex].type;
switch (switchState) { switch (switchState) {
case "variant": case "variant":
return <AnswerOptions totalIndex={totalIndex} />; return <AnswerOptions totalIndex={totalIndex} />;

@ -16,85 +16,95 @@ import {useParams} from "react-router-dom";
import { questionStore, updateQuestionsList } from "@root/questions"; import { questionStore, updateQuestionsList } from "@root/questions";
interface Props { interface Props {
totalIndex: number totalIndex: number;
} }
export default function TypeQuestions({ totalIndex }: Props) { export default function TypeQuestions({ totalIndex }: Props) {
const theme = useTheme() const theme = useTheme();
const params = Number(useParams().quizId); const quizId = Number(useParams().quizId);
const {listQuestions} = questionStore() const { listQuestions } = questionStore();
const switchState = listQuestions[totalIndex].type const switchState = listQuestions[quizId][totalIndex].type;
const buttonTypeQuestions: { icon: JSX.Element; title: string; value: string }[] = [ const buttonTypeQuestions: {
icon: JSX.Element;
title: string;
value: string;
}[] = [
{ {
icon: <Answer color={theme.palette.grey2.main} />, icon: <Answer color={theme.palette.grey2.main} />,
title: 'Варианты ответов', title: "Варианты ответов",
value: 'variant', value: "variant",
}, },
{ {
icon: <OptionsPict color={theme.palette.grey2.main} />, icon: <OptionsPict color={theme.palette.grey2.main} />,
title: 'Варианты с картинками', title: "Варианты с картинками",
value: 'images', value: "images",
}, },
{ {
icon: <OptionsAndPict color={theme.palette.grey2.main} />, icon: <OptionsAndPict color={theme.palette.grey2.main} />,
title: 'Варианты и картинка', title: "Варианты и картинка",
value: 'varimg', value: "varimg",
}, },
{ {
icon: <Emoji color={theme.palette.grey2.main} />, icon: <Emoji color={theme.palette.grey2.main} />,
title: 'Эмоджи', title: "Эмоджи",
value: 'emoji', value: "emoji",
}, },
{ {
icon: <Input color={theme.palette.grey2.main} />, icon: <Input color={theme.palette.grey2.main} />,
title: 'Своё поле для ввода', title: "Своё поле для ввода",
value: 'text', value: "text",
}, },
{ {
icon: <DropDown color={theme.palette.grey2.main} />, icon: <DropDown color={theme.palette.grey2.main} />,
title: 'Выпадающий список', title: "Выпадающий список",
value: 'select', value: "select",
}, },
{ {
icon: <Date color={theme.palette.grey2.main} />, icon: <Date color={theme.palette.grey2.main} />,
title: 'Дата', title: "Дата",
value: 'date', value: "date",
}, },
{ {
icon: <Slider color={theme.palette.grey2.main} />, icon: <Slider color={theme.palette.grey2.main} />,
title: 'Ползунок', title: "Ползунок",
value: 'number', value: "number",
}, },
{ {
icon: <Download color={theme.palette.grey2.main} />, icon: <Download color={theme.palette.grey2.main} />,
title: 'Загрузка файла', title: "Загрузка файла",
value: 'file', value: "file",
}, },
{ {
icon: <Page color={theme.palette.grey2.main} />, icon: <Page color={theme.palette.grey2.main} />,
title: 'Страница', title: "Страница",
value: 'page', value: "page",
}, },
{ {
icon: <RatingIcon color={theme.palette.grey2.main} />, icon: <RatingIcon color={theme.palette.grey2.main} />,
title: 'Рейтинг', title: "Рейтинг",
value: 'rating', value: "rating",
}, },
]; ];
return ( return (
<Box sx={{display: 'flex', flexWrap: 'wrap', gap: '20px', padding: '8px 20px 20px'}}> <Box
sx={{
display: "flex",
flexWrap: "wrap",
gap: "20px",
padding: "8px 20px 20px",
}}
>
{buttonTypeQuestions.map(({ icon, title, value }) => ( {buttonTypeQuestions.map(({ icon, title, value }) => (
<QuestionsMiniButton <QuestionsMiniButton
key={title} key={title}
onClick={() => { onClick={() => {
console.log(value) console.log(value);
updateQuestionsList(totalIndex, {type: value}) updateQuestionsList(quizId, totalIndex, { type: value });
}} }}
icon={icon} icon={icon}
text={title} text={title}
/> />
))} ))}
</Box> </Box>
) );
} }

@ -1,4 +1,5 @@
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import { import {
Box, Box,
FormControl, FormControl,
@ -30,6 +31,7 @@ const DESIGN_TYPES = [
export default function UploadFile({ totalIndex }: Props) { export default function UploadFile({ totalIndex }: Props) {
const [switchState, setSwitchState] = useState("setting"); const [switchState, setSwitchState] = useState("setting");
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
const theme = useTheme(); const theme = useTheme();
@ -38,20 +40,20 @@ export default function UploadFile({ totalIndex }: Props) {
}; };
const handleChange = ({ target }: SelectChangeEvent) => { const handleChange = ({ target }: SelectChangeEvent) => {
const clonContent = listQuestions[totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.type = target.value; clonContent.type = target.value;
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}; };
useEffect(() => { useEffect(() => {
const isTypeSetted = DESIGN_TYPES.find( const isTypeSetted = DESIGN_TYPES.find(
({ value }) => value === listQuestions[totalIndex].content.type ({ value }) => value === listQuestions[quizId][totalIndex].content.type
); );
if (!isTypeSetted) { if (!isTypeSetted) {
const clonContent = listQuestions[totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.type = DESIGN_TYPES[0].value; clonContent.type = DESIGN_TYPES[0].value;
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
} }
}, []); }, []);
@ -80,7 +82,7 @@ export default function UploadFile({ totalIndex }: Props) {
<Select <Select
id="category-select" id="category-select"
variant="outlined" variant="outlined"
value={listQuestions[totalIndex].content.type} value={listQuestions[quizId][totalIndex].content.type}
displayEmpty displayEmpty
onChange={handleChange} onChange={handleChange}
sx={{ sx={{

@ -1,3 +1,4 @@
import { useParams } from "react-router-dom";
import { Box, Typography } from "@mui/material"; import { Box, Typography } from "@mui/material";
import CustomCheckbox from "@ui_kit/CustomCheckbox"; import CustomCheckbox from "@ui_kit/CustomCheckbox";
@ -10,6 +11,7 @@ type SettingsUploadProps = {
}; };
export default function SettingsUpload({ totalIndex }: SettingsUploadProps) { export default function SettingsUpload({ totalIndex }: SettingsUploadProps) {
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
return ( return (
@ -17,11 +19,11 @@ export default function SettingsUpload({ totalIndex }: SettingsUploadProps) {
<Typography>Настройки вопроса</Typography> <Typography>Настройки вопроса</Typography>
<CustomCheckbox <CustomCheckbox
label={"Автозаполнение адреса"} label={"Автозаполнение адреса"}
checked={listQuestions[totalIndex].content.autofill} checked={listQuestions[quizId][totalIndex].content.autofill}
handleChange={({ target }) => { handleChange={({ target }) => {
const clonContent = listQuestions[totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.autofill = target.checked; clonContent.autofill = target.checked;
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}} }}
/> />
<CustomCheckbox label={"Необязательный вопрос"} /> <CustomCheckbox label={"Необязательный вопрос"} />

@ -1,3 +1,4 @@
import { useParams } from "react-router-dom";
import { useState } from "react"; import { useState } from "react";
import { Typography, Box, useTheme, ButtonBase } from "@mui/material"; import { Typography, Box, useTheme, ButtonBase } from "@mui/material";
import UploadBox from "@ui_kit/UploadBox"; import UploadBox from "@ui_kit/UploadBox";
@ -14,6 +15,7 @@ type UploadImageProps = {
}; };
export default function UploadImage({ totalIndex }: UploadImageProps) { export default function UploadImage({ totalIndex }: UploadImageProps) {
const quizId = Number(useParams().quizId);
const theme = useTheme(); const theme = useTheme();
const [open, setOpen] = React.useState(false); const [open, setOpen] = React.useState(false);
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
@ -24,9 +26,9 @@ export default function UploadImage({ totalIndex }: UploadImageProps) {
if (files?.length) { if (files?.length) {
const [file] = Array.from(files); const [file] = Array.from(files);
let clonContent = listQuestions[totalIndex].content; let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.back = URL.createObjectURL(file); clonContent.back = URL.createObjectURL(file);
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
handleClose(); handleClose();
setOpened(true); setOpened(true);
@ -68,7 +70,7 @@ export default function UploadImage({ totalIndex }: UploadImageProps) {
<CroppingModal <CroppingModal
opened={opened} opened={opened}
onClose={() => setOpened(false)} onClose={() => setOpened(false)}
picture={listQuestions[totalIndex].content.back} picture={listQuestions[quizId][totalIndex].content.back}
/> />
</Box> </Box>
); );

@ -1,4 +1,5 @@
import { useState } from "react"; import { useState } from "react";
import { useParams } from "react-router-dom";
import { Box, Typography, Link, useTheme } from "@mui/material"; import { Box, Typography, Link, useTheme } from "@mui/material";
import EnterIcon from "../../../assets/icons/questionsPage/enterIcon"; import EnterIcon from "../../../assets/icons/questionsPage/enterIcon";
import SwitchAnswerOptions from "./switchAnswerOptions"; import SwitchAnswerOptions from "./switchAnswerOptions";
@ -14,8 +15,9 @@ interface Props {
export default function AnswerOptions({ totalIndex }: Props) { export default function AnswerOptions({ totalIndex }: Props) {
const [switchState, setSwitchState] = useState("setting"); const [switchState, setSwitchState] = useState("setting");
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
const variants = listQuestions[totalIndex].content.variants; const variants = listQuestions[quizId][totalIndex].content.variants;
const theme = useTheme(); const theme = useTheme();
const SSHC = (data: string) => { const SSHC = (data: string) => {
@ -26,8 +28,11 @@ export default function AnswerOptions({ totalIndex }: Props) {
const answerNew = variants.slice(); // Create a shallow copy of the array const answerNew = variants.slice(); // Create a shallow copy of the array
answerNew.push({ answer: "", answerLong: "", hints: "" }); answerNew.push({ answer: "", answerLong: "", hints: "" });
updateQuestionsList(totalIndex, { updateQuestionsList(quizId, totalIndex, {
content: { ...listQuestions[totalIndex].content, variants: answerNew }, content: {
...listQuestions[quizId][totalIndex].content,
variants: answerNew,
},
}); });
}; };

@ -1,3 +1,4 @@
import { useParams } from "react-router-dom";
import { Box, Typography } from "@mui/material"; import { Box, Typography } from "@mui/material";
import CustomCheckbox from "@ui_kit/CustomCheckbox"; import CustomCheckbox from "@ui_kit/CustomCheckbox";
import InfoIcon from "../../../assets/icons/InfoIcon"; import InfoIcon from "../../../assets/icons/InfoIcon";
@ -9,6 +10,7 @@ interface Props {
} }
export default function ResponseSettings({ totalIndex }: Props) { export default function ResponseSettings({ totalIndex }: Props) {
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
return ( return (
@ -17,45 +19,45 @@ export default function ResponseSettings({ totalIndex }: Props) {
<Typography>Настройки ответов</Typography> <Typography>Настройки ответов</Typography>
<CustomCheckbox <CustomCheckbox
label={"Длинный текстовый ответ"} label={"Длинный текстовый ответ"}
checked={listQuestions[totalIndex].content.largeCheck} checked={listQuestions[quizId][totalIndex].content.largeCheck}
handleChange={(e) => { handleChange={(e) => {
let clonContent = listQuestions[totalIndex].content; let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.largeCheck = e.target.checked; clonContent.largeCheck = e.target.checked;
if (!e.target.checked) { if (!e.target.checked) {
clonContent.large = ""; clonContent.large = "";
} }
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}} }}
/> />
{listQuestions[totalIndex].content.largeCheck && ( {listQuestions[quizId][totalIndex].content.largeCheck && (
<CustomTextField <CustomTextField
placeholder={"Развёрнутый ответ"} placeholder={"Развёрнутый ответ"}
text={listQuestions[totalIndex].content.large} text={listQuestions[quizId][totalIndex].content.large}
onChange={({ target }) => { onChange={({ target }) => {
let clonContent = listQuestions[totalIndex].content; let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.large = target.value; clonContent.large = target.value;
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}} }}
/> />
)} )}
<CustomCheckbox <CustomCheckbox
label={"Можно несколько"} label={"Можно несколько"}
checked={listQuestions[totalIndex].content.multi} checked={listQuestions[quizId][totalIndex].content.multi}
handleChange={(e) => { handleChange={(e) => {
let clonContent = listQuestions[totalIndex].content; let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.multi = e.target.checked; clonContent.multi = e.target.checked;
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}} }}
/> />
<CustomCheckbox <CustomCheckbox
label={'Вариант "свой ответ"'} label={'Вариант "свой ответ"'}
checked={listQuestions[totalIndex].content.own} checked={listQuestions[quizId][totalIndex].content.own}
handleChange={(e) => { handleChange={(e) => {
let clonContent = listQuestions[totalIndex].content; let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.own = e.target.checked; clonContent.own = e.target.checked;
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}} }}
/> />
</Box> </Box>
@ -63,36 +65,38 @@ export default function ResponseSettings({ totalIndex }: Props) {
<Typography>Настройки вопросов</Typography> <Typography>Настройки вопросов</Typography>
<CustomCheckbox <CustomCheckbox
label={"Необязательный вопрос"} label={"Необязательный вопрос"}
checked={!listQuestions[totalIndex].required} checked={!listQuestions[quizId][totalIndex].required}
handleChange={(e) => { handleChange={(e) => {
updateQuestionsList(totalIndex, { required: !e.target.checked }); updateQuestionsList(quizId, totalIndex, {
required: !e.target.checked,
});
}} }}
/> />
<Box sx={{ display: "flex" }}> <Box sx={{ display: "flex" }}>
<CustomCheckbox <CustomCheckbox
label={"Внутреннее название вопроса"} label={"Внутреннее название вопроса"}
checked={listQuestions[totalIndex].content.innerNameCheck} checked={listQuestions[quizId][totalIndex].content.innerNameCheck}
handleChange={(e) => { handleChange={(e) => {
let clonContent = listQuestions[totalIndex].content; let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.innerNameCheck = e.target.checked; clonContent.innerNameCheck = e.target.checked;
if (!e.target.checked) { if (!e.target.checked) {
clonContent.innerName = ""; clonContent.innerName = "";
} }
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}} }}
/>{" "} />{" "}
<InfoIcon /> <InfoIcon />
</Box> </Box>
{listQuestions[totalIndex].content.innerNameCheck && ( {listQuestions[quizId][totalIndex].content.innerNameCheck && (
<CustomTextField <CustomTextField
placeholder={"Развёрнутое описание вопроса"} placeholder={"Развёрнутое описание вопроса"}
text={listQuestions[totalIndex].content.innerName} text={listQuestions[quizId][totalIndex].content.innerName}
onChange={({ target }) => { onChange={({ target }) => {
let clonContent = listQuestions[totalIndex].content; let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.innerName = target.value; clonContent.innerName = target.value;
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}} }}
/> />
)} )}

@ -1,3 +1,4 @@
import { useParams } from "react-router-dom";
import { import {
Box, Box,
Button, Button,
@ -39,6 +40,7 @@ const CONDITIONS = [
export default function BranchingQuestions({ export default function BranchingQuestions({
totalIndex, totalIndex,
}: BranchingQuestionsProps) { }: BranchingQuestionsProps) {
const quizId = Number(useParams().quizId);
const { openedModalSettings, listQuestions } = questionStore(); const { openedModalSettings, listQuestions } = questionStore();
const theme = useTheme(); const theme = useTheme();
@ -99,20 +101,22 @@ export default function BranchingQuestions({
<Select <Select
items={ACTIONS} items={ACTIONS}
activeItemIndex={ activeItemIndex={
listQuestions[totalIndex].content.rule.show ? 0 : 1 listQuestions[quizId][totalIndex].content.rule.show ? 0 : 1
} }
sx={{ maxWidth: "140px" }} sx={{ maxWidth: "140px" }}
onChange={(action) => { onChange={(action) => {
const clonContent = listQuestions[totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.rule.show = action === ACTIONS[0]; clonContent.rule.show = action === ACTIONS[0];
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, {
content: clonContent,
});
}} }}
/> />
<Typography sx={{ color: theme.palette.grey2.main }}> <Typography sx={{ color: theme.palette.grey2.main }}>
если в ответе на вопрос если в ответе на вопрос
</Typography> </Typography>
</Box> </Box>
{listQuestions[totalIndex].content.rule.reqs.map( {listQuestions[quizId][totalIndex].content.rule.reqs.map(
(request, index) => ( (request, index) => (
<Box <Box
key={index} key={index}
@ -137,10 +141,11 @@ export default function BranchingQuestions({
<IconButton <IconButton
sx={{ borderRadius: "6px", padding: "2px" }} sx={{ borderRadius: "6px", padding: "2px" }}
onClick={() => { onClick={() => {
const clonContent = listQuestions[totalIndex].content; const clonContent =
listQuestions[quizId][totalIndex].content;
clonContent.rule.reqs.splice(index, 1); clonContent.rule.reqs.splice(index, 1);
updateQuestionsList(totalIndex, { updateQuestionsList(quizId, totalIndex, {
content: clonContent, content: clonContent,
}); });
}} }}
@ -153,7 +158,8 @@ export default function BranchingQuestions({
activeItemIndex={request.id ? Number(request.id) : -1} activeItemIndex={request.id ? Number(request.id) : -1}
items={STIPULATIONS} items={STIPULATIONS}
onChange={(stipulation) => { onChange={(stipulation) => {
const clonContent = listQuestions[totalIndex].content; const clonContent =
listQuestions[quizId][totalIndex].content;
clonContent.rule.reqs[index] = { clonContent.rule.reqs[index] = {
id: String( id: String(
@ -164,7 +170,9 @@ export default function BranchingQuestions({
vars: request.vars, vars: request.vars,
}; };
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, {
content: clonContent,
});
}} }}
sx={{ marginBottom: "15px" }} sx={{ marginBottom: "15px" }}
/> />
@ -191,7 +199,8 @@ export default function BranchingQuestions({
activeItemIndex={-1} activeItemIndex={-1}
items={ANSWERS} items={ANSWERS}
onChange={(answer) => { onChange={(answer) => {
const clonContent = listQuestions[totalIndex].content; const clonContent =
listQuestions[quizId][totalIndex].content;
const answerItemIndex = ANSWERS.findIndex( const answerItemIndex = ANSWERS.findIndex(
(answerItem) => answerItem === answer (answerItem) => answerItem === answer
); );
@ -201,12 +210,12 @@ export default function BranchingQuestions({
answerItemIndex answerItemIndex
) )
) { ) {
listQuestions[totalIndex].content.rule.reqs[ listQuestions[quizId][totalIndex].content.rule.reqs[
index index
].vars.push(answerItemIndex); ].vars.push(answerItemIndex);
} }
updateQuestionsList(totalIndex, { updateQuestionsList(quizId, totalIndex, {
content: clonContent, content: clonContent,
}); });
}} }}
@ -223,7 +232,7 @@ export default function BranchingQuestions({
gap: "10px", gap: "10px",
}} }}
> >
{listQuestions[totalIndex].content.rule.reqs[ {listQuestions[quizId][totalIndex].content.rule.reqs[
index index
].vars.map((item, varIndex) => ( ].vars.map((item, varIndex) => (
<Chip <Chip
@ -232,7 +241,7 @@ export default function BranchingQuestions({
variant="outlined" variant="outlined"
onDelete={() => { onDelete={() => {
const clonContent = const clonContent =
listQuestions[totalIndex].content; listQuestions[quizId][totalIndex].content;
const removedItemIndex = clonContent.rule.reqs[ const removedItemIndex = clonContent.rule.reqs[
index index
].vars.findIndex((varItem) => varItem === item); ].vars.findIndex((varItem) => varItem === item);
@ -242,7 +251,7 @@ export default function BranchingQuestions({
1 1
); );
updateQuestionsList(totalIndex, { updateQuestionsList(quizId, totalIndex, {
content: clonContent, content: clonContent,
}); });
}} }}
@ -268,9 +277,11 @@ export default function BranchingQuestions({
marginBottom: "10px", marginBottom: "10px",
}} }}
onClick={() => { onClick={() => {
const clonContent = listQuestions[totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.rule.reqs.push({ id: "", vars: [] }); clonContent.rule.reqs.push({ id: "", vars: [] });
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, {
content: clonContent,
});
}} }}
> >
Добавить условие Добавить условие
@ -279,12 +290,15 @@ export default function BranchingQuestions({
<RadioGroup <RadioGroup
aria-labelledby="demo-controlled-radio-buttons-group" aria-labelledby="demo-controlled-radio-buttons-group"
defaultValue={ defaultValue={
listQuestions[totalIndex].content.rule.or ? 0 : 1 listQuestions[quizId][totalIndex].content.rule.or ? 0 : 1
} }
onChange={({ target }) => { onChange={({ target }) => {
const clonContent = listQuestions[totalIndex].content; const clonContent =
listQuestions[quizId][totalIndex].content;
clonContent.rule.or = target.value === CONDITIONS[0]; clonContent.rule.or = target.value === CONDITIONS[0];
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, {
content: clonContent,
});
}} }}
> >
{CONDITIONS.map((condition, index) => ( {CONDITIONS.map((condition, index) => (

@ -1,5 +1,5 @@
import { Box, ButtonBase, Typography } from "@mui/material"; import { Box, ButtonBase, Typography } from "@mui/material";
import * as React from "react"; import { useParams } from "react-router-dom";
import SelectableButton from "@ui_kit/SelectableButton"; import SelectableButton from "@ui_kit/SelectableButton";
import CustomTextField from "@ui_kit/CustomTextField"; import CustomTextField from "@ui_kit/CustomTextField";
import { useState } from "react"; import { useState } from "react";
@ -17,12 +17,13 @@ type HelpQuestionsProps = {
export default function HelpQuestions({ totalIndex }: HelpQuestionsProps) { export default function HelpQuestions({ totalIndex }: HelpQuestionsProps) {
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const [backgroundType, setBackgroundType] = useState<BackgroundType>("text"); const [backgroundType, setBackgroundType] = useState<BackgroundType>("text");
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore(); const { listQuestions } = questionStore();
const videoHC = (url: string) => { const videoHC = (url: string) => {
const clonContent = listQuestions[totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.hint.video = url; clonContent.hint.video = url;
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}; };
return ( return (
@ -60,11 +61,11 @@ export default function HelpQuestions({ totalIndex }: HelpQuestionsProps) {
<> <>
<CustomTextField <CustomTextField
placeholder={"Текст консультанта"} placeholder={"Текст консультанта"}
text={listQuestions[totalIndex].content.hint.text} text={listQuestions[quizId][totalIndex].content.hint.text}
onChange={({ target }) => { onChange={({ target }) => {
let clonContent = listQuestions[totalIndex].content; let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.hint.text = target.value; clonContent.hint.text = target.value;
updateQuestionsList(totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}} }}
/> />
</> </>
@ -77,9 +78,9 @@ export default function HelpQuestions({ totalIndex }: HelpQuestionsProps) {
onClick={() => setOpen(true)} onClick={() => setOpen(true)}
sx={{ justifyContent: "flex-start" }} sx={{ justifyContent: "flex-start" }}
> >
{listQuestions[totalIndex].content.hint.video ? ( {listQuestions[quizId][totalIndex].content.hint.video ? (
<video <video
src={listQuestions[totalIndex].content.hint.video} src={listQuestions[quizId][totalIndex].content.hint.video}
width="400" width="400"
controls controls
/> />
@ -98,7 +99,7 @@ export default function HelpQuestions({ totalIndex }: HelpQuestionsProps) {
<UploadVideoModal <UploadVideoModal
open={open} open={open}
onClose={() => setOpen(false)} onClose={() => setOpen(false)}
video={listQuestions[totalIndex].content.hint.video} video={listQuestions[quizId][totalIndex].content.hint.video}
onUpload={videoHC} onUpload={videoHC}
/> />
</Box> </Box>

@ -89,40 +89,48 @@ export const questionStore = create<QuestionStore>()(
) )
); );
export const updateQuestionsList = ( export const updateQuestionsList = (
questionId: number, quizId: number,
index: number,
data: Partial<Question> data: Partial<Question>
) => { ) => {
const questionListClone = { ...questionStore.getState()["listQuestions"] }; const questionListClone = { ...questionStore.getState()["listQuestions"] };
questionListClone[questionId] = { ...questionListClone[questionId], ...data }; questionListClone[quizId][index] = {
...questionListClone[quizId][index],
...data,
};
questionStore.setState({ listQuestions: questionListClone }); questionStore.setState({ listQuestions: questionListClone });
}; };
export const updateQuestionsListDragAndDrop = ( export const updateQuestionsListDragAndDrop = (
questionId: number, quizId: number,
updatedQuestions: Question[] updatedQuestions: Question[]
) => { ) => {
const questionListClone = { ...questionStore.getState()["listQuestions"] }; const questionListClone = { ...questionStore.getState()["listQuestions"] };
questionStore.setState({ questionStore.setState({
listQuestions: { ...questionListClone, [questionId]: updatedQuestions }, listQuestions: { ...questionListClone, [quizId]: updatedQuestions },
}); });
}; };
export const updateVariants = ( export const updateVariants = (
questionId: number, quizId: number,
index: number, index: number,
variants: Variants[] variants: Variants[]
) => { ) => {
const listQuestions = { ...questionStore.getState()["listQuestions"] }; const listQuestions = { ...questionStore.getState()["listQuestions"] };
listQuestions[questionId][index].content.variants = variants; listQuestions[quizId][index].content.variants = variants;
questionStore.setState({ listQuestions }); questionStore.setState({ listQuestions });
}; };
export const createQuestion = (questionId: number) => { export const createQuestion = (quizId: number) => {
const id = getRandom(1000000, 10000000); const id = getRandom(1000000, 10000000);
const newData = { ...questionStore.getState()["listQuestions"] }; const newData = { ...questionStore.getState()["listQuestions"] };
newData[questionId].push({ if (!newData[quizId]) {
newData[quizId] = [];
}
newData[quizId].push({
id, id,
title: "", title: "",
description: "", description: "",
@ -191,23 +199,20 @@ export const createQuestion = (questionId: number) => {
questionStore.setState({ listQuestions: newData }); questionStore.setState({ listQuestions: newData });
}; };
export const copyQuestion = ( export const copyQuestion = (quizId: number, copiedQuestionIndex: number) => {
questionId: number,
copiedQuestionIndex: number
) => {
const listQuestions = { ...questionStore.getState()["listQuestions"] }; const listQuestions = { ...questionStore.getState()["listQuestions"] };
listQuestions[questionId].push({ listQuestions[quizId].push({
...listQuestions[questionId][copiedQuestionIndex], ...listQuestions[quizId][copiedQuestionIndex],
}); });
questionStore.setState({ listQuestions }); questionStore.setState({ listQuestions });
}; };
export const removeQuestion = (questionId: number, index: number) => { export const removeQuestion = (quizId: number, index: number) => {
const questionListClone = { ...questionStore.getState()["listQuestions"] }; const questionListClone = { ...questionStore.getState()["listQuestions"] };
questionListClone[questionId].splice(index, 1); questionListClone[quizId].splice(index, 1);
questionStore.setState({ listQuestions: questionListClone }); questionStore.setState({ listQuestions: questionListClone });
}; };
@ -216,12 +221,12 @@ export const resetSomeField = (data: Record<string, string>) => {
questionStore.setState(data); questionStore.setState(data);
}; };
export const findQuestionById = (questionId: number) => { export const findQuestionById = (quizId: number) => {
let found = null; let found = null;
questionStore questionStore
.getState() .getState()
["listQuestions"][questionId].some((quiz: Question, index: number) => { ["listQuestions"][quizId].some((quiz: Question, index: number) => {
if (quiz.id === questionId) { if (quiz.id === quizId) {
found = { quiz, index }; found = { quiz, index };
return true; return true;
} }