fix: endless errors(WIP)

This commit is contained in:
IlyaDoronin 2023-10-03 17:03:57 +03:00
parent 6f21c992a6
commit ade9e25d5f
50 changed files with 960 additions and 783 deletions

16
src/constants/base.ts Normal file

@ -0,0 +1,16 @@
import type { QuizQuestionBase } from "../model/questionTypes/shared";
export const QUIZ_QUESTION_BASE: Omit<QuizQuestionBase, "id"> = {
title: "",
type: "",
expanded: false,
required: false,
content: {
hint: {
text: "",
video: "",
},
back: "",
autofill: false,
},
};

@ -1,9 +1,12 @@
import { QUIZ_QUESTION_BASE } from "./base";
import type { QuizQuestionDate } from "../model/questionTypes/date";
export const QuizQuestionDateEmpty: Omit<QuizQuestionDate, "id"> = {
title: "",
export const QUIZ_QUESTION_DATE: Omit<QuizQuestionDate, "id"> = {
...QUIZ_QUESTION_BASE,
type: "date",
content: {
...QUIZ_QUESTION_BASE.content,
required: false,
innerNameCheck: false,
innerName: "",

@ -1,9 +1,12 @@
import { QUIZ_QUESTION_BASE } from "./base";
import type { QuizQuestionEmoji } from "../model/questionTypes/emoji";
export const QuizQuestionEmojiEmpty: Omit<QuizQuestionEmoji, "id"> = {
title: "",
export const QUIZ_QUESTION_EMOJI: Omit<QuizQuestionEmoji, "id"> = {
...QUIZ_QUESTION_BASE,
type: "emoji",
content: {
...QUIZ_QUESTION_BASE.content,
multi: false,
own: false,
innerNameCheck: false,
@ -13,7 +16,7 @@ export const QuizQuestionEmojiEmpty: Omit<QuizQuestionEmoji, "id"> = {
{
answer: "",
hints: "",
emoji: "",
extendedText: "",
},
],
hint: {

@ -1,13 +1,15 @@
import { QUIZ_QUESTION_BASE } from "./base";
import type { QuizQuestionFile } from "../model/questionTypes/file";
export const QuizQuestionFileEmpty: Omit<QuizQuestionFile, "id"> = {
title: "",
export const QUIZ_QUESTION_FILE: Omit<QuizQuestionFile, "id"> = {
...QUIZ_QUESTION_BASE,
type: "file",
content: {
...QUIZ_QUESTION_BASE.content,
required: false,
innerNameCheck: false,
innerName: "",
autofill: false,
type: "all",
hint: {
text: "",

@ -1,9 +1,12 @@
import { QUIZ_QUESTION_BASE } from "./base";
import type { QuizQuestionImages } from "../model/questionTypes/images";
export const QuizQuestionImagesEmpty: Omit<QuizQuestionImages, "id"> = {
title: "",
export const QUIZ_QUESTION_IMAGES: Omit<QuizQuestionImages, "id"> = {
...QUIZ_QUESTION_BASE,
type: "images",
content: {
...QUIZ_QUESTION_BASE.content,
own: false,
multi: false,
xy: "1:1",
@ -16,6 +19,7 @@ export const QuizQuestionImagesEmpty: Omit<QuizQuestionImages, "id"> = {
{
answer: "",
hints: "",
extendedText: "",
},
],
hint: {
@ -32,5 +36,6 @@ export const QuizQuestionImagesEmpty: Omit<QuizQuestionImages, "id"> = {
},
],
},
largeCheck: false,
},
};

@ -1,15 +1,20 @@
import { QUIZ_QUESTION_BASE } from "./base";
import type { QuizQuestionNumber } from "../model/questionTypes/number";
export const QuizQuestionNumberEmpty: Omit<QuizQuestionNumber, "id"> = {
title: "",
export const QUIZ_QUESTION_NUMBER: Omit<QuizQuestionNumber, "id"> = {
...QUIZ_QUESTION_BASE,
type: "number",
content: {
...QUIZ_QUESTION_BASE.content,
required: false,
innerNameCheck: false,
innerName: "",
range: [0, 1],
range: "",
defaultValue: 0,
step: 1,
steps: 5,
start: 50,
chooseRange: false,
hint: {
text: "",
@ -25,5 +30,6 @@ export const QuizQuestionNumberEmpty: Omit<QuizQuestionNumber, "id"> = {
},
],
},
form: "star",
},
};

@ -1,9 +1,12 @@
import { QUIZ_QUESTION_BASE } from "./base";
import type { QuizQuestionPage } from "../model/questionTypes/page";
export const QuizQuestionPageEmpty: Omit<QuizQuestionPage, "id"> = {
title: "",
export const QUIZ_QUESTION_PAGE: Omit<QuizQuestionPage, "id"> = {
...QUIZ_QUESTION_BASE,
type: "page",
content: {
...QUIZ_QUESTION_BASE.content,
innerNameCheck: false,
innerName: "",
text: "",

@ -1,9 +1,12 @@
import { QUIZ_QUESTION_BASE } from "./base";
import type { QuizQuestionRating } from "../model/questionTypes/rating";
export const QuizQuestionRatingEmpty: Omit<QuizQuestionRating, "id"> = {
title: "",
export const QUIZ_QUESTION_RATING: Omit<QuizQuestionRating, "id"> = {
...QUIZ_QUESTION_BASE,
type: "rating",
content: {
...QUIZ_QUESTION_BASE.content,
required: false,
innerNameCheck: false,
innerName: "",

@ -1,9 +1,12 @@
import { QUIZ_QUESTION_BASE } from "./base";
import type { QuizQuestionSelect } from "../model/questionTypes/select";
export const QuizQuestionSelectEmpty: Omit<QuizQuestionSelect, "id"> = {
title: "",
export const QUIZ_QUESTION_SELECT: Omit<QuizQuestionSelect, "id"> = {
...QUIZ_QUESTION_BASE,
type: "select",
content: {
...QUIZ_QUESTION_BASE.content,
multi: false,
required: false,
innerNameCheck: false,

@ -1,14 +1,16 @@
import { QUIZ_QUESTION_BASE } from "./base";
import type { QuizQuestionText } from "../model/questionTypes/text";
export const QuizQuestionTextEmpty: Omit<QuizQuestionText, "id"> = {
title: "",
export const QUIZ_QUESTION_TEXT: Omit<QuizQuestionText, "id"> = {
...QUIZ_QUESTION_BASE,
type: "text",
content: {
...QUIZ_QUESTION_BASE.content,
placeholder: "",
innerNameCheck: false,
innerName: "",
required: false,
autofill: false,
answerType: "single",
hint: {
text: "",

@ -1,21 +1,19 @@
import { QUIZ_QUESTION_BASE } from "./base";
import type { QuizQuestionVariant } from "../model/questionTypes/variant";
export const QuizQuestionVariantEmpty: Omit<QuizQuestionVariant, "id"> = {
title: "",
export const QUIZ_QUESTION_VARIANT: Omit<QuizQuestionVariant, "id"> = {
...QUIZ_QUESTION_BASE,
type: "variant",
content: {
...QUIZ_QUESTION_BASE.content,
largeCheck: false,
multi: false,
own: false,
innerNameCheck: false,
required: false,
innerName: "",
variants: [
{
answer: "",
hints: "",
},
],
variants: [{ answer: "", hints: "", extendedText: "" }],
hint: {
text: "",
video: "",

@ -1,19 +1,17 @@
import { QUIZ_QUESTION_BASE } from "./base";
import type { QuizQuestionVarImg } from "../model/questionTypes/varimg";
export const QuizQuestionVarImgEmpty: Omit<QuizQuestionVarImg, "id"> = {
title: "",
export const QUIZ_QUESTION_VARIMG: Omit<QuizQuestionVarImg, "id"> = {
...QUIZ_QUESTION_BASE,
type: "varimg",
content: {
...QUIZ_QUESTION_BASE.content,
own: false,
innerNameCheck: false,
innerName: "",
required: false,
variants: [
{
answer: "",
hints: "",
},
],
variants: [{ answer: "", hints: "", extendedText: "" }],
hint: {
text: "",
video: "",
@ -28,5 +26,7 @@ export const QuizQuestionVarImgEmpty: Omit<QuizQuestionVarImg, "id"> = {
},
],
},
largeCheck: false,
replText: "",
},
};

@ -1,19 +1,24 @@
import { QuizQuestionBase, QuizQuestionBranchingRules, QuizQuestionHint } from "./shared";
import type {
QuizQuestionBase,
QuizQuestionBranchingRules,
QuizQuestionHint,
} from "./shared";
export interface QuizQuestionDate extends QuizQuestionBase {
type: "date";
content: {
/** Чекбокс "Необязательный вопрос" */
required: boolean;
/** Чекбокс "Внутреннее название вопроса" */
innerNameCheck: boolean;
/** Поле "Внутреннее название вопроса" */
innerName: string;
type: "calendar" | "mask";
dateRange: boolean;
time: boolean;
hint: QuizQuestionHint;
rule: QuizQuestionBranchingRules;
};
type: "date";
content: {
/** Чекбокс "Необязательный вопрос" */
required: boolean;
/** Чекбокс "Внутреннее название вопроса" */
innerNameCheck: boolean;
/** Поле "Внутреннее название вопроса" */
innerName: string;
type: "calendar" | "mask";
dateRange: boolean;
time: boolean;
hint: QuizQuestionHint;
rule: QuizQuestionBranchingRules;
back: string;
autofill: boolean;
};
}

@ -1,25 +1,27 @@
import { QuizQuestionBase, QuizQuestionBranchingRules, QuizQuestionHint } from "./shared";
import type {
QuizQuestionBase,
QuizQuestionBranchingRules,
QuizQuestionHint,
Variant,
} from "./shared";
export interface QuizQuestionEmoji extends QuizQuestionBase {
type: "emoji";
content: {
/** Чекбокс "Можно несколько" */
multi: boolean;
/** Чекбокс "Вариант "свой ответ"" */
own: boolean;
/** Чекбокс "Внутреннее название вопроса" */
innerNameCheck: boolean;
/** Поле "Внутреннее название вопроса" */
innerName: string;
/** Чекбокс "Необязательный вопрос" */
required: boolean;
variants: {
answer: string;
hints: string;
emoji: string;
}[];
hint: QuizQuestionHint;
rule: QuizQuestionBranchingRules;
};
type: "emoji";
content: {
/** Чекбокс "Можно несколько" */
multi: boolean;
/** Чекбокс "Вариант "свой ответ"" */
own: boolean;
/** Чекбокс "Внутреннее название вопроса" */
innerNameCheck: boolean;
/** Поле "Внутреннее название вопроса" */
innerName: string;
/** Чекбокс "Необязательный вопрос" */
required: boolean;
variants: Variant[];
hint: QuizQuestionHint;
rule: QuizQuestionBranchingRules;
back: string;
autofill: boolean;
};
}

@ -1,29 +1,33 @@
import { QuizQuestionBase, QuizQuestionBranchingRules, QuizQuestionHint } from "./shared";
import type {
QuizQuestionBase,
QuizQuestionBranchingRules,
QuizQuestionHint,
} from "./shared";
export const uploadFileTypesMap = {
"all": "Все типы файлов",
"picture": "Изображения",
"video": "Видео",
"audio": "Аудио",
"document": "Документ",
all: "Все типы файлов",
picture: "Изображения",
video: "Видео",
audio: "Аудио",
document: "Документ",
} as const;
export type UploadFileType = keyof typeof uploadFileTypesMap;
export interface QuizQuestionFile extends QuizQuestionBase {
type: "file";
content: {
/** Чекбокс "Необязательный вопрос" */
required: boolean;
/** Чекбокс "Внутреннее название вопроса" */
innerNameCheck: boolean;
/** Поле "Внутреннее название вопроса" */
innerName: string;
/** Чекбокс "Автозаполнение адреса" */
autofill: boolean;
type: UploadFileType;
hint: QuizQuestionHint;
rule: QuizQuestionBranchingRules;
};
type: "file";
content: {
/** Чекбокс "Необязательный вопрос" */
required: boolean;
/** Чекбокс "Внутреннее название вопроса" */
innerNameCheck: boolean;
/** Поле "Внутреннее название вопроса" */
innerName: string;
/** Чекбокс "Автозаполнение адреса" */
autofill: boolean;
type: UploadFileType;
hint: QuizQuestionHint;
rule: QuizQuestionBranchingRules;
back: string;
};
}

@ -1,31 +1,35 @@
import { QuizQuestionBase, QuizQuestionBranchingRules, QuizQuestionHint } from "./shared";
import type {
QuizQuestionBase,
QuizQuestionBranchingRules,
QuizQuestionHint,
Variant,
} from "./shared";
export interface QuizQuestionImages extends QuizQuestionBase {
type: "images";
content: {
/** Чекбокс "Вариант "свой ответ"" */
own: boolean;
/** Чекбокс "Можно несколько" */
multi: boolean;
/** Пропорции */
xy: "1:1" | "1:2" | "2:1";
/** Чекбокс "Внутреннее название вопроса" */
innerNameCheck: boolean;
/** Поле "Внутреннее название вопроса" */
innerName: string;
/** Чекбокс "Большие картинки" */
large: boolean;
/** Форма */
format: "carousel" | "masonry";
/** Чекбокс "Необязательный вопрос" */
required: boolean;
/** Варианты (картинки) */
variants: {
answer: string;
hints: string;
}[];
hint: QuizQuestionHint;
rule: QuizQuestionBranchingRules;
};
type: "images";
content: {
/** Чекбокс "Вариант "свой ответ"" */
own: boolean;
/** Чекбокс "Можно несколько" */
multi: boolean;
/** Пропорции */
xy: "1:1" | "1:2" | "2:1";
/** Чекбокс "Внутреннее название вопроса" */
innerNameCheck: boolean;
/** Поле "Внутреннее название вопроса" */
innerName: string;
/** Чекбокс "Большие картинки" */
large: boolean;
/** Форма */
format: "carousel" | "masonry";
/** Чекбокс "Необязательный вопрос" */
required: boolean;
/** Варианты (картинки) */
variants: Variant[];
hint: QuizQuestionHint;
rule: QuizQuestionBranchingRules;
back: string;
autofill: boolean;
largeCheck: boolean;
};
}

@ -1,24 +1,33 @@
import { QuizQuestionBase, QuizQuestionBranchingRules, QuizQuestionHint } from "./shared";
import type {
QuizQuestionBase,
QuizQuestionBranchingRules,
QuizQuestionHint,
} from "./shared";
export interface QuizQuestionNumber extends QuizQuestionBase {
type: "number";
content: {
/** Чекбокс "Необязательный вопрос" */
required: boolean;
/** Чекбокс "Внутреннее название вопроса" */
innerNameCheck: boolean;
/** Поле "Внутреннее название вопроса" */
innerName: string;
/** Диапазон */
range: [number, number];
/** Начальное значение */
defaultValue: number;
/** Шаг */
step: number;
/** Чекбокс "Выбор диапазона (два ползунка)" */
chooseRange: boolean;
hint: QuizQuestionHint;
rule: QuizQuestionBranchingRules;
};
type: "number";
content: {
/** Чекбокс "Необязательный вопрос" */
required: boolean;
/** Чекбокс "Внутреннее название вопроса" */
innerNameCheck: boolean;
/** Поле "Внутреннее название вопроса" */
innerName: string;
/** Диапазон */
range: string;
/** Начальное значение */
start: number;
/** Начальное значение */
defaultValue: number;
/** Шаг */
step: number;
steps: number;
/** Чекбокс "Выбор диапазона (два ползунка)" */
chooseRange: boolean;
hint: QuizQuestionHint;
rule: QuizQuestionBranchingRules;
back: string;
autofill: boolean;
form: "star" | "trophie" | "flag" | "heart" | "like" | "bubble" | "hashtag";
};
}

@ -1,16 +1,21 @@
import { QuizQuestionBase, QuizQuestionBranchingRules, QuizQuestionHint } from "./shared";
import type {
QuizQuestionBase,
QuizQuestionBranchingRules,
QuizQuestionHint,
} from "./shared";
export interface QuizQuestionPage extends QuizQuestionBase {
type: "page";
content: {
/** Чекбокс "Внутреннее название вопроса" */
innerNameCheck: boolean;
/** Поле "Внутреннее название вопроса" */
innerName: string;
text: string;
video: string;
hint: QuizQuestionHint;
rule: QuizQuestionBranchingRules;
};
type: "page";
content: {
/** Чекбокс "Внутреннее название вопроса" */
innerNameCheck: boolean;
/** Поле "Внутреннее название вопроса" */
innerName: string;
text: string;
video: string;
hint: QuizQuestionHint;
rule: QuizQuestionBranchingRules;
back: string;
autofill: boolean;
};
}

@ -1,21 +1,26 @@
import { QuizQuestionBase, QuizQuestionBranchingRules, QuizQuestionHint } from "./shared";
import type {
QuizQuestionBase,
QuizQuestionBranchingRules,
QuizQuestionHint,
} from "./shared";
export interface QuizQuestionRating extends QuizQuestionBase {
type: "rating";
content: {
/** Чекбокс "Необязательный вопрос" */
required: boolean;
/** Чекбокс "Внутреннее название вопроса" */
innerNameCheck: boolean;
/** Поле "Внутреннее название вопроса" */
innerName: string;
steps: number;
ratingExpanded: boolean;
ratingDescription: string;
/** Форма иконки */
form: string;
hint: QuizQuestionHint;
rule: QuizQuestionBranchingRules;
};
type: "rating";
content: {
/** Чекбокс "Необязательный вопрос" */
required: boolean;
/** Чекбокс "Внутреннее название вопроса" */
innerNameCheck: boolean;
/** Поле "Внутреннее название вопроса" */
innerName: string;
steps: number;
ratingExpanded: boolean;
ratingDescription: string;
/** Форма иконки */
form: string;
hint: QuizQuestionHint;
rule: QuizQuestionBranchingRules;
back: string;
autofill: boolean;
};
}

@ -1,20 +1,27 @@
import { QuizQuestionBase, QuizQuestionBranchingRules, QuizQuestionHint } from "./shared";
import type {
QuizQuestionBase,
QuizQuestionBranchingRules,
QuizQuestionHint,
Variant,
} from "./shared";
export interface QuizQuestionSelect extends QuizQuestionBase {
type: "select";
content: {
/** Чекбокс "Можно несколько" */
multi: boolean;
/** Чекбокс "Необязательный вопрос" */
required: boolean;
/** Чекбокс "Внутреннее название вопроса" */
innerNameCheck: boolean;
/** Поле "Внутреннее название вопроса" */
innerName: string;
/** Поле "Текст в выпадающем списке" */
default: string;
hint: QuizQuestionHint;
rule: QuizQuestionBranchingRules;
};
type: "select";
content: {
/** Чекбокс "Можно несколько" */
multi: boolean;
/** Чекбокс "Необязательный вопрос" */
required: boolean;
/** Чекбокс "Внутреннее название вопроса" */
innerNameCheck: boolean;
/** Поле "Внутреннее название вопроса" */
innerName: string;
/** Поле "Текст в выпадающем списке" */
default: string;
hint: QuizQuestionHint;
rule: QuizQuestionBranchingRules;
variants: Variant[];
back: string;
autofill: boolean;
};
}

@ -10,41 +10,60 @@ import type { QuizQuestionText } from "./text";
import type { QuizQuestionVariant } from "./variant";
import type { QuizQuestionVarImg } from "./varimg";
export interface QuizQuestionBranchingRules {
/** Радиокнопка "Все условия обязательны" */
or: boolean;
show: boolean;
reqs: {
id: string;
/** Список выбранных вариантов */
vars: number[];
}[];
/** Радиокнопка "Все условия обязательны" */
or: boolean;
show: boolean;
reqs: {
id: string;
/** Список выбранных вариантов */
vars: number[];
}[];
}
export interface QuizQuestionHint {
/** Текст подсказки */
text: string;
/** URL видео подсказки */
video: string;
/** Текст подсказки */
text: string;
/** URL видео подсказки */
video: string;
}
export type Variant = {
answer: string;
hints: string;
extendedText: string;
};
export type Hint = {
text: string;
video: string;
};
export interface QuizQuestionBase {
id: number;
title: string;
id: number;
title: string;
type: string;
expanded: boolean;
required: boolean;
content: {
hint: Hint;
back: string;
autofill: boolean;
};
}
export type AnyQuizQuestion =
| QuizQuestionVariant
| QuizQuestionImages
| QuizQuestionVarImg
| QuizQuestionEmoji
| QuizQuestionText
| QuizQuestionSelect
| QuizQuestionDate
| QuizQuestionNumber
| QuizQuestionFile
| QuizQuestionPage
| QuizQuestionRating;
| QuizQuestionVariant
| QuizQuestionImages
| QuizQuestionVarImg
| QuizQuestionEmoji
| QuizQuestionText
| QuizQuestionSelect
| QuizQuestionDate
| QuizQuestionNumber
| QuizQuestionFile
| QuizQuestionPage
| QuizQuestionRating
| QuizQuestionBase;
export type QuizQuestionType = AnyQuizQuestion["type"];

@ -1,20 +1,24 @@
import { QuizQuestionBase, QuizQuestionBranchingRules, QuizQuestionHint } from "./shared";
import type {
QuizQuestionBase,
QuizQuestionBranchingRules,
QuizQuestionHint,
} from "./shared";
export interface QuizQuestionText extends QuizQuestionBase {
type: "text";
content: {
placeholder: string;
/** Чекбокс "Внутреннее название вопроса" */
innerNameCheck: boolean;
/** Поле "Внутреннее название вопроса" */
innerName: string;
/** Чекбокс "Необязательный вопрос" */
required: boolean;
/** Чекбокс "Автозаполнение адреса" */
autofill: boolean;
answerType: "single" | "multi" | "number";
hint: QuizQuestionHint;
rule: QuizQuestionBranchingRules;
};
type: "text";
content: {
placeholder: string;
/** Чекбокс "Внутреннее название вопроса" */
innerNameCheck: boolean;
/** Поле "Внутреннее название вопроса" */
innerName: string;
/** Чекбокс "Необязательный вопрос" */
required: boolean;
/** Чекбокс "Автозаполнение адреса" */
autofill: boolean;
answerType: "single" | "multi" | "number";
hint: QuizQuestionHint;
rule: QuizQuestionBranchingRules;
back: string;
};
}

@ -1,27 +1,30 @@
import { QuizQuestionBase, QuizQuestionBranchingRules, QuizQuestionHint } from "./shared";
import type {
QuizQuestionBase,
QuizQuestionBranchingRules,
QuizQuestionHint,
Variant,
} from "./shared";
export interface QuizQuestionVariant extends QuizQuestionBase {
type: "variant";
content: {
/** Чекбокс "Длинный текстовый ответ" */
largeCheck: boolean;
/** Чекбокс "Можно несколько" */
multi: boolean;
/** Чекбокс "Вариант "свой ответ"" */
own: boolean;
/** Чекбокс "Внутреннее название вопроса" */
innerNameCheck: boolean;
/** Чекбокс "Необязательный вопрос" */
required: boolean;
/** Поле "Внутреннее название вопроса" */
innerName: string;
/** Варианты ответов */
variants: {
answer: string;
hints: string;
}[];
hint: QuizQuestionHint;
rule: QuizQuestionBranchingRules;
};
type: "variant";
content: {
/** Чекбокс "Длинный текстовый ответ" */
largeCheck: boolean;
/** Чекбокс "Можно несколько" */
multi: boolean;
/** Чекбокс "Вариант "свой ответ"" */
own: boolean;
/** Чекбокс "Внутреннее название вопроса" */
innerNameCheck: boolean;
/** Чекбокс "Необязательный вопрос" */
required: boolean;
/** Поле "Внутреннее название вопроса" */
innerName: string;
/** Варианты ответов */
variants: Variant[];
hint: QuizQuestionHint;
rule: QuizQuestionBranchingRules;
back: string;
autofill: boolean;
};
}

@ -1,19 +1,27 @@
import { QuizQuestionBase, QuizQuestionBranchingRules, QuizQuestionHint } from "./shared";
import type {
QuizQuestionBase,
QuizQuestionBranchingRules,
QuizQuestionHint,
Variant,
} from "./shared";
export interface QuizQuestionVarImg extends QuizQuestionBase {
type: "varimg";
content: {
/** Чекбокс "Вариант "свой ответ"" */
own: boolean;
/** Чекбокс "Внутреннее название вопроса" */
innerNameCheck: boolean;
/** Поле "Внутреннее название вопроса" */
innerName: string;
/** Чекбокс "Необязательный вопрос" */
required: boolean;
variants: unknown;
hint: QuizQuestionHint;
rule: QuizQuestionBranchingRules;
};
type: "varimg";
content: {
/** Чекбокс "Вариант "свой ответ"" */
own: boolean;
/** Чекбокс "Внутреннее название вопроса" */
innerNameCheck: boolean;
/** Поле "Внутреннее название вопроса" */
innerName: string;
/** Чекбокс "Необязательный вопрос" */
required: boolean;
variants: Variant[];
hint: QuizQuestionHint;
rule: QuizQuestionBranchingRules;
back: string;
autofill: boolean;
largeCheck: boolean;
replText: string;
};
}

@ -12,6 +12,8 @@ import CustomTextField from "@ui_kit/CustomTextField";
import InfoIcon from "../../../assets/icons/InfoIcon";
import { questionStore, updateQuestionsList } from "@root/questions";
import type { QuizQuestionDate } from "../../../model/questionTypes/date";
type SettingsDataProps = {
totalIndex: number;
};
@ -22,11 +24,11 @@ export default function SettingsData({ totalIndex }: SettingsDataProps) {
const theme = useTheme();
const isWrappColumn = useMediaQuery(theme.breakpoints.down(980));
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const question = listQuestions[quizId][totalIndex] as QuizQuestionDate;
const debounced = useDebouncedCallback((value) => {
let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.innerName = value;
updateQuestionsList(quizId, totalIndex, { content: clonContent });
updateQuestionsList(quizId, totalIndex, {
content: { ...question.content, innerName: value },
});
}, 1000);
return (
@ -42,21 +44,21 @@ export default function SettingsData({ totalIndex }: SettingsDataProps) {
<CustomCheckbox
sx={{ display: "block", mr: isMobile ? "0px" : "16px" }}
label={"Выбор диапазона дат"}
checked={listQuestions[quizId][totalIndex].content.dateRange}
checked={question.content.dateRange}
handleChange={({ target }) => {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.dateRange = target.checked;
updateQuestionsList(quizId, totalIndex, { content: clonContent });
updateQuestionsList(quizId, totalIndex, {
content: { ...question.content, dateRange: target.checked },
});
}}
/>
<CustomCheckbox
sx={{ display: "block", mr: isMobile ? "0px" : "16px" }}
label={"Выбор времени"}
checked={listQuestions[quizId][totalIndex].content.time}
checked={question.content.time}
handleChange={({ target }) => {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.time = target.checked;
updateQuestionsList(quizId, totalIndex, { content: clonContent });
updateQuestionsList(quizId, totalIndex, {
content: { ...question.content, time: target.checked },
});
}}
/>
</Box>
@ -73,27 +75,32 @@ export default function SettingsData({ totalIndex }: SettingsDataProps) {
<CustomCheckbox
sx={{ mr: isMobile ? "0px" : "16px" }}
label={"Необязательный вопрос"}
checked={!listQuestions[quizId][totalIndex].required}
handleChange={(e) => {
checked={!question.required}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
required: !e.target.checked,
required: !target.checked,
});
}}
/>
<Box sx={{ width: isMobile ? "93%" : "auto", display: "flex", alignItems: "center" }}>
<Box
sx={{
width: isMobile ? "93%" : "auto",
display: "flex",
alignItems: "center",
}}
>
<CustomCheckbox
sx={{ mr: isMobile ? "0px" : "16px" }}
label={"Внутреннее название вопроса"}
checked={listQuestions[quizId][totalIndex].content.innerNameCheck}
handleChange={(e) => {
let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.innerNameCheck = e.target.checked;
if (!e.target.checked) {
clonContent.innerName = "";
}
updateQuestionsList(quizId, totalIndex, { content: clonContent });
checked={question.content.innerNameCheck}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
content: {
...question.content,
innerNameCheck: target.checked,
innerName: target.checked ? question.content.innerName : "",
},
});
}}
/>
<Tooltip
@ -105,10 +112,10 @@ export default function SettingsData({ totalIndex }: SettingsDataProps) {
</Box>
</Tooltip>
</Box>
{listQuestions[quizId][totalIndex].content.innerNameCheck && (
{question.content.innerNameCheck && (
<CustomTextField
placeholder={"Развёрнутое описание вопроса"}
text={listQuestions[quizId][totalIndex].content.innerName}
text={question.content.innerName}
onChange={({ target }) => debounced(target.value)}
/>
)}

@ -16,11 +16,14 @@ import {
import {
questionStore,
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";
type ChooseAnswerModalProps = {
open: boolean;
@ -36,7 +39,7 @@ export const ChooseAnswerModal = ({
totalIndex,
}: ChooseAnswerModalProps) => {
const [openModal, setOpenModal] = useState<boolean>(false);
const [selectedValue, setSelectedValue] = useState<string>("");
const [selectedValue, setSelectedValue] = useState<QuizQuestionType>("text");
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore();
@ -110,10 +113,11 @@ export const ChooseAnswerModal = ({
setOpenModal(false);
const question = listQuestions[quizId][totalIndex];
removeQuestion(quizId, totalIndex);
createQuestion(quizId, selectedValue, totalIndex);
updateQuestionsList(quizId, totalIndex, {
...DEFAULT_QUESTION,
expanded: question.expanded,
type: selectedValue,
});
}}
>

@ -338,7 +338,7 @@ export default function QuestionsPageCard({
}}
>
<Box
onClick={() => createQuestion(quizId, totalIndex + 1)}
onClick={() => createQuestion(quizId, "", totalIndex + 1)}
sx={{
display: plusVisible && !isDragging ? "flex" : "none",
width: "100%",

@ -9,6 +9,8 @@ import EnterIcon from "../../../assets/icons/questionsPage/enterIcon";
import SwitchDropDown from "./switchDropDown";
import ButtonsOptions from "../ButtonsOptions";
import type { QuizQuestionSelect } from "../../../model/questionTypes/select";
interface Props {
totalIndex: number;
}
@ -19,21 +21,18 @@ export default function DropDown({ totalIndex }: Props) {
const { listQuestions } = questionStore();
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const variants = listQuestions[quizId][totalIndex].content.variants;
const question = listQuestions[quizId][totalIndex] as QuizQuestionSelect;
const SSHC = (data: string) => {
setSwitchState(data);
};
const addNewAnswer = () => {
const answerNew = variants.slice();
answerNew.push({ answer: "", hints: "", emoji: "" });
const answerNew = question.content.variants.slice();
answerNew.push({ answer: "", hints: "", extendedText: "" });
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
variants: answerNew,
},
content: { ...question.content, variants: answerNew },
});
};
@ -44,7 +43,7 @@ export default function DropDown({ totalIndex }: Props) {
padding: isMobile ? "15px 20px 20px 20px" : "20px 20px 20px 20px ",
}}
>
{variants.length === 0 ? (
{question.content.variants.length === 0 ? (
<Typography
sx={{
padding: "0 0 33px 80px",
@ -57,7 +56,10 @@ export default function DropDown({ totalIndex }: Props) {
Добавьте ответ
</Typography>
) : (
<AnswerDraggableList variants={variants} totalIndex={totalIndex} />
<AnswerDraggableList
variants={question.content.variants}
totalIndex={totalIndex}
/>
)}
<Box sx={{ display: "flex", alignItems: "center", gap: "10px" }}>
<Link

@ -8,6 +8,8 @@ import { questionStore, updateQuestionsList } from "@root/questions";
import InfoIcon from "../../../assets/icons/InfoIcon";
import type { QuizQuestionSelect } from "../../../model/questionTypes/select";
type SettingDropDownProps = {
totalIndex: number;
};
@ -17,17 +19,17 @@ export default function SettingDropDown({ totalIndex }: SettingDropDownProps) {
const { listQuestions } = questionStore();
const theme = useTheme();
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const question = listQuestions[quizId][totalIndex] as QuizQuestionSelect;
const debounced = useDebouncedCallback((value) => {
let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.innerName = value;
updateQuestionsList(quizId, totalIndex, { content: clonContent });
updateQuestionsList(quizId, totalIndex, {
content: { ...question.content, innerName: value },
});
}, 1000);
const debounceAnswer = useDebouncedCallback((value) => {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.default = value;
updateQuestionsList(quizId, totalIndex, { content: clonContent });
updateQuestionsList(quizId, totalIndex, {
content: { ...question.content, default: value },
});
}, 1000);
return (
@ -52,13 +54,10 @@ export default function SettingDropDown({ totalIndex }: SettingDropDownProps) {
</Typography>
<CustomCheckbox
label={"Можно несколько"}
checked={listQuestions[quizId][totalIndex].content.multi}
checked={question.content.multi}
handleChange={({ target }) =>
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
multi: target.checked,
},
content: { ...question.content, multi: target.checked },
})
}
/>
@ -69,7 +68,7 @@ export default function SettingDropDown({ totalIndex }: SettingDropDownProps) {
<CustomTextField
sx={{ maxWidth: "360px" }}
placeholder={"Выберите вариант"}
text={listQuestions[quizId][totalIndex].content.default}
text={question.content.default}
onChange={({ target }) => debounceAnswer(target.value)}
/>
</Box>
@ -80,7 +79,7 @@ export default function SettingDropDown({ totalIndex }: SettingDropDownProps) {
</Typography>
<CustomCheckbox
label={"Необязательный вопрос"}
checked={!listQuestions[quizId][totalIndex].required}
checked={!question.required}
handleChange={(e) => {
updateQuestionsList(quizId, totalIndex, {
required: !e.target.checked,
@ -92,17 +91,14 @@ export default function SettingDropDown({ totalIndex }: SettingDropDownProps) {
>
<CustomCheckbox
label={"Внутреннее название вопроса"}
checked={listQuestions[quizId][totalIndex].content.innerNameCheck}
handleChange={(e) => {
let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.innerNameCheck = e.target.checked;
if (!e.target.checked) {
clonContent.innerName = "";
}
checked={question.content.innerNameCheck}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
content: {
...question.content,
innerNameCheck: target.checked,
innerName: target.checked ? question.content.innerName : "",
},
});
}}
/>
@ -126,14 +122,14 @@ export default function SettingDropDown({ totalIndex }: SettingDropDownProps) {
</Typography>
<CustomTextField
placeholder={"Выберите вариант"}
text={listQuestions[quizId][totalIndex].content.default}
text={question.content.default}
onChange={({ target }) => debounceAnswer(target.value)}
/>
</Box>
{listQuestions[quizId][totalIndex].content.innerNameCheck && (
{question.content.innerNameCheck && (
<CustomTextField
placeholder={"Развёрнутое описание вопроса"}
text={listQuestions[quizId][totalIndex].content.innerName}
text={question.content.innerName}
onChange={({ target }) => debounced(target.value)}
/>
)}

@ -40,7 +40,7 @@ export default function Emoji({ totalIndex }: Props) {
sx={{ color: theme.palette.brightPurple.main }}
onClick={() => {
const answerNew = question.content.variants.slice();
answerNew.push({ answer: "", hints: "", emoji: "" });
answerNew.push({ answer: "", hints: "", extendedText: "" });
updateQuestionsList(quizId, totalIndex, {
content: {

@ -12,6 +12,8 @@ import CustomTextField from "@ui_kit/CustomTextField";
import InfoIcon from "../../../assets/icons/InfoIcon";
import { questionStore, updateQuestionsList } from "@root/questions";
import type { QuizQuestionEmoji } from "../../../model/questionTypes/emoji";
type SettingEmojiProps = {
totalIndex: number;
};
@ -22,10 +24,11 @@ export default function SettingEmoji({ totalIndex }: SettingEmojiProps) {
const theme = useTheme();
const isWrappColumn = useMediaQuery(theme.breakpoints.down(980));
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const question = listQuestions[quizId][totalIndex] as QuizQuestionEmoji;
const debounced = useDebouncedCallback((value) => {
let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.innerName = value;
updateQuestionsList(quizId, totalIndex, { content: clonContent });
updateQuestionsList(quizId, totalIndex, {
content: { ...question.content, innerName: value },
});
}, 1000);
return (
@ -41,21 +44,21 @@ export default function SettingEmoji({ totalIndex }: SettingEmojiProps) {
<CustomCheckbox
sx={{ display: "block", mr: isMobile ? "0px" : "16px" }}
label={"Можно несколько"}
checked={listQuestions[quizId][totalIndex].content.multi}
handleChange={(e) => {
let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.multi = e.target.checked;
updateQuestionsList(quizId, totalIndex, { content: clonContent });
checked={question.content.multi}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
content: { ...question.content, multi: target.checked },
});
}}
/>
<CustomCheckbox
sx={{ display: "block", mr: isMobile ? "0px" : "16px" }}
label={'Вариант "свой ответ"'}
checked={listQuestions[quizId][totalIndex].content.own}
handleChange={(e) => {
let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.own = e.target.checked;
updateQuestionsList(quizId, totalIndex, { content: clonContent });
checked={question.content.own}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
content: { ...question.content, own: target },
});
}}
/>
</Box>
@ -72,27 +75,32 @@ export default function SettingEmoji({ totalIndex }: SettingEmojiProps) {
<CustomCheckbox
sx={{ mr: isMobile ? "0px" : "16px" }}
label={"Необязательный вопрос"}
checked={!listQuestions[quizId][totalIndex].required}
checked={!question.required}
handleChange={(e) => {
updateQuestionsList(quizId, totalIndex, {
required: !e.target.checked,
});
}}
/>
<Box sx={{ width: isMobile ? "90%" : "auto", display: "flex", alignItems: "center" }}>
<Box
sx={{
width: isMobile ? "90%" : "auto",
display: "flex",
alignItems: "center",
}}
>
<CustomCheckbox
sx={{ mr: isMobile ? "0px" : "16px" }}
label={"Внутреннее название вопроса"}
checked={listQuestions[quizId][totalIndex].content.innerNameCheck}
handleChange={(e) => {
let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.innerNameCheck = e.target.checked;
if (!e.target.checked) {
clonContent.innerName = "";
}
updateQuestionsList(quizId, totalIndex, { content: clonContent });
checked={question.content.innerNameCheck}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
content: {
...question.content,
innerNameCheck: target.checked,
innerName: target.checked ? question.content.innerName : "",
},
});
}}
/>
<Tooltip
@ -104,10 +112,10 @@ export default function SettingEmoji({ totalIndex }: SettingEmojiProps) {
</Box>
</Tooltip>
</Box>
{listQuestions[quizId][totalIndex].content.innerNameCheck && (
{question.content.innerNameCheck && (
<CustomTextField
placeholder={"Развёрнутое описание вопроса"}
text={listQuestions[quizId][totalIndex].content.innerName}
text={question.content.innerName}
onChange={({ target }) => debounced(target.value)}
/>
)}

@ -23,6 +23,8 @@ import PointsIcon from "@icons/questionsPage/PointsIcon";
import MessageIcon from "@icons/messagIcon";
import DeleteIcon from "@icons/questionsPage/deleteIcon";
import type { QuizQuestionVarImg } from "../../../model/questionTypes/varimg";
interface Props {
totalIndex: number;
}
@ -34,6 +36,7 @@ export default function OptionsAndPicture({ totalIndex }: Props) {
const theme = useTheme();
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const question = listQuestions[quizId][totalIndex] as QuizQuestionVarImg;
const SSHC = (data: string) => {
setSwitchState(data);
@ -43,54 +46,51 @@ export default function OptionsAndPicture({ totalIndex }: Props) {
<>
<Box sx={{ padding: "20px" }}>
<Box sx={{ paddingBottom: "25px" }}>
{listQuestions[quizId][totalIndex].content.variants.map(
(_, index) => (
<ButtonBase
key={index}
component="label"
{question.content.variants.map((_, index) => (
<ButtonBase
key={index}
component="label"
sx={{
display: isTablet ? "none" : "flex",
cursor: "pointer",
alignItems: "center",
justifyContent: "flex-start",
marginBottom: "15px",
}}
>
<input
onChange={({ target }) => {
if (target.files?.length) {
const clonContent = { ...question.content };
clonContent.variants[index].answer = URL.createObjectURL(
target.files[0]
);
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
});
}
}}
hidden
accept="image/*"
multiple
type="file"
/>
<AddImage />
<Typography
sx={{
display: isTablet ? "none" : "flex",
cursor: "pointer",
alignItems: "center",
justifyContent: "flex-start",
marginBottom: "15px",
padding: "0 0 0 20px",
fontWeight: 400,
fontSize: "18px",
lineHeight: "21.33px",
color: theme.palette.grey2.main,
}}
>
<input
onChange={({ target }) => {
if (target.files?.length) {
const clonContent =
listQuestions[quizId][totalIndex].content;
clonContent.variants[index].answer = URL.createObjectURL(
target.files[0]
);
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
});
}
}}
hidden
accept="image/*"
multiple
type="file"
/>
<AddImage />
<Typography
sx={{
padding: "0 0 0 20px",
fontWeight: 400,
fontSize: "18px",
lineHeight: "21.33px",
color: theme.palette.grey2.main,
}}
>
Добавьте ответ
</Typography>
</ButtonBase>
)
)}
Добавьте ответ
</Typography>
</ButtonBase>
))}
<Box
sx={{
width: "100%",
@ -103,7 +103,7 @@ export default function OptionsAndPicture({ totalIndex }: Props) {
fullWidth
focused={false}
placeholder={"Добавьте ответ"}
multiline={listQuestions[quizId][totalIndex].content.largeCheck}
multiline={question.content.largeCheck}
InputProps={{
startAdornment: (
<>
@ -196,9 +196,8 @@ export default function OptionsAndPicture({ totalIndex }: Props) {
variant="body2"
sx={{ color: theme.palette.brightPurple.main }}
onClick={() => {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.variants.push({ answer: "", hints: "", emoji: "" });
const clonContent = { ...question.content };
clonContent.variants.push({ answer: "", hints: "", extendedText: "" });
updateQuestionsList(quizId, totalIndex, { content: clonContent });
}}
>

@ -13,6 +13,8 @@ import InfoIcon from "../../../assets/icons/InfoIcon";
import { questionStore, updateQuestionsList } from "@root/questions";
import type { QuizQuestionVarImg } from "../../../model/questionTypes/varimg";
type SettingOptionsAndPictProps = {
totalIndex: number;
};
@ -25,19 +27,15 @@ export default function SettingOptionsAndPict({
const theme = useTheme();
const isWrappColumn = useMediaQuery(theme.breakpoints.down(980));
const isMobile = useMediaQuery(theme.breakpoints.down(680));
const question = listQuestions[quizId][totalIndex] as QuizQuestionVarImg;
const debounced = useDebouncedCallback((replText) => {
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
replText,
},
content: { ...question.content, replText },
});
}, 1000);
const debounceDescription = useDebouncedCallback((value) => {
let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.innerName = value;
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
content: { ...question.content, innerName: value },
});
}, 1000);
@ -51,20 +49,24 @@ export default function SettingOptionsAndPict({
flexDirection: isWrappColumn ? "column" : null,
}}
>
<Box sx={{ pt: "20px", pb: "20px", pl: "20px", width: isMobile ? "85%" : "100%" }}>
<Box
sx={{
pt: "20px",
pb: "20px",
pl: "20px",
width: isMobile ? "85%" : "100%",
}}
>
<Typography sx={{ marginBottom: "15px" }}>
Настройки ответов
</Typography>
<CustomCheckbox
sx={{ mr: isMobile ? "0px" : "16px" }}
label={'Вариант "свой ответ"'}
checked={listQuestions[quizId][totalIndex].content.own}
checked={question.content.own}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
own: target.checked,
},
content: { ...question.content, own: target.checked },
});
}}
/>
@ -74,9 +76,13 @@ export default function SettingOptionsAndPict({
Текст-заглушка на картинке
</Typography>
<CustomTextField
sx={{ maxWidth: "330px", width: "100%", mr: isMobile ? "0px" : "16px" }}
sx={{
maxWidth: "330px",
width: "100%",
mr: isMobile ? "0px" : "16px",
}}
placeholder={"Пример текста"}
text={listQuestions[quizId][totalIndex].content.replText}
text={question.content.replText}
onChange={({ target }) => debounced(target.value)}
/>
</>
@ -94,27 +100,27 @@ export default function SettingOptionsAndPict({
Настройки вопросов
</Typography>
<CustomCheckbox
sx={{ mr: isMobile ? "0px" : "16px" }}
sx={{ mr: isMobile ? "0px" : "16px" }}
label={"Необязательный вопрос"}
checked={listQuestions[quizId][totalIndex].content.required}
checked={question.content.required}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
required: target.checked,
},
content: { ...question.content, required: target.checked },
});
}}
/>
<Box sx={{ display: "flex", alignItems: "center" }}>
<CustomCheckbox
sx={{ width: isMobile ? "90%" : "auto", mr: isMobile ? "0px" : "16px" }}
sx={{
width: isMobile ? "90%" : "auto",
mr: isMobile ? "0px" : "16px",
}}
label={"Внутреннее название вопроса"}
checked={listQuestions[quizId][totalIndex].content.innerNameCheck}
checked={question.content.innerNameCheck}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
...question.content,
innerNameCheck: target.checked,
innerName: "",
},
@ -130,10 +136,10 @@ export default function SettingOptionsAndPict({
</Box>
</Tooltip>
</Box>
{listQuestions[quizId][totalIndex].content.innerNameCheck && (
{question.content.innerNameCheck && (
<CustomTextField
placeholder={"Развёрнутое описание вопроса"}
text={listQuestions[quizId][totalIndex].content.innerName}
text={question.content.innerName}
onChange={({ target }) => debounceDescription(target.value)}
/>
)}
@ -145,7 +151,7 @@ export default function SettingOptionsAndPict({
<CustomTextField
sx={{ maxWidth: "330px", width: "100%" }}
placeholder={"Пример текста"}
text={listQuestions[quizId][totalIndex].content.replText}
text={question.content.replText}
onChange={({ target }) => debounced(target.value)}
/>
</>

@ -27,6 +27,8 @@ import MessageIcon from "@icons/messagIcon";
import DeleteIcon from "@icons/questionsPage/deleteIcon";
import { ImageAddIcons } from "@icons/ImageAddIcons";
import type { QuizQuestionImages } from "../../../model/questionTypes/images";
interface Props {
totalIndex: number;
}
@ -38,23 +40,24 @@ export default function OptionsPicture({ totalIndex }: Props) {
const quizId = Number(useParams().quizId);
const [switchState, setSwitchState] = useState("setting");
const { listQuestions } = questionStore();
const question = listQuestions[quizId][totalIndex] as QuizQuestionImages;
const SSHC = (data: string) => {
setSwitchState(data);
};
const addImage = ({ target }: ChangeEvent<HTMLInputElement>) => {
if (target.files?.length) {
const clonContent = listQuestions[quizId][totalIndex].content;
// if (target.files?.length) {
// const clonContent = question.content;
clonContent.images.push(URL.createObjectURL(target.files[0]));
// clonContent.images.push(URL.createObjectURL(target.files[0]));
updateQuestionsList(quizId, totalIndex, { content: clonContent });
}
// updateQuestionsList(quizId, totalIndex, {
// content: { ...question.content, images },
// });
// }
};
console.log();
return (
<>
<Box sx={{ padding: "20px" }}>
@ -91,7 +94,7 @@ export default function OptionsPicture({ totalIndex }: Props) {
fullWidth
focused={false}
placeholder={"Добавьте ответ"}
multiline={listQuestions[quizId][totalIndex].content.largeCheck}
multiline={question.content.largeCheck}
InputProps={{
startAdornment: (
<>

@ -21,6 +21,8 @@ import ProportionsIcon11 from "../../../assets/icons/questionsPage/ProportionsIc
import ProportionsIcon21 from "../../../assets/icons/questionsPage/ProportionsIcon21";
import ProportionsIcon12 from "../../../assets/icons/questionsPage/ProportionsIcon12";
import type { QuizQuestionImages } from "../../../model/questionTypes/images";
interface Props {
Icon: React.ElementType;
isActive?: boolean;
@ -86,24 +88,23 @@ export default function SettingOpytionsPict({
const theme = useTheme();
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const question = listQuestions[quizId][totalIndex] as QuizQuestionImages;
const debounced = useDebouncedCallback((value) => {
let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.innerName = value;
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
content: { ...question.content, innerName: value },
});
}, 1000);
useEffect(() => {
if (!listQuestions[quizId][totalIndex].content.xy) {
if (!question.content.xy) {
updateProportions("1:1");
}
}, []);
const updateProportions = (proportions: string) => {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.xy = proportions;
updateQuestionsList(quizId, totalIndex, { content: clonContent });
updateQuestionsList(quizId, totalIndex, {
content: { ...question.content, xy: proportions },
});
};
return (
@ -129,9 +130,7 @@ export default function SettingOpytionsPict({
<SelectIconButton
key={index}
onClick={() => updateProportions(value)}
isActive={
listQuestions[quizId][totalIndex].content.xy === value
}
isActive={question.content.xy === value}
Icon={icon}
/>
))}
@ -144,39 +143,30 @@ export default function SettingOpytionsPict({
<CustomCheckbox
sx={{ display: "block", mr: isMobile ? "0px" : "16px" }}
label={"Можно несколько"}
checked={listQuestions[quizId][totalIndex].content.multi}
checked={question.content.multi}
handleChange={({ target }) =>
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
multi: target.checked,
},
content: { ...question.content, multi: target.checked },
})
}
/>
<CustomCheckbox
sx={{ display: "block", mr: isMobile ? "0px" : "16px" }}
label={"Большие картинки"}
checked={listQuestions[quizId][totalIndex].content.largeCheck}
checked={question.content.largeCheck}
handleChange={({ target }) =>
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
largeCheck: target.checked,
},
content: { ...question.content, largeCheck: target.checked },
})
}
/>
<CustomCheckbox
sx={{ display: "block", mr: isMobile ? "0px" : "16px" }}
label={'Вариант "свой ответ"'}
checked={listQuestions[quizId][totalIndex].content.own}
checked={question.content.own}
handleChange={({ target }) =>
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
own: target.checked,
},
content: { ...question.content, own: target.checked },
})
}
/>
@ -193,29 +183,19 @@ export default function SettingOpytionsPict({
<SelectIconButton
onClick={() =>
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
format: "carousel",
},
content: { ...question.content, format: "carousel" },
})
}
isActive={
listQuestions[quizId][totalIndex].content.format === "carousel"
}
isActive={question.content.format === "carousel"}
Icon={FormatIcon2}
/>
<SelectIconButton
onClick={() =>
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
format: "masonry",
},
content: { ...question.content, format: "masonry" },
})
}
isActive={
listQuestions[quizId][totalIndex].content.format === "masonry"
}
isActive={question.content.format === "masonry"}
Icon={FormatIcon1}
/>
</Box>
@ -224,24 +204,27 @@ export default function SettingOpytionsPict({
</Typography>
<CustomCheckbox
label={"Необязательный вопрос"}
checked={listQuestions[quizId][totalIndex].content.required}
checked={question.content.required}
handleChange={({ target }) =>
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
required: target.checked,
},
content: { ...question.content, required: target.checked },
})
}
/>
<Box sx={{ width: isMobile ? "90%" : "auto", display: "flex", alignItems: "center" }}>
<Box
sx={{
width: isMobile ? "90%" : "auto",
display: "flex",
alignItems: "center",
}}
>
<CustomCheckbox
label={"Внутреннее название вопроса"}
checked={listQuestions[quizId][totalIndex].content.innerNameCheck}
checked={question.content.innerNameCheck}
handleChange={({ target }) =>
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
...question.content,
innerNameCheck: target.checked,
innerName: "",
},
@ -257,10 +240,10 @@ export default function SettingOpytionsPict({
</Box>
</Tooltip>
</Box>
{listQuestions[quizId][totalIndex].content.innerNameCheck && (
{question.content.innerNameCheck && (
<CustomTextField
placeholder={"Внутреннее описание вопроса"}
text={listQuestions[quizId][totalIndex].content.innerName}
text={question.content.innerName}
onChange={({ target }) => debounced(target.value)}
/>
)}

@ -11,6 +11,8 @@ import { questionStore, updateQuestionsList } from "@root/questions";
import InfoIcon from "../../../assets/icons/InfoIcon";
import type { QuizQuestionText } from "../../../model/questionTypes/text";
interface Props {
totalIndex: number;
}
@ -19,10 +21,11 @@ export default function OwnTextField({ totalIndex }: Props) {
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore();
const theme = useTheme();
const question = listQuestions[quizId][totalIndex] as QuizQuestionText;
const debounced = useDebouncedCallback((value) => {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.placeholder = value;
updateQuestionsList(quizId, totalIndex, { content: clonContent });
updateQuestionsList(quizId, totalIndex, {
content: { ...question.content, placeholder: value },
});
}, 1000);
const SSHC = (data: string) => {
@ -43,7 +46,7 @@ export default function OwnTextField({ totalIndex }: Props) {
>
<CustomTextField
placeholder={"Пример ответа"}
text={listQuestions[quizId][totalIndex].content.placeholder}
text={question.content.placeholder}
onChange={({ target }) => debounced(target.value)}
/>
<Box sx={{ display: "flex", alignItems: "center", gap: "12px" }}>

@ -20,6 +20,8 @@ import CheckedIcon from "@ui_kit/RadioCheck";
import CheckIcon from "@ui_kit/RadioIcon";
import InfoIcon from "../../../assets/icons/InfoIcon";
import type { QuizQuestionText } from "../../../model/questionTypes/text";
type SettingTextFieldProps = {
totalIndex: number;
};
@ -43,10 +45,11 @@ export default function SettingTextField({
const theme = useTheme();
const isWrapperColumn = useMediaQuery(theme.breakpoints.down(980));
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const question = listQuestions[quizId][totalIndex] as QuizQuestionText;
const debounced = useDebouncedCallback((value) => {
let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.innerName = value;
updateQuestionsList(quizId, totalIndex, { content: clonContent });
updateQuestionsList(quizId, totalIndex, {
content: { ...question.content, innerName: value },
});
}, 1000);
return (
@ -64,12 +67,24 @@ export default function SettingTextField({
<RadioGroup
aria-labelledby="demo-controlled-radio-buttons-group"
name="controlled-radio-buttons-group"
value={ANSWER_TYPES.findIndex(
({ value }) => listQuestions[quizId][totalIndex].content[value]
)}
value={ANSWER_TYPES.findIndex(({ value }) => {
switch (value) {
case "multi":
return value === "multi";
case "number":
return value === "number";
case "single":
return value === "single";
default:
return false;
}
})}
onChange={({ target }: React.ChangeEvent<HTMLInputElement>) => {
const clonContent = {
...listQuestions[quizId][totalIndex].content,
...question.content,
single: false,
multi: false,
number: false,
@ -101,37 +116,42 @@ export default function SettingTextField({
<CustomCheckbox
sx={{ display: "block", mr: isMobile ? "0px" : "16px" }}
label={"Автозаполнение адреса"}
checked={listQuestions[quizId][totalIndex].content.autofill}
checked={question.content.autofill}
handleChange={({ target }) => {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.autofill = target.checked;
updateQuestionsList(quizId, totalIndex, { content: clonContent });
updateQuestionsList(quizId, totalIndex, {
content: { ...question.content, autofill: target.checked },
});
}}
/>
<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,
});
}}
/>
<Box sx={{ width: isMobile ? "90%" : "auto", display: "flex", alignItems: "center" }}>
<Box
sx={{
width: isMobile ? "90%" : "auto",
display: "flex",
alignItems: "center",
}}
>
<CustomCheckbox
sx={{ display: "block", mr: isMobile ? "0px" : "16px" }}
label={"Внутреннее название вопроса"}
checked={listQuestions[quizId][totalIndex].content.innerNameCheck}
handleChange={(e) => {
let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.innerNameCheck = e.target.checked;
if (!e.target.checked) {
clonContent.innerName = "";
}
updateQuestionsList(quizId, totalIndex, { content: clonContent });
checked={question.content.innerNameCheck}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
content: {
...question.content,
innerNameCheck: target.checked,
innerName: target.checked ? question.content.innerName : "",
},
});
}}
/>
<Tooltip
@ -143,10 +163,10 @@ export default function SettingTextField({
</Box>
</Tooltip>
</Box>
{listQuestions[quizId][totalIndex].content.innerNameCheck && (
{question.content.innerNameCheck && (
<CustomTextField
placeholder={"Развёрнутое описание вопроса"}
text={listQuestions[quizId][totalIndex].content.innerName}
text={question.content.innerName}
onChange={({ target }) => debounced(target.value)}
/>
)}

@ -13,6 +13,8 @@ import { UploadVideoModal } from "../UploadVideoModal";
import { AddPlusImage } from "@icons/questionsPage/addPlusImage";
import { AddPlusVideo } from "@icons/questionsPage/addPlusVideo";
import type { QuizQuestionPage } from "../../../model/questionTypes/page";
type Props = {
disableInput?: boolean;
totalIndex: number;
@ -27,10 +29,11 @@ export default function PageOptions({ disableInput, totalIndex }: Props) {
const theme = useTheme();
const isTablet = useMediaQuery(theme.breakpoints.down(980));
const isMobile = useMediaQuery(theme.breakpoints.down(780));
const question = listQuestions[quizId][totalIndex] as QuizQuestionPage;
const debounced = useDebouncedCallback((value) => {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.text = value;
updateQuestionsList(quizId, totalIndex, { content: clonContent });
updateQuestionsList(quizId, totalIndex, {
content: { ...question.content, text: value },
});
}, 1000);
const SSHC = (data: string) => {
@ -52,7 +55,7 @@ export default function PageOptions({ disableInput, totalIndex }: Props) {
<Box sx={{ display: disableInput ? "none" : "" }}>
<CustomTextField
placeholder={"Можно добавить текст"}
text={listQuestions[quizId][totalIndex].content.text}
text={question.content.text}
onChange={({ target }) => debounced(target.value)}
/>
</Box>
@ -92,10 +95,11 @@ export default function PageOptions({ disableInput, totalIndex }: Props) {
onClose={() => setOpenImageModal(false)}
imgHC={(fileList) => {
if (fileList?.length) {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.picture = URL.createObjectURL(fileList[0]);
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
content: {
...question.content,
picture: URL.createObjectURL(fileList[0]),
},
});
}
}}
@ -127,11 +131,11 @@ export default function PageOptions({ disableInput, totalIndex }: Props) {
<UploadVideoModal
open={openVideoModal}
onClose={() => setOpenVideoModal(false)}
video={listQuestions[quizId][totalIndex].content.video}
video={question.content.video}
onUpload={(url) => {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.video = url;
updateQuestionsList(quizId, totalIndex, { content: clonContent });
updateQuestionsList(quizId, totalIndex, {
content: { ...question.content, video: url },
});
}}
/>
</Box>

@ -14,6 +14,8 @@ import { questionStore, updateQuestionsList } from "@root/questions";
import InfoIcon from "../../../assets/icons/InfoIcon";
import type { QuizQuestionPage } from "../../../model/questionTypes/page";
type SettingPageOptionsProps = {
totalIndex: number;
};
@ -23,11 +25,10 @@ export default function SettingPageOptions({
}: SettingPageOptionsProps) {
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore();
const question = listQuestions[quizId][totalIndex] as QuizQuestionPage;
const debounced = useDebouncedCallback((value) => {
let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.innerName = value;
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
content: { ...question.content, innerName: value },
});
}, 1000);
@ -55,11 +56,11 @@ export default function SettingPageOptions({
<CustomCheckbox
sx={{ mr: isMobile ? "0px" : "16px" }}
label={"Внутреннее название вопроса"}
checked={listQuestions[quizId][totalIndex].content.innerNameCheck}
checked={question.content.innerNameCheck}
handleChange={({ target }) =>
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
...question.content,
innerNameCheck: target.checked,
innerName: "",
},
@ -75,10 +76,10 @@ export default function SettingPageOptions({
</Box>
</Tooltip>
</Box>
{listQuestions[quizId][totalIndex].content.innerNameCheck && (
{question.content.innerNameCheck && (
<CustomTextField
placeholder={"Внутреннее описание вопроса"}
text={listQuestions[quizId][totalIndex].content.innerName}
text={question.content.innerName}
onChange={({ target }) => debounced(target.value)}
/>
)}

@ -14,6 +14,8 @@ import LightbulbIcon from "../../../assets/icons/questionsPage/lightbulbIcon";
import HashtagIcon from "../../../assets/icons/questionsPage/hashtagIcon";
import StarIconMini from "../../../assets/icons/questionsPage/StarIconMini";
import type { QuizQuestionRating } from "../../../model/questionTypes/rating";
interface Props {
totalIndex: number;
}
@ -29,6 +31,7 @@ export default function RatingOptions({ totalIndex }: Props) {
const { listQuestions } = questionStore();
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const question = listQuestions[quizId][totalIndex] as QuizQuestionRating;
const buttonRatingForm: ButtonRatingFrom[] = [
{ name: "star", icon: <StarIconMini color={theme.palette.grey2.main} /> },
@ -51,9 +54,7 @@ export default function RatingOptions({ totalIndex }: Props) {
<>
<Box
sx={{
width: isMobile
? "auto"
: `${listQuestions[quizId][totalIndex].content.steps * 44}px`,
width: isMobile ? "auto" : `${question.content.steps * 44}px`,
minWidth: "200px",
maxWidth: "440px",
display: "flex",
@ -64,19 +65,15 @@ export default function RatingOptions({ totalIndex }: Props) {
>
<Box sx={{ display: "flex", gap: isMobile ? "10px" : "15px" }}>
{Array.from(
{ length: listQuestions[quizId][totalIndex].content.steps },
{ length: question.content.steps },
(_, index) => index
).map((itemNumber) => (
<Box
{...(itemNumber === 0 ||
itemNumber === listQuestions[quizId][totalIndex].content.steps - 1
{...(itemNumber === 0 || itemNumber === question.content.steps - 1
? {
onClick: () => {
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
ratingExpanded: true,
},
content: { ...question.content, ratingExpanded: true },
});
},
sx: {
@ -92,14 +89,13 @@ export default function RatingOptions({ totalIndex }: Props) {
>
{
buttonRatingForm.find(
({ name }) =>
listQuestions[quizId][totalIndex].content.form === name
({ name }) => question.content.form === name
)?.icon
}
</Box>
))}
</Box>
{!listQuestions[quizId][totalIndex].content.ratingDescription && (
{!question.content.ratingDescription && (
<Box
sx={{
display: "flex",
@ -127,22 +123,20 @@ export default function RatingOptions({ totalIndex }: Props) {
</Typography>
</Box>
)}
{listQuestions[quizId][totalIndex].content.ratingExpanded &&
(listQuestions[quizId][totalIndex].content.ratingDescription ? (
<Typography>
{listQuestions[quizId][totalIndex].content.ratingDescription}
</Typography>
{question.content.ratingExpanded &&
(question.content.ratingDescription ? (
<Typography>{question.content.ratingDescription}</Typography>
) : (
<CustomTextField
placeholder={"Описание"}
text={listQuestions[quizId][totalIndex].content.ratingDescription}
text={question.content.ratingDescription}
onKeyDown={({ target, key }) => {
if (key === "Enter") {
const currentTarget = target as HTMLInputElement;
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
...question.content,
ratingDescription: currentTarget.value.substring(0, 20),
},
});
@ -151,7 +145,7 @@ export default function RatingOptions({ totalIndex }: Props) {
onBlur={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
...question.content,
ratingDescription: target.value.substring(0, 20),
},
});

@ -24,6 +24,7 @@ import HashtagIcon from "../../../assets/icons/questionsPage/hashtagIcon";
import StarIconMini from "../../../assets/icons/questionsPage/StarIconMini";
import type { ButtonRatingFrom } from "./RatingOptions";
import type { QuizQuestionNumber } from "../../../model/questionTypes/number";
type SettingSliderProps = {
totalIndex: number;
@ -35,10 +36,11 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const isWrappColumn = useMediaQuery(theme.breakpoints.down(980));
const { listQuestions } = questionStore();
const question = listQuestions[quizId][totalIndex] as QuizQuestionNumber;
const debounced = useDebouncedCallback((value) => {
let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.innerName = value;
updateQuestionsList(quizId, totalIndex, { content: clonContent });
updateQuestionsList(quizId, totalIndex, {
content: { ...question.content, innerName: value },
});
}, 1000);
const buttonRatingForm: ButtonRatingFrom[] = [
@ -80,19 +82,17 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
<ButtonBase
key={index}
onClick={() => {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.form = name;
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
content: { ...question.content, form: name },
});
}}
sx={{
backgroundColor:
listQuestions[quizId][totalIndex].content.form === name
question.content.form === name
? theme.palette.brightPurple.main
: "transparent",
color:
listQuestions[quizId][totalIndex].content.form === name
question.content.form === name
? "#ffffff"
: theme.palette.grey3.main,
width: "40px",
@ -114,16 +114,16 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
Количество
</Typography>
<Slider
value={listQuestions[quizId][totalIndex].content.steps}
value={question.content.steps}
min={2}
max={10}
aria-label="Default"
valueLabelDisplay="auto"
sx={{ color: theme.palette.brightPurple.main }}
onChange={(_, value) => {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.steps = Number(value) || 1;
updateQuestionsList(quizId, totalIndex, { content: clonContent });
updateQuestionsList(quizId, totalIndex, {
content: { ...question.content, steps: Number(value) || 1 },
});
}}
/>
</Box>
@ -149,16 +149,15 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
<CustomCheckbox
sx={{ mr: isMobile ? "0px" : "16px" }}
label={"Внутреннее название вопроса"}
checked={listQuestions[quizId][totalIndex].content.innerNameCheck}
handleChange={(e) => {
let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.innerNameCheck = e.target.checked;
if (!e.target.checked) {
clonContent.innerName = "";
}
updateQuestionsList(quizId, totalIndex, { content: clonContent });
checked={question.content.innerNameCheck}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
content: {
...question.content,
innerNameCheck: target.checked,
innerName: target.checked ? question.content.innerName : "",
},
});
}}
/>
<Tooltip
@ -170,10 +169,10 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
</Box>
</Tooltip>
</Box>
{listQuestions[quizId][totalIndex].content.innerNameCheck && (
{question.content.innerNameCheck && (
<CustomTextField
placeholder={"Развёрнутое описание вопроса"}
text={listQuestions[quizId][totalIndex].content.innerName}
text={question.content.innerName}
onChange={({ target }) => debounced(target.value)}
/>
)}

@ -6,6 +6,8 @@ import CustomNumberField from "@ui_kit/CustomNumberField";
import SwitchSlider from "./switchSlider";
import { questionStore, updateQuestionsList } from "@root/questions";
import type { QuizQuestionNumber } from "../../../model/questionTypes/number";
interface Props {
totalIndex: number;
}
@ -18,6 +20,7 @@ export default function SliderOptions({ totalIndex }: Props) {
const [stepError, setStepError] = useState("");
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore();
const question = listQuestions[quizId][totalIndex] as QuizQuestionNumber;
const SSHC = (data: string) => {
setSwitchState(data);
@ -51,43 +54,36 @@ export default function SliderOptions({ totalIndex }: Props) {
placeholder={"0"}
min={0}
max={99}
value={
listQuestions[quizId][totalIndex].content.range.split("—")[0]
}
value={question.content.range.split("—")[0]}
onChange={({ target }) => {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.range = `${target.value}${
listQuestions[quizId][totalIndex].content.range.split("—")[1]
}`;
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
content: {
...question.content,
range: `${target.value}${
question.content.range.split("—")[1]
}`,
},
});
}}
onBlur={({ target }) => {
const start = listQuestions[quizId][totalIndex].content.start;
const start = question.content.start;
const min = Number(target.value);
const max = Number(
listQuestions[quizId][totalIndex].content.range.split("—")[1]
);
const max = Number(question.content.range.split("—")[1]);
if (min >= max) {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.range = `${max - 1 >= 0 ? max - 1 : 0}${
listQuestions[quizId][totalIndex].content.range.split(
"—"
)[1]
}`;
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
content: {
...question.content,
range: `${max - 1 >= 0 ? max - 1 : 0}${
question.content.range.split("—")[1]
}`,
},
});
}
if (start < min) {
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
start: min,
},
content: { ...question.content, start: min },
});
}
}}
@ -97,54 +93,44 @@ export default function SliderOptions({ totalIndex }: Props) {
placeholder={"100"}
min={0}
max={100}
value={
listQuestions[quizId][totalIndex].content.range.split("—")[1]
}
value={question.content.range.split("—")[1]}
onChange={({ target }) => {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.range = `${
listQuestions[quizId][totalIndex].content.range.split("—")[0]
}${target.value}`;
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
content: {
...question.content,
range: `${question.content.range.split("—")[0]}${
target.value
}`,
},
});
}}
onBlur={({ target }) => {
const start = listQuestions[quizId][totalIndex].content.start;
const step = listQuestions[quizId][totalIndex].content.step;
const min = Number(
listQuestions[quizId][totalIndex].content.range.split("—")[0]
);
const start = question.content.start;
const step = question.content.step;
const min = Number(question.content.range.split("—")[0]);
const max = Number(target.value);
const range = max - min;
if (max <= min) {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.range = `${
listQuestions[quizId][totalIndex].content.range.split(
"—"
)[0]
}${min + 1 >= 100 ? 100 : min + 1}`;
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
content: {
...question.content,
range: `${question.content.range.split("—")[0]}${
min + 1 >= 100 ? 100 : min + 1
}`,
},
});
}
if (start > max) {
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
start: max,
},
content: { ...question.content, start: max },
});
}
if (step > max) {
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
step: max,
},
content: { ...question.content, step: max },
});
if (range % step) {
@ -183,18 +169,12 @@ export default function SliderOptions({ totalIndex }: Props) {
</Typography>
<CustomNumberField
placeholder={"50"}
min={Number(
listQuestions[quizId][totalIndex].content.range.split("—")[0]
)}
max={Number(
listQuestions[quizId][totalIndex].content.range.split("—")[1]
)}
value={String(listQuestions[quizId][totalIndex].content.start)}
min={Number(question.content.range.split("—")[0])}
max={Number(question.content.range.split("—")[1])}
value={String(question.content.start)}
onChange={({ target }) => {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.start = Number(target.value);
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
content: { ...question.content, start: Number(target.value) },
});
}}
/>
@ -215,30 +195,21 @@ export default function SliderOptions({ totalIndex }: Props) {
max={100}
placeholder={"1"}
error={stepError}
value={String(listQuestions[quizId][totalIndex].content.step)}
value={String(question.content.step)}
onChange={({ target }) => {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.step = Number(target.value);
updateQuestionsList(quizId, totalIndex, {
content: clonContent,
content: { ...question.content, step: Number(target.value) },
});
}}
onBlur={({ target }) => {
const min = Number(
listQuestions[quizId][totalIndex].content.range.split("—")[0]
);
const max = Number(
listQuestions[quizId][totalIndex].content.range.split("—")[1]
);
const min = Number(question.content.range.split("—")[0]);
const max = Number(question.content.range.split("—")[1]);
const range = max - min;
const step = Number(target.value);
if (step > max) {
updateQuestionsList(quizId, totalIndex, {
content: {
...listQuestions[quizId][totalIndex].content,
step: max,
},
content: { ...question.content, step: max },
});
}

@ -12,6 +12,8 @@ import CustomTextField from "@ui_kit/CustomTextField";
import InfoIcon from "../../../assets/icons/InfoIcon";
import { questionStore, updateQuestionsList } from "@root/questions";
import type { QuizQuestionNumber } from "../../../model/questionTypes/number";
type SettingSliderProps = {
totalIndex: number;
};
@ -22,10 +24,11 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
const theme = useTheme();
const isWrappColumn = useMediaQuery(theme.breakpoints.down(980));
const isMobile = useMediaQuery(theme.breakpoints.down(790));
const question = listQuestions[quizId][totalIndex] as QuizQuestionNumber;
const debounced = useDebouncedCallback((value) => {
let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.innerName = value;
updateQuestionsList(quizId, totalIndex, { content: clonContent });
updateQuestionsList(quizId, totalIndex, {
content: { ...question.content, innerName: value },
});
}, 1000);
return (
@ -41,11 +44,11 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
<CustomCheckbox
sx={{ mr: isMobile ? "0px" : "16px" }}
label={"Выбор диапозона (два ползунка)"}
checked={listQuestions[quizId][totalIndex].content.chooseRange}
handleChange={(e) => {
let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.chooseRange = e.target.checked;
updateQuestionsList(quizId, totalIndex, { content: clonContent });
checked={question.content.chooseRange}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
content: { ...question.content, chooseRange: target.checked },
});
}}
/>
</Box>
@ -71,16 +74,15 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
<CustomCheckbox
sx={{ mr: isMobile ? "0px" : "16px" }}
label={"Внутреннее название вопроса"}
checked={listQuestions[quizId][totalIndex].content.innerNameCheck}
handleChange={(e) => {
let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.innerNameCheck = e.target.checked;
if (!e.target.checked) {
clonContent.innerName = "";
}
updateQuestionsList(quizId, totalIndex, { content: clonContent });
checked={question.content.innerNameCheck}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
content: {
...question.content,
innerNameCheck: target.checked,
innerName: target.checked ? question.content.innerName : "",
},
});
}}
/>
<Tooltip
@ -92,10 +94,10 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) {
</Box>
</Tooltip>
</Box>
{listQuestions[quizId][totalIndex].content.innerNameCheck && (
{question.content.innerNameCheck && (
<CustomTextField
placeholder={"Развёрнутое описание вопроса"}
text={listQuestions[quizId][totalIndex].content.innerName}
text={question.content.innerName}
onChange={({ target }) => debounced(target.value)}
/>
)}

@ -13,7 +13,14 @@ import RatingIcon from "../../assets/icons/questionsPage/rating";
import { Box } from "@mui/material";
import React from "react";
import { useParams } from "react-router-dom";
import { questionStore, updateQuestionsList } from "@root/questions";
import {
questionStore,
updateQuestionsList,
createQuestion,
removeQuestion,
} from "@root/questions";
import type { QuizQuestionType } from "../../model/questionTypes/shared";
interface Props {
totalIndex: number;
@ -22,7 +29,7 @@ interface Props {
type ButtonTypeQuestion = {
icon: JSX.Element;
title: string;
value: string;
value: QuizQuestionType;
};
export const BUTTON_TYPE_QUESTIONS: ButtonTypeQuestion[] = [
@ -101,8 +108,13 @@ export default function TypeQuestions({ totalIndex }: Props) {
<QuestionsMiniButton
key={title}
onClick={() => {
console.log(value);
updateQuestionsList(quizId, totalIndex, { type: value });
const question = listQuestions[quizId][totalIndex];
removeQuestion(quizId, totalIndex);
createQuestion(quizId, value, totalIndex);
updateQuestionsList(quizId, totalIndex, {
expanded: question.expanded,
});
}}
icon={icon}
text={title}

@ -18,6 +18,8 @@ import InfoIcon from "../../../assets/icons/InfoIcon";
import ArrowDown from "../../../assets/icons/ArrowDownIcon";
import SwitchUpload from "./switchUpload";
import type { QuizQuestionFile } from "../../../model/questionTypes/file";
interface Props {
totalIndex: number;
}
@ -36,24 +38,27 @@ export default function UploadFile({ totalIndex }: Props) {
const { listQuestions } = questionStore();
const theme = useTheme();
const isTablet = useMediaQuery(theme.breakpoints.down(980));
const question = listQuestions[quizId][totalIndex] as QuizQuestionFile;
const SSHC = (data: string) => {
setSwitchState(data);
};
const handleChange = ({ target }: SelectChangeEvent) => {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.type = target.value;
updateQuestionsList(quizId, totalIndex, { content: clonContent });
updateQuestionsList(quizId, totalIndex, {
content: { ...question.content, type: target.value },
});
};
useEffect(() => {
const isTypeSetted = DESIGN_TYPES.find(({ value }) => value === listQuestions[quizId][totalIndex].content.type);
const isTypeSetted = DESIGN_TYPES.find(
({ value }) => value === question.content.type
);
if (!isTypeSetted) {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.type = DESIGN_TYPES[0].value;
updateQuestionsList(quizId, totalIndex, { content: clonContent });
updateQuestionsList(quizId, totalIndex, {
content: { ...question.content, type: DESIGN_TYPES[0].value },
});
}
}, []);
@ -82,7 +87,7 @@ export default function UploadFile({ totalIndex }: Props) {
<Select
id="category-select"
variant="outlined"
value={listQuestions[quizId][totalIndex].content.type}
value={question.type}
displayEmpty
onChange={handleChange}
sx={{
@ -159,7 +164,11 @@ export default function UploadFile({ totalIndex }: Props) {
<InfoIcon />
</Box>
</Box>
<ButtonsOptions switchState={switchState} SSHC={SSHC} totalIndex={totalIndex} />
<ButtonsOptions
switchState={switchState}
SSHC={SSHC}
totalIndex={totalIndex}
/>
<SwitchUpload switchState={switchState} totalIndex={totalIndex} />
</>
);

@ -1,5 +1,11 @@
import { useParams } from "react-router-dom";
import { Box, Typography, useMediaQuery, useTheme, Tooltip } from "@mui/material";
import {
Box,
Typography,
useMediaQuery,
useTheme,
Tooltip,
} from "@mui/material";
import CustomCheckbox from "@ui_kit/CustomCheckbox";
import CustomTextField from "@ui_kit/CustomTextField";
import { useDebouncedCallback } from "use-debounce";
@ -8,6 +14,8 @@ import { questionStore, updateQuestionsList } from "@root/questions";
import InfoIcon from "../../../assets/icons/InfoIcon";
import type { QuizQuestionFile } from "../../../model/questionTypes/file";
type SettingsUploadProps = {
totalIndex: number;
};
@ -16,50 +24,64 @@ export default function SettingsUpload({ totalIndex }: SettingsUploadProps) {
const theme = useTheme();
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore();
const question = listQuestions[quizId][totalIndex] as QuizQuestionFile;
const debounced = useDebouncedCallback((value) => {
let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.innerName = value;
updateQuestionsList(quizId, totalIndex, { content: clonContent });
updateQuestionsList(quizId, totalIndex, {
content: { ...question.content, innerName: value },
});
}, 1000);
const isMobile = useMediaQuery(theme.breakpoints.down(790));
return (
<Box sx={{ display: "flex", flexDirection: "column", pt: "20px", pb: "20px", pl: "20px" }}>
<Box
sx={{
display: "flex",
flexDirection: "column",
pt: "20px",
pb: "20px",
pl: "20px",
}}
>
<Typography>Настройки вопроса</Typography>
<CustomCheckbox
sx={{ display: "block", mr: isMobile ? "0px" : "16px" }}
label={"Автозаполнение адреса"}
checked={listQuestions[quizId][totalIndex].content.autofill}
checked={question.content.autofill}
handleChange={({ target }) => {
const clonContent = listQuestions[quizId][totalIndex].content;
clonContent.autofill = target.checked;
updateQuestionsList(quizId, totalIndex, { content: clonContent });
updateQuestionsList(quizId, totalIndex, {
content: { ...question.content, autofill: target.checked },
});
}}
/>
<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,
});
}}
/>
<Box sx={{ width: isMobile ? "90%" : "auto", display: "flex", alignItems: "center" }}>
<Box
sx={{
width: isMobile ? "90%" : "auto",
display: "flex",
alignItems: "center",
}}
>
<CustomCheckbox
sx={{ mr: isMobile ? "0px" : "16px" }}
label={"Внутреннее название вопроса"}
checked={listQuestions[quizId][totalIndex].content.innerNameCheck}
handleChange={(e) => {
let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.innerNameCheck = e.target.checked;
if (!e.target.checked) {
clonContent.innerName = "";
}
updateQuestionsList(quizId, totalIndex, { content: clonContent });
checked={question.content.innerNameCheck}
handleChange={({ target }) => {
updateQuestionsList(quizId, totalIndex, {
content: {
...question.content,
innerNameCheck: target.checked,
innerName: target.checked ? question.content.innerName : "",
},
});
}}
/>
<Tooltip
@ -71,10 +93,10 @@ export default function SettingsUpload({ totalIndex }: SettingsUploadProps) {
</Box>
</Tooltip>
</Box>
{listQuestions[quizId][totalIndex].content.innerNameCheck && (
{question.content.innerNameCheck && (
<CustomTextField
placeholder={"Развёрнутое описание вопроса"}
text={listQuestions[quizId][totalIndex].content.innerName}
text={question.content.innerName}
onChange={({ target }) => debounced(target.value)}
/>
)}

@ -9,6 +9,7 @@ import { questionStore, updateQuestionsList } from "@root/questions";
import { UploadImageModal } from "./UploadImageModal";
import type { DragEvent } from "react";
import type { QuizQuestionImages } from "../../../model/questionTypes/images";
type UploadImageProps = {
totalIndex: number;
@ -19,6 +20,7 @@ export default function UploadImage({ totalIndex }: UploadImageProps) {
const theme = useTheme();
const [open, setOpen] = React.useState(false);
const { listQuestions } = questionStore();
const question = listQuestions[quizId][totalIndex] as QuizQuestionImages;
const handleOpen = () => setOpen(true);
const handleClose = () => setOpen(false);
@ -26,9 +28,10 @@ export default function UploadImage({ totalIndex }: UploadImageProps) {
if (files?.length) {
const [file] = Array.from(files);
let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.back = URL.createObjectURL(file);
updateQuestionsList(quizId, totalIndex, { content: clonContent });
updateQuestionsList(quizId, totalIndex, {
...question,
back: URL.createObjectURL(file),
});
handleClose();
setOpened(true);
@ -70,7 +73,7 @@ export default function UploadImage({ totalIndex }: UploadImageProps) {
<CropModal
opened={opened}
onClose={() => setOpened(false)}
picture={listQuestions[quizId][totalIndex].content.back}
picture={question.content.back}
/>
</Box>
);

@ -7,6 +7,8 @@ import { AnswerDraggableList } from "../AnswerDraggableList";
import ButtonsOptionsAndPict from "../ButtonsOptionsAndPict";
import { questionStore, updateQuestionsList } from "@root/questions";
import type { QuizQuestionVariant } from "../../../model/questionTypes/variant";
interface Props {
totalIndex: number;
}
@ -15,7 +17,7 @@ export default function AnswerOptions({ totalIndex }: Props) {
const [switchState, setSwitchState] = useState("setting");
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore();
const variants = listQuestions[quizId][totalIndex].content.variants;
const question = listQuestions[quizId][totalIndex] as QuizQuestionVariant;
const theme = useTheme();
const isMobile = useMediaQuery(theme.breakpoints.down(790));
@ -24,8 +26,8 @@ export default function AnswerOptions({ totalIndex }: Props) {
};
const addNewAnswer = () => {
const answerNew = variants.slice();
answerNew.push({ answer: "", hints: "", emoji: "" });
const answerNew = question.content.variants.slice();
answerNew.push({ answer: "", hints: "", extendedText: "" });
updateQuestionsList(quizId, totalIndex, {
content: {
@ -38,7 +40,7 @@ export default function AnswerOptions({ totalIndex }: Props) {
return (
<>
<Box sx={{ padding: "0 20px 20px 20px" }}>
{variants.length === 0 ? (
{question.content.variants.length === 0 ? (
<Typography
sx={{
padding: "0 0 33px 80px",
@ -51,7 +53,10 @@ export default function AnswerOptions({ totalIndex }: Props) {
Добавьте ответ
</Typography>
) : (
<AnswerDraggableList variants={variants} totalIndex={totalIndex} />
<AnswerDraggableList
variants={question.content.variants}
totalIndex={totalIndex}
/>
)}
<Box

@ -9,6 +9,8 @@ import UploadBox from "@ui_kit/UploadBox";
import { questionStore, updateQuestionsList } from "@root/questions";
import { UploadVideoModal } from "./UploadVideoModal";
import type { QuizQuestionBase } from "../../model/questionTypes/shared";
type BackgroundType = "text" | "video";
type HelpQuestionsProps = {
@ -20,16 +22,25 @@ export default function HelpQuestions({ totalIndex }: HelpQuestionsProps) {
const [backgroundType, setBackgroundType] = useState<BackgroundType>("text");
const quizId = Number(useParams().quizId);
const { listQuestions } = questionStore();
const question = listQuestions[quizId][totalIndex] as QuizQuestionBase;
const debounced = useDebouncedCallback((value) => {
let clonContent = listQuestions[quizId][totalIndex].content;
clonContent.hint.text = value;
updateQuestionsList(quizId, totalIndex, { content: clonContent });
updateQuestionsList(quizId, totalIndex, {
content: {
...question.content,
hint: { text: value, video: question.content.hint.video },
},
});
}, 1000);
const videoHC = (url: string) => {
const clonContent = listQuestions[quizId][totalIndex].content;
const clonContent = question.content;
clonContent.hint.video = url;
updateQuestionsList(quizId, totalIndex, { content: clonContent });
updateQuestionsList(quizId, totalIndex, {
content: {
...question.content,
hint: { video: url, text: question.content.hint.text },
},
});
};
return (
@ -67,7 +78,7 @@ export default function HelpQuestions({ totalIndex }: HelpQuestionsProps) {
<>
<CustomTextField
placeholder={"Текст консультанта"}
text={listQuestions[quizId][totalIndex].content.hint.text}
text={question.content.hint.text}
onChange={({ target }) => debounced(target.value)}
/>
</>
@ -80,12 +91,8 @@ export default function HelpQuestions({ totalIndex }: HelpQuestionsProps) {
onClick={() => setOpen(true)}
sx={{ justifyContent: "flex-start" }}
>
{listQuestions[quizId][totalIndex].content.hint.video ? (
<video
src={listQuestions[quizId][totalIndex].content.hint.video}
width="400"
controls
/>
{question.content.hint.video ? (
<video src={question.content.hint.video} width="400" controls />
) : (
<>
<UploadBox
@ -101,7 +108,7 @@ export default function HelpQuestions({ totalIndex }: HelpQuestionsProps) {
<UploadVideoModal
open={open}
onClose={() => setOpen(false)}
video={listQuestions[quizId][totalIndex].content.hint.video}
video={question.content.hint.video}
onUpload={videoHC}
/>
</Box>

@ -9,24 +9,21 @@ import { QuizQuestionVarImg } from "../model/questionTypes/varimg";
import type {
AnyQuizQuestion,
QuizQuestionType,
Variant,
} from "../model/questionTypes/shared";
import { QuizQuestionDateEmpty } from "../constants/date";
import { QuizQuestionEmojiEmpty } from "../constants/emoji";
import { QuizQuestionFileEmpty } from "../constants/file";
import { QuizQuestionImagesEmpty } from "../constants/images";
import { QuizQuestionNumberEmpty } from "../constants/number";
import { QuizQuestionPageEmpty } from "../constants/page";
import { QuizQuestionRatingEmpty } from "../constants/rating";
import { QuizQuestionSelectEmpty } from "../constants/select";
import { QuizQuestionTextEmpty } from "../constants/text";
import { QuizQuestionVariantEmpty } from "../constants/variant";
import { QuizQuestionVarImgEmpty } from "../constants/varimg";
export type Variants = {
answer: string;
hints: string;
emoji: string;
};
import { QUIZ_QUESTION_BASE } from "../constants/base";
import { QUIZ_QUESTION_DATE } from "../constants/date";
import { QUIZ_QUESTION_EMOJI } from "../constants/emoji";
import { QUIZ_QUESTION_FILE } from "../constants/file";
import { QUIZ_QUESTION_IMAGES } from "../constants/images";
import { QUIZ_QUESTION_NUMBER } from "../constants/number";
import { QUIZ_QUESTION_PAGE } from "../constants/page";
import { QUIZ_QUESTION_RATING } from "../constants/rating";
import { QUIZ_QUESTION_SELECT } from "../constants/select";
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;
@ -53,7 +50,7 @@ export interface Question {
deleted: true;
page: number;
content: {
variants: Variants[];
variants: Variant[];
hint: Hint;
rule: Rule;
images: string[];
@ -143,7 +140,7 @@ export const DEFAULT_QUESTION: Omit<Question, "id"> = {
{
answer: "",
hints: "",
emoji: "",
extendedText: "",
},
],
hint: {
@ -195,7 +192,7 @@ export const updateQuestionsList = <T = AnyQuizQuestion>(
export const updateQuestionsListDragAndDrop = (
quizId: number,
updatedQuestions: Question[]
updatedQuestions: AnyQuizQuestion[]
) => {
const questionListClone = { ...questionStore.getState()["listQuestions"] };
questionStore.setState({
@ -206,7 +203,7 @@ export const updateQuestionsListDragAndDrop = (
export const updateVariants = (
quizId: number,
index: number,
variants: Variants[]
variants: Variant[]
) => {
const listQuestions = { ...questionStore.getState()["listQuestions"] };
@ -235,7 +232,7 @@ export const updateVariants = (
export const createQuestion = (
quizId: number,
questionType: QuizQuestionType,
questionType: QuizQuestionType = "",
placeIndex = -1
) => {
const id = getRandom(1000000, 10000000);
@ -246,17 +243,18 @@ export const createQuestion = (
}
const defaultObject = [
QuizQuestionDateEmpty,
QuizQuestionEmojiEmpty,
QuizQuestionFileEmpty,
QuizQuestionImagesEmpty,
QuizQuestionNumberEmpty,
QuizQuestionPageEmpty,
QuizQuestionRatingEmpty,
QuizQuestionSelectEmpty,
QuizQuestionTextEmpty,
QuizQuestionVariantEmpty,
QuizQuestionVarImgEmpty,
QUIZ_QUESTION_BASE,
QUIZ_QUESTION_DATE,
QUIZ_QUESTION_EMOJI,
QUIZ_QUESTION_FILE,
QUIZ_QUESTION_IMAGES,
QUIZ_QUESTION_NUMBER,
QUIZ_QUESTION_PAGE,
QUIZ_QUESTION_RATING,
QUIZ_QUESTION_SELECT,
QUIZ_QUESTION_TEXT,
QUIZ_QUESTION_VARIANT,
QUIZ_QUESTION_VARIMG,
].find((defaultObjectItem) => defaultObjectItem.type === questionType);
if (defaultObject) {