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