публикация ветвится в вопросах - вариантах
This commit is contained in:
parent
ab4d99c3ba
commit
e1b9ada5af
@ -62,7 +62,7 @@ export default function App() {
|
|||||||
<Route path="/" element={<Landing />} />
|
<Route path="/" element={<Landing />} />
|
||||||
<Route path="/signin" element={<SigninDialog />} />
|
<Route path="/signin" element={<SigninDialog />} />
|
||||||
<Route path="/signup" element={<SignupDialog />} />
|
<Route path="/signup" element={<SignupDialog />} />
|
||||||
<Route path="view/:quizId" element={<ViewPage />} />
|
<Route path="/view" element={<ViewPage />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@ -33,7 +33,7 @@ export interface QuizConfig {
|
|||||||
noStartPage: boolean;
|
noStartPage: boolean;
|
||||||
startpageType: QuizStartpageType;
|
startpageType: QuizStartpageType;
|
||||||
results: QuizResultsType;
|
results: QuizResultsType;
|
||||||
haveRoot: boolean;
|
haveRoot: string | null;
|
||||||
startpage: {
|
startpage: {
|
||||||
description: string;
|
description: string;
|
||||||
button: string;
|
button: string;
|
||||||
@ -62,7 +62,7 @@ export const defaultQuizConfig: QuizConfig = {
|
|||||||
noStartPage: false,
|
noStartPage: false,
|
||||||
startpageType: null,
|
startpageType: null,
|
||||||
results: null,
|
results: null,
|
||||||
haveRoot: false,
|
haveRoot: null,
|
||||||
startpage: {
|
startpage: {
|
||||||
description: "",
|
description: "",
|
||||||
button: "",
|
button: "",
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { MessageIcon } from "@icons/messagIcon";
|
import { MessageIcon } from "@icons/messagIcon";
|
||||||
import { PointsIcon } from "@icons/questionsPage/PointsIcon";
|
import { PointsIcon } from "@icons/questionsPage/PointsIcon";
|
||||||
import { DeleteIcon } from "@icons/questionsPage/deleteIcon";
|
import { DeleteIcon } from "@icons/questionsPage/deleteIcon";
|
||||||
import { TextareaAutosize } from "@mui/base/TextareaAutosize";
|
import TextareaAutosize from "@mui/base/TextareaAutosize";
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
FormControl,
|
FormControl,
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import Cytoscape from "cytoscape";
|
|||||||
import CytoscapeComponent from "react-cytoscapejs";
|
import CytoscapeComponent from "react-cytoscapejs";
|
||||||
import popper from "cytoscape-popper";
|
import popper from "cytoscape-popper";
|
||||||
import { useCurrentQuiz } from "@root/quizes/hooks";
|
import { useCurrentQuiz } from "@root/quizes/hooks";
|
||||||
import { updateRootInfo } from "@root/quizes/actions"
|
import { updateRootContentId } from "@root/quizes/actions"
|
||||||
import { AnyQuizQuestion } from "@model/questionTypes/shared"
|
import { AnyQuizQuestion } from "@model/questionTypes/shared"
|
||||||
import { useQuestionsStore } from "@root/questions/store";
|
import { useQuestionsStore } from "@root/questions/store";
|
||||||
import { cleardragQuestionContentId, updateQuestion, updateOpenedModalSettingsId, getQuestionByContentId } from "@root/questions/actions";
|
import { cleardragQuestionContentId, updateQuestion, updateOpenedModalSettingsId, getQuestionByContentId } from "@root/questions/actions";
|
||||||
@ -211,7 +211,7 @@ export const CsComponent = ({
|
|||||||
question.content.rule.main = []
|
question.content.rule.main = []
|
||||||
question.content.rule.default = ""
|
question.content.rule.default = ""
|
||||||
})
|
})
|
||||||
updateRootInfo(quiz?.id, false)
|
updateRootContentId(quiz?.id, false)
|
||||||
} else {
|
} else {
|
||||||
console.log("click not ROOT")
|
console.log("click not ROOT")
|
||||||
const parentQuestionContentId = cy?.$('edge[target = "' + targetNodeContentId + '"]')?.toArray()?.[0]?.data()?.source
|
const parentQuestionContentId = cy?.$('edge[target = "' + targetNodeContentId + '"]')?.toArray()?.[0]?.data()?.source
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { Box } from "@mui/material"
|
import { Box } from "@mui/material"
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import { updateDragQuestionContentId, updateQuestion } from "@root/questions/actions"
|
import { updateDragQuestionContentId, updateQuestion } from "@root/questions/actions"
|
||||||
import { updateRootInfo } from "@root/quizes/actions"
|
import { updateRootContentId } from "@root/quizes/actions"
|
||||||
import { useQuestionsStore } from "@root/questions/store"
|
import { useQuestionsStore } from "@root/questions/store"
|
||||||
import { useCurrentQuiz } from "@root/quizes/hooks";
|
import { useCurrentQuiz } from "@root/quizes/hooks";
|
||||||
import { enqueueSnackbar } from "notistack";
|
import { enqueueSnackbar } from "notistack";
|
||||||
@ -23,7 +23,7 @@ export const FirstNodeField = ({ setOpenedModalQuestions, modalQuestionTargetCon
|
|||||||
console.log(dragQuestionContentId)
|
console.log(dragQuestionContentId)
|
||||||
|
|
||||||
if (dragQuestionContentId) {
|
if (dragQuestionContentId) {
|
||||||
updateRootInfo(quiz?.id, true)
|
updateRootContentId(quiz?.id, dragQuestionContentId)
|
||||||
updateQuestion(dragQuestionContentId, (question) => question.content.rule.parentId = "root")
|
updateQuestion(dragQuestionContentId, (question) => question.content.rule.parentId = "root")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -44,7 +44,7 @@ export const FirstNodeField = ({ setOpenedModalQuestions, modalQuestionTargetCon
|
|||||||
if (quiz) {
|
if (quiz) {
|
||||||
|
|
||||||
if (modalQuestionTargetContentId) {
|
if (modalQuestionTargetContentId) {
|
||||||
updateRootInfo(quiz?.id, true)
|
updateRootContentId(quiz?.id, modalQuestionTargetContentId)
|
||||||
updateQuestion(modalQuestionTargetContentId, (question) => question.content.rule.parentId = "root")
|
updateQuestion(modalQuestionTargetContentId, (question) => question.content.rule.parentId = "root")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -1,20 +1,20 @@
|
|||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { Box, Typography, Button, useTheme } from "@mui/material";
|
import { Box, Typography, Button, useTheme } from "@mui/material";
|
||||||
|
|
||||||
import { useQuizViewStore } from "@root/quizView";
|
import { useQuizViewStore, getAnswersByQuestionId } from "@root/quizView";
|
||||||
|
|
||||||
import type { QuizQuestionBase } from "../../model/questionTypes/shared";
|
import type { AnyTypedQuizQuestion, QuizQuestionBase } from "../../model/questionTypes/shared";
|
||||||
|
import { getQuestionByContentId } from "@root/questions/actions";
|
||||||
|
import { enqueueSnackbar } from "notistack";
|
||||||
|
|
||||||
type FooterProps = {
|
type FooterProps = {
|
||||||
stepNumber: number;
|
setCurrentQuestion: (step: AnyTypedQuizQuestion) => void;
|
||||||
setStepNumber: (step: number) => void;
|
question: QuizQuestionBase;
|
||||||
questions: QuizQuestionBase[];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Footer = ({
|
export const Footer = ({
|
||||||
stepNumber,
|
setCurrentQuestion,
|
||||||
setStepNumber,
|
question,
|
||||||
questions,
|
|
||||||
}: FooterProps) => {
|
}: FooterProps) => {
|
||||||
const [disabledQuestionsId, setDisabledQuestionsId] = useState<Set<string>>(
|
const [disabledQuestionsId, setDisabledQuestionsId] = useState<Set<string>>(
|
||||||
new Set()
|
new Set()
|
||||||
@ -22,37 +22,62 @@ export const Footer = ({
|
|||||||
const { answers } = useQuizViewStore();
|
const { answers } = useQuizViewStore();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
clearDisabledQuestions();
|
|
||||||
|
|
||||||
const disabledIds = [] as string[];
|
|
||||||
|
|
||||||
const newDisabledIds = new Set([...disabledQuestionsId, ...disabledIds]);
|
|
||||||
setDisabledQuestionsId(newDisabledIds);
|
|
||||||
}, [answers]);
|
|
||||||
|
|
||||||
const clearDisabledQuestions = () => {
|
|
||||||
const cleanDisabledQuestions = new Set<string>();
|
|
||||||
|
|
||||||
answers.forEach(({ step, answer }) => {
|
|
||||||
questions[step - 1].content.rule.main.forEach(({ next, rules }) => {
|
|
||||||
rules.forEach(({ answers }) => {
|
|
||||||
if (answer !== answers[0]) {
|
|
||||||
cleanDisabledQuestions.add(next);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
setDisabledQuestionsId(cleanDisabledQuestions);
|
|
||||||
};
|
|
||||||
|
|
||||||
const followPreviousStep = () => {
|
const followPreviousStep = () => {
|
||||||
setStepNumber(stepNumber - 1);
|
if (question?.content.rule.parentId !== "root") {
|
||||||
|
const parent = getQuestionByContentId(question?.content.rule.parentId)
|
||||||
|
if (parent) {
|
||||||
|
setCurrentQuestion(parent)
|
||||||
|
} else {
|
||||||
|
enqueueSnackbar("не могу получить предыдущий вопрос")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
enqueueSnackbar("вы находитесь на первом вопросе")
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const followNextStep = () => {
|
const followNextStep = () => {
|
||||||
setStepNumber(stepNumber + 1);
|
const answers = getAnswersByQuestionId(question.content.id) || []
|
||||||
|
console.log(answers)
|
||||||
|
if (answers) {
|
||||||
|
|
||||||
|
let readyBeNextQuestion = ""
|
||||||
|
question.content.rule.main.forEach(({ next, rules }) => {
|
||||||
|
console.log({ next, rules })
|
||||||
|
|
||||||
|
console.log("[storeAnswers] ", rules[0].answers)
|
||||||
|
console.log("[answers.answer] ", [answers.answer])
|
||||||
|
|
||||||
|
let longerArray = Math.max(rules[0].answers.length, [answers.answer].length)
|
||||||
|
|
||||||
|
for (var i = 0; i < longerArray; i++) // Цикл по всем элементам бОльшего массива
|
||||||
|
if (rules[0].answers[i] !== [answers.answer][i]) readyBeNextQuestion = next; // Если хоть один элемент отличается, массивы не равны
|
||||||
|
|
||||||
|
|
||||||
|
})
|
||||||
|
if (readyBeNextQuestion) {
|
||||||
|
console.log("мы нашли совпадение в " + readyBeNextQuestion)
|
||||||
|
|
||||||
|
const nextQuestion = getQuestionByContentId(readyBeNextQuestion)
|
||||||
|
console.log("next question ", nextQuestion)
|
||||||
|
if (nextQuestion) {
|
||||||
|
console.log("я устанавливаю следующий вопрос " + question.title)
|
||||||
|
setCurrentQuestion(nextQuestion)
|
||||||
|
return
|
||||||
|
} else {
|
||||||
|
enqueueSnackbar("не могу получить последующий вопрос")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const nextQuestion = getQuestionByContentId(question.content.rule.default)
|
||||||
|
console.log("я устанавливаю дефолтный вопрос")
|
||||||
|
if (nextQuestion) {
|
||||||
|
setCurrentQuestion(nextQuestion)
|
||||||
|
} else {
|
||||||
|
enqueueSnackbar("не могу получить последующий вопрос (дефолтный)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -82,7 +107,7 @@ export const Footer = ({
|
|||||||
color: theme.palette.grey1.main,
|
color: theme.palette.grey1.main,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography>Шаг</Typography>
|
{/* <Typography>Шаг</Typography>
|
||||||
<Typography
|
<Typography
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@ -96,16 +121,15 @@ export const Footer = ({
|
|||||||
background: theme.palette.brightPurple.main,
|
background: theme.palette.brightPurple.main,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{stepNumber}
|
{stepNumber} */}
|
||||||
</Typography>
|
{/* </Typography> */}
|
||||||
<Typography>Из</Typography>
|
{/* <Typography>Из</Typography>
|
||||||
<Typography sx={{ fontWeight: "bold" }}>
|
<Typography sx={{ fontWeight: "bold" }}>
|
||||||
{questions.length}
|
{questions.length}
|
||||||
</Typography>
|
</Typography> */}
|
||||||
</Box>
|
</Box>
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
disabled={stepNumber <= 1}
|
|
||||||
sx={{ fontSize: "16px", padding: "10px 15px" }}
|
sx={{ fontSize: "16px", padding: "10px 15px" }}
|
||||||
onClick={followPreviousStep}
|
onClick={followPreviousStep}
|
||||||
>
|
>
|
||||||
@ -113,7 +137,6 @@ export const Footer = ({
|
|||||||
</Button>
|
</Button>
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
disabled={questions.length <= stepNumber}
|
|
||||||
sx={{ fontSize: "16px", padding: "10px 15px" }}
|
sx={{ fontSize: "16px", padding: "10px 15px" }}
|
||||||
onClick={followNextStep}
|
onClick={followNextStep}
|
||||||
>
|
>
|
||||||
|
|||||||
@ -13,9 +13,11 @@ import { Page } from "./questions/Page";
|
|||||||
import { Rating } from "./questions/Rating";
|
import { Rating } from "./questions/Rating";
|
||||||
import { Footer } from "./Footer";
|
import { Footer } from "./Footer";
|
||||||
|
|
||||||
import type { FC } from "react";
|
import { useState, type FC } from "react";
|
||||||
import type { QuestionType } from "../../model/question/question";
|
import type { QuestionType } from "../../model/question/question";
|
||||||
import type { AnyTypedQuizQuestion } from "../../model/questionTypes/shared";
|
import type { AnyTypedQuizQuestion } from "../../model/questionTypes/shared";
|
||||||
|
import { useCurrentQuiz } from "@root/quizes/hooks";
|
||||||
|
import { getQuestionByContentId } from "@root/questions/actions";
|
||||||
|
|
||||||
type QuestionProps = {
|
type QuestionProps = {
|
||||||
stepNumber: number;
|
stepNumber: number;
|
||||||
@ -23,10 +25,7 @@ type QuestionProps = {
|
|||||||
questions: AnyTypedQuizQuestion[];
|
questions: AnyTypedQuizQuestion[];
|
||||||
};
|
};
|
||||||
|
|
||||||
const QUESTIONS_MAP: Record<
|
const QUESTIONS_MAP: any = {
|
||||||
Exclude<QuestionType, "nonselected">,
|
|
||||||
FC<{ stepNumber: number; question: any }>
|
|
||||||
> = {
|
|
||||||
variant: Variant,
|
variant: Variant,
|
||||||
images: Images,
|
images: Images,
|
||||||
varimg: Varimg,
|
varimg: Varimg,
|
||||||
@ -41,13 +40,15 @@ const QUESTIONS_MAP: Record<
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const Question = ({
|
export const Question = ({
|
||||||
stepNumber,
|
|
||||||
setStepNumber,
|
|
||||||
questions,
|
questions,
|
||||||
}: QuestionProps) => {
|
}: QuestionProps) => {
|
||||||
const question = questions[stepNumber - 1] as AnyTypedQuizQuestion;
|
const quiz = useCurrentQuiz();
|
||||||
|
const [currentQuestion, setCurrentQuestion] = useState(getQuestionByContentId(quiz?.config.haveRoot || ""))
|
||||||
|
console.log("root " + quiz?.config.haveRoot)
|
||||||
|
if (!currentQuestion) return <>не смог отобразить вопрос</>
|
||||||
|
|
||||||
const QuestionComponent =
|
const QuestionComponent =
|
||||||
QUESTIONS_MAP[question.type as Exclude<QuestionType, "nonselected">];
|
QUESTIONS_MAP[currentQuestion.type as Exclude<QuestionType, "nonselected">];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
@ -60,12 +61,11 @@ export const Question = ({
|
|||||||
margin: "0 auto",
|
margin: "0 auto",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<QuestionComponent question={question} stepNumber={stepNumber} />
|
<QuestionComponent currentQuestion={currentQuestion}/>
|
||||||
</Box>
|
</Box>
|
||||||
<Footer
|
<Footer
|
||||||
stepNumber={stepNumber}
|
question={currentQuestion}
|
||||||
setStepNumber={setStepNumber}
|
setCurrentQuestion={setCurrentQuestion}
|
||||||
questions={questions}
|
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -18,13 +18,13 @@ import { useQuestions } from "@root/questions/hooks";
|
|||||||
import { setQuizes } from "@root/quizes/actions";
|
import { setQuizes } from "@root/quizes/actions";
|
||||||
|
|
||||||
type StartPageViewPublicationProps = {
|
type StartPageViewPublicationProps = {
|
||||||
setStepNumber: (step: number) => void;
|
setVisualStartPage: (bool: boolean) => void;
|
||||||
showNextButton: boolean;
|
showNextButton:boolean
|
||||||
};
|
};
|
||||||
|
|
||||||
export const StartPageViewPublication = ({
|
export const StartPageViewPublication = ({
|
||||||
setStepNumber,
|
setVisualStartPage,
|
||||||
showNextButton,
|
showNextButton
|
||||||
}: StartPageViewPublicationProps) => {
|
}: StartPageViewPublicationProps) => {
|
||||||
const quizId = Number(useParams().quizId);
|
const quizId = Number(useParams().quizId);
|
||||||
const { quizes } = useQuizStore();
|
const { quizes } = useQuizStore();
|
||||||
@ -109,8 +109,8 @@ export const StartPageViewPublication = ({
|
|||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
sx={{ fontSize: "16px", padding: "10px 15px" }}
|
sx={{ fontSize: "16px", padding: "10px 15px" }}
|
||||||
disabled={!questions.length}
|
// disabled={!questions.length}
|
||||||
onClick={() => setStepNumber(1)}
|
onClick={() => setVisualStartPage(false)}
|
||||||
>
|
>
|
||||||
{quiz?.config.startpage.button
|
{quiz?.config.startpage.button
|
||||||
? quiz?.config.startpage.button
|
? quiz?.config.startpage.button
|
||||||
|
|||||||
@ -9,15 +9,12 @@ import { useCurrentQuiz } from "@root/quizes/hooks";
|
|||||||
import type { AnyTypedQuizQuestion } from "../../model/questionTypes/shared";
|
import type { AnyTypedQuizQuestion } from "../../model/questionTypes/shared";
|
||||||
|
|
||||||
export const ViewPage = () => {
|
export const ViewPage = () => {
|
||||||
const [stepNumber, setStepNumber] = useState<number>(0);
|
|
||||||
const quiz = useCurrentQuiz();
|
const quiz = useCurrentQuiz();
|
||||||
const { questions } = useQuestions();
|
const { questions } = useQuestions();
|
||||||
|
console.log(questions)
|
||||||
|
|
||||||
|
const [visualStartPage, setVisualStartPage] = useState<boolean>(!quiz?.config.noStartPage);
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
|
||||||
if (stepNumber === 0 && quiz?.config.noStartPage) {
|
|
||||||
setStepNumber(1);
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const filteredQuestions = questions.filter(
|
const filteredQuestions = questions.filter(
|
||||||
({ type }) => type
|
({ type }) => type
|
||||||
@ -25,16 +22,14 @@ export const ViewPage = () => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
{stepNumber ? (
|
{visualStartPage ? (
|
||||||
<Question
|
<StartPageViewPublication
|
||||||
stepNumber={stepNumber}
|
setVisualStartPage={setVisualStartPage}
|
||||||
setStepNumber={setStepNumber}
|
showNextButton={!!filteredQuestions.length}
|
||||||
questions={filteredQuestions}
|
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<StartPageViewPublication
|
<Question
|
||||||
setStepNumber={setStepNumber}
|
questions={filteredQuestions}
|
||||||
showNextButton={!!filteredQuestions.length}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@ -8,17 +8,16 @@ import "react-datepicker/dist/react-datepicker.css";
|
|||||||
import type { QuizQuestionDate } from "../../../model/questionTypes/date";
|
import type { QuizQuestionDate } from "../../../model/questionTypes/date";
|
||||||
|
|
||||||
type DateProps = {
|
type DateProps = {
|
||||||
stepNumber: number;
|
currentQuestion: QuizQuestionDate;
|
||||||
question: QuizQuestionDate;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Date = ({ stepNumber, question }: DateProps) => {
|
export const Date = ({ currentQuestion }: DateProps) => {
|
||||||
const { answers } = useQuizViewStore();
|
const { answers } = useQuizViewStore();
|
||||||
const { answer } = answers.find(({ step }) => step === stepNumber) ?? {};
|
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.content.id) ?? {};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Typography variant="h5">{question.title}</Typography>
|
<Typography variant="h5">{currentQuestion.title}</Typography>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@ -29,7 +28,7 @@ export const Date = ({ stepNumber, question }: DateProps) => {
|
|||||||
>
|
>
|
||||||
<DatePicker
|
<DatePicker
|
||||||
selected={answer ? new window.Date(answer) : new window.Date()}
|
selected={answer ? new window.Date(answer) : new window.Date()}
|
||||||
onChange={(date) => updateAnswer(stepNumber, String(date))}
|
onChange={(date) => updateAnswer(currentQuestion.content.id, String(date))}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@ -16,31 +16,30 @@ import RadioIcon from "@ui_kit/RadioIcon";
|
|||||||
import type { QuizQuestionEmoji } from "../../../model/questionTypes/emoji";
|
import type { QuizQuestionEmoji } from "../../../model/questionTypes/emoji";
|
||||||
|
|
||||||
type EmojiProps = {
|
type EmojiProps = {
|
||||||
stepNumber: number;
|
currentQuestion: QuizQuestionEmoji;
|
||||||
question: QuizQuestionEmoji;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Emoji = ({ stepNumber, question }: EmojiProps) => {
|
export const Emoji = ({ currentQuestion }: EmojiProps) => {
|
||||||
const { answers } = useQuizViewStore();
|
const { answers } = useQuizViewStore();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { answer } = answers.find(({ step }) => step === stepNumber) ?? {};
|
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.content.id) ?? {};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!answer) {
|
if (!answer) {
|
||||||
updateAnswer(stepNumber, question.content.variants[0].id);
|
updateAnswer(currentQuestion.content.id, currentQuestion.content.variants[0].id);
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Typography variant="h5">{question.title}</Typography>
|
<Typography variant="h5">{currentQuestion.title}</Typography>
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
name={question.id}
|
name={currentQuestion.id}
|
||||||
value={question.content.variants.findIndex(({ id }) => answer === id)}
|
value={currentQuestion.content.variants.findIndex(({ id }) => answer === id)}
|
||||||
onChange={({ target }) =>
|
onChange={({ target }) =>
|
||||||
updateAnswer(
|
updateAnswer(
|
||||||
stepNumber,
|
currentQuestion.content.id,
|
||||||
question.content.variants[Number(target.value)].id
|
currentQuestion.content.variants[Number(target.value)].id
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
sx={{
|
sx={{
|
||||||
@ -52,7 +51,7 @@ export const Emoji = ({ stepNumber, question }: EmojiProps) => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box sx={{ display: "flex", flexDirection: "column", width: "100%" }}>
|
<Box sx={{ display: "flex", flexDirection: "column", width: "100%" }}>
|
||||||
{question.content.variants.map(
|
{currentQuestion.content.variants.map(
|
||||||
({ id, answer, extendedText }, index) => (
|
({ id, answer, extendedText }, index) => (
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
key={id}
|
key={id}
|
||||||
|
|||||||
@ -11,25 +11,24 @@ import type { ChangeEvent } from "react";
|
|||||||
import type { QuizQuestionFile } from "../../../model/questionTypes/file";
|
import type { QuizQuestionFile } from "../../../model/questionTypes/file";
|
||||||
|
|
||||||
type FileProps = {
|
type FileProps = {
|
||||||
stepNumber: number;
|
currentQuestion: QuizQuestionFile;
|
||||||
question: QuizQuestionFile;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const File = ({ stepNumber, question }: FileProps) => {
|
export const File = ({ currentQuestion }: FileProps) => {
|
||||||
const { answers } = useQuizViewStore();
|
const { answers } = useQuizViewStore();
|
||||||
const { answer } = answers.find(({ step }) => step === stepNumber) ?? {};
|
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.content.id) ?? {};
|
||||||
|
|
||||||
const uploadFile = ({ target }: ChangeEvent<HTMLInputElement>) => {
|
const uploadFile = ({ target }: ChangeEvent<HTMLInputElement>) => {
|
||||||
const file = target.files?.[0];
|
const file = target.files?.[0];
|
||||||
|
|
||||||
if (file) {
|
if (file) {
|
||||||
updateAnswer(stepNumber, `${file.name}|${URL.createObjectURL(file)}`);
|
updateAnswer(currentQuestion.content.id, `${file.name}|${URL.createObjectURL(file)}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Typography variant="h5">{question.title}</Typography>
|
<Typography variant="h5">{currentQuestion.title}</Typography>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@ -42,7 +41,7 @@ export const File = ({ stepNumber, question }: FileProps) => {
|
|||||||
<input
|
<input
|
||||||
onChange={uploadFile}
|
onChange={uploadFile}
|
||||||
hidden
|
hidden
|
||||||
accept={UPLOAD_FILE_TYPES_MAP[question.content.type]}
|
accept={UPLOAD_FILE_TYPES_MAP[currentQuestion.content.type]}
|
||||||
multiple
|
multiple
|
||||||
type="file"
|
type="file"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -17,33 +17,32 @@ import RadioIcon from "@ui_kit/RadioIcon";
|
|||||||
import type { QuizQuestionImages } from "../../../model/questionTypes/images";
|
import type { QuizQuestionImages } from "../../../model/questionTypes/images";
|
||||||
|
|
||||||
type ImagesProps = {
|
type ImagesProps = {
|
||||||
stepNumber: number;
|
currentQuestion: QuizQuestionImages;
|
||||||
question: QuizQuestionImages;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Images = ({ stepNumber, question }: ImagesProps) => {
|
export const Images = ({ currentQuestion }: ImagesProps) => {
|
||||||
const { answers } = useQuizViewStore();
|
const { answers } = useQuizViewStore();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { answer } = answers.find(({ step }) => step === stepNumber) ?? {};
|
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.content.id) ?? {};
|
||||||
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
const isTablet = useMediaQuery(theme.breakpoints.down(1000));
|
||||||
const isMobile = useMediaQuery(theme.breakpoints.down(500));
|
const isMobile = useMediaQuery(theme.breakpoints.down(500));
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!answer) {
|
if (!answer) {
|
||||||
updateAnswer(stepNumber, question.content.variants[0].id);
|
updateAnswer(currentQuestion.content.id, currentQuestion.content.variants[0].id);
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Typography variant="h5">{question.title}</Typography>
|
<Typography variant="h5">{currentQuestion.title}</Typography>
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
name={question.id}
|
name={currentQuestion.id}
|
||||||
value={question.content.variants.findIndex(({ id }) => answer === id)}
|
value={currentQuestion.content.variants.findIndex(({ id }) => answer === id)}
|
||||||
onChange={({ target }) =>
|
onChange={({ target }) =>
|
||||||
updateAnswer(
|
updateAnswer(
|
||||||
stepNumber,
|
currentQuestion.content.id,
|
||||||
question.content.variants[Number(target.value)].id
|
currentQuestion.content.variants[Number(target.value)].id
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
sx={{
|
sx={{
|
||||||
@ -66,7 +65,7 @@ export const Images = ({ stepNumber, question }: ImagesProps) => {
|
|||||||
width: "100%",
|
width: "100%",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{question.content.variants.map(
|
{currentQuestion.content.variants.map(
|
||||||
({ id, answer, extendedText }, index) => (
|
({ id, answer, extendedText }, index) => (
|
||||||
<Box
|
<Box
|
||||||
key={index}
|
key={index}
|
||||||
|
|||||||
@ -8,27 +8,26 @@ import { useQuizViewStore, updateAnswer } from "@root/quizView";
|
|||||||
import type { QuizQuestionNumber } from "../../../model/questionTypes/number";
|
import type { QuizQuestionNumber } from "../../../model/questionTypes/number";
|
||||||
|
|
||||||
type NumberProps = {
|
type NumberProps = {
|
||||||
stepNumber: number;
|
currentQuestion: QuizQuestionNumber;
|
||||||
question: QuizQuestionNumber;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Number = ({ stepNumber, question }: NumberProps) => {
|
export const Number = ({ currentQuestion }: NumberProps) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { answers } = useQuizViewStore();
|
const { answers } = useQuizViewStore();
|
||||||
const { answer } = answers.find(({ step }) => step === stepNumber) ?? {};
|
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.content.id) ?? {};
|
||||||
|
|
||||||
const min = window.Number(question.content.range.split("—")[0]);
|
const min = window.Number(currentQuestion.content.range.split("—")[0]);
|
||||||
const max = window.Number(question.content.range.split("—")[1]);
|
const max = window.Number(currentQuestion.content.range.split("—")[1]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!answer) {
|
if (!answer) {
|
||||||
updateAnswer(stepNumber, "1");
|
updateAnswer(currentQuestion.content.id, "1");
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Typography variant="h5">{question.title}</Typography>
|
<Typography variant="h5">{currentQuestion.title}</Typography>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@ -42,7 +41,7 @@ export const Number = ({ stepNumber, question }: NumberProps) => {
|
|||||||
value={answer || ""}
|
value={answer || ""}
|
||||||
onChange={({ target }) => {
|
onChange={({ target }) => {
|
||||||
updateAnswer(
|
updateAnswer(
|
||||||
stepNumber,
|
currentQuestion.content.id,
|
||||||
window.Number(target.value) > max
|
window.Number(target.value) > max
|
||||||
? String(max)
|
? String(max)
|
||||||
: window.Number(target.value) < min
|
: window.Number(target.value) < min
|
||||||
@ -59,14 +58,14 @@ export const Number = ({ stepNumber, question }: NumberProps) => {
|
|||||||
value={window.Number(answer || 1)}
|
value={window.Number(answer || 1)}
|
||||||
min={min}
|
min={min}
|
||||||
max={max}
|
max={max}
|
||||||
step={question.content.step || 1}
|
step={currentQuestion.content.step || 1}
|
||||||
sx={{
|
sx={{
|
||||||
color: theme.palette.brightPurple.main,
|
color: theme.palette.brightPurple.main,
|
||||||
padding: "0",
|
padding: "0",
|
||||||
marginTop: "25px",
|
marginTop: "25px",
|
||||||
}}
|
}}
|
||||||
onChange={(_, value) => {
|
onChange={(_, value) => {
|
||||||
updateAnswer(stepNumber, String(value));
|
updateAnswer(currentQuestion.content.id, String(value));
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@ -5,17 +5,16 @@ import { useQuizViewStore, updateAnswer } from "@root/quizView";
|
|||||||
import type { QuizQuestionPage } from "../../../model/questionTypes/page";
|
import type { QuizQuestionPage } from "../../../model/questionTypes/page";
|
||||||
|
|
||||||
type PageProps = {
|
type PageProps = {
|
||||||
stepNumber: number;
|
currentQuestion: QuizQuestionPage;
|
||||||
question: QuizQuestionPage;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Page = ({ stepNumber, question }: PageProps) => {
|
export const Page = ({ currentQuestion }: PageProps) => {
|
||||||
const { answers } = useQuizViewStore();
|
const { answers } = useQuizViewStore();
|
||||||
const { answer } = answers.find(({ step }) => step === stepNumber) ?? {};
|
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.content.id) ?? {};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Typography variant="h5">{question.title}</Typography>
|
<Typography variant="h5">{currentQuestion.title}</Typography>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@ -24,9 +23,9 @@ export const Page = ({ stepNumber, question }: PageProps) => {
|
|||||||
marginTop: "20px",
|
marginTop: "20px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{question.content.picture && (
|
{currentQuestion.content.picture && (
|
||||||
<img
|
<img
|
||||||
src={question.content.picture}
|
src={currentQuestion.content.picture}
|
||||||
alt=""
|
alt=""
|
||||||
style={{
|
style={{
|
||||||
display: "block",
|
display: "block",
|
||||||
@ -37,9 +36,9 @@ export const Page = ({ stepNumber, question }: PageProps) => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{question.content.video && (
|
{currentQuestion.content.video && (
|
||||||
<video
|
<video
|
||||||
src={question.content.video}
|
src={currentQuestion.content.video}
|
||||||
controls
|
controls
|
||||||
style={{
|
style={{
|
||||||
width: "100%",
|
width: "100%",
|
||||||
|
|||||||
@ -12,18 +12,17 @@ import StarIconMini from "@icons/questionsPage/StarIconMini";
|
|||||||
import type { QuizQuestionRating } from "../../../model/questionTypes/rating";
|
import type { QuizQuestionRating } from "../../../model/questionTypes/rating";
|
||||||
|
|
||||||
type RatingProps = {
|
type RatingProps = {
|
||||||
stepNumber: number;
|
currentQuestion: QuizQuestionRating;
|
||||||
question: QuizQuestionRating;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Rating = ({ stepNumber, question }: RatingProps) => {
|
export const Rating = ({ currentQuestion }: RatingProps) => {
|
||||||
const { answers } = useQuizViewStore();
|
const { answers } = useQuizViewStore();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { answer } = answers.find(({ step }) => step === stepNumber) ?? {};
|
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.content.id) ?? {};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Typography variant="h5">{question.title}</Typography>
|
<Typography variant="h5">{currentQuestion.title}</Typography>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@ -34,9 +33,9 @@ export const Rating = ({ stepNumber, question }: RatingProps) => {
|
|||||||
>
|
>
|
||||||
<RatingComponent
|
<RatingComponent
|
||||||
value={Number(answer || 0)}
|
value={Number(answer || 0)}
|
||||||
onChange={(_, value) => updateAnswer(stepNumber, String(value))}
|
onChange={(_, value) => updateAnswer(currentQuestion.content.id, String(value))}
|
||||||
sx={{ height: "50px" }}
|
sx={{ height: "50px" }}
|
||||||
max={question.content.steps}
|
max={currentQuestion.content.steps}
|
||||||
icon={
|
icon={
|
||||||
<StarIconMini
|
<StarIconMini
|
||||||
color={theme.palette.brightPurple.main}
|
color={theme.palette.brightPurple.main}
|
||||||
@ -56,12 +55,12 @@ export const Rating = ({ stepNumber, question }: RatingProps) => {
|
|||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
justifyContent: "space-between",
|
justifyContent: "space-between",
|
||||||
maxWidth: `${question.content.steps * 50}px`,
|
maxWidth: `${currentQuestion.content.steps * 50}px`,
|
||||||
color: theme.palette.grey2.main,
|
color: theme.palette.grey2.main,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Typography>{question.content.ratingNegativeDescription}</Typography>
|
<Typography>{currentQuestion.content.ratingNegativeDescription}</Typography>
|
||||||
<Typography>{question.content.ratingPositiveDescription}</Typography>
|
<Typography>{currentQuestion.content.ratingPositiveDescription}</Typography>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@ -7,17 +7,16 @@ import { useQuizViewStore, updateAnswer } from "@root/quizView";
|
|||||||
import type { QuizQuestionSelect } from "../../../model/questionTypes/select";
|
import type { QuizQuestionSelect } from "../../../model/questionTypes/select";
|
||||||
|
|
||||||
type SelectProps = {
|
type SelectProps = {
|
||||||
stepNumber: number;
|
currentQuestion: QuizQuestionSelect;
|
||||||
question: QuizQuestionSelect;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Select = ({ stepNumber, question }: SelectProps) => {
|
export const Select = ({ currentQuestion }: SelectProps) => {
|
||||||
const { answers } = useQuizViewStore();
|
const { answers } = useQuizViewStore();
|
||||||
const { answer } = answers.find(({ step }) => step === stepNumber) ?? {};
|
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.content.id) ?? {};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Typography variant="h5">{question.title}</Typography>
|
<Typography variant="h5">{currentQuestion.title}</Typography>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@ -28,9 +27,9 @@ export const Select = ({ stepNumber, question }: SelectProps) => {
|
|||||||
>
|
>
|
||||||
<SelectComponent
|
<SelectComponent
|
||||||
activeItemIndex={Number(answer) || 0}
|
activeItemIndex={Number(answer) || 0}
|
||||||
items={question.content.variants.map(({ answer }) => answer)}
|
items={currentQuestion.content.variants.map(({ answer }) => answer)}
|
||||||
onChange={(_, value) => {
|
onChange={(_, value) => {
|
||||||
updateAnswer(stepNumber, String(value));
|
updateAnswer(currentQuestion.content.id, String(value));
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@ -7,17 +7,16 @@ import { useQuizViewStore, updateAnswer } from "@root/quizView";
|
|||||||
import type { QuizQuestionText } from "../../../model/questionTypes/text";
|
import type { QuizQuestionText } from "../../../model/questionTypes/text";
|
||||||
|
|
||||||
type TextProps = {
|
type TextProps = {
|
||||||
stepNumber: number;
|
currentQuestion: QuizQuestionText;
|
||||||
question: QuizQuestionText;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Text = ({ stepNumber, question }: TextProps) => {
|
export const Text = ({ currentQuestion }: TextProps) => {
|
||||||
const { answers } = useQuizViewStore();
|
const { answers } = useQuizViewStore();
|
||||||
const { answer } = answers.find(({ step }) => step === stepNumber) ?? {};
|
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.content.id) ?? {};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Typography variant="h5">{question.title}</Typography>
|
<Typography variant="h5">{currentQuestion.title}</Typography>
|
||||||
<Box
|
<Box
|
||||||
sx={{
|
sx={{
|
||||||
display: "flex",
|
display: "flex",
|
||||||
@ -27,9 +26,9 @@ export const Text = ({ stepNumber, question }: TextProps) => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<CustomTextField
|
<CustomTextField
|
||||||
placeholder={question.content.placeholder}
|
placeholder={currentQuestion.content.placeholder}
|
||||||
value={answer || ""}
|
value={answer || ""}
|
||||||
onChange={({ target }) => updateAnswer(stepNumber, target.value)}
|
onChange={({ target }) => updateAnswer(currentQuestion.content.id, target.value)}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@ -17,31 +17,31 @@ import type { QuizQuestionVariant } from "../../../model/questionTypes/variant";
|
|||||||
|
|
||||||
type VariantProps = {
|
type VariantProps = {
|
||||||
stepNumber: number;
|
stepNumber: number;
|
||||||
question: QuizQuestionVariant;
|
currentQuestion: QuizQuestionVariant;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Variant = ({ stepNumber, question }: VariantProps) => {
|
export const Variant = ({ currentQuestion }: VariantProps) => {
|
||||||
const { answers } = useQuizViewStore();
|
const { answers } = useQuizViewStore();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { answer } = answers.find(({ step }) => step === stepNumber) ?? {};
|
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.content.id) ?? {};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!answer) {
|
if (!answer) {
|
||||||
updateAnswer(stepNumber, question.content.variants[0].id);
|
updateAnswer(currentQuestion.content.id, currentQuestion.content.variants[0].id);
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Typography variant="h5">{question.title}</Typography>
|
<Typography variant="h5">{currentQuestion.title}</Typography>
|
||||||
<Box sx={{ display: "flex" }}>
|
<Box sx={{ display: "flex" }}>
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
name={question.id}
|
name={currentQuestion.id}
|
||||||
value={question.content.variants.findIndex(({ id }) => answer === id)}
|
value={currentQuestion.content.variants.findIndex(({ id }) => answer === id)}
|
||||||
onChange={({ target }) =>
|
onChange={({ target }) =>
|
||||||
updateAnswer(
|
updateAnswer(
|
||||||
stepNumber,
|
currentQuestion.content.id,
|
||||||
question.content.variants[Number(target.value)].id
|
currentQuestion.content.variants[Number(target.value)].id
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
sx={{
|
sx={{
|
||||||
@ -54,7 +54,7 @@ export const Variant = ({ stepNumber, question }: VariantProps) => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box sx={{ display: "flex", flexDirection: "column", width: "100%" }}>
|
<Box sx={{ display: "flex", flexDirection: "column", width: "100%" }}>
|
||||||
{question.content.variants.map(({ id, answer }, index) => (
|
{currentQuestion.content.variants.map(({ id, answer }, index) => (
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
key={id}
|
key={id}
|
||||||
sx={{
|
sx={{
|
||||||
@ -75,10 +75,10 @@ export const Variant = ({ stepNumber, question }: VariantProps) => {
|
|||||||
))}
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
{question.content.back && (
|
{currentQuestion.content.back && (
|
||||||
<Box sx={{ maxWidth: "400px", width: "100%", height: "300px" }}>
|
<Box sx={{ maxWidth: "400px", width: "100%", height: "300px" }}>
|
||||||
<img
|
<img
|
||||||
src={question.content.back}
|
src={currentQuestion.content.back}
|
||||||
style={{ width: "100%", height: "100%", objectFit: "cover" }}
|
style={{ width: "100%", height: "100%", objectFit: "cover" }}
|
||||||
alt=""
|
alt=""
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -16,33 +16,32 @@ import RadioIcon from "@ui_kit/RadioIcon";
|
|||||||
import type { QuizQuestionVarImg } from "../../../model/questionTypes/varimg";
|
import type { QuizQuestionVarImg } from "../../../model/questionTypes/varimg";
|
||||||
|
|
||||||
type VarimgProps = {
|
type VarimgProps = {
|
||||||
stepNumber: number;
|
currentQuestion: QuizQuestionVarImg;
|
||||||
question: QuizQuestionVarImg;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Varimg = ({ stepNumber, question }: VarimgProps) => {
|
export const Varimg = ({ currentQuestion }: VarimgProps) => {
|
||||||
const { answers } = useQuizViewStore();
|
const { answers } = useQuizViewStore();
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const { answer } = answers.find(({ step }) => step === stepNumber) ?? {};
|
const { answer } = answers.find(({ questionId }) => questionId === currentQuestion.content.id) ?? {};
|
||||||
const variant = question.content.variants.find(({ id }) => answer === id);
|
const variant = currentQuestion.content.variants.find(({ id }) => answer === id);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!answer) {
|
if (!answer) {
|
||||||
updateAnswer(stepNumber, question.content.variants[0].id);
|
updateAnswer(currentQuestion.content.id, currentQuestion.content.variants[0].id);
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box>
|
<Box>
|
||||||
<Typography variant="h5">{question.title}</Typography>
|
<Typography variant="h5">{currentQuestion.title}</Typography>
|
||||||
<Box sx={{ display: "flex" }}>
|
<Box sx={{ display: "flex" }}>
|
||||||
<RadioGroup
|
<RadioGroup
|
||||||
name={question.id}
|
name={currentQuestion.id}
|
||||||
value={question.content.variants.findIndex(({ id }) => answer === id)}
|
value={currentQuestion.content.variants.findIndex(({ id }) => answer === id)}
|
||||||
onChange={({ target }) =>
|
onChange={({ target }) =>
|
||||||
updateAnswer(
|
updateAnswer(
|
||||||
stepNumber,
|
currentQuestion.content.id,
|
||||||
question.content.variants[Number(target.value)].id
|
currentQuestion.content.variants[Number(target.value)].id
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
sx={{
|
sx={{
|
||||||
@ -55,7 +54,7 @@ export const Varimg = ({ stepNumber, question }: VarimgProps) => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Box sx={{ display: "flex", flexDirection: "column", width: "100%" }}>
|
<Box sx={{ display: "flex", flexDirection: "column", width: "100%" }}>
|
||||||
{question.content.variants.map(({ id, answer }, index) => (
|
{currentQuestion.content.variants.map(({ id, answer }, index) => (
|
||||||
<FormControlLabel
|
<FormControlLabel
|
||||||
key={id}
|
key={id}
|
||||||
sx={{
|
sx={{
|
||||||
@ -75,10 +74,10 @@ export const Varimg = ({ stepNumber, question }: VarimgProps) => {
|
|||||||
))}
|
))}
|
||||||
</Box>
|
</Box>
|
||||||
</RadioGroup>
|
</RadioGroup>
|
||||||
{(variant?.extendedText || question.content.back) && (
|
{(variant?.extendedText || currentQuestion.content.back) && (
|
||||||
<Box sx={{ maxWidth: "400px", width: "100%", height: "300px" }}>
|
<Box sx={{ maxWidth: "400px", width: "100%", height: "300px" }}>
|
||||||
<img
|
<img
|
||||||
src={answer ? variant?.extendedText : question.content.back}
|
src={answer ? variant?.extendedText : currentQuestion.content.back}
|
||||||
style={{ width: "100%", height: "100%", objectFit: "cover" }}
|
style={{ width: "100%", height: "100%", objectFit: "cover" }}
|
||||||
alt=""
|
alt=""
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -171,7 +171,7 @@ export default function StartPage() {
|
|||||||
gap: "15px",
|
gap: "15px",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<a href={`/view/${quiz?.backendId}`} target="_blank" rel="noreferrer" style={{ textDecoration: "none" }}>
|
<a href={`/view`} target="_blank" rel="noreferrer" style={{ textDecoration: "none" }}>
|
||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
sx={{
|
sx={{
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { create } from "zustand";
|
|||||||
import { devtools } from "zustand/middleware";
|
import { devtools } from "zustand/middleware";
|
||||||
|
|
||||||
type Answer = {
|
type Answer = {
|
||||||
step: number;
|
questionId: string;
|
||||||
answer: string;
|
answer: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -21,15 +21,21 @@ export const useQuizViewStore = create<QuizViewStore>()(
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
export const updateAnswer = (step: number, answer: string) => {
|
export const updateAnswer = (questionId: string, answer: string) => {
|
||||||
const answers = [...useQuizViewStore.getState().answers];
|
const answers = [...useQuizViewStore.getState().answers];
|
||||||
const answerIndex = answers.findIndex((answer) => step === answer.step);
|
const answerIndex = answers.findIndex((answer) => questionId === answer.questionId);
|
||||||
|
|
||||||
if (answerIndex < 0) {
|
if (answerIndex < 0) {
|
||||||
answers.push({ step, answer });
|
answers.push({ questionId, answer });
|
||||||
} else {
|
} else {
|
||||||
answers[answerIndex] = { step, answer };
|
answers[answerIndex] = { questionId, answer };
|
||||||
}
|
}
|
||||||
|
|
||||||
useQuizViewStore.setState({ answers });
|
useQuizViewStore.setState({ answers });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const getAnswersByQuestionId = (questionId: string) => {
|
||||||
|
if (questionId === null) return null;
|
||||||
|
const answers = [...useQuizViewStore.getState().answers];
|
||||||
|
return answers.find(a => a.questionId === questionId) || null;
|
||||||
|
}
|
||||||
@ -175,10 +175,10 @@ export const deleteQuiz = async (quizId: string) => requestQueue.enqueue(async (
|
|||||||
enqueueSnackbar(`Не удалось удалить квиз. ${message}`);
|
enqueueSnackbar(`Не удалось удалить квиз. ${message}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
export const updateRootInfo = (quizId: string, have:boolean) => updateQuiz(
|
export const updateRootContentId = (quizId: string, id:string) => updateQuiz(
|
||||||
quizId,
|
quizId,
|
||||||
quiz => {
|
quiz => {
|
||||||
quiz.config.haveRoot = have;
|
quiz.config.haveRoot = id;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user