fix: question store interaction

This commit is contained in:
IlyaDoronin 2023-09-07 17:14:48 +03:00
parent 365287d446
commit 2575d776a4
11 changed files with 223 additions and 59 deletions

@ -1,22 +1,51 @@
import { Box, useTheme } from "@mui/material"; import { Box, useTheme } from "@mui/material";
import type { SxProps } from "@mui/material";
export default function InfoIcon() { type InfoIconProps = {
const theme = useTheme(); sx?: SxProps;
};
return ( export default function InfoIcon({ sx }: InfoIconProps) {
<Box sx={{ const theme = useTheme();
height: "24px",
width: "24px", return (
display: "flex", <Box
alignItems: "center", sx={{
justifyContent: "center", height: "24px",
}}> width: "24px",
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none"> display: "flex",
<path d="M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21Z" stroke={theme.palette.brightPurple.main} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" /> alignItems: "center",
<path d="M11.25 11.25H12V16.5H12.75" stroke={theme.palette.brightPurple.main} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" /> justifyContent: "center",
<path d="M11.8125 9C12.4338 9 12.9375 8.49632 12.9375 7.875C12.9375 7.25368 12.4338 6.75 11.8125 6.75C11.1912 6.75 10.6875 7.25368 10.6875 7.875C10.6875 8.49632 11.1912 9 11.8125 9Z" fill={theme.palette.brightPurple.main} /> ...sx,
</svg> }}
</Box> >
); <svg
} xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
>
<path
d="M12 21C16.9706 21 21 16.9706 21 12C21 7.02944 16.9706 3 12 3C7.02944 3 3 7.02944 3 12C3 16.9706 7.02944 21 12 21Z"
stroke={theme.palette.brightPurple.main}
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M11.25 11.25H12V16.5H12.75"
stroke={theme.palette.brightPurple.main}
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
<path
d="M11.8125 9C12.4338 9 12.9375 8.49632 12.9375 7.875C12.9375 7.25368 12.4338 6.75 11.8125 6.75C11.1912 6.75 10.6875 7.25368 10.6875 7.875C10.6875 8.49632 11.1912 9 11.8125 9Z"
fill={theme.palette.brightPurple.main}
/>
</svg>
</Box>
);
}

@ -67,7 +67,7 @@ export const AnswerItem = ({
const addNewAnswer = () => { const addNewAnswer = () => {
const answerNew = variants.slice(); const answerNew = variants.slice();
answerNew.push({ answer: "", answerLong: "", hints: "" }); answerNew.push({ answer: "", hints: "" });
updateQuestionsList(quizId, totalIndex, { updateQuestionsList(quizId, totalIndex, {
content: { content: {

@ -26,7 +26,7 @@ export default function DropDown({ totalIndex }: Props) {
const addNewAnswer = () => { const addNewAnswer = () => {
const answerNew = variants.slice(); const answerNew = variants.slice();
answerNew.push({ answer: "", answerLong: "", hints: "" }); answerNew.push({ answer: "", hints: "" });
updateQuestionsList(quizId, totalIndex, { updateQuestionsList(quizId, totalIndex, {
content: { content: {

@ -41,7 +41,7 @@ export default function Emoji({ totalIndex }: Props) {
onClick={() => { onClick={() => {
const answerNew = const answerNew =
listQuestions[quizId][totalIndex].content.variants.slice(); listQuestions[quizId][totalIndex].content.variants.slice();
answerNew.push({ answer: "", answerLong: "", hints: "" }); answerNew.push({ answer: "", hints: "" });
updateQuestionsList(quizId, totalIndex, { updateQuestionsList(quizId, totalIndex, {
content: { content: {

@ -79,11 +79,7 @@ export default function OptionsAndPicture({ totalIndex }: Props) {
sx={{ color: theme.palette.brightPurple.main }} sx={{ color: theme.palette.brightPurple.main }}
onClick={() => { onClick={() => {
const clonContent = listQuestions[quizId][totalIndex].content; const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.variants.push({ clonContent.variants.push({ answer: "", hints: "" });
answer: "",
answerLong: "",
hints: "",
});
updateQuestionsList(quizId, totalIndex, { content: clonContent }); updateQuestionsList(quizId, totalIndex, { content: clonContent });
}} }}

@ -1,25 +1,106 @@
import {Box, Typography} from "@mui/material"; import { useParams } from "react-router-dom";
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";
import InfoIcon from "../../../assets/icons/InfoIcon"; import InfoIcon from "../../../assets/icons/InfoIcon";
export default function SettingOptionsAndPict() { import { questionStore, updateQuestionsList } from "@root/questions";
return(
<>
<Box sx={{display: 'flex', width: '100%', justifyContent: 'space-between'}}>
<Box sx={{padding: '20px', width: '100%'}}>
<Typography sx={{marginBottom: '15px'}}>Настройки ответов</Typography>
<CustomCheckbox label={'Вариант "свой ответ"'}/>
<Typography sx={{marginBottom: '15px'}}>Текст-заглушка на картинке</Typography> type SettingOptionsAndPictProps = {
<CustomTextField placeholder={'Пример текста'} text={''}/> totalIndex: number;
</Box> };
<Box sx={{padding: '20px'}}>
<Typography sx={{marginBottom: '15px'}}>Настройки вопросов</Typography> export default function SettingOptionsAndPict({
<CustomCheckbox label={'Необязательный вопрос'}/> totalIndex,
<CustomCheckbox label={'Внутреннее название вопроса'}/> <InfoIcon /> }: SettingOptionsAndPictProps) {
</Box> const quizId = Number(useParams().quizId);
</Box> const { listQuestions } = questionStore();
</>
) return (
} <>
<Box
sx={{ display: "flex", width: "100%", justifyContent: "space-between" }}
>
<Box sx={{ padding: "20px", width: "100%" }}>
<Typography sx={{ marginBottom: "15px" }}>
Настройки ответов
</Typography>
<CustomCheckbox
label={'Вариант "свой ответ"'}
checked={listQuestions[quizId][totalIndex].content.own}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
own: target.checked,
},
});
}}
/>
<Typography sx={{ marginBottom: "15px" }}>
Текст-заглушка на картинке
</Typography>
<CustomTextField
placeholder={"Пример текста"}
text={listQuestions[quizId][totalIndex].content.replText}
onChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
replText: target.value,
},
});
}}
/>
</Box>
<Box sx={{ padding: "20px", width: "100%" }}>
<Typography sx={{ marginBottom: "15px" }}>
Настройки вопросов
</Typography>
<CustomCheckbox
label={"Необязательный вопрос"}
checked={listQuestions[quizId][totalIndex].content.required}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
required: target.checked,
},
});
}}
/>
<Box sx={{ display: "flex", alignItems: "center" }}>
<CustomCheckbox
sx={{ width: "100%" }}
label={"Внутреннее название вопроса"}
checked={listQuestions[quizId][totalIndex].content.innerNameCheck}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
innerNameCheck: target.checked,
innerName: "",
},
});
}}
/>{" "}
<InfoIcon />
</Box>
{listQuestions[quizId][totalIndex].content.innerNameCheck && (
<CustomTextField
placeholder={"Развёрнутое описание вопроса"}
text={listQuestions[quizId][totalIndex].content.innerName}
onChange={({ target }) => {
let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.innerName = target.value;
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
});
}}
/>
)}
</Box>
</Box>
</>
);
}

@ -15,7 +15,7 @@ export default function SwitchOptionsAndPict({
}: Props) { }: Props) {
switch (switchState) { switch (switchState) {
case "setting": case "setting":
return <SettingOptionsAndPict />; return <SettingOptionsAndPict totalIndex={totalIndex} />;
break; break;
case "help": case "help":
return <HelpQuestions totalIndex={totalIndex} />; return <HelpQuestions totalIndex={totalIndex} />;

@ -2,6 +2,7 @@ import { useEffect } from "react";
import { useParams } from "react-router-dom"; 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";
import CustomTextField from "@ui_kit/CustomTextField";
import { questionStore, updateQuestionsList } from "@root/questions"; import { questionStore, updateQuestionsList } from "@root/questions";
@ -114,13 +115,14 @@ export default function SettingOpytionsPict({
</Typography> </Typography>
<CustomCheckbox <CustomCheckbox
sx={{ display: "block" }}
label={"Можно несколько"} label={"Можно несколько"}
checked={listQuestions[quizId][totalIndex].content.multi} checked={listQuestions[quizId][totalIndex].content.multi}
handleChange={() => handleChange={({ target }) =>
updateQuestionsList(quizId, totalIndex, { updateQuestionsList(quizId, totalIndex, {
content: { content: {
...listQuestions[quizId][totalIndex].content, ...listQuestions[quizId][totalIndex].content,
multi: !listQuestions[quizId][totalIndex].content.multi, multi: target.checked,
}, },
}) })
} }
@ -128,17 +130,27 @@ export default function SettingOpytionsPict({
<CustomCheckbox <CustomCheckbox
label={"Большие картинки"} label={"Большие картинки"}
checked={listQuestions[quizId][totalIndex].content.largeCheck} checked={listQuestions[quizId][totalIndex].content.largeCheck}
handleChange={() => handleChange={({ target }) =>
updateQuestionsList(quizId, totalIndex, { updateQuestionsList(quizId, totalIndex, {
content: { content: {
...listQuestions[quizId][totalIndex].content, ...listQuestions[quizId][totalIndex].content,
largeCheck: largeCheck: target.checked,
!listQuestions[quizId][totalIndex].content.largeCheck, },
})
}
/>
<CustomCheckbox
label={'Вариант "свой ответ"'}
checked={listQuestions[quizId][totalIndex].content.own}
handleChange={({ target }) =>
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
own: target.checked,
}, },
}) })
} }
/> />
<CustomCheckbox label={'Вариант "свой ответ"'} />
</Box> </Box>
<Box sx={{ padding: "20px" }}> <Box sx={{ padding: "20px" }}>
<Typography sx={{ marginBottom: "15px" }}>Форма</Typography> <Typography sx={{ marginBottom: "15px" }}>Форма</Typography>
@ -181,8 +193,48 @@ export default function SettingOpytionsPict({
<Typography sx={{ marginBottom: "15px" }}> <Typography sx={{ marginBottom: "15px" }}>
Настройки вопросов Настройки вопросов
</Typography> </Typography>
<CustomCheckbox label={"Необязательный вопрос"} /> <CustomCheckbox
<CustomCheckbox label={"Внутреннее название вопроса"} /> <InfoIcon /> label={"Необязательный вопрос"}
checked={listQuestions[quizId][totalIndex].content.required}
handleChange={({ target }) =>
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
required: target.checked,
},
})
}
/>
<Box sx={{ display: "flex" }}>
<CustomCheckbox
sx={{ width: "100%" }}
label={"Внутреннее название вопроса"}
checked={listQuestions[quizId][totalIndex].content.innerNameCheck}
handleChange={({ target }) =>
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
innerNameCheck: target.checked,
innerName: "",
},
})
}
/>
<InfoIcon />
</Box>
{listQuestions[quizId][totalIndex].content.innerNameCheck && (
<CustomTextField
placeholder={"Внутреннее описание вопроса"}
text={listQuestions[quizId][totalIndex].content.innerName}
onChange={({ target }) => {
let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.innerName = target.value;
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
});
}}
/>
)}
</Box> </Box>
</Box> </Box>
</> </>

@ -26,7 +26,7 @@ export default function AnswerOptions({ totalIndex }: Props) {
const addNewAnswer = () => { const addNewAnswer = () => {
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: "", hints: "" });
updateQuestionsList(quizId, totalIndex, { updateQuestionsList(quizId, totalIndex, {
content: { content: {

@ -3,7 +3,6 @@ import { persist } from "zustand/middleware";
export type Variants = { export type Variants = {
answer: string; answer: string;
answerLong: string;
hints: string; hints: string;
}; };
@ -63,6 +62,8 @@ export interface Question {
start: number; start: number;
step: number; step: number;
chooseRange: boolean; chooseRange: boolean;
required: boolean;
replText: string;
}; };
version: number; version: number;
parent_ids: number[]; parent_ids: number[];
@ -167,10 +168,11 @@ export const createQuestion = (quizId: number) => {
start: 50, start: 50,
step: 1, step: 1,
chooseRange: false, chooseRange: false,
required: false,
replText: "",
variants: [ variants: [
{ {
answer: "", answer: "",
answerLong: "",
hints: "", hints: "",
}, },
], ],

@ -1,14 +1,17 @@
import { FormControlLabel, Checkbox, useTheme, Box } from "@mui/material"; import { FormControlLabel, Checkbox, useTheme, Box } from "@mui/material";
import React from "react"; import React from "react";
import type { SxProps } from "@mui/material";
interface Props { interface Props {
label: string; label: string;
handleChange?: (event: React.ChangeEvent<HTMLInputElement>) => void; handleChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
checked?: boolean; checked?: boolean;
sx?: SxProps;
} }
export default function CustomCheckbox({ label, handleChange, checked}: Props) { export default function CustomCheckbox({ label, handleChange, checked, sx}: Props) {
const theme = useTheme(); const theme = useTheme();
return ( return (
@ -25,6 +28,7 @@ export default function CustomCheckbox({ label, handleChange, checked}: Props) {
color: theme.palette.grey2.main, color: theme.palette.grey2.main,
ml: "-9px", ml: "-9px",
userSelect: "none", userSelect: "none",
...sx,
}} }}
/> />