w-aura/src/components/pages/Questionnaire/index.tsx
Денис Катаев 37833a888f Questionnaire
2023-12-31 00:33:55 +00:00

183 lines
6.0 KiB
TypeScript

import { useNavigate, useParams } from "react-router-dom";
import styles from "./styles.module.css";
import Stepper from "@/components/Stepper";
import { useEffect, useState } from "react";
import { IAnswer, IQuestion, stepsQuestionary } from "@/data";
import Title from "@/components/Title";
import Answer from "@/components/Answer";
import routes from "@/routes";
import { useDispatch, useSelector } from "react-redux";
import { actions } from "@/store";
import { IQuestionnaire, selectQuestionnaire } from "@/store/questionnaire";
function QuestionnairePage(): JSX.Element {
const { question, stepId } = useParams();
const navigate = useNavigate();
const dispatch = useDispatch();
const [currentStep, setCurrentStep] = useState<number>();
const [currentQuestion, setCurrentQuestion] = useState<IQuestion>();
const steps = stepsQuestionary.filter((item) => !!item.questions.length);
const questionsAnswers = useSelector(selectQuestionnaire);
useEffect(() => {
const currentStepIndex = steps.findIndex((item) => item.id === stepId);
if (currentStepIndex === -1) return navigate(routes.client.notFound());
setCurrentStep(currentStepIndex || 0);
const _currentQuestion = steps[currentStepIndex].questions.find(
(item) => item.id === question
);
if (!_currentQuestion) return navigate(routes.client.gender());
setCurrentQuestion(_currentQuestion);
}, [navigate, question, stepId, steps]);
// useEffect(() => {
// if (!question) {
// navigate(routes.client.gender());
// }
// console.log(question);
// const currentQuestionIndex = questions.findIndex(
// (item) => item.id === question
// );
// const _currentQuestion = questions[currentQuestionIndex];
// setCurrentQuestion(_currentQuestion);
// console.log(_currentQuestion);
// if (!_currentQuestion) {
// navigate(routes.client.gender());
// }
// }, [currentQuestion, navigate, question]);
const answerClickHandler = (answer: IAnswer) => {
if (!stepId || !question) return;
const questionIndex = getIndexOfQuestion(question);
if (questionIndex === -1) return;
const currentStepIndex = steps.findIndex((item) => item.id === stepId);
const questionsLength = steps[currentStepIndex].questions.length;
const currentQuestion = steps[currentStepIndex].questions[questionIndex];
dispatch(
actions.questionnaire.update({
[currentQuestion.id]: answer.id,
})
);
if (answer.navigateToUrl?.length) {
return navigate(answer.navigateToUrl);
}
if (currentQuestion.navigateToUrl?.length) {
return navigate(currentQuestion.navigateToUrl);
}
if (
currentStepIndex >= steps.length - 1 &&
questionIndex >= questionsLength - 1
) {
return navigate(routes.client.priceList());
}
if (questionIndex < questionsLength - 1) {
return navigate(
`${routes.client.questionnaire()}/${steps[currentStepIndex].id}/${
steps[currentStepIndex].questions[questionIndex + 1].id
}`
);
}
if (
currentStepIndex < steps.length - 1 &&
questionIndex >= questionsLength - 1
) {
return navigate(
`${routes.client.questionnaire()}/${steps[currentStepIndex + 1].id}/${
steps[currentStepIndex + 1].questions[0].id
}`
);
}
};
const getIndexOfQuestion = (questionId: string) => {
const currentStepIndex = steps.findIndex((item) => item.id === stepId);
if (currentStepIndex === -1) return -1;
return steps[currentStepIndex].questions.findIndex(
(item) => item.id === questionId
);
};
const getPreviousQuestion = () => {
if (!currentQuestion) return null;
const currentQuestionIndex = getIndexOfQuestion(currentQuestion.id);
const currentStepIndex = steps.findIndex((item) => item.id === stepId);
if (currentQuestionIndex === -1 || currentStepIndex === -1) return null;
if (currentStepIndex === 0 && currentQuestionIndex === 0) return null;
if (currentStepIndex > 0 && currentQuestionIndex === 0)
return steps[currentStepIndex - 1].questions[
steps[currentStepIndex - 1].questions.length - 1
];
return steps[currentStepIndex].questions[currentQuestionIndex - 1];
};
const isShowAnswer = (answer: IAnswer) => {
const previousQuestion = getPreviousQuestion();
if (!previousQuestion) return true;
const previousAnswer =
questionsAnswers[previousQuestion.id as keyof IQuestionnaire];
if (!previousAnswer) return true;
if (!answer.conditionalValues) return true;
return answer.conditionalValues?.includes(previousAnswer);
};
return (
<section
className={`${styles.page} page`}
style={{
backgroundImage: `url(${currentQuestion?.backgroundImage || ""})`,
}}
>
{currentQuestion && (!!currentStep || currentStep === 0) && (
<>
<Stepper
steps={steps}
currentStep={currentStep}
currentQuestion={getIndexOfQuestion(currentQuestion.id)}
/>
<span className={styles["current-step"]}>
{steps[currentStep].label}
</span>
<Title className={styles.title} variant="h1">
{currentQuestion.question}
</Title>
{!!currentQuestion.description && (
<p className={styles.description}>{currentQuestion.description}</p>
)}
<div className={styles["answers-container"]}>
{!currentQuestion.answersElement &&
currentQuestion.answers &&
currentQuestion.answers.map((answer) => {
if (!isShowAnswer(answer)) return null;
return (
<Answer
key={answer.id}
answer={answer}
onClick={() => {
answerClickHandler(answer);
}}
/>
);
})}
{!!currentQuestion.answersElement && currentQuestion.answersElement}
</div>
</>
)}
</section>
);
}
export default QuestionnairePage;