diff --git a/src/components/LoadingData.tsx b/src/components/LoadingData.tsx index 290ec9e..e9c544a 100644 --- a/src/components/LoadingData.tsx +++ b/src/components/LoadingData.tsx @@ -1,7 +1,7 @@ import {ReactElement} from "react"; import {Link} from "react-router-dom"; -export function LoadingData({data, children}: {data: object|null|undefined, children: ReactElement}) { +export function LoadingData({data, children}: {data: object|null|undefined, children: (ReactElement | null | undefined | boolean)[]}) { if (data === null){ return
Идёт загрузка...
diff --git a/src/pages/SurveyPage.tsx b/src/pages/SurveyPage.tsx index 2c3598e..5a836a6 100644 --- a/src/pages/SurveyPage.tsx +++ b/src/pages/SurveyPage.tsx @@ -1,109 +1,167 @@ -import {LoadingList} from "../components/LoadingList.tsx"; -import {AgreementQuestion, Question, QuestionPair, QuestionType, Survey} from "../types/survey.ts"; -import {Link, useParams} from "react-router-dom"; -import React, { useState } from "react"; -import {useData, useDataPage} from "../API/common.ts"; -import {LoadingData} from "../components/LoadingData.tsx"; - - +import React, { useState, useEffect } from "react"; +import { Navigate, useNavigate, useParams } from "react-router-dom"; +import { + Survey, + Question, + QuestionPair, + AgreementQuestion, + QuestionType, + ScoreVariable, +} from "../types/survey"; +import { useData, useDataPage } from "../API/common"; +import { LoadingData } from "../components/LoadingData"; +import { LoadingList } from "../components/LoadingList"; export function SurveyPage() { + const { surveyId } = useParams<{ surveyId: string }>(); + const navigate = useNavigate(); - const {surveyId} = useParams(); + // Загрузка теста + const survey = useData("surveys", "surveys", surveyId || 0); - const survey = useData("surveys", "surveys", surveyId); + // Загрузка вопросов + const [questions, setQuestions] = useState(null); + const questionsPairs = useDataPage("surveys", "question-pairs", { survey: surveyId || 0 }); + const questionsAgreement = useDataPage("surveys", "agreement-questions", { survey: surveyId || 0 }); + + // Загрузка score variables + const scoreVariables = useDataPage("surveys", "score-variables"); + + // Состояние для ответов + const [answers, setAnswers] = useState>({}); + const [isCompleted, setIsCompleted] = useState(false); + + // Объединение вопросов после загрузки + useEffect(() => { + if ( + questions === null && + questionsPairs.items !== null && + questionsAgreement.items !== null + ) { + const mergedQuestions = [ + ...questionsPairs.items.map((q:Question) => ({ ...q, questionType: QuestionType.QuestionPair })), + ...questionsAgreement.items.map((q:Question) => ({ ...q, questionType: QuestionType.AgreementQuestion })), + ]; + mergedQuestions.sort(() => Math.random() - 0.5); // Перемешивание + setQuestions(mergedQuestions); + } + }, [questions, questionsPairs.items, questionsAgreement.items]); + + // Проверка завершения теста + useEffect(() => { + if (questions && Object.keys(answers).length === questions.length) { + setIsCompleted(true); + } else { + setIsCompleted(false); + } + }, [questions, answers]); + + // Обработка ответов + const handleAnswer = (questionKey: string, answerValue: number) => { + setAnswers((prev) => ({ ...prev, [questionKey]: answerValue })); + }; + + // Вычисление итогового score_variable + const calculateResults = () => { + if (!questions || !scoreVariables.items) return; + + const scoreCounts: Record = {}; + + questions.forEach((question) => { + const questionKey = `${question.questionType}_${question.id}`; + const answer = answers[questionKey]; + if (answer !== undefined) { + if (question.questionType === QuestionType.QuestionPair) { + const selectedStatement = (question as QuestionPair).statements.find( + (s) => s.id === answer + ); + if (selectedStatement) { + scoreCounts[selectedStatement.score_variable] = + (scoreCounts[selectedStatement.score_variable] || 0) + 1; + } + } else if (question.questionType === QuestionType.AgreementQuestion) { + const scoreVariable = (question as AgreementQuestion).score_variable; + scoreCounts[scoreVariable] = (scoreCounts[scoreVariable] || 0) + answer; + } + } + }); + + const maxScoreVariable = Object.keys(scoreCounts).reduce((a, b) => + scoreCounts[a] > scoreCounts[b] ? a : b + ); + + navigate(`/surveys/results/${maxScoreVariable}`); + }; return (
-

- {survey?.title} -

-
- {survey?.description} -
+

{survey?.title}

+
{survey?.description}
- + ( + + )} /> + {isCompleted && ( + + )}
-
); } - -function SurveyQuestions({survey}: { survey: Survey | null | undefined }) { - - const _survey = survey as Survey; - - const [questions, setQuestions] = useState(null); - - const questionsPairs = useDataPage("surveys", "question-pairs", {survey:_survey.id}); - const questionsAgreement = useDataPage("surveys", "agreement-questions", {survey:_survey.id}); - - if (questions === null && questionsPairs.items !== null && questionsAgreement.items !== null){ - - function setQuestionType(question: Question, questionType: QuestionType) { - question.questionType = questionType; - return question; - } - - var _questions = [...questionsPairs.items.map(q=>setQuestionType(q, QuestionType.QuestionPair)), ...questionsAgreement.items.map(q=>setQuestionType(q, QuestionType.AgreementQuestion))]; - _questions.sort(()=>Math.random() - .5); - console.log(questionsPairs.items.map(q=>setQuestionType(q, QuestionType.QuestionPair))); - - setQuestions(_questions); - } - - //console.log(questions); - - - return ( - <> - ( - - - ))}/> - - - ); -} - -function QuestionBlock({question}:{question: Question}) { - +function QuestionBlock({ + question, + onAnswer, + answered, +}: { + question: Question; + onAnswer: (questionId: string, answerValue: number) => void; + answered?: number; +}) { switch (question.questionType) { case QuestionType.AgreementQuestion: - const qa = question as AgreementQuestion; + const agreementQuestion = question as AgreementQuestion; return ( -
- (Вы согласны с утверждением?) - {qa.question} - - +
+ {agreementQuestion.question} + + +
); - + case QuestionType.QuestionPair: - - const qp = question as QuestionPair; + const pairQuestion = question as QuestionPair; return ( -
- (Выберите подходящий ответ) - {qp.statements.map(s=>())} - +
+ {pairQuestion.statements.map((statement) => ( + + ))}
); - + default: - break; + return null; } - - - return null; } - diff --git a/src/types/survey.ts b/src/types/survey.ts index cf5b18c..c46e559 100644 --- a/src/types/survey.ts +++ b/src/types/survey.ts @@ -32,3 +32,12 @@ export interface AgreementQuestion extends Question{ question: string; score_variable: number; } + + +export interface ScoreVariable { + id: string; + name: string; + title: string; + description: string; + survey: string; +} \ No newline at end of file