use question id for current question state

This commit is contained in:
nflnkr 2024-04-12 14:29:37 +03:00
parent a5051e8ebc
commit 61ee7553e6
3 changed files with 33 additions and 21 deletions

@ -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",