refactor: updateQuestionsList typing

This commit is contained in:
IlyaDoronin 2023-10-04 14:35:02 +03:00
parent 149c618597
commit 4e92fb934a
31 changed files with 184 additions and 130 deletions

@ -10,6 +10,7 @@ export const QUIZ_QUESTION_PAGE: Omit<QuizQuestionPage, "id"> = {
innerNameCheck: false,
innerName: "",
text: "",
picture: "",
video: "",
},
};

@ -12,6 +12,7 @@ export interface QuizQuestionPage extends QuizQuestionBase {
/** Поле "Внутреннее название вопроса" */
innerName: string;
text: string;
picture: string;
video: string;
hint: QuestionHint;
rule: QuestionBranchingRule;

@ -52,7 +52,7 @@ export const AnswerItem = ({
const answerNew = variants.slice();
answerNew[index].answer = value;
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionVariant>(quizId, totalIndex, {
content: {
...question.content,
variants: answerNew,
@ -76,7 +76,7 @@ export const AnswerItem = ({
const answerNew = variants.slice();
answerNew.push({ answer: "", hints: "", extendedText: "" });
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionVariant>(quizId, totalIndex, {
content: { ...question.content, variants: answerNew },
});
};
@ -85,7 +85,7 @@ export const AnswerItem = ({
const answerNew = variants.slice();
answerNew.splice(index, 1);
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionVariant>(quizId, totalIndex, {
content: { ...question.content, variants: answerNew },
});
};
@ -94,7 +94,7 @@ export const AnswerItem = ({
const answerNew = variants.slice();
answerNew[index].hints = event.target.value;
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionVariant>(quizId, totalIndex, {
content: { ...question.content, variants: answerNew },
});
};
@ -173,12 +173,16 @@ export const AnswerItem = ({
extendedText: native,
};
updateQuestionsList(quizId, totalIndex, {
content: {
...question.content,
variants: cloneVariants,
},
});
updateQuestionsList<QuizQuestionVariant>(
quizId,
totalIndex,
{
content: {
...question.content,
variants: cloneVariants,
},
}
);
}}
/>
</Popover>

@ -33,7 +33,7 @@ export default function DataOptions({ totalIndex }: Props) {
useEffect(() => {
if (question.content.type !== "mask") {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionDate>(quizId, totalIndex, {
content: { ...question.content, type: "calendar" },
});
}
@ -55,7 +55,7 @@ export default function DataOptions({ totalIndex }: Props) {
<SelectableButton
isSelected={question.content.type === "calendar"}
onClick={() => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionDate>(quizId, totalIndex, {
content: { ...question.content, type: "calendar" },
});
}}
@ -66,7 +66,7 @@ export default function DataOptions({ totalIndex }: Props) {
<SelectableButton
isSelected={question.content.type === "mask"}
onClick={() => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionDate>(quizId, totalIndex, {
content: { ...question.content, type: "mask" },
});
}}

@ -26,7 +26,7 @@ export default function SettingsData({ totalIndex }: SettingsDataProps) {
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const question = listQuestions[quizId][totalIndex] as QuizQuestionDate;
const debounced = useDebouncedCallback((value) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionDate>(quizId, totalIndex, {
content: { ...question.content, innerName: value },
});
}, 1000);
@ -46,7 +46,7 @@ export default function SettingsData({ totalIndex }: SettingsDataProps) {
label={"Выбор диапазона дат"}
checked={question.content.dateRange}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionDate>(quizId, totalIndex, {
content: { ...question.content, dateRange: target.checked },
});
}}
@ -56,7 +56,7 @@ export default function SettingsData({ totalIndex }: SettingsDataProps) {
label={"Выбор времени"}
checked={question.content.time}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionDate>(quizId, totalIndex, {
content: { ...question.content, time: target.checked },
});
}}
@ -77,7 +77,7 @@ export default function SettingsData({ totalIndex }: SettingsDataProps) {
label={"Необязательный вопрос"}
checked={!question.required}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionDate>(quizId, totalIndex, {
required: !target.checked,
});
}}
@ -94,7 +94,7 @@ export default function SettingsData({ totalIndex }: SettingsDataProps) {
label={"Внутреннее название вопроса"}
checked={question.content.innerNameCheck}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionDate>(quizId, totalIndex, {
content: {
...question.content,
innerNameCheck: target.checked,

@ -18,12 +18,14 @@ import {
updateQuestionsList,
removeQuestion,
createQuestion,
DEFAULT_QUESTION,
} from "@root/questions";
import { BUTTON_TYPE_QUESTIONS } from "../TypeQuestions";
import type { RefObject } from "react";
import type { QuizQuestionType } from "../../../model/questionTypes/shared";
import type {
QuizQuestionType,
QuizQuestionBase,
} from "../../../model/questionTypes/shared";
type ChooseAnswerModalProps = {
open: boolean;
@ -116,7 +118,7 @@ export const ChooseAnswerModal = ({
removeQuestion(quizId, totalIndex);
createQuestion(quizId, selectedValue, totalIndex);
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionBase>(quizId, totalIndex, {
expanded: question.expanded,
});
}}

@ -48,6 +48,7 @@ import RatingIcon from "@icons/questionsPage/rating";
import { ReactComponent as PlusIcon } from "../../../assets/icons/plus.svg";
import type { DraggableProvidedDragHandleProps } from "react-beautiful-dnd";
import type { QuizQuestionBase } from "../../../model/questionTypes/shared";
interface Props {
totalIndex: number;
@ -157,7 +158,7 @@ export default function QuestionsPageCard({
} = listQuestions[quizId][totalIndex];
const anchorRef = useRef(null);
const debounced = useDebouncedCallback((title) => {
updateQuestionsList(quizId, totalIndex, { title });
updateQuestionsList<QuizQuestionBase>(quizId, totalIndex, { title });
}, 1000);
return (
@ -252,7 +253,7 @@ export default function QuestionsPageCard({
>
<IconButton
onClick={() =>
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionBase>(quizId, totalIndex, {
expanded: !isExpanded,
})
}

@ -31,7 +31,7 @@ export default function DropDown({ totalIndex }: Props) {
const answerNew = question.content.variants.slice();
answerNew.push({ answer: "", hints: "", extendedText: "" });
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionSelect>(quizId, totalIndex, {
content: { ...question.content, variants: answerNew },
});
};

@ -22,12 +22,12 @@ export default function SettingDropDown({ totalIndex }: SettingDropDownProps) {
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const question = listQuestions[quizId][totalIndex] as QuizQuestionSelect;
const debounced = useDebouncedCallback((value) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionSelect>(quizId, totalIndex, {
content: { ...question.content, innerName: value },
});
}, 1000);
const debounceAnswer = useDebouncedCallback((value) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionSelect>(quizId, totalIndex, {
content: { ...question.content, default: value },
});
}, 1000);
@ -56,7 +56,7 @@ export default function SettingDropDown({ totalIndex }: SettingDropDownProps) {
label={"Можно несколько"}
checked={question.content.multi}
handleChange={({ target }) =>
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionSelect>(quizId, totalIndex, {
content: { ...question.content, multi: target.checked },
})
}
@ -81,7 +81,7 @@ export default function SettingDropDown({ totalIndex }: SettingDropDownProps) {
label={"Необязательный вопрос"}
checked={!question.required}
handleChange={(e) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionSelect>(quizId, totalIndex, {
required: !e.target.checked,
});
}}
@ -93,7 +93,7 @@ export default function SettingDropDown({ totalIndex }: SettingDropDownProps) {
label={"Внутреннее название вопроса"}
checked={question.content.innerNameCheck}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionSelect>(quizId, totalIndex, {
content: {
...question.content,
innerNameCheck: target.checked,

@ -42,7 +42,7 @@ export default function Emoji({ totalIndex }: Props) {
const answerNew = question.content.variants.slice();
answerNew.push({ answer: "", hints: "", extendedText: "" });
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionEmoji>(quizId, totalIndex, {
content: { ...question.content, variants: answerNew },
});
}}

@ -26,7 +26,7 @@ export default function SettingEmoji({ totalIndex }: SettingEmojiProps) {
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const question = listQuestions[quizId][totalIndex] as QuizQuestionEmoji;
const debounced = useDebouncedCallback((value) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionEmoji>(quizId, totalIndex, {
content: { ...question.content, innerName: value },
});
}, 1000);
@ -46,7 +46,7 @@ export default function SettingEmoji({ totalIndex }: SettingEmojiProps) {
label={"Можно несколько"}
checked={question.content.multi}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionEmoji>(quizId, totalIndex, {
content: { ...question.content, multi: target.checked },
});
}}
@ -56,8 +56,8 @@ export default function SettingEmoji({ totalIndex }: SettingEmojiProps) {
label={'Вариант "свой ответ"'}
checked={question.content.own}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
content: { ...question.content, own: target },
updateQuestionsList<QuizQuestionEmoji>(quizId, totalIndex, {
content: { ...question.content, own: target.checked },
});
}}
/>
@ -77,7 +77,7 @@ export default function SettingEmoji({ totalIndex }: SettingEmojiProps) {
label={"Необязательный вопрос"}
checked={!question.required}
handleChange={(e) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionEmoji>(quizId, totalIndex, {
required: !e.target.checked,
});
}}
@ -94,7 +94,7 @@ export default function SettingEmoji({ totalIndex }: SettingEmojiProps) {
label={"Внутреннее название вопроса"}
checked={question.content.innerNameCheck}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionEmoji>(quizId, totalIndex, {
content: {
...question.content,
innerNameCheck: target.checked,

@ -67,9 +67,13 @@ export default function OptionsAndPicture({ totalIndex }: Props) {
target.files[0]
);
updateQuestionsList(quizId, totalIndex, {
content: clonedContent,
});
updateQuestionsList<QuizQuestionVarImg>(
quizId,
totalIndex,
{
content: clonedContent,
}
);
}
}}
hidden
@ -202,7 +206,7 @@ export default function OptionsAndPicture({ totalIndex }: Props) {
hints: "",
extendedText: "",
});
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionVarImg>(quizId, totalIndex, {
content: clonedContent,
});
}}

@ -29,12 +29,12 @@ export default function SettingOptionsAndPict({
const isMobile = useMediaQuery(theme.breakpoints.down(680));
const question = listQuestions[quizId][totalIndex] as QuizQuestionVarImg;
const debounced = useDebouncedCallback((replText) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionVarImg>(quizId, totalIndex, {
content: { ...question.content, replText },
});
}, 1000);
const debounceDescription = useDebouncedCallback((value) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionVarImg>(quizId, totalIndex, {
content: { ...question.content, innerName: value },
});
}, 1000);
@ -65,7 +65,7 @@ export default function SettingOptionsAndPict({
label={'Вариант "свой ответ"'}
checked={question.content.own}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionVarImg>(quizId, totalIndex, {
content: { ...question.content, own: target.checked },
});
}}
@ -104,7 +104,7 @@ export default function SettingOptionsAndPict({
label={"Необязательный вопрос"}
checked={question.content.required}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionVarImg>(quizId, totalIndex, {
content: { ...question.content, required: target.checked },
});
}}
@ -118,7 +118,7 @@ export default function SettingOptionsAndPict({
label={"Внутреннее название вопроса"}
checked={question.content.innerNameCheck}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionVarImg>(quizId, totalIndex, {
content: {
...question.content,
innerNameCheck: target.checked,

@ -52,7 +52,7 @@ export default function OptionsPicture({ totalIndex }: Props) {
// clonedContent.images.push(URL.createObjectURL(target.files[0]));
// updateQuestionsList(quizId, totalIndex, {
// updateQuestionsList<QuizQuestionImages>(quizId, totalIndex, {
// content: clonedContent,
// });
// }

@ -24,7 +24,8 @@ import ProportionsIcon12 from "../../../assets/icons/questionsPage/ProportionsIc
import type { QuizQuestionImages } from "../../../model/questionTypes/images";
interface Props {
Icon: React.ElementType;
Icon: (props: { color: string }) => JSX.Element;
// Icon: React.ElementType;
isActive?: boolean;
onClick: () => void;
}
@ -33,7 +34,14 @@ type SettingOpytionsPictProps = {
totalIndex: number;
};
const PROPORTIONS = [
type Proportion = "1:1" | "2:1" | "1:2";
type ProportionItem = {
value: Proportion;
icon: (props: { color: string }) => JSX.Element;
};
const PROPORTIONS: ProportionItem[] = [
{ value: "1:1", icon: ProportionsIcon11 },
{ value: "2:1", icon: ProportionsIcon21 },
{ value: "1:2", icon: ProportionsIcon12 },
@ -90,7 +98,7 @@ export default function SettingOpytionsPict({
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const question = listQuestions[quizId][totalIndex] as QuizQuestionImages;
const debounced = useDebouncedCallback((value) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionImages>(quizId, totalIndex, {
content: { ...question.content, innerName: value },
});
}, 1000);
@ -101,8 +109,8 @@ export default function SettingOpytionsPict({
}
}, []);
const updateProportions = (proportions: string) => {
updateQuestionsList(quizId, totalIndex, {
const updateProportions = (proportions: Proportion) => {
updateQuestionsList<QuizQuestionImages>(quizId, totalIndex, {
content: { ...question.content, xy: proportions },
});
};
@ -145,7 +153,7 @@ export default function SettingOpytionsPict({
label={"Можно несколько"}
checked={question.content.multi}
handleChange={({ target }) =>
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionImages>(quizId, totalIndex, {
content: { ...question.content, multi: target.checked },
})
}
@ -155,7 +163,7 @@ export default function SettingOpytionsPict({
label={"Большие картинки"}
checked={question.content.largeCheck}
handleChange={({ target }) =>
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionImages>(quizId, totalIndex, {
content: { ...question.content, largeCheck: target.checked },
})
}
@ -165,7 +173,7 @@ export default function SettingOpytionsPict({
label={'Вариант "свой ответ"'}
checked={question.content.own}
handleChange={({ target }) =>
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionImages>(quizId, totalIndex, {
content: { ...question.content, own: target.checked },
})
}
@ -182,7 +190,7 @@ export default function SettingOpytionsPict({
>
<SelectIconButton
onClick={() =>
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionImages>(quizId, totalIndex, {
content: { ...question.content, format: "carousel" },
})
}
@ -191,7 +199,7 @@ export default function SettingOpytionsPict({
/>
<SelectIconButton
onClick={() =>
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionImages>(quizId, totalIndex, {
content: { ...question.content, format: "masonry" },
})
}
@ -206,7 +214,7 @@ export default function SettingOpytionsPict({
label={"Необязательный вопрос"}
checked={question.content.required}
handleChange={({ target }) =>
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionImages>(quizId, totalIndex, {
content: { ...question.content, required: target.checked },
})
}
@ -222,7 +230,7 @@ export default function SettingOpytionsPict({
label={"Внутреннее название вопроса"}
checked={question.content.innerNameCheck}
handleChange={({ target }) =>
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionImages>(quizId, totalIndex, {
content: {
...question.content,
innerNameCheck: target.checked,

@ -23,7 +23,7 @@ export default function OwnTextField({ totalIndex }: Props) {
const theme = useTheme();
const question = listQuestions[quizId][totalIndex] as QuizQuestionText;
const debounced = useDebouncedCallback((value) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionText>(quizId, totalIndex, {
content: { ...question.content, placeholder: value },
});
}, 1000);

@ -47,7 +47,7 @@ export default function SettingTextField({
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const question = listQuestions[quizId][totalIndex] as QuizQuestionText;
const debounced = useDebouncedCallback((value) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionText>(quizId, totalIndex, {
content: { ...question.content, innerName: value },
});
}, 1000);
@ -91,7 +91,7 @@ export default function SettingTextField({
[ANSWER_TYPES[Number(target.value)].value]: true,
};
updateQuestionsList(quizId, totalIndex, { content: clonedContent });
updateQuestionsList<QuizQuestionText>(quizId, totalIndex, { content: clonedContent });
}}
>
{ANSWER_TYPES.map(({ name }, index) => (
@ -118,7 +118,7 @@ export default function SettingTextField({
label={"Автозаполнение адреса"}
checked={question.content.autofill}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionText>(quizId, totalIndex, {
content: { ...question.content, autofill: target.checked },
});
}}
@ -128,7 +128,7 @@ export default function SettingTextField({
label={"Необязательный вопрос"}
checked={!question.required}
handleChange={(e) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionText>(quizId, totalIndex, {
required: !e.target.checked,
});
}}
@ -145,7 +145,7 @@ export default function SettingTextField({
label={"Внутреннее название вопроса"}
checked={question.content.innerNameCheck}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionText>(quizId, totalIndex, {
content: {
...question.content,
innerNameCheck: target.checked,

@ -31,7 +31,7 @@ export default function PageOptions({ disableInput, totalIndex }: Props) {
const isMobile = useMediaQuery(theme.breakpoints.down(780));
const question = listQuestions[quizId][totalIndex] as QuizQuestionPage;
const debounced = useDebouncedCallback((value) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionPage>(quizId, totalIndex, {
content: { ...question.content, text: value },
});
}, 1000);
@ -95,7 +95,7 @@ export default function PageOptions({ disableInput, totalIndex }: Props) {
onClose={() => setOpenImageModal(false)}
imgHC={(fileList) => {
if (fileList?.length) {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionPage>(quizId, totalIndex, {
content: {
...question.content,
picture: URL.createObjectURL(fileList[0]),
@ -133,7 +133,7 @@ export default function PageOptions({ disableInput, totalIndex }: Props) {
onClose={() => setOpenVideoModal(false)}
video={question.content.video}
onUpload={(url) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionPage>(quizId, totalIndex, {
content: { ...question.content, video: url },
});
}}

@ -27,7 +27,7 @@ export default function SettingPageOptions({
const { listQuestions } = questionStore();
const question = listQuestions[quizId][totalIndex] as QuizQuestionPage;
const debounced = useDebouncedCallback((value) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionPage>(quizId, totalIndex, {
content: { ...question.content, innerName: value },
});
}, 1000);
@ -58,7 +58,7 @@ export default function SettingPageOptions({
label={"Внутреннее название вопроса"}
checked={question.content.innerNameCheck}
handleChange={({ target }) =>
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionPage>(quizId, totalIndex, {
content: {
...question.content,
innerNameCheck: target.checked,

@ -21,7 +21,7 @@ interface Props {
}
export type ButtonRatingFrom = {
name: string;
name: "star" | "trophie" | "flag" | "heart" | "like" | "bubble" | "hashtag";
icon: JSX.Element;
};
@ -73,9 +73,16 @@ export default function RatingOptions({ totalIndex }: Props) {
{...(itemNumber === 0 || itemNumber === question.content.steps - 1
? {
onClick: () => {
updateQuestionsList(quizId, totalIndex, {
content: { ...question.content, ratingExpanded: true },
});
updateQuestionsList<QuizQuestionRating>(
quizId,
totalIndex,
{
content: {
...question.content,
ratingExpanded: true,
},
}
);
},
sx: {
cursor: "pointer",
@ -135,7 +142,7 @@ export default function RatingOptions({ totalIndex }: Props) {
if (key === "Enter") {
const currentTarget = target as HTMLInputElement;
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionRating>(quizId, totalIndex, {
content: {
...question.content,
ratingDescription: currentTarget.value.substring(0, 20),
@ -144,7 +151,7 @@ export default function RatingOptions({ totalIndex }: Props) {
}
}}
onBlur={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionRating>(quizId, totalIndex, {
content: {
...question.content,
ratingDescription: target.value.substring(0, 20),

@ -38,7 +38,7 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
const { listQuestions } = questionStore();
const question = listQuestions[quizId][totalIndex] as QuizQuestionNumber;
const debounced = useDebouncedCallback((value) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionNumber>(quizId, totalIndex, {
content: { ...question.content, innerName: value },
});
}, 1000);
@ -82,7 +82,7 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
<ButtonBase
key={index}
onClick={() => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionNumber>(quizId, totalIndex, {
content: { ...question.content, form: name },
});
}}
@ -121,7 +121,7 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
valueLabelDisplay="auto"
sx={{ color: theme.palette.brightPurple.main }}
onChange={(_, value) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionNumber>(quizId, totalIndex, {
content: { ...question.content, steps: Number(value) || 1 },
});
}}
@ -134,7 +134,7 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
label={"Необязательный вопрос"}
checked={!question.required}
handleChange={(e) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionNumber>(quizId, totalIndex, {
required: !e.target.checked,
});
}}
@ -151,7 +151,7 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
label={"Внутреннее название вопроса"}
checked={question.content.innerNameCheck}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionNumber>(quizId, totalIndex, {
content: {
...question.content,
innerNameCheck: target.checked,

@ -56,7 +56,7 @@ export default function SliderOptions({ totalIndex }: Props) {
max={99}
value={question.content.range.split("—")[0]}
onChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionNumber>(quizId, totalIndex, {
content: {
...question.content,
range: `${target.value}${
@ -71,7 +71,7 @@ export default function SliderOptions({ totalIndex }: Props) {
const max = Number(question.content.range.split("—")[1]);
if (min >= max) {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionNumber>(quizId, totalIndex, {
content: {
...question.content,
range: `${max - 1 >= 0 ? max - 1 : 0}${
@ -82,7 +82,7 @@ export default function SliderOptions({ totalIndex }: Props) {
}
if (start < min) {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionNumber>(quizId, totalIndex, {
content: { ...question.content, start: min },
});
}
@ -95,7 +95,7 @@ export default function SliderOptions({ totalIndex }: Props) {
max={100}
value={question.content.range.split("—")[1]}
onChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionNumber>(quizId, totalIndex, {
content: {
...question.content,
range: `${question.content.range.split("—")[0]}${
@ -112,7 +112,7 @@ export default function SliderOptions({ totalIndex }: Props) {
const range = max - min;
if (max <= min) {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionNumber>(quizId, totalIndex, {
content: {
...question.content,
range: `${question.content.range.split("—")[0]}${
@ -123,13 +123,13 @@ export default function SliderOptions({ totalIndex }: Props) {
}
if (start > max) {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionNumber>(quizId, totalIndex, {
content: { ...question.content, start: max },
});
}
if (step > max) {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionNumber>(quizId, totalIndex, {
content: { ...question.content, step: max },
});
@ -173,7 +173,7 @@ export default function SliderOptions({ totalIndex }: Props) {
max={Number(question.content.range.split("—")[1])}
value={String(question.content.start)}
onChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionNumber>(quizId, totalIndex, {
content: { ...question.content, start: Number(target.value) },
});
}}
@ -197,7 +197,7 @@ export default function SliderOptions({ totalIndex }: Props) {
error={stepError}
value={String(question.content.step)}
onChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionNumber>(quizId, totalIndex, {
content: { ...question.content, step: Number(target.value) },
});
}}
@ -208,7 +208,7 @@ export default function SliderOptions({ totalIndex }: Props) {
const step = Number(target.value);
if (step > max) {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionNumber>(quizId, totalIndex, {
content: { ...question.content, step: max },
});
}

@ -26,7 +26,7 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const question = listQuestions[quizId][totalIndex] as QuizQuestionNumber;
const debounced = useDebouncedCallback((value) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionNumber>(quizId, totalIndex, {
content: { ...question.content, innerName: value },
});
}, 1000);
@ -46,7 +46,7 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
label={"Выбор диапозона (два ползунка)"}
checked={question.content.chooseRange}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionNumber>(quizId, totalIndex, {
content: { ...question.content, chooseRange: target.checked },
});
}}
@ -59,7 +59,7 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
label={"Необязательный вопрос"}
checked={!question.required}
handleChange={(e) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionNumber>(quizId, totalIndex, {
required: !e.target.checked,
});
}}
@ -76,7 +76,7 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
label={"Внутреннее название вопроса"}
checked={question.content.innerNameCheck}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionNumber>(quizId, totalIndex, {
content: {
...question.content,
innerNameCheck: target.checked,

@ -20,7 +20,10 @@ import {
removeQuestion,
} from "@root/questions";
import type { QuizQuestionType } from "../../model/questionTypes/shared";
import type {
QuizQuestionType,
QuizQuestionBase,
} from "../../model/questionTypes/shared";
interface Props {
totalIndex: number;
@ -111,7 +114,7 @@ export default function TypeQuestions({ totalIndex }: Props) {
removeQuestion(quizId, totalIndex);
createQuestion(quizId, value, totalIndex);
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionBase>(quizId, totalIndex, {
expanded: question.expanded,
});
}}

@ -18,13 +18,22 @@ import InfoIcon from "../../../assets/icons/InfoIcon";
import ArrowDown from "../../../assets/icons/ArrowDownIcon";
import SwitchUpload from "./switchUpload";
import type { QuizQuestionFile } from "../../../model/questionTypes/file";
import type { AnyQuizQuestion } from "../../../model/questionTypes/shared";
import type {
QuizQuestionFile,
UploadFileType,
} from "../../../model/questionTypes/file";
interface Props {
totalIndex: number;
}
const DESIGN_TYPES = [
type DesignItem = {
name: string;
value: UploadFileType;
};
const DESIGN_TYPES: DesignItem[] = [
{ name: "Все типы файлов", value: "all" },
{ name: "Изображения", value: "picture" },
{ name: "Видео", value: "video" },
@ -45,8 +54,8 @@ export default function UploadFile({ totalIndex }: Props) {
};
const handleChange = ({ target }: SelectChangeEvent) => {
updateQuestionsList(quizId, totalIndex, {
content: { ...question.content, type: target.value },
updateQuestionsList<AnyQuizQuestion>(quizId, totalIndex, {
content: { ...question.content, type: target.value as UploadFileType },
});
};
@ -56,7 +65,7 @@ export default function UploadFile({ totalIndex }: Props) {
);
if (!isTypeSetted) {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<AnyQuizQuestion>(quizId, totalIndex, {
content: { ...question.content, type: DESIGN_TYPES[0].value },
});
}

@ -26,7 +26,7 @@ export default function SettingsUpload({ totalIndex }: SettingsUploadProps) {
const { listQuestions } = questionStore();
const question = listQuestions[quizId][totalIndex] as QuizQuestionFile;
const debounced = useDebouncedCallback((value) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionFile>(quizId, totalIndex, {
content: { ...question.content, innerName: value },
});
}, 1000);
@ -48,7 +48,7 @@ export default function SettingsUpload({ totalIndex }: SettingsUploadProps) {
label={"Автозаполнение адреса"}
checked={question.content.autofill}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionFile>(quizId, totalIndex, {
content: { ...question.content, autofill: target.checked },
});
}}
@ -58,7 +58,7 @@ export default function SettingsUpload({ totalIndex }: SettingsUploadProps) {
label={"Необязательный вопрос"}
checked={!question.required}
handleChange={(e) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionFile>(quizId, totalIndex, {
required: !e.target.checked,
});
}}
@ -75,7 +75,7 @@ export default function SettingsUpload({ totalIndex }: SettingsUploadProps) {
label={"Внутреннее название вопроса"}
checked={question.content.innerNameCheck}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionFile>(quizId, totalIndex, {
content: {
...question.content,
innerNameCheck: target.checked,

@ -28,9 +28,11 @@ export default function UploadImage({ totalIndex }: UploadImageProps) {
if (files?.length) {
const [file] = Array.from(files);
updateQuestionsList(quizId, totalIndex, {
...question,
back: URL.createObjectURL(file),
updateQuestionsList<QuizQuestionImages>(quizId, totalIndex, {
content: {
...question.content,
back: URL.createObjectURL(file),
},
});
handleClose();

@ -29,7 +29,7 @@ export default function AnswerOptions({ totalIndex }: Props) {
const answerNew = question.content.variants.slice();
answerNew.push({ answer: "", hints: "", extendedText: "" });
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionVariant>(quizId, totalIndex, {
content: { ...question.content, variants: answerNew },
});
};

@ -26,7 +26,7 @@ export default function ResponseSettings({ totalIndex }: Props) {
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const question = listQuestions[quizId][totalIndex] as QuizQuestionVariant;
const debounced = useDebouncedCallback((value) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionVariant>(quizId, totalIndex, {
content: { ...question.content, innerName: value },
});
}, 1000);
@ -55,7 +55,7 @@ export default function ResponseSettings({ totalIndex }: Props) {
label={"Длинный текстовый ответ"}
checked={question.content.largeCheck}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionVariant>(quizId, totalIndex, {
content: {
...question.content,
largeCheck: target.checked,
@ -68,7 +68,7 @@ export default function ResponseSettings({ totalIndex }: Props) {
label={"Можно несколько"}
checked={question.content.multi}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionVariant>(quizId, totalIndex, {
content: { ...question.content, multi: target.checked },
});
}}
@ -78,7 +78,7 @@ export default function ResponseSettings({ totalIndex }: Props) {
label={'Вариант "свой ответ"'}
checked={question.content.own}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionVariant>(quizId, totalIndex, {
content: { ...question.content, own: target.checked },
});
}}
@ -91,7 +91,7 @@ export default function ResponseSettings({ totalIndex }: Props) {
label={"Необязательный вопрос"}
checked={!question.required}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionVariant>(quizId, totalIndex, {
required: !target.checked,
});
}}
@ -108,7 +108,7 @@ export default function ResponseSettings({ totalIndex }: Props) {
label={"Внутреннее название вопроса"}
checked={question.content.innerNameCheck}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionVariant>(quizId, totalIndex, {
content: {
...question.content,
innerNameCheck: target.checked,

@ -144,7 +144,7 @@ export default function BranchingQuestions({
activeItemIndex={question.content.rule.show ? 0 : 1}
sx={{ maxWidth: "140px" }}
onChange={(action) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionBase>(quizId, totalIndex, {
content: {
...question.content,
rule: {
@ -185,9 +185,13 @@ export default function BranchingQuestions({
onClick={() => {
const clonedContent = { ...question.content };
clonedContent.rule.reqs.splice(index, 1);
updateQuestionsList(quizId, totalIndex, {
content: clonedContent,
});
updateQuestionsList<QuizQuestionBase>(
quizId,
totalIndex,
{
content: clonedContent,
}
);
}}
>
<DeleteIcon color={"#4D4D4D"} />
@ -209,7 +213,7 @@ export default function BranchingQuestions({
vars: request.vars,
};
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionBase>(quizId, totalIndex, {
content: clonedContent,
});
}}
@ -251,9 +255,13 @@ export default function BranchingQuestions({
);
}
updateQuestionsList(quizId, totalIndex, {
content: clonedContent,
});
updateQuestionsList<QuizQuestionBase>(
quizId,
totalIndex,
{
content: clonedContent,
}
);
}}
sx={{
marginBottom: "10px",
@ -285,9 +293,13 @@ export default function BranchingQuestions({
1
);
updateQuestionsList(quizId, totalIndex, {
content: clonedContent,
});
updateQuestionsList<QuizQuestionBase>(
quizId,
totalIndex,
{
content: clonedContent,
}
);
}}
/>
)
@ -313,7 +325,7 @@ export default function BranchingQuestions({
onClick={() => {
const clonedContent = { ...question.content };
clonedContent.rule.reqs.push({ id: "", vars: [] });
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionBase>(quizId, totalIndex, {
content: clonedContent,
});
}}
@ -325,7 +337,7 @@ export default function BranchingQuestions({
aria-labelledby="demo-controlled-radio-buttons-group"
value={question.content.rule.or ? 1 : 0}
onChange={(_, value) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionBase>(quizId, totalIndex, {
content: {
...question.content,
rule: {

@ -24,7 +24,7 @@ export default function HelpQuestions({ totalIndex }: HelpQuestionsProps) {
const { listQuestions } = questionStore();
const question = listQuestions[quizId][totalIndex] as QuizQuestionBase;
const debounced = useDebouncedCallback((value) => {
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionBase>(quizId, totalIndex, {
content: {
...question.content,
hint: { text: value, video: question.content.hint.video },
@ -35,7 +35,7 @@ export default function HelpQuestions({ totalIndex }: HelpQuestionsProps) {
const videoHC = (url: string) => {
const clonedContent = { ...question.content };
clonedContent.hint.video = url;
updateQuestionsList(quizId, totalIndex, {
updateQuestionsList<QuizQuestionBase>(quizId, totalIndex, {
content: {
...question.content,
hint: { video: url, text: question.content.hint.text },