use question id for current question state
This commit is contained in:
parent
a5051e8ebc
commit
61ee7553e6
@ -1,6 +1,6 @@
|
||||
import { sendAnswer } from "@api/quizRelase";
|
||||
import { useQuizData } from "@contexts/QuizDataContext";
|
||||
import { ThemeProvider } from "@mui/material";
|
||||
import { ThemeProvider, Typography } from "@mui/material";
|
||||
import { useQuizViewStore } from "@stores/quizView";
|
||||
import { useQuestionFlowControl } from "@utils/hooks/useQuestionFlowControl";
|
||||
import { notReachable } from "@utils/notReachable";
|
||||
@ -31,7 +31,7 @@ export default function ViewPublicationPage() {
|
||||
setQuestion,
|
||||
} = useQuestionFlowControl();
|
||||
|
||||
const isAnswer = answers.some(ans => ans.questionId === currentQuestion.id);
|
||||
const isAnswer = answers.some(ans => ans.questionId === currentQuestion?.id);
|
||||
|
||||
useEffect(function setFaviconAndTitle() {
|
||||
if (!changeFaviconAndTitle) return;
|
||||
@ -45,8 +45,15 @@ export default function ViewPublicationPage() {
|
||||
}, [changeFaviconAndTitle, settings.cfg.startpage.favIcon, settings.name]);
|
||||
|
||||
if (recentlyCompleted) throw new Error("Quiz already completed");
|
||||
if (currentQuizStep === "startpage" && settings.cfg.noStartPage)
|
||||
currentQuizStep = "question";
|
||||
if (currentQuizStep === "startpage" && settings.cfg.noStartPage) currentQuizStep = "question";
|
||||
|
||||
if (!currentQuestion) return (
|
||||
<ThemeProvider
|
||||
theme={quizThemes[settings.cfg.theme || "StandardTheme"].theme}
|
||||
>
|
||||
<Typography textAlign={"center"} mt="50px">Вопрос не выбран</Typography>
|
||||
</ThemeProvider>
|
||||
);
|
||||
|
||||
let quizStepElement: ReactElement;
|
||||
switch (currentQuizStep) {
|
||||
|
@ -1,4 +1,3 @@
|
||||
import { AnyTypedQuizQuestion } from "@model/questionTypes/shared";
|
||||
import { useQuizViewStore } from "@stores/quizView";
|
||||
import { useCallback, useDebugValue, useMemo, useState } from "react";
|
||||
import { isResultQuestionEmpty } from "../../components/ViewPublicationPage/tools/checkEmptyData";
|
||||
@ -9,17 +8,19 @@ import { enqueueSnackbar } from "notistack";
|
||||
|
||||
export function useQuestionFlowControl() {
|
||||
const { settings, questions } = useQuizData();
|
||||
const [currentQuestion, setCurrentQuestion] = useState<AnyTypedQuizQuestion>(getFirstQuestion);
|
||||
const [currentQuestionId, setCurrentQuestionId] = useState<string | null>(getFirstQuestionId);
|
||||
const answers = useQuizViewStore(state => state.answers);
|
||||
const pointsSum = useQuizViewStore(state => state.pointsSum);
|
||||
const setCurrentQuizStep = useQuizViewStore(state => state.setCurrentQuizStep);
|
||||
|
||||
const linearQuestionIndex = questions.every(({ content }) => content.rule.parentId !== "root") // null when branching enabled
|
||||
const currentQuestion = questions.find(question => question.id === currentQuestionId) ?? null;
|
||||
|
||||
const linearQuestionIndex = currentQuestion && questions.every(({ content }) => content.rule.parentId !== "root") // null when branching enabled
|
||||
? questions.indexOf(currentQuestion)
|
||||
: null;
|
||||
|
||||
function getFirstQuestion() {
|
||||
if (questions.length === 0) throw new Error("No questions found");
|
||||
function getFirstQuestionId() {
|
||||
if (questions.length === 0) return null;
|
||||
|
||||
if (settings.cfg.haveRoot) {
|
||||
const nextQuestion = questions.find(
|
||||
@ -27,10 +28,10 @@ export function useQuestionFlowControl() {
|
||||
);
|
||||
if (!nextQuestion) throw new Error("Root question not found");
|
||||
|
||||
return nextQuestion;
|
||||
return nextQuestion.id;
|
||||
}
|
||||
|
||||
return questions[0];
|
||||
return questions[0].id;
|
||||
}
|
||||
|
||||
|
||||
@ -41,6 +42,8 @@ export function useQuestionFlowControl() {
|
||||
};
|
||||
|
||||
const nextQuestionIdMainLogic = () => {
|
||||
if (!currentQuestion) return null;
|
||||
|
||||
const questionAnswer = answers.find(({ questionId }) => questionId === currentQuestion.id);
|
||||
|
||||
//Если ответ существует и не является объектом момента
|
||||
@ -82,8 +85,8 @@ export function useQuestionFlowControl() {
|
||||
const prevQuestion = linearQuestionIndex !== null
|
||||
? questions[linearQuestionIndex - 1]
|
||||
: questions.find(q =>
|
||||
q.id === currentQuestion.content.rule.parentId
|
||||
|| q.content.id === currentQuestion.content.rule.parentId
|
||||
q.id === currentQuestion?.content.rule.parentId
|
||||
|| q.content.id === currentQuestion?.content.rule.parentId
|
||||
);
|
||||
|
||||
const findResultPointsLogic = () => {
|
||||
@ -137,14 +140,14 @@ export function useQuestionFlowControl() {
|
||||
}
|
||||
}
|
||||
console.log("next", next);
|
||||
if (!next && currentQuestion.type !== "result") throw new Error("Не найден следующий вопрос");
|
||||
if (!next && currentQuestion?.type !== "result") throw new Error("Не найден следующий вопрос");
|
||||
return next;
|
||||
};
|
||||
const nextQuestion = getNextQuestion();
|
||||
const showResult = useCallback(() => {
|
||||
if (nextQuestion?.type !== "result") throw new Error("Current question is not result");
|
||||
|
||||
setCurrentQuestion(nextQuestion);
|
||||
setCurrentQuestionId(nextQuestion.id);
|
||||
if (
|
||||
settings.cfg.resultInfo.showResultForm === "after"
|
||||
|| isResultQuestionEmpty(nextQuestion)
|
||||
@ -152,7 +155,7 @@ export function useQuestionFlowControl() {
|
||||
}, [nextQuestion, setCurrentQuizStep, settings.cfg.resultInfo.showResultForm]);
|
||||
|
||||
const showResultAfterContactForm = useCallback(() => {
|
||||
if (currentQuestion.type !== "result") throw new Error("Current question is not result");
|
||||
if (currentQuestion?.type !== "result") throw new Error("Current question is not result");
|
||||
if (isResultQuestionEmpty(currentQuestion)) {
|
||||
enqueueSnackbar("Данные отправлены");
|
||||
return;
|
||||
@ -164,7 +167,7 @@ export function useQuestionFlowControl() {
|
||||
const moveToPrevQuestion = useCallback(() => {
|
||||
if (!prevQuestion) throw new Error("Previous question not found");
|
||||
|
||||
setCurrentQuestion(prevQuestion);
|
||||
setCurrentQuestionId(prevQuestion.id);
|
||||
}, [prevQuestion]);
|
||||
|
||||
const moveToNextQuestion = useCallback(() => {
|
||||
@ -172,19 +175,21 @@ export function useQuestionFlowControl() {
|
||||
|
||||
if (nextQuestion.type === "result") return showResult();
|
||||
|
||||
setCurrentQuestion(nextQuestion);
|
||||
setCurrentQuestionId(nextQuestion.id);
|
||||
}, [nextQuestion, showResult]);
|
||||
|
||||
const setQuestion = useCallback((questionId: string) => {
|
||||
const question = questions.find(q => q.id === questionId);
|
||||
if (!question) return;
|
||||
|
||||
setCurrentQuestion(question);
|
||||
setCurrentQuestionId(question.id);
|
||||
}, [questions]);
|
||||
|
||||
const isPreviousButtonEnabled = Boolean(prevQuestion);
|
||||
|
||||
const isNextButtonEnabled = useMemo(() => {
|
||||
if (!currentQuestion) return false;
|
||||
|
||||
const hasAnswer = answers.some(({ questionId }) => questionId === currentQuestion.id);
|
||||
|
||||
if ("required" in currentQuestion.content && currentQuestion.content.required) {
|
||||
@ -192,7 +197,7 @@ export function useQuestionFlowControl() {
|
||||
}
|
||||
|
||||
return Boolean(nextQuestion);
|
||||
}, [answers, currentQuestion.content, currentQuestion.id, nextQuestion]);
|
||||
}, [answers, currentQuestion, nextQuestion]);
|
||||
|
||||
useDebugValue({
|
||||
linearQuestionIndex,
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@frontend/squzanswerer",
|
||||
"version": "1.0.26",
|
||||
"version": "1.0.27",
|
||||
"type": "module",
|
||||
"main": "./dist-package/index.js",
|
||||
"module": "./dist-package/index.js",
|
||||
|
Loading…
Reference in New Issue
Block a user