frontPanel/src/pages/ViewPublicationPage/Footer.tsx

360 lines
12 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useState, useEffect } from "react";
import {Box, Button, Typography, useMediaQuery, useTheme} from "@mui/material";
import { useQuizViewStore } from "@root/quizView";
import { useCurrentQuiz } from "@root/quizes/hooks";
import { useQuestionsStore } from "@root/questions/store";
import type { AnyTypedQuizQuestion, QuizQuestionBase } from "../../model/questionTypes/shared";
import { getQuestionByContentId } from "@root/questions/actions";
import { enqueueSnackbar } from "notistack";
import { NameplateLogoFQ } from "@icons/NameplateLogoFQ";
import {NameplateLogoFQDark} from "@icons/NameplateLogoFQDark";
import {modes} from "../../utils/themes/Publication/themePublication";
import { checkEmptyData } from "../ResultPage/cards/ResultCard";
type FooterProps = {
setCurrentQuestion: (step: AnyTypedQuizQuestion) => void;
question: AnyTypedQuizQuestion;
setShowContactForm: (show: boolean) => void;
setShowResultForm: (show: boolean) => void;
};
export const Footer = ({ setCurrentQuestion, question, setShowContactForm, setShowResultForm }: FooterProps) => {
const [disablePreviousButton, setDisablePreviousButton] = useState<boolean>(false);
const [disableNextButton, setDisableNextButton] = useState<boolean>(false);
const [stepNumber, setStepNumber] = useState(1);
const quiz = useCurrentQuiz();
const mode = modes;
const { answers } = useQuizViewStore();
const questions = useQuestionsStore().questions as AnyTypedQuizQuestion[];
const theme = useTheme();
const isMobileMini = useMediaQuery(theme.breakpoints.down(382));
const linear = !questions.find(({ content }) => content.rule.parentId === "root");
useEffect(() => {
// Логика для аргумента disabled у кнопки "Назад"
if (linear) {
const questionIndex = questions.findIndex(({ id }) => id === question.id);
const previousQuestion = questions[questionIndex - 1];
if (previousQuestion) {
setDisablePreviousButton(false);
} else {
setDisablePreviousButton(true);
}
} else {
if (question?.content.rule.parentId === "root") {
setDisablePreviousButton(true);
} else {
setDisablePreviousButton(false);
}
}
// Логика для аргумента disabled у кнопки "Далее"
const answer = answers.find(({ questionId }) => questionId === question.content.id);
if ("required" in question.content && question.content.required && answer) {
setDisableNextButton(false);
return;
}
if ("required" in question.content && question.content.required && !answer) {
setDisableNextButton(true);
return;
}
if (linear) {
return;
}
const nextQuestionId = getNextQuestionId();
if (nextQuestionId) {
setDisableNextButton(false);
} else {
const nextQuestion = getQuestionByContentId(question.content.rule.default);
if (nextQuestion?.type) {
setDisableNextButton(false);
}
}
}, [question, answers]);
const showResult = (nextQuestion) => {
if (nextQuestion && quiz?.config.resultInfo.when === "email") {
setShowContactForm(true);
return;
}
const isEmpty = checkEmptyData({ resultData: nextQuestion })
console.log("пустой результат? ", isEmpty)
if (nextQuestion) {
if (nextQuestion && quiz?.config.resultInfo.when === "before") {
if (isEmpty) {
setShowContactForm(true); //до+пустая = кидать на ФК
console.log("до+пустая = кидать на ФК")
} else {
setShowResultForm(true); //до+заполнена = показать
console.log("до+заполнена = показать")
}
}
if (nextQuestion && quiz?.config.resultInfo.when === "after") {
if (isEmpty) {
setShowContactForm(true); //после+пустая
console.log("после+пустая")
} else {
setShowContactForm(true); //после+заполнена = показать ФК
console.log("после+заполнена = показать")
}
}
}
};
const getNextQuestionId = () => {
console.log("net")
console.log(question)
let readyBeNextQuestion = "";
//вопрос обязателен, анализируем ответ и условия ветвления
if (answers.length) {
const answer = answers.find(({ questionId }) => questionId === question.content.id);
(question as QuizQuestionBase).content.rule.main.forEach(({ next, rules }) => {
let longerArray = Math.max(
rules[0].answers.length,
answer?.answer && Array.isArray(answer?.answer) ? answer?.answer.length : [answer?.answer].length
);
for (
var i = 0;
i < longerArray;
i++ // Цикл по всем эле­мен­там бОльшего массива
) {
if (Array.isArray(answer?.answer)) {
if (answer?.answer.find((item) => String(item === rules[0].answers[i]))) {
readyBeNextQuestion = next; // Ес­ли хоть один эле­мент от­ли­ча­ет­ся, мас­си­вы не рав­ны
}
return;
}
if (String(rules[0].answers[i]) === answer?.answer) {
readyBeNextQuestion = next; // Ес­ли хоть один эле­мент от­ли­ча­ет­ся, мас­си­вы не рав­ны
}
}
});
if (readyBeNextQuestion) return readyBeNextQuestion;
}
if (!question.required) {//вопрос не обязателен и не нашли совпадений между ответами и условиями ветвления
console.log("вопрос не обязателен ищем дальше")
const defaultQ = question.content.rule.default
if (defaultQ) return defaultQ
//Вопросы типа страница, ползунок, своё поле для ввода и дата не могут иметь больше 1 ребёнка. Пользователь не может настроить там дефолт
//Кинуть на ребёнка надо даже если там нет дефолта
if (
(question?.type === "date" ||
question?.type === "text" ||
question?.type === "number" ||
question?.type === "page") && question.content.rule.children.length === 1
) return question.content.rule.children[0]
}
//ничё не нашли, ищем резулт
console.log("ничё не нашли, ищем резулт ")
return questions.find(q => {
console.log('q.type === "result"', q.type === "result")
console.log('q.content.rule.parentId === question.content.id', q.content.rule.parentId === question.content.id)
return q.type === "result" && q.content.rule.parentId === question.content.id
})?.content.id
};
const followPreviousStep = () => {
if (linear) {
setStepNumber(q => q - 1)
const questionIndex = questions.findIndex(({ id }) => id === question.id);
const previousQuestion = questions[questionIndex - 1];
if (previousQuestion) {
setCurrentQuestion(previousQuestion);
}
return;
}
if (question?.content.rule.parentId !== "root") {
const parent = getQuestionByContentId(question?.content.rule.parentId);
if (parent?.type) {
setCurrentQuestion(parent);
} else {
enqueueSnackbar("не могу получить предыдущий вопрос");
}
} else {
enqueueSnackbar("вы находитесь на первом вопросе");
}
};
const followNextStep = () => {
if (linear) {
setStepNumber(q => q + 1)
const questionIndex = questions.findIndex(({ id }) => id === question.id);
const nextQuestion = questions[questionIndex + 1];
if (nextQuestion && nextQuestion.type !== "result") {
setCurrentQuestion(nextQuestion);
} else {
showResult(nextQuestion);
}
return;
}
const nextQuestionId = getNextQuestionId();
console.log(nextQuestionId)
if (nextQuestionId) {
const nextQuestion = getQuestionByContentId(nextQuestionId);
console.log(nextQuestion)
if (nextQuestion?.type && nextQuestion.type === "result") {
showResult(nextQuestion);
} else {
setCurrentQuestion(nextQuestion);
}
} else {
enqueueSnackbar("не могу получить последующий вопрос");
}
};
return (
<Box
sx={{
position: "relative",
padding: "15px 0",
borderTop: `1px solid ${theme.palette.grey[400]}`,
height: '75px',
display: "flex"
}}
>
<Box
sx={{
width: "100%",
maxWidth: "1000px",
padding: "0 10px",
margin: "0 auto",
display: "flex",
alignItems: "center",
gap: "10px",
}}
>
{/*{mode[quiz.config.theme] ? (*/}
{/* <NameplateLogoFQ style={{ fontSize: "34px", width:"200px", height:"auto" }} />*/}
{/*):(*/}
{/* <NameplateLogoFQDark style={{ fontSize: "34px", width:"200px", height:"auto" }} />*/}
{/*)}*/}
{linear &&
<>
<Box
sx={{
display: "flex",
alignItems: "center",
gap: "10px",
marginRight: "auto",
color: theme.palette.text.primary,
}}
>
<Typography>Шаг</Typography>
<Typography
sx={{
display: "flex",
justifyContent: "center",
alignItems: "center",
fontWeight: "bold",
borderRadius: "50%",
width: "30px",
height: "30px",
color: "#FFF",
background: theme.palette.primary.main,
}}
>
{stepNumber}
</Typography>
<Typography>Из</Typography>
<Typography sx={{ fontWeight: "bold" }}>
{questions.filter(q => q.type !== "result").length}
</Typography>
</Box>
</>
}
<Box
sx={{
display: "flex",
alignItems: "center",
gap: "10px",
marginRight: "auto",
// color: theme.palette.grey1.main,
}}
>
{/* <Typography>Шаг</Typography>
<Typography
sx={{
display: "flex",
justifyContent: "center",
alignItems: "center",
fontWeight: "bold",
borderRadius: "50%",
width: "30px",
height: "30px",
color: "#FFF",
background: theme.palette.brightPurple.main,
}}
>
{stepNumber} */}
{/* </Typography> */}
{/* <Typography>Из</Typography>
<Typography sx={{ fontWeight: "bold" }}>
{questions.length}
</Typography> */}
</Box>
<Button
disabled={disablePreviousButton}
variant="contained"
sx={{ fontSize: "16px", padding: "10px 15px",}}
onClick={followPreviousStep}
>
{isMobileMini ? (
"←"
) : (
"← Назад"
)}
</Button>
<Button
disabled={disableNextButton}
variant="contained"
sx={{ fontSize: "16px", padding: "10px 15px" }}
onClick={followNextStep}
>
Далее
</Button>
</Box>
</Box>
);
};