frontPanel/src/stores/questions.ts

313 lines
7.4 KiB
TypeScript
Raw Normal View History

2023-08-10 13:45:44 +00:00
import { create } from "zustand";
import { persist } from "zustand/middleware";
2023-10-02 19:43:07 +00:00
import { QuizQuestionEmoji } from "../model/questionTypes/emoji";
import { QuizQuestionImages } from "../model/questionTypes/images";
import { QuizQuestionVariant } from "../model/questionTypes/variant";
import { QuizQuestionVarImg } from "../model/questionTypes/varimg";
import type {
AnyQuizQuestion,
QuizQuestionType,
2023-10-03 14:03:57 +00:00
Variant,
2023-10-02 19:43:07 +00:00
} from "../model/questionTypes/shared";
2023-10-03 14:03:57 +00:00
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";
2023-08-24 11:09:47 +00:00
type Hint = {
text: string;
video: string;
};
2023-08-24 20:53:27 +00:00
type Rule = {
or: boolean;
show: boolean;
reqs: [
{
id: string;
vars: number[];
}
];
};
export interface Question {
id: number;
2023-08-10 13:45:44 +00:00
title: string;
description: string;
type: string;
required: boolean;
deleted: true;
2023-08-10 13:45:44 +00:00
page: number;
content: {
2023-10-03 14:03:57 +00:00
variants: Variant[];
2023-08-24 11:09:47 +00:00
hint: Hint;
2023-08-24 20:53:27 +00:00
rule: Rule;
2023-08-28 08:20:09 +00:00
images: string[];
2023-09-05 08:25:47 +00:00
largeCheck: boolean;
large: string;
multi: boolean;
2023-08-24 09:09:43 +00:00
own: boolean;
2023-09-05 08:25:47 +00:00
innerNameCheck: boolean;
2023-08-24 09:09:43 +00:00
innerName: string;
2023-08-24 11:57:42 +00:00
back: string;
2023-08-25 08:29:42 +00:00
placeholder: string;
2023-08-25 09:14:53 +00:00
type: string;
2023-08-25 09:30:25 +00:00
autofill: boolean;
2023-08-25 10:27:43 +00:00
default: string;
2023-08-28 08:20:09 +00:00
single: boolean;
number: boolean;
2023-08-28 09:31:34 +00:00
xy: string;
format: "carousel" | "masonry";
2023-09-05 13:54:41 +00:00
text: string;
picture: string;
video: string;
2023-09-06 08:01:44 +00:00
dateRange: boolean;
2023-09-05 16:34:52 +00:00
time: boolean;
2023-09-06 06:47:23 +00:00
form: string;
steps: number;
2023-09-06 08:01:44 +00:00
range: string;
start: number;
step: number;
chooseRange: boolean;
2023-09-07 14:14:48 +00:00
required: boolean;
replText: string;
2023-09-12 09:56:15 +00:00
ratingExpanded: boolean;
ratingDescription: string;
};
2023-08-10 13:45:44 +00:00
version: number;
parent_ids: number[];
created_at: string;
updated_at: string;
2023-08-24 09:09:43 +00:00
expanded: boolean;
}
interface QuestionStore {
2023-10-02 19:43:07 +00:00
listQuestions: Record<string, AnyQuizQuestion[]>;
openedModalSettings: string;
}
2023-09-20 12:42:14 +00:00
export const DEFAULT_QUESTION: Omit<Question, "id"> = {
title: "",
description: "",
type: "",
required: true,
deleted: true,
page: 0,
content: {
largeCheck: false,
large: "",
multi: false,
own: false,
innerNameCheck: false,
innerName: "",
back: "",
placeholder: "",
type: "all",
autofill: true,
default: "",
images: [],
number: false,
single: false,
xy: "",
format: "carousel",
text: "",
picture: "",
video: "",
dateRange: false,
time: false,
form: "star",
steps: 5,
range: "0—100",
start: 50,
step: 1,
chooseRange: false,
required: false,
replText: "",
ratingExpanded: false,
ratingDescription: "",
variants: [
{
answer: "",
hints: "",
2023-10-03 14:03:57 +00:00
extendedText: "",
2023-09-20 12:42:14 +00:00
},
],
hint: {
text: "",
video: "",
},
rule: {
or: true,
show: true,
reqs: [
{
id: "",
vars: [],
},
],
},
},
version: 0,
parent_ids: [0],
created_at: "",
updated_at: "",
expanded: false,
};
export const questionStore = create<QuestionStore>()(
2023-07-30 15:48:41 +00:00
persist<QuestionStore>(
() => ({
2023-09-06 11:51:08 +00:00
listQuestions: {},
openedModalSettings: "",
2023-08-10 13:45:44 +00:00
}),
2023-08-10 13:45:44 +00:00
{
name: "question",
}
)
);
2023-10-02 19:43:07 +00:00
export const updateQuestionsList = <T = AnyQuizQuestion>(
2023-09-06 13:20:12 +00:00
quizId: number,
index: number,
2023-10-02 19:43:07 +00:00
data: Partial<T>
2023-09-06 11:51:08 +00:00
) => {
const questionListClone = { ...questionStore.getState()["listQuestions"] };
2023-09-06 13:20:12 +00:00
questionListClone[quizId][index] = {
...questionListClone[quizId][index],
...data,
};
2023-09-06 11:51:08 +00:00
questionStore.setState({ listQuestions: questionListClone });
};
2023-08-11 06:15:04 +00:00
export const updateQuestionsListDragAndDrop = (
2023-09-06 13:20:12 +00:00
quizId: number,
2023-10-03 14:03:57 +00:00
updatedQuestions: AnyQuizQuestion[]
2023-08-11 06:15:04 +00:00
) => {
2023-09-06 11:51:08 +00:00
const questionListClone = { ...questionStore.getState()["listQuestions"] };
questionStore.setState({
2023-09-06 13:20:12 +00:00
listQuestions: { ...questionListClone, [quizId]: updatedQuestions },
2023-09-06 11:51:08 +00:00
});
};
2023-09-06 11:51:08 +00:00
export const updateVariants = (
2023-09-06 13:20:12 +00:00
quizId: number,
2023-09-06 11:51:08 +00:00
index: number,
2023-10-03 14:03:57 +00:00
variants: Variant[]
2023-09-06 11:51:08 +00:00
) => {
const listQuestions = { ...questionStore.getState()["listQuestions"] };
2023-08-18 11:16:56 +00:00
2023-10-02 19:43:07 +00:00
switch (listQuestions[quizId][index].type) {
case "emoji":
const emojiState = listQuestions[quizId][index] as QuizQuestionEmoji;
emojiState.content.variants = variants;
return questionStore.setState({ listQuestions });
case "images":
const imagesState = listQuestions[quizId][index] as QuizQuestionImages;
imagesState.content.variants = variants;
return questionStore.setState({ listQuestions });
case "variant":
const variantState = listQuestions[quizId][index] as QuizQuestionVariant;
variantState.content.variants = variants;
return questionStore.setState({ listQuestions });
case "varimg":
const varImgState = listQuestions[quizId][index] as QuizQuestionVarImg;
varImgState.content.variants = variants;
return questionStore.setState({ listQuestions });
}
2023-08-18 11:16:56 +00:00
};
2023-10-02 19:43:07 +00:00
export const createQuestion = (
quizId: number,
2023-10-03 14:03:57 +00:00
questionType: QuizQuestionType = "",
2023-10-02 19:43:07 +00:00
placeIndex = -1
) => {
2023-09-06 11:51:08 +00:00
const id = getRandom(1000000, 10000000);
const newData = { ...questionStore.getState()["listQuestions"] };
2023-09-06 13:20:12 +00:00
if (!newData[quizId]) {
newData[quizId] = [];
}
2023-10-02 19:43:07 +00:00
const defaultObject = [
2023-10-03 14:03:57 +00:00
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,
2023-10-02 19:43:07 +00:00
].find((defaultObjectItem) => defaultObjectItem.type === questionType);
if (defaultObject) {
newData[quizId].splice(
placeIndex < 0 ? newData[quizId].length : placeIndex,
0,
{ ...defaultObject, id }
);
2023-09-06 13:20:12 +00:00
2023-10-02 19:43:07 +00:00
questionStore.setState({ listQuestions: newData });
}
};
2023-09-06 13:20:12 +00:00
export const copyQuestion = (quizId: number, copiedQuestionIndex: number) => {
2023-09-06 11:51:08 +00:00
const listQuestions = { ...questionStore.getState()["listQuestions"] };
2023-08-11 07:25:28 +00:00
2023-09-08 11:24:09 +00:00
listQuestions[quizId].splice(
copiedQuestionIndex,
0,
listQuestions[quizId][copiedQuestionIndex]
);
2023-08-11 07:25:28 +00:00
questionStore.setState({ listQuestions });
};
2023-09-06 13:20:12 +00:00
export const removeQuestion = (quizId: number, index: number) => {
2023-09-06 11:51:08 +00:00
const questionListClone = { ...questionStore.getState()["listQuestions"] };
2023-09-06 13:20:12 +00:00
questionListClone[quizId].splice(index, 1);
2023-09-06 11:51:08 +00:00
questionStore.setState({ listQuestions: questionListClone });
};
2023-07-30 15:35:40 +00:00
export const resetSomeField = (data: Record<string, string>) => {
questionStore.setState(data);
};
2023-09-06 13:20:12 +00:00
export const findQuestionById = (quizId: number) => {
let found = null;
2023-08-11 06:15:04 +00:00
questionStore
.getState()
2023-10-02 19:43:07 +00:00
["listQuestions"][quizId].some((quiz: AnyQuizQuestion, index: number) => {
2023-09-06 13:20:12 +00:00
if (quiz.id === quizId) {
2023-08-11 06:15:04 +00:00
found = { quiz, index };
return true;
}
});
return found;
};
function getRandom(min: number, max: number) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min)) + min;
}