refactor: clonedContent

This commit is contained in:
IlyaDoronin 2023-10-04 12:45:51 +03:00
parent 8f32af7d7e
commit 149c618597
13 changed files with 166 additions and 184 deletions

@ -175,7 +175,7 @@ export const AnswerItem = ({
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
...question.content,
variants: cloneVariants,
},
});

@ -150,8 +150,11 @@ export default function QuestionsPageCard({
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const { listQuestions } = questionStore();
const { type: switchState, expanded: isExpanded } =
listQuestions[quizId][totalIndex];
const {
title,
type: switchState,
expanded: isExpanded,
} = listQuestions[quizId][totalIndex];
const anchorRef = useRef(null);
const debounced = useDebouncedCallback((title) => {
updateQuestionsList(quizId, totalIndex, { title });
@ -187,7 +190,7 @@ export default function QuestionsPageCard({
}}
>
<TextField
defaultValue={listQuestions[quizId][totalIndex].title}
defaultValue={title}
placeholder={"Заголовок вопроса"}
onChange={({ target }) => debounced(target.value)}
InputProps={{

@ -43,10 +43,7 @@ export default function Emoji({ totalIndex }: Props) {
answerNew.push({ answer: "", hints: "", extendedText: "" });
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
variants: answerNew,
},
content: { ...question.content, variants: answerNew },
});
}}
>

@ -61,14 +61,14 @@ export default function OptionsAndPicture({ totalIndex }: Props) {
<input
onChange={({ target }) => {
if (target.files?.length) {
const clonContent = { ...question.content };
const clonedContent = { ...question.content };
clonContent.variants[index].answer = URL.createObjectURL(
clonedContent.variants[index].answer = URL.createObjectURL(
target.files[0]
);
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
content: clonedContent,
});
}
}}
@ -196,9 +196,15 @@ export default function OptionsAndPicture({ totalIndex }: Props) {
variant="body2"
sx={{ color: theme.palette.brightPurple.main }}
onClick={() => {
const clonContent = { ...question.content };
clonContent.variants.push({ answer: "", hints: "", extendedText: "" });
updateQuestionsList(quizId, totalIndex, { content: clonContent });
const clonedContent = { ...question.content };
clonedContent.variants.push({
answer: "",
hints: "",
extendedText: "",
});
updateQuestionsList(quizId, totalIndex, {
content: clonedContent,
});
}}
>
Добавьте ответ

@ -48,12 +48,12 @@ export default function OptionsPicture({ totalIndex }: Props) {
const addImage = ({ target }: ChangeEvent<HTMLInputElement>) => {
// if (target.files?.length) {
// const clonContent = question.content;
// const clonedContent = { ...question.content };
// clonContent.images.push(URL.createObjectURL(target.files[0]));
// clonedContent.images.push(URL.createObjectURL(target.files[0]));
// updateQuestionsList(quizId, totalIndex, {
// content: { ...question.content, images },
// content: clonedContent,
// });
// }
};

@ -83,7 +83,7 @@ export default function SettingTextField({
}
})}
onChange={({ target }: React.ChangeEvent<HTMLInputElement>) => {
const clonContent = {
const clonedContent = {
...question.content,
single: false,
multi: false,
@ -91,7 +91,7 @@ export default function SettingTextField({
[ANSWER_TYPES[Number(target.value)].value]: true,
};
updateQuestionsList(quizId, totalIndex, { content: clonContent });
updateQuestionsList(quizId, totalIndex, { content: clonedContent });
}}
>
{ANSWER_TYPES.map(({ name }, index) => (

@ -132,7 +132,7 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
<CustomCheckbox
sx={{ display: "block", mr: isMobile ? "0px" : "16px" }}
label={"Необязательный вопрос"}
checked={!listQuestions[quizId][totalIndex].required}
checked={!question.required}
handleChange={(e) => {
updateQuestionsList(quizId, totalIndex, {
required: !e.target.checked,

@ -57,7 +57,7 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
<CustomCheckbox
sx={{ mr: isMobile ? "0px" : "16px" }}
label={"Необязательный вопрос"}
checked={!listQuestions[quizId][totalIndex].required}
checked={!question.required}
handleChange={(e) => {
updateQuestionsList(quizId, totalIndex, {
required: !e.target.checked,

@ -93,7 +93,6 @@ export const BUTTON_TYPE_QUESTIONS: ButtonTypeQuestion[] = [
export default function TypeQuestions({ totalIndex }: Props) {
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore();
const switchState = listQuestions[quizId][totalIndex].type;
return (
<Box

@ -30,10 +30,7 @@ export default function AnswerOptions({ totalIndex }: Props) {
answerNew.push({ answer: "", hints: "", extendedText: "" });
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
variants: answerNew,
},
content: { ...question.content, variants: answerNew },
});
};

@ -141,15 +141,17 @@ export default function BranchingQuestions({
>
<Select
items={ACTIONS}
activeItemIndex={
listQuestions[quizId][totalIndex].content.rule.show ? 0 : 1
}
activeItemIndex={question.content.rule.show ? 0 : 1}
sx={{ maxWidth: "140px" }}
onChange={(action) => {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.rule.show = action === ACTIONS[0];
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
content: {
...question.content,
rule: {
...question.content.rule,
show: action === ACTIONS[0],
},
},
});
}}
/>
@ -157,153 +159,144 @@ export default function BranchingQuestions({
если в ответе на вопрос
</Typography>
</Box>
{listQuestions[quizId][totalIndex].content.rule.reqs.map(
(request, index) => (
{question.content.rule.reqs.map((request, index) => (
<Box
key={index}
sx={{
padding: "20px",
borderRadius: "8px",
height: "100%",
bgcolor: "#F2F3F7",
}}
>
<Box
key={index}
sx={{
padding: "20px",
borderRadius: "8px",
height: "100%",
bgcolor: "#F2F3F7",
display: "flex",
justifyContent: "space-between",
alignItems: "center",
pb: "5px",
}}
>
<Box
sx={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
pb: "5px",
}}
>
<Typography sx={{ color: "#4D4D4D", fontWeight: "500" }}>
Условие 1
</Typography>
<IconButton
sx={{ borderRadius: "6px", padding: "2px" }}
onClick={() => {
const clonContent =
listQuestions[quizId][totalIndex].content;
clonContent.rule.reqs.splice(index, 1);
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
});
}}
>
<DeleteIcon color={"#4D4D4D"} />
</IconButton>
</Box>
<Select
empty
activeItemIndex={request.id ? Number(request.id) : -1}
items={STIPULATIONS}
onChange={(stipulation) => {
const clonContent =
listQuestions[quizId][totalIndex].content;
clonContent.rule.reqs[index] = {
id: String(
STIPULATIONS.findIndex((item) =>
item.includes(stipulation)
)
),
vars: request.vars,
};
<Typography sx={{ color: "#4D4D4D", fontWeight: "500" }}>
Условие 1
</Typography>
<IconButton
sx={{ borderRadius: "6px", padding: "2px" }}
onClick={() => {
const clonedContent = { ...question.content };
clonedContent.rule.reqs.splice(index, 1);
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
content: clonedContent,
});
}}
sx={{ marginBottom: "15px" }}
/>
{request.id && (
<>
<Box
sx={{
display: "flex",
alignItems: "center",
pb: "10px",
}}
>
<Typography
sx={{ color: "#4D4D4D", fontWeight: "500" }}
>
Дан ответ
</Typography>
<Typography sx={{ color: "#7E2AEA", pl: "10px" }}>
(Укажите один или несколько вариантов)
</Typography>
</Box>
<Select
empty
activeItemIndex={-1}
items={ANSWERS}
onChange={(answer) => {
const clonContent =
listQuestions[quizId][totalIndex].content;
const answerItemIndex = ANSWERS.findIndex(
(answerItem) => answerItem === answer
>
<DeleteIcon color={"#4D4D4D"} />
</IconButton>
</Box>
<Select
empty
activeItemIndex={request.id ? Number(request.id) : -1}
items={STIPULATIONS}
onChange={(stipulation) => {
const clonedContent = { ...question.content };
clonedContent.rule.reqs[index] = {
id: String(
STIPULATIONS.findIndex((item) =>
item.includes(stipulation)
)
),
vars: request.vars,
};
updateQuestionsList(quizId, totalIndex, {
content: clonedContent,
});
}}
sx={{ marginBottom: "15px" }}
/>
{request.id && (
<>
<Box
sx={{
display: "flex",
alignItems: "center",
pb: "10px",
}}
>
<Typography sx={{ color: "#4D4D4D", fontWeight: "500" }}>
Дан ответ
</Typography>
<Typography sx={{ color: "#7E2AEA", pl: "10px" }}>
(Укажите один или несколько вариантов)
</Typography>
</Box>
<Select
empty
activeItemIndex={-1}
items={ANSWERS}
onChange={(answer) => {
const clonedContent = { ...question.content };
const answerItemIndex = ANSWERS.findIndex(
(answerItem) => answerItem === answer
);
if (
!clonedContent.rule.reqs[index].vars.includes(
answerItemIndex
)
) {
question.content.rule.reqs[index].vars.push(
answerItemIndex
);
}
if (
!clonContent.rule.reqs[index].vars.includes(
answerItemIndex
)
) {
listQuestions[quizId][totalIndex].content.rule.reqs[
index
].vars.push(answerItemIndex);
}
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
});
}}
sx={{
marginBottom: "10px",
".MuiSelect-select.MuiInputBase-input": {
color: "transparent",
},
}}
/>
<Box
sx={{
display: "flex",
gap: "10px",
}}
>
{listQuestions[quizId][totalIndex].content.rule.reqs[
index
].vars.map((item, varIndex) => (
updateQuestionsList(quizId, totalIndex, {
content: clonedContent,
});
}}
sx={{
marginBottom: "10px",
".MuiSelect-select.MuiInputBase-input": {
color: "transparent",
},
}}
/>
<Box
sx={{
display: "flex",
gap: "10px",
}}
>
{question.content.rule.reqs[index].vars.map(
(item, varIndex) => (
<Chip
key={varIndex}
label={ANSWERS[item]}
variant="outlined"
onDelete={() => {
const clonContent =
listQuestions[quizId][totalIndex].content;
const removedItemIndex = clonContent.rule.reqs[
const clonedContent = { ...question.content };
const removedItemIndex = clonedContent.rule.reqs[
index
].vars.findIndex((varItem) => varItem === item);
clonContent.rule.reqs[index].vars.splice(
clonedContent.rule.reqs[index].vars.splice(
removedItemIndex,
1
);
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
content: clonedContent,
});
}}
/>
))}
</Box>
</>
)}
</Box>
)
)}
)
)}
</Box>
</>
)}
</Box>
))}
<Box
sx={{
display: "flex",
@ -318,10 +311,10 @@ export default function BranchingQuestions({
marginBottom: "10px",
}}
onClick={() => {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.rule.reqs.push({ id: "", vars: [] });
const clonedContent = { ...question.content };
clonedContent.rule.reqs.push({ id: "", vars: [] });
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
content: clonedContent,
});
}}
>
@ -330,15 +323,16 @@ export default function BranchingQuestions({
<FormControl>
<RadioGroup
aria-labelledby="demo-controlled-radio-buttons-group"
value={
listQuestions[quizId][totalIndex].content.rule.or ? 1 : 0
}
value={question.content.rule.or ? 1 : 0}
onChange={(_, value) => {
const clonContent =
listQuestions[quizId][totalIndex].content;
clonContent.rule.or = Boolean(Number(value));
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
content: {
...question.content,
rule: {
...question.content.rule,
or: Boolean(Number(value)),
},
},
});
}}
>

@ -33,8 +33,8 @@ export default function HelpQuestions({ totalIndex }: HelpQuestionsProps) {
}, 1000);
const videoHC = (url: string) => {
const clonContent = question.content;
clonContent.hint.video = url;
const clonedContent = { ...question.content };
clonedContent.hint.video = url;
updateQuestionsList(quizId, totalIndex, {
content: {
...question.content,

@ -10,6 +10,8 @@ import type {
AnyQuizQuestion,
QuizQuestionType,
QuestionVariant,
QuestionBranchingRule,
QuestionHint,
} from "../model/questionTypes/shared";
import { QUIZ_QUESTION_BASE } from "../constants/base";
@ -25,22 +27,6 @@ import { QUIZ_QUESTION_TEXT } from "../constants/text";
import { QUIZ_QUESTION_VARIANT } from "../constants/variant";
import { QUIZ_QUESTION_VARIMG } from "../constants/varimg";
type Hint = {
text: string;
video: string;
};
type Rule = {
or: boolean;
show: boolean;
reqs: [
{
id: string;
vars: number[];
}
];
};
export interface Question {
id: number;
title: string;
@ -51,8 +37,8 @@ export interface Question {
page: number;
content: {
variants: QuestionVariant[];
hint: Hint;
rule: Rule;
hint: QuestionHint;
rule: QuestionBranchingRule;
images: string[];
largeCheck: boolean;
large: string;