fix: endless errors(WIP)
This commit is contained in:
parent
6f21c992a6
commit
ade9e25d5f
16
src/constants/base.ts
Normal file
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) {
|
||||
|
Loading…
Reference in New Issue
Block a user