diff --git a/src/constants/base.ts b/src/constants/base.ts new file mode 100644 index 00000000..09602098 --- /dev/null +++ b/src/constants/base.ts @@ -0,0 +1,16 @@ +import type { QuizQuestionBase } from "../model/questionTypes/shared"; + +export const QUIZ_QUESTION_BASE: Omit = { + title: "", + type: "", + expanded: false, + required: false, + content: { + hint: { + text: "", + video: "", + }, + back: "", + autofill: false, + }, +}; diff --git a/src/constants/date.ts b/src/constants/date.ts index 245add21..8b217313 100644 --- a/src/constants/date.ts +++ b/src/constants/date.ts @@ -1,9 +1,12 @@ +import { QUIZ_QUESTION_BASE } from "./base"; + import type { QuizQuestionDate } from "../model/questionTypes/date"; -export const QuizQuestionDateEmpty: Omit = { - title: "", +export const QUIZ_QUESTION_DATE: Omit = { + ...QUIZ_QUESTION_BASE, type: "date", content: { + ...QUIZ_QUESTION_BASE.content, required: false, innerNameCheck: false, innerName: "", diff --git a/src/constants/emoji.ts b/src/constants/emoji.ts index cc5bf678..4751a692 100644 --- a/src/constants/emoji.ts +++ b/src/constants/emoji.ts @@ -1,9 +1,12 @@ +import { QUIZ_QUESTION_BASE } from "./base"; + import type { QuizQuestionEmoji } from "../model/questionTypes/emoji"; -export const QuizQuestionEmojiEmpty: Omit = { - title: "", +export const QUIZ_QUESTION_EMOJI: Omit = { + ...QUIZ_QUESTION_BASE, type: "emoji", content: { + ...QUIZ_QUESTION_BASE.content, multi: false, own: false, innerNameCheck: false, @@ -13,7 +16,7 @@ export const QuizQuestionEmojiEmpty: Omit = { { answer: "", hints: "", - emoji: "", + extendedText: "", }, ], hint: { diff --git a/src/constants/file.ts b/src/constants/file.ts index 815f5eb2..922d6d18 100644 --- a/src/constants/file.ts +++ b/src/constants/file.ts @@ -1,13 +1,15 @@ +import { QUIZ_QUESTION_BASE } from "./base"; + import type { QuizQuestionFile } from "../model/questionTypes/file"; -export const QuizQuestionFileEmpty: Omit = { - title: "", +export const QUIZ_QUESTION_FILE: Omit = { + ...QUIZ_QUESTION_BASE, type: "file", content: { + ...QUIZ_QUESTION_BASE.content, required: false, innerNameCheck: false, innerName: "", - autofill: false, type: "all", hint: { text: "", diff --git a/src/constants/images.ts b/src/constants/images.ts index 77cf47e0..7cb27e0f 100644 --- a/src/constants/images.ts +++ b/src/constants/images.ts @@ -1,9 +1,12 @@ +import { QUIZ_QUESTION_BASE } from "./base"; + import type { QuizQuestionImages } from "../model/questionTypes/images"; -export const QuizQuestionImagesEmpty: Omit = { - title: "", +export const QUIZ_QUESTION_IMAGES: Omit = { + ...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 = { { answer: "", hints: "", + extendedText: "", }, ], hint: { @@ -32,5 +36,6 @@ export const QuizQuestionImagesEmpty: Omit = { }, ], }, + largeCheck: false, }, }; diff --git a/src/constants/number.ts b/src/constants/number.ts index 307b22ea..10af288e 100644 --- a/src/constants/number.ts +++ b/src/constants/number.ts @@ -1,15 +1,20 @@ +import { QUIZ_QUESTION_BASE } from "./base"; + import type { QuizQuestionNumber } from "../model/questionTypes/number"; -export const QuizQuestionNumberEmpty: Omit = { - title: "", +export const QUIZ_QUESTION_NUMBER: Omit = { + ...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 = { }, ], }, + form: "star", }, }; diff --git a/src/constants/page.ts b/src/constants/page.ts index 2fa08a13..c4faa34d 100644 --- a/src/constants/page.ts +++ b/src/constants/page.ts @@ -1,9 +1,12 @@ +import { QUIZ_QUESTION_BASE } from "./base"; + import type { QuizQuestionPage } from "../model/questionTypes/page"; -export const QuizQuestionPageEmpty: Omit = { - title: "", +export const QUIZ_QUESTION_PAGE: Omit = { + ...QUIZ_QUESTION_BASE, type: "page", content: { + ...QUIZ_QUESTION_BASE.content, innerNameCheck: false, innerName: "", text: "", diff --git a/src/constants/rating.ts b/src/constants/rating.ts index 779d8853..27ec6cc6 100644 --- a/src/constants/rating.ts +++ b/src/constants/rating.ts @@ -1,9 +1,12 @@ +import { QUIZ_QUESTION_BASE } from "./base"; + import type { QuizQuestionRating } from "../model/questionTypes/rating"; -export const QuizQuestionRatingEmpty: Omit = { - title: "", +export const QUIZ_QUESTION_RATING: Omit = { + ...QUIZ_QUESTION_BASE, type: "rating", content: { + ...QUIZ_QUESTION_BASE.content, required: false, innerNameCheck: false, innerName: "", diff --git a/src/constants/select.ts b/src/constants/select.ts index 29c9a99e..d67b7ca2 100644 --- a/src/constants/select.ts +++ b/src/constants/select.ts @@ -1,9 +1,12 @@ +import { QUIZ_QUESTION_BASE } from "./base"; + import type { QuizQuestionSelect } from "../model/questionTypes/select"; -export const QuizQuestionSelectEmpty: Omit = { - title: "", +export const QUIZ_QUESTION_SELECT: Omit = { + ...QUIZ_QUESTION_BASE, type: "select", content: { + ...QUIZ_QUESTION_BASE.content, multi: false, required: false, innerNameCheck: false, diff --git a/src/constants/text.ts b/src/constants/text.ts index 342bb9d9..5d32ff4f 100644 --- a/src/constants/text.ts +++ b/src/constants/text.ts @@ -1,14 +1,16 @@ +import { QUIZ_QUESTION_BASE } from "./base"; + import type { QuizQuestionText } from "../model/questionTypes/text"; -export const QuizQuestionTextEmpty: Omit = { - title: "", +export const QUIZ_QUESTION_TEXT: Omit = { + ...QUIZ_QUESTION_BASE, type: "text", content: { + ...QUIZ_QUESTION_BASE.content, placeholder: "", innerNameCheck: false, innerName: "", required: false, - autofill: false, answerType: "single", hint: { text: "", diff --git a/src/constants/variant.ts b/src/constants/variant.ts index f22b4f76..b49963c5 100644 --- a/src/constants/variant.ts +++ b/src/constants/variant.ts @@ -1,21 +1,19 @@ +import { QUIZ_QUESTION_BASE } from "./base"; + import type { QuizQuestionVariant } from "../model/questionTypes/variant"; -export const QuizQuestionVariantEmpty: Omit = { - title: "", +export const QUIZ_QUESTION_VARIANT: Omit = { + ...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: "", diff --git a/src/constants/varimg.ts b/src/constants/varimg.ts index 27e5b9a7..027af803 100644 --- a/src/constants/varimg.ts +++ b/src/constants/varimg.ts @@ -1,19 +1,17 @@ +import { QUIZ_QUESTION_BASE } from "./base"; + import type { QuizQuestionVarImg } from "../model/questionTypes/varimg"; -export const QuizQuestionVarImgEmpty: Omit = { - title: "", +export const QUIZ_QUESTION_VARIMG: Omit = { + ...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 = { }, ], }, + largeCheck: false, + replText: "", }, }; diff --git a/src/model/questionTypes/date.ts b/src/model/questionTypes/date.ts index cfa04a45..3d3cd287 100644 --- a/src/model/questionTypes/date.ts +++ b/src/model/questionTypes/date.ts @@ -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; + }; } diff --git a/src/model/questionTypes/emoji.ts b/src/model/questionTypes/emoji.ts index b2f4f52a..0f3f5272 100644 --- a/src/model/questionTypes/emoji.ts +++ b/src/model/questionTypes/emoji.ts @@ -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; + }; } diff --git a/src/model/questionTypes/file.ts b/src/model/questionTypes/file.ts index 1562bbfe..603b7bcb 100644 --- a/src/model/questionTypes/file.ts +++ b/src/model/questionTypes/file.ts @@ -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; + }; } diff --git a/src/model/questionTypes/images.ts b/src/model/questionTypes/images.ts index 7a036d72..86cae425 100644 --- a/src/model/questionTypes/images.ts +++ b/src/model/questionTypes/images.ts @@ -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; + }; } diff --git a/src/model/questionTypes/number.ts b/src/model/questionTypes/number.ts index 5fbf2646..727515ea 100644 --- a/src/model/questionTypes/number.ts +++ b/src/model/questionTypes/number.ts @@ -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"; + }; } diff --git a/src/model/questionTypes/page.ts b/src/model/questionTypes/page.ts index ff7238fe..de3b1845 100644 --- a/src/model/questionTypes/page.ts +++ b/src/model/questionTypes/page.ts @@ -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; + }; } diff --git a/src/model/questionTypes/rating.ts b/src/model/questionTypes/rating.ts index 0f9ddaea..bb440881 100644 --- a/src/model/questionTypes/rating.ts +++ b/src/model/questionTypes/rating.ts @@ -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; + }; } diff --git a/src/model/questionTypes/select.ts b/src/model/questionTypes/select.ts index f8c89a54..5a5e5860 100644 --- a/src/model/questionTypes/select.ts +++ b/src/model/questionTypes/select.ts @@ -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; + }; } diff --git a/src/model/questionTypes/shared.ts b/src/model/questionTypes/shared.ts index d8b6e935..751514fa 100644 --- a/src/model/questionTypes/shared.ts +++ b/src/model/questionTypes/shared.ts @@ -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"]; diff --git a/src/model/questionTypes/text.ts b/src/model/questionTypes/text.ts index 89ffa5f3..6c220a95 100644 --- a/src/model/questionTypes/text.ts +++ b/src/model/questionTypes/text.ts @@ -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; + }; } diff --git a/src/model/questionTypes/variant.ts b/src/model/questionTypes/variant.ts index cddc2474..f2fa5f80 100644 --- a/src/model/questionTypes/variant.ts +++ b/src/model/questionTypes/variant.ts @@ -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; + }; } diff --git a/src/model/questionTypes/varimg.ts b/src/model/questionTypes/varimg.ts index 27b1be80..8bb27f7f 100644 --- a/src/model/questionTypes/varimg.ts +++ b/src/model/questionTypes/varimg.ts @@ -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; + }; } diff --git a/src/pages/Questions/DataOptions/settingData.tsx b/src/pages/Questions/DataOptions/settingData.tsx index 01063740..bcefd193 100644 --- a/src/pages/Questions/DataOptions/settingData.tsx +++ b/src/pages/Questions/DataOptions/settingData.tsx @@ -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) { { - const clonContent = listQuestions[quizId][totalIndex].content; - clonContent.dateRange = target.checked; - updateQuestionsList(quizId, totalIndex, { content: clonContent }); + updateQuestionsList(quizId, totalIndex, { + content: { ...question.content, dateRange: target.checked }, + }); }} /> { - const clonContent = listQuestions[quizId][totalIndex].content; - clonContent.time = target.checked; - updateQuestionsList(quizId, totalIndex, { content: clonContent }); + updateQuestionsList(quizId, totalIndex, { + content: { ...question.content, time: target.checked }, + }); }} /> @@ -73,27 +75,32 @@ export default function SettingsData({ totalIndex }: SettingsDataProps) { { + checked={!question.required} + handleChange={({ target }) => { updateQuestionsList(quizId, totalIndex, { - required: !e.target.checked, + required: !target.checked, }); }} /> - + { - 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 : "", + }, + }); }} /> - {listQuestions[quizId][totalIndex].content.innerNameCheck && ( + {question.content.innerNameCheck && ( debounced(target.value)} /> )} diff --git a/src/pages/Questions/DraggableList/ChooseAnswerModal.tsx b/src/pages/Questions/DraggableList/ChooseAnswerModal.tsx index 90e10705..e2438fee 100644 --- a/src/pages/Questions/DraggableList/ChooseAnswerModal.tsx +++ b/src/pages/Questions/DraggableList/ChooseAnswerModal.tsx @@ -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(false); - const [selectedValue, setSelectedValue] = useState(""); + const [selectedValue, setSelectedValue] = useState("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, }); }} > diff --git a/src/pages/Questions/DraggableList/QuestionPageCard.tsx b/src/pages/Questions/DraggableList/QuestionPageCard.tsx index 48ed112b..3cddbf19 100644 --- a/src/pages/Questions/DraggableList/QuestionPageCard.tsx +++ b/src/pages/Questions/DraggableList/QuestionPageCard.tsx @@ -338,7 +338,7 @@ export default function QuestionsPageCard({ }} > createQuestion(quizId, totalIndex + 1)} + onClick={() => createQuestion(quizId, "", totalIndex + 1)} sx={{ display: plusVisible && !isDragging ? "flex" : "none", width: "100%", diff --git a/src/pages/Questions/DropDown/DropDown.tsx b/src/pages/Questions/DropDown/DropDown.tsx index 95dc201c..c585758c 100644 --- a/src/pages/Questions/DropDown/DropDown.tsx +++ b/src/pages/Questions/DropDown/DropDown.tsx @@ -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 ? ( ) : ( - + )} { - 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) { 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) { debounceAnswer(target.value)} /> @@ -80,7 +79,7 @@ export default function SettingDropDown({ totalIndex }: SettingDropDownProps) { { updateQuestionsList(quizId, totalIndex, { required: !e.target.checked, @@ -92,17 +91,14 @@ export default function SettingDropDown({ totalIndex }: SettingDropDownProps) { > { - 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) { debounceAnswer(target.value)} /> - {listQuestions[quizId][totalIndex].content.innerNameCheck && ( + {question.content.innerNameCheck && ( debounced(target.value)} /> )} diff --git a/src/pages/Questions/Emoji/Emoji.tsx b/src/pages/Questions/Emoji/Emoji.tsx index 94f278e7..143f4a0a 100644 --- a/src/pages/Questions/Emoji/Emoji.tsx +++ b/src/pages/Questions/Emoji/Emoji.tsx @@ -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: { diff --git a/src/pages/Questions/Emoji/settingEmoji.tsx b/src/pages/Questions/Emoji/settingEmoji.tsx index 54d3ad8e..45c0a50a 100644 --- a/src/pages/Questions/Emoji/settingEmoji.tsx +++ b/src/pages/Questions/Emoji/settingEmoji.tsx @@ -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) { { - 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 }, + }); }} /> { - 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 }, + }); }} /> @@ -72,27 +75,32 @@ export default function SettingEmoji({ totalIndex }: SettingEmojiProps) { { updateQuestionsList(quizId, totalIndex, { required: !e.target.checked, }); }} /> - + { - 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 : "", + }, + }); }} /> - {listQuestions[quizId][totalIndex].content.innerNameCheck && ( + {question.content.innerNameCheck && ( debounced(target.value)} /> )} diff --git a/src/pages/Questions/OptionsAndPicture/OptionsAndPicture.tsx b/src/pages/Questions/OptionsAndPicture/OptionsAndPicture.tsx index 3a519398..a25cebb5 100644 --- a/src/pages/Questions/OptionsAndPicture/OptionsAndPicture.tsx +++ b/src/pages/Questions/OptionsAndPicture/OptionsAndPicture.tsx @@ -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) { <> - {listQuestions[quizId][totalIndex].content.variants.map( - (_, index) => ( - ( + + { + 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" + /> + + - { - 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" - /> - - - Добавьте ответ - - - ) - )} + Добавьте ответ + + + ))} @@ -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 }); }} > diff --git a/src/pages/Questions/OptionsAndPicture/SettingOptionsAndPict.tsx b/src/pages/Questions/OptionsAndPicture/SettingOptionsAndPict.tsx index cf9bda0c..42d3fc2e 100644 --- a/src/pages/Questions/OptionsAndPicture/SettingOptionsAndPict.tsx +++ b/src/pages/Questions/OptionsAndPicture/SettingOptionsAndPict.tsx @@ -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, }} > - + Настройки ответов { 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({ Текст-заглушка на картинке debounced(target.value)} /> @@ -94,27 +100,27 @@ export default function SettingOptionsAndPict({ Настройки вопросов { updateQuestionsList(quizId, totalIndex, { - content: { - ...listQuestions[quizId][totalIndex].content, - required: target.checked, - }, + content: { ...question.content, required: target.checked }, }); }} /> { updateQuestionsList(quizId, totalIndex, { content: { - ...listQuestions[quizId][totalIndex].content, + ...question.content, innerNameCheck: target.checked, innerName: "", }, @@ -130,10 +136,10 @@ export default function SettingOptionsAndPict({ - {listQuestions[quizId][totalIndex].content.innerNameCheck && ( + {question.content.innerNameCheck && ( debounceDescription(target.value)} /> )} @@ -145,7 +151,7 @@ export default function SettingOptionsAndPict({ debounced(target.value)} /> diff --git a/src/pages/Questions/OptionsPicture/OptionsPicture.tsx b/src/pages/Questions/OptionsPicture/OptionsPicture.tsx index 81db9f50..54070a89 100644 --- a/src/pages/Questions/OptionsPicture/OptionsPicture.tsx +++ b/src/pages/Questions/OptionsPicture/OptionsPicture.tsx @@ -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) => { - 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 ( <> @@ -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: ( <> diff --git a/src/pages/Questions/OptionsPicture/settingOpytionsPict.tsx b/src/pages/Questions/OptionsPicture/settingOpytionsPict.tsx index 1f4c65cc..14697b35 100644 --- a/src/pages/Questions/OptionsPicture/settingOpytionsPict.tsx +++ b/src/pages/Questions/OptionsPicture/settingOpytionsPict.tsx @@ -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({ updateProportions(value)} - isActive={ - listQuestions[quizId][totalIndex].content.xy === value - } + isActive={question.content.xy === value} Icon={icon} /> ))} @@ -144,39 +143,30 @@ export default function SettingOpytionsPict({ updateQuestionsList(quizId, totalIndex, { - content: { - ...listQuestions[quizId][totalIndex].content, - multi: target.checked, - }, + content: { ...question.content, multi: target.checked }, }) } /> updateQuestionsList(quizId, totalIndex, { - content: { - ...listQuestions[quizId][totalIndex].content, - largeCheck: target.checked, - }, + content: { ...question.content, largeCheck: target.checked }, }) } /> 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({ 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} /> 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} /> @@ -224,24 +204,27 @@ export default function SettingOpytionsPict({ updateQuestionsList(quizId, totalIndex, { - content: { - ...listQuestions[quizId][totalIndex].content, - required: target.checked, - }, + content: { ...question.content, required: target.checked }, }) } /> - + updateQuestionsList(quizId, totalIndex, { content: { - ...listQuestions[quizId][totalIndex].content, + ...question.content, innerNameCheck: target.checked, innerName: "", }, @@ -257,10 +240,10 @@ export default function SettingOpytionsPict({ - {listQuestions[quizId][totalIndex].content.innerNameCheck && ( + {question.content.innerNameCheck && ( debounced(target.value)} /> )} diff --git a/src/pages/Questions/OwnTextField/OwnTextField.tsx b/src/pages/Questions/OwnTextField/OwnTextField.tsx index 3bf2cc64..addfed59 100644 --- a/src/pages/Questions/OwnTextField/OwnTextField.tsx +++ b/src/pages/Questions/OwnTextField/OwnTextField.tsx @@ -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) { > debounced(target.value)} /> diff --git a/src/pages/Questions/OwnTextField/settingTextField.tsx b/src/pages/Questions/OwnTextField/settingTextField.tsx index ebda3c55..7513743e 100644 --- a/src/pages/Questions/OwnTextField/settingTextField.tsx +++ b/src/pages/Questions/OwnTextField/settingTextField.tsx @@ -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({ 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) => { const clonContent = { - ...listQuestions[quizId][totalIndex].content, + ...question.content, single: false, multi: false, number: false, @@ -101,37 +116,42 @@ export default function SettingTextField({ { - const clonContent = listQuestions[quizId][totalIndex].content; - clonContent.autofill = target.checked; - updateQuestionsList(quizId, totalIndex, { content: clonContent }); + updateQuestionsList(quizId, totalIndex, { + content: { ...question.content, autofill: target.checked }, + }); }} /> { updateQuestionsList(quizId, totalIndex, { required: !e.target.checked, }); }} /> - + { - 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 : "", + }, + }); }} /> - {listQuestions[quizId][totalIndex].content.innerNameCheck && ( + {question.content.innerNameCheck && ( debounced(target.value)} /> )} diff --git a/src/pages/Questions/PageOptions/PageOptions.tsx b/src/pages/Questions/PageOptions/PageOptions.tsx index 90426bf5..94caab89 100644 --- a/src/pages/Questions/PageOptions/PageOptions.tsx +++ b/src/pages/Questions/PageOptions/PageOptions.tsx @@ -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) { debounced(target.value)} /> @@ -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) { 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 }, + }); }} /> diff --git a/src/pages/Questions/PageOptions/SettingPageOptions.tsx b/src/pages/Questions/PageOptions/SettingPageOptions.tsx index 58146688..1e773c89 100644 --- a/src/pages/Questions/PageOptions/SettingPageOptions.tsx +++ b/src/pages/Questions/PageOptions/SettingPageOptions.tsx @@ -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({ updateQuestionsList(quizId, totalIndex, { content: { - ...listQuestions[quizId][totalIndex].content, + ...question.content, innerNameCheck: target.checked, innerName: "", }, @@ -75,10 +76,10 @@ export default function SettingPageOptions({ - {listQuestions[quizId][totalIndex].content.innerNameCheck && ( + {question.content.innerNameCheck && ( debounced(target.value)} /> )} diff --git a/src/pages/Questions/RatingOptions/RatingOptions.tsx b/src/pages/Questions/RatingOptions/RatingOptions.tsx index 733a4aed..ea1c5226 100644 --- a/src/pages/Questions/RatingOptions/RatingOptions.tsx +++ b/src/pages/Questions/RatingOptions/RatingOptions.tsx @@ -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: }, @@ -51,9 +54,7 @@ export default function RatingOptions({ totalIndex }: Props) { <> {Array.from( - { length: listQuestions[quizId][totalIndex].content.steps }, + { length: question.content.steps }, (_, index) => index ).map((itemNumber) => ( { 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 } ))} - {!listQuestions[quizId][totalIndex].content.ratingDescription && ( + {!question.content.ratingDescription && ( )} - {listQuestions[quizId][totalIndex].content.ratingExpanded && - (listQuestions[quizId][totalIndex].content.ratingDescription ? ( - - {listQuestions[quizId][totalIndex].content.ratingDescription} - + {question.content.ratingExpanded && + (question.content.ratingDescription ? ( + {question.content.ratingDescription} ) : ( { 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), }, }); diff --git a/src/pages/Questions/RatingOptions/settingRating.tsx b/src/pages/Questions/RatingOptions/settingRating.tsx index 48207ce9..117bedbb 100644 --- a/src/pages/Questions/RatingOptions/settingRating.tsx +++ b/src/pages/Questions/RatingOptions/settingRating.tsx @@ -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) { { - 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) { Количество { - 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 }, + }); }} /> @@ -149,16 +149,15 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) { { - 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 : "", + }, + }); }} /> - {listQuestions[quizId][totalIndex].content.innerNameCheck && ( + {question.content.innerNameCheck && ( debounced(target.value)} /> )} diff --git a/src/pages/Questions/SliderOptions/SliderOptions.tsx b/src/pages/Questions/SliderOptions/SliderOptions.tsx index 6e1b075e..84778774 100644 --- a/src/pages/Questions/SliderOptions/SliderOptions.tsx +++ b/src/pages/Questions/SliderOptions/SliderOptions.tsx @@ -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) { { - 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 }, }); } diff --git a/src/pages/Questions/SliderOptions/settingSlider.tsx b/src/pages/Questions/SliderOptions/settingSlider.tsx index ea58d11e..014bea27 100644 --- a/src/pages/Questions/SliderOptions/settingSlider.tsx +++ b/src/pages/Questions/SliderOptions/settingSlider.tsx @@ -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) { { - 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 }, + }); }} /> @@ -71,16 +74,15 @@ export default function SettingSlider({ totalIndex }: SettingSliderProps) { { - 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 : "", + }, + }); }} /> - {listQuestions[quizId][totalIndex].content.innerNameCheck && ( + {question.content.innerNameCheck && ( debounced(target.value)} /> )} diff --git a/src/pages/Questions/TypeQuestions.tsx b/src/pages/Questions/TypeQuestions.tsx index 74c28e4a..a87c4ae0 100755 --- a/src/pages/Questions/TypeQuestions.tsx +++ b/src/pages/Questions/TypeQuestions.tsx @@ -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) { { - 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} diff --git a/src/pages/Questions/UploadFile/UploadFile.tsx b/src/pages/Questions/UploadFile/UploadFile.tsx index a500348c..e42cd8cc 100644 --- a/src/pages/Questions/UploadFile/UploadFile.tsx +++ b/src/pages/Questions/UploadFile/UploadFile.tsx @@ -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) {