183 lines
6.0 KiB
TypeScript
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;
|