quiz #3
@@ -108,7 +108,7 @@ const App = () => {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
          <Route exact path="quiz">
 | 
					          <Route exact path="quiz">
 | 
				
			||||||
            <Route index element={<QuizPage />} />
 | 
					            <Route index element={<QuizPage />} />
 | 
				
			||||||
            <Route exact path="test" element={<PassingTests />} />
 | 
					            <Route exact path="test/:uuid" element={<PassingTests />} />
 | 
				
			||||||
            <Route exact path="report" element={<QuizReportPage />} />
 | 
					            <Route exact path="report" element={<QuizReportPage />} />
 | 
				
			||||||
          </Route>
 | 
					          </Route>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,15 +5,16 @@ import StarRating from "@components/StarRating/StarRating";
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import rightArrow from "assets/icons/arrows/arrowRight.svg";
 | 
					import rightArrow from "assets/icons/arrows/arrowRight.svg";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const CardAvailableTest = ({ title, description, path, passedTest }) => {
 | 
					export const CardAvailableTest = ({ title, description, path, status }) => {
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <div className="card-available-test">
 | 
					    <div className="card-available-test">
 | 
				
			||||||
      <Link
 | 
					      <Link
 | 
				
			||||||
        to={`/${path}`}
 | 
					        to={`/${path}`}
 | 
				
			||||||
 | 
					        aria-disabled={true}
 | 
				
			||||||
        className="card-available-test__container"
 | 
					        className="card-available-test__container"
 | 
				
			||||||
        style={{
 | 
					        style={{
 | 
				
			||||||
          opacity: passedTest ? 0.3 : 1,
 | 
					          // opacity: status !== 1 ? 0.3 : 1,
 | 
				
			||||||
          pointerEvents: passedTest ? "none" : "all",
 | 
					          // pointerEvents: status !== 1 ? "none" : "all",
 | 
				
			||||||
        }}
 | 
					        }}
 | 
				
			||||||
      >
 | 
					      >
 | 
				
			||||||
        <div className="card-available-test__top-head">
 | 
					        <div className="card-available-test__top-head">
 | 
				
			||||||
@@ -27,8 +28,7 @@ export const CardAvailableTest = ({ title, description, path, passedTest }) => {
 | 
				
			|||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </Link>
 | 
					      </Link>
 | 
				
			||||||
 | 
					      {status === 2 && (
 | 
				
			||||||
      {passedTest && (
 | 
					 | 
				
			||||||
        <div className="card-available-test__finished">
 | 
					        <div className="card-available-test__finished">
 | 
				
			||||||
          <p>Получить отчет по тестированию</p>
 | 
					          <p>Получить отчет по тестированию</p>
 | 
				
			||||||
          <Link to={"/quiz/report"}>Отчет по тесту</Link>
 | 
					          <Link to={"/quiz/report"}>Отчет по тесту</Link>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,44 +1,18 @@
 | 
				
			|||||||
import React from "react";
 | 
					import React from "react";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const GetOptionTask = ({ type, answer, handleChange, inputValue }) => {
 | 
					export const GetOptionTask = ({ type, answer, handleChange }) => {
 | 
				
			||||||
  switch (type) {
 | 
					  const {answer_body,id} = answer
 | 
				
			||||||
    case "1":
 | 
					 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
        <div className="form-task__group">
 | 
					    <div className="form-task__group" key={id}>
 | 
				
			||||||
          <textarea
 | 
					 | 
				
			||||||
            className="form-task__field"
 | 
					 | 
				
			||||||
            value={inputValue}
 | 
					 | 
				
			||||||
            onChange={handleChange}
 | 
					 | 
				
			||||||
          />
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
    case "3":
 | 
					 | 
				
			||||||
      return (
 | 
					 | 
				
			||||||
        <div className="form-task__group" key={answer.id}>
 | 
					 | 
				
			||||||
      <input
 | 
					      <input
 | 
				
			||||||
        className="form-task__check"
 | 
					        className="form-task__check"
 | 
				
			||||||
            type="checkbox"
 | 
					        type={+type === 3 ? "checkbox" : "radio"}
 | 
				
			||||||
            value={answer.answer_body}
 | 
					        value={answer_body}
 | 
				
			||||||
            id={answer.id}
 | 
					        name={+type === 3 ? "checkbox" : "radio"}
 | 
				
			||||||
 | 
					        id={id}
 | 
				
			||||||
        onChange={handleChange}
 | 
					        onChange={handleChange}
 | 
				
			||||||
      />
 | 
					      />
 | 
				
			||||||
          <label htmlFor={answer.id}>{answer.answer_body}</label>
 | 
					      <label htmlFor={id}>{answer_body}</label>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 | 
					 | 
				
			||||||
    default:
 | 
					 | 
				
			||||||
      return (
 | 
					 | 
				
			||||||
        <div className="form-task__group" key={answer.id}>
 | 
					 | 
				
			||||||
          <input
 | 
					 | 
				
			||||||
            className="form-task__check"
 | 
					 | 
				
			||||||
            type="radio"
 | 
					 | 
				
			||||||
            value={answer.answer_body}
 | 
					 | 
				
			||||||
            name={"radio"}
 | 
					 | 
				
			||||||
            id={answer.id}
 | 
					 | 
				
			||||||
            onChange={handleChange}
 | 
					 | 
				
			||||||
          />
 | 
					 | 
				
			||||||
          <label htmlFor={answer.id}>{answer.answer_body}</label>
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
      );
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
import React, { useEffect } from "react";
 | 
					import React from "react";
 | 
				
			||||||
import { useDispatch, useSelector } from "react-redux";
 | 
					import { useDispatch, useSelector } from "react-redux";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { selectUserInfo, setUserInfo } from "@redux/quizSlice";
 | 
					import { selectUserInfo } from "@redux/quizSlice";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { urlForLocal } from "@utils/helper";
 | 
					import { urlForLocal } from "@utils/helper";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -13,14 +13,6 @@ export const HeaderQuiz = ({ header }) => {
 | 
				
			|||||||
  const userId = localStorage.getItem("id");
 | 
					  const userId = localStorage.getItem("id");
 | 
				
			||||||
  const userInfo = useSelector(selectUserInfo);
 | 
					  const userInfo = useSelector(selectUserInfo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  useEffect(() => {
 | 
					 | 
				
			||||||
    dispatch(setUserInfo(userId));
 | 
					 | 
				
			||||||
  }, [userId, dispatch]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  useEffect(() => {
 | 
					 | 
				
			||||||
    // apiRequest(`/user-questionnaire/questionnaires-list?user_id=${userId}`)
 | 
					 | 
				
			||||||
    //     .then(res => dispatch(setQuestionnairesList(res)))
 | 
					 | 
				
			||||||
  }, [userId, dispatch]);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <div>
 | 
					    <div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,36 +1,67 @@
 | 
				
			|||||||
import React, { useEffect } from "react";
 | 
					import React, { useEffect } from "react";
 | 
				
			||||||
import { useSelector } from "react-redux";
 | 
					import { useDispatch, useSelector } from "react-redux";
 | 
				
			||||||
import { useTimer } from "react-timer-hook";
 | 
					import { setQuestions } from "@redux/quizSlice";
 | 
				
			||||||
 | 
					 | 
				
			||||||
import { completedTestSelector } from "@redux/quizSlice";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import StarRating from "@components/StarRating/StarRating";
 | 
					import StarRating from "@components/StarRating/StarRating";
 | 
				
			||||||
 | 
					 | 
				
			||||||
import accempt from "assets/images/quiz/accempt.png";
 | 
					import accempt from "assets/images/quiz/accempt.png";
 | 
				
			||||||
import timer from "assets/images/quiz/timer.png";
 | 
					import iconTomer from "assets/images/quiz/timer.png";
 | 
				
			||||||
 | 
					import { apiRequest } from "@api/request";
 | 
				
			||||||
 | 
					import moment from "moment";
 | 
				
			||||||
 | 
					import { useNavigate } from "react-router-dom";
 | 
				
			||||||
 | 
					import { useNotification } from "@hooks/useNotification";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const QuizPassingInformation = ({ expiryTimestamp, setStartTest }) => {
 | 
					export const QuizPassingInformation = ({ setStartTest, uuid, timer }) => {
 | 
				
			||||||
  const { seconds, minutes, isRunning, start, restart } = useTimer({
 | 
					
 | 
				
			||||||
    expiryTimestamp,
 | 
					  const { restart, pause, hours, minutes, seconds, isRunning } = timer;
 | 
				
			||||||
    autoStart: false,
 | 
					  const navigate = useNavigate();
 | 
				
			||||||
    onExpire: () => {
 | 
					  const { showNotification } = useNotification();
 | 
				
			||||||
      console.warn("onExpire called");
 | 
					  const dispatch = useDispatch();
 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  });
 | 
					 | 
				
			||||||
  const completedTest = useSelector(completedTestSelector);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const startTesting = () => {
 | 
					  const startTesting = () => {
 | 
				
			||||||
 | 
					    apiRequest(
 | 
				
			||||||
 | 
					      `/question/get-questions?uuid=${uuid}`
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					      .then((res) => {
 | 
				
			||||||
 | 
					        if (res.status === 400) {
 | 
				
			||||||
 | 
					          dispatch(setQuestions(null));
 | 
				
			||||||
 | 
					          showNotification({
 | 
				
			||||||
 | 
					            show: true,
 | 
				
			||||||
 | 
					            text: res?.message || "",
 | 
				
			||||||
 | 
					            type: "error"
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					          return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        dispatch(setQuestions(res));
 | 
				
			||||||
        setStartTest(true);
 | 
					        setStartTest(true);
 | 
				
			||||||
    start();
 | 
					        restart(moment()
 | 
				
			||||||
 | 
					          .add(res[0]?.time_limit.split(":")[0], "hours")
 | 
				
			||||||
 | 
					          .add(res[0]?.time_limit.split(":")[1], "minutes")
 | 
				
			||||||
 | 
					          .add(res[0]?.time_limit.split(":")[2], "seconds"), true);
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      .catch(e => {
 | 
				
			||||||
 | 
					        dispatch(setQuestions(null));
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const checkTest = () => apiRequest(
 | 
				
			||||||
 | 
					    `user-questionnaire/questionnaire-completed?user_questionnaire_uuid=${uuid}`
 | 
				
			||||||
 | 
					  );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const completeTest = () => apiRequest(
 | 
				
			||||||
 | 
					    "/user-questionnaire/questionnaire-completed", {
 | 
				
			||||||
 | 
					      method: "POST"
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const finishQuiz = async () => {
 | 
				
			||||||
 | 
					    Promise.all([checkTest, completeTest])
 | 
				
			||||||
 | 
					      .then(function() {
 | 
				
			||||||
 | 
					        pause();
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      .catch(e => {
 | 
				
			||||||
 | 
					        console.log(e);
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  useEffect(() => {
 | 
					 | 
				
			||||||
    if (completedTest) {
 | 
					 | 
				
			||||||
      const time = new Date();
 | 
					 | 
				
			||||||
      time.setSeconds(time.getSeconds() + 0); //600 - кол-во секунд для прохождения теста
 | 
					 | 
				
			||||||
      restart(time, false);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
  }, [completedTest]);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <div className="quiz-passing-information">
 | 
					    <div className="quiz-passing-information">
 | 
				
			||||||
@@ -48,22 +79,25 @@ export const QuizPassingInformation = ({ expiryTimestamp, setStartTest }) => {
 | 
				
			|||||||
              разработчик
 | 
					              разработчик
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
          <div className="quiz-passing-information__timer timer-quiz">
 | 
					          {isRunning && <div className="quiz-passing-information__timer timer-quiz">
 | 
				
			||||||
            <div className="quiz-passing-information__icon">
 | 
					            <div className="quiz-passing-information__icon">
 | 
				
			||||||
              <img src={timer} alt="" />
 | 
					              <img src={iconTomer} alt="" />
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            <div className="quiz-passing-information__text">
 | 
					            <div className="quiz-passing-information__text">
 | 
				
			||||||
              {completedTest ? "Время вышло" : "Время на прохождение теста:"}{" "}
 | 
					              Время на прохождение теста:
 | 
				
			||||||
              <br />
 | 
					              <br />
 | 
				
			||||||
              <span>
 | 
					              <span>
 | 
				
			||||||
                {minutes.toString().padStart(2, "0") +
 | 
					                {hours.toString().padStart(2, "0") +
 | 
				
			||||||
                  ":" +
 | 
					                  ":" +
 | 
				
			||||||
                  seconds.toString().padStart(2, "0")}{" "}
 | 
					                  minutes.toString().padStart(2, "0") +
 | 
				
			||||||
 | 
					                  ":" +
 | 
				
			||||||
 | 
					                  seconds.toString().padStart(2, "0")
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
                секунд
 | 
					                секунд
 | 
				
			||||||
              </span>
 | 
					              </span>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
          </div>
 | 
					          </div>}
 | 
				
			||||||
          <div className="quiz-passing-information__attempt">
 | 
					          {!isRunning && <div className="quiz-passing-information__attempt">
 | 
				
			||||||
            <div className="quiz-passing-information__icon">
 | 
					            <div className="quiz-passing-information__icon">
 | 
				
			||||||
              <img src={accempt} alt="" />
 | 
					              <img src={accempt} alt="" />
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
@@ -71,9 +105,9 @@ export const QuizPassingInformation = ({ expiryTimestamp, setStartTest }) => {
 | 
				
			|||||||
              Попыток прохождения: <br />
 | 
					              Попыток прохождения: <br />
 | 
				
			||||||
              <span>1 попытка</span>
 | 
					              <span>1 попытка</span>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
          </div>
 | 
					          </div>}
 | 
				
			||||||
          <div>
 | 
					          <div>
 | 
				
			||||||
            {!completedTest && !isRunning && (
 | 
					            {!isRunning && (
 | 
				
			||||||
              <button
 | 
					              <button
 | 
				
			||||||
                className="quiz-passing-information__button btn-green"
 | 
					                className="quiz-passing-information__button btn-green"
 | 
				
			||||||
                onClick={startTesting}
 | 
					                onClick={startTesting}
 | 
				
			||||||
@@ -82,9 +116,9 @@ export const QuizPassingInformation = ({ expiryTimestamp, setStartTest }) => {
 | 
				
			|||||||
              </button>
 | 
					              </button>
 | 
				
			||||||
            )}
 | 
					            )}
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
 | 
					          {isRunning &&
 | 
				
			||||||
 | 
					            <button className="quiz-passing-information__button quiz-btn" onClick={finishQuiz}>Завершить</button>}
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					 | 
				
			||||||
        {/* {isRunning && <button className="quiz-passing-information__button quiz-btn" onClick={pause}>Завершить</button>} */}
 | 
					 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,148 +1,138 @@
 | 
				
			|||||||
import React, { useEffect, useState } from "react";
 | 
					import React, { useState } from "react";
 | 
				
			||||||
import { useDispatch, useSelector } from "react-redux";
 | 
					import { useSelector } from "react-redux";
 | 
				
			||||||
 | 
					import { questionsSelector } from "@redux/quizSlice";
 | 
				
			||||||
import {
 | 
					 | 
				
			||||||
  answersSelector,
 | 
					 | 
				
			||||||
  fetchGetAnswers, // fetchUserAnswerOne,
 | 
					 | 
				
			||||||
  // fetchUserAnswersMany,
 | 
					 | 
				
			||||||
  questionsSelector,
 | 
					 | 
				
			||||||
  selectedTest, // setAnswers,
 | 
					 | 
				
			||||||
  setCompleteTest,
 | 
					 | 
				
			||||||
} from "@redux/quizSlice";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import { apiRequest } from "@api/request";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import questionIcon from "assets/images/question.png";
 | 
					import questionIcon from "assets/images/question.png";
 | 
				
			||||||
 | 
					 | 
				
			||||||
import { GetOptionTask } from "./GetOptionTask";
 | 
					import { GetOptionTask } from "./GetOptionTask";
 | 
				
			||||||
// import { HeaderQuiz } from "./HeaderQuiz";
 | 
					 | 
				
			||||||
// import { Progressbar } from "./ProgressbarQuiz";
 | 
					 | 
				
			||||||
import "./quiz.scss";
 | 
					import "./quiz.scss";
 | 
				
			||||||
 | 
					import { useHandlerFieldTest } from "@hooks/useHandlerFieldTest";
 | 
				
			||||||
 | 
					import { useParams } from "react-router-dom";
 | 
				
			||||||
 | 
					import moment from "moment";
 | 
				
			||||||
 | 
					import { Loader } from "@components/Common/Loader/Loader";
 | 
				
			||||||
 | 
					import { apiRequest } from "@api/request";
 | 
				
			||||||
 | 
					import { useNotification } from "@hooks/useNotification";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const TaskQuiz = () => {
 | 
					export const TaskQuiz = ({ timer }) => {
 | 
				
			||||||
  const dispatch = useDispatch();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const answers = useSelector(answersSelector);
 | 
					  const { restart } = timer;
 | 
				
			||||||
 | 
					  const { uuid } = useParams();
 | 
				
			||||||
  const questions = useSelector(questionsSelector);
 | 
					  const questions = useSelector(questionsSelector);
 | 
				
			||||||
 | 
					 | 
				
			||||||
  const dataTest = useSelector(selectedTest);
 | 
					 | 
				
			||||||
  const [index, setIndex] = useState(0);
 | 
					  const [index, setIndex] = useState(0);
 | 
				
			||||||
  const [checkedValues, setCheckedValues] = useState([]);
 | 
					  const [isLoadingSendAnswers, setLoadingSendAnswers] = useState(false);
 | 
				
			||||||
  //const [stripValue, setStripValue] = useState(0);
 | 
					  const { showNotification } = useNotification();
 | 
				
			||||||
  const [inputValue, setInputValue] = useState("");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const id = localStorage.getItem("id");
 | 
					  const { values, handleChange, setValues } = useHandlerFieldTest({
 | 
				
			||||||
 | 
					    uuid,
 | 
				
			||||||
  useEffect(() => {
 | 
					    questions,
 | 
				
			||||||
    // fetch('https://itguild.info/api/user-questionnaire/questionnaires-list?user_id=110').then(response => response.json())
 | 
					    indexQuestion: index
 | 
				
			||||||
    // .then(json => console.log(json))
 | 
					  });
 | 
				
			||||||
    apiRequest(`/question/get-questions?uuid=${dataTest.uuid}`).then(
 | 
					 | 
				
			||||||
      (response) => {
 | 
					 | 
				
			||||||
        dispatch(fetchGetAnswers(response[0].id));
 | 
					 | 
				
			||||||
        setStripValue(((+index + 1) * 100) / response.length);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    );
 | 
					 | 
				
			||||||
  }, [dispatch]);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const nextQuestion = async (e) => {
 | 
					  const nextQuestion = async (e) => {
 | 
				
			||||||
    e.preventDefault();
 | 
					    e.preventDefault();
 | 
				
			||||||
    //Проверка на валидацию ответов
 | 
					    //Проверка на существование овтетов
 | 
				
			||||||
    if (!(checkedValues.length || inputValue)) {
 | 
					    if (!(values.length)) {
 | 
				
			||||||
      alert("Вы не ответили на вопрос");
 | 
					      alert("Вы не ответили на вопрос");
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //отправка ответов на сервер
 | 
					    //отправка ответов на сервер
 | 
				
			||||||
    if (questions[index].question_type_id != 3) {
 | 
					    setLoadingSendAnswers(true);
 | 
				
			||||||
      //dispatch(fetchUserAnswerOne(checkedValues));
 | 
					    await apiRequest(`/user-response/set-responses`, {
 | 
				
			||||||
    } else {
 | 
					      method: "POST",
 | 
				
			||||||
      console.log(checkedValues);
 | 
					      data: values
 | 
				
			||||||
      // dispatch(fetchUserAnswersMany(checkedValues));
 | 
					    })
 | 
				
			||||||
 | 
					      .then(res => {
 | 
				
			||||||
 | 
					        if (String(res?.status)[0] !== "2") {
 | 
				
			||||||
 | 
					          showNotification({
 | 
				
			||||||
 | 
					            show: true,
 | 
				
			||||||
 | 
					            text: res?.message || "",
 | 
				
			||||||
 | 
					            type: "error"
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					          return
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //Проверка на окончание теста
 | 
					        if (index === questions.length - 1) return;
 | 
				
			||||||
    if (!(index < questions.length - 1)) {
 | 
					 | 
				
			||||||
      dispatch(setCompleteTest());
 | 
					 | 
				
			||||||
      return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    dispatch(fetchGetAnswers(questions[index + 1].id));
 | 
					        //установка таймера на вопрос если он существует
 | 
				
			||||||
 | 
					        if (questions[index + 1]?.time_limit !== "00:00:00") setValueTimer();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // очищение полей и переход на следующий вопрос
 | 
				
			||||||
        setIndex((prev) => prev + 1);
 | 
					        setIndex((prev) => prev + 1);
 | 
				
			||||||
    setCheckedValues([]);
 | 
					        setValues([]);
 | 
				
			||||||
    setInputValue("");
 | 
					      })
 | 
				
			||||||
 | 
					      .catch(e => {
 | 
				
			||||||
 | 
					        showNotification({
 | 
				
			||||||
 | 
					          show: true,
 | 
				
			||||||
 | 
					          text: e?.message || "",
 | 
				
			||||||
 | 
					          type: "error"
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      .finally(() => setLoadingSendAnswers(false));
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const handleChange = (e) => {
 | 
					  const complete = (e) => {
 | 
				
			||||||
    const checked = e.target.checked;
 | 
					    e.preventDefault();
 | 
				
			||||||
 | 
					    console.log(values);
 | 
				
			||||||
    if (questions[index].question_type_id != 3) {
 | 
					 | 
				
			||||||
      setCheckedValues([
 | 
					 | 
				
			||||||
        {
 | 
					 | 
				
			||||||
          user_id: id,
 | 
					 | 
				
			||||||
          user_questionnaire_uuid: dataTest.uuid,
 | 
					 | 
				
			||||||
          question_id: questions[index].id,
 | 
					 | 
				
			||||||
          response_body: e.target.value,
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
      ]);
 | 
					 | 
				
			||||||
      return;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    checked
 | 
					 | 
				
			||||||
      ? setCheckedValues((prev) => [
 | 
					 | 
				
			||||||
          ...prev,
 | 
					 | 
				
			||||||
          {
 | 
					 | 
				
			||||||
            user_id: id,
 | 
					 | 
				
			||||||
            user_questionnaire_uuid: dataTest.uuid,
 | 
					 | 
				
			||||||
            question_id: questions[index].id,
 | 
					 | 
				
			||||||
            response_body: e.target.value,
 | 
					 | 
				
			||||||
          },
 | 
					 | 
				
			||||||
        ])
 | 
					 | 
				
			||||||
      : setCheckedValues((prev) => [
 | 
					 | 
				
			||||||
          ...prev.filter((item) => item.response_body !== e.target.value),
 | 
					 | 
				
			||||||
        ]);
 | 
					 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  console.log("render task");
 | 
					  const setValueTimer = () => {
 | 
				
			||||||
 | 
					    const time_limit = questions[index + 1].time_limit.split(":");
 | 
				
			||||||
 | 
					    restart(moment()
 | 
				
			||||||
 | 
					      .add(time_limit[0], "hours")
 | 
				
			||||||
 | 
					      .add(time_limit[1], "minutes")
 | 
				
			||||||
 | 
					      .add(time_limit[2], "seconds"));
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  console.log(questions);
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <div className="task">
 | 
					    <div className="task">
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
 | 
					        questions ?
 | 
				
			||||||
          <div className="task__container">
 | 
					          <div className="task__container">
 | 
				
			||||||
            <div className="task__header">
 | 
					            <div className="task__header">
 | 
				
			||||||
            <img src={questionIcon} alt="" />
 | 
					              <img src={questionIcon} alt="questionIcon" />
 | 
				
			||||||
              <h3 className="task__title quiz-title_h3">
 | 
					              <h3 className="task__title quiz-title_h3">
 | 
				
			||||||
                {questions[index].question_body}
 | 
					                {questions[index].question_body}
 | 
				
			||||||
              </h3>
 | 
					              </h3>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 | 
					 | 
				
			||||||
            <div className="task__body">
 | 
					            <div className="task__body">
 | 
				
			||||||
            <form className="task__form form-task" onSubmit={nextQuestion}>
 | 
					              <form className="task__form form-task"
 | 
				
			||||||
              {answers.map((answer) => (
 | 
					                    onSubmit={index !== questions.length - 1 ? nextQuestion : complete}>
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                  questions[index].question_type_id === 1 ?
 | 
				
			||||||
 | 
					                    <div className="form-task__group">
 | 
				
			||||||
 | 
					                    <textarea
 | 
				
			||||||
 | 
					                      className="form-task__field"
 | 
				
			||||||
 | 
					                      value={values[0]?.response_body}
 | 
				
			||||||
 | 
					                      onChange={handleChange}
 | 
				
			||||||
 | 
					                    />
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                    : questions[index]?.answers?.map((answer) => (
 | 
				
			||||||
                      <GetOptionTask
 | 
					                      <GetOptionTask
 | 
				
			||||||
                        key={answer.id}
 | 
					                        key={answer.id}
 | 
				
			||||||
                        type={questions[index].question_type_id}
 | 
					                        type={questions[index].question_type_id}
 | 
				
			||||||
                        handleChange={handleChange}
 | 
					                        handleChange={handleChange}
 | 
				
			||||||
                        answer={answer}
 | 
					                        answer={answer}
 | 
				
			||||||
                      />
 | 
					                      />
 | 
				
			||||||
              ))}
 | 
					                    ))
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
                <div className="form-task__buttons">
 | 
					                <div className="form-task__buttons">
 | 
				
			||||||
                {/* {
 | 
					 | 
				
			||||||
                  index != 0 && <button type='submit' className='form-task__btn quiz-btn quiz-btn_back'
 | 
					 | 
				
			||||||
                    onClick={prevQuestion}>Назад</button>
 | 
					 | 
				
			||||||
                } */}
 | 
					 | 
				
			||||||
                {index != questions.length && (
 | 
					 | 
				
			||||||
                  <button
 | 
					                  <button
 | 
				
			||||||
                    onClick={nextQuestion}
 | 
					                    onClick={nextQuestion}
 | 
				
			||||||
 | 
					                    disabled={isLoadingSendAnswers}
 | 
				
			||||||
                    className="form-task__btn quiz-btn"
 | 
					                    className="form-task__btn quiz-btn"
 | 
				
			||||||
                  >
 | 
					                  >
 | 
				
			||||||
                    Далее
 | 
					                    {isLoadingSendAnswers ? <Loader width={25} height={25} />
 | 
				
			||||||
 | 
					                      : (index !== questions.length - 1 ? "Далее" : "Завершить")
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                  </button>
 | 
					                  </button>
 | 
				
			||||||
                )}
 | 
					 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
              </form>
 | 
					              </form>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
 | 
					          :
 | 
				
			||||||
 | 
					          <h1>ОШибка</h1>
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										40
									
								
								src/hooks/useHandlerFieldTest.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/hooks/useHandlerFieldTest.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
				
			|||||||
 | 
					import { useState } from "react";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const useHandlerFieldTest = ({uuid,questions,indexQuestion}) => {
 | 
				
			||||||
 | 
					  const [values, setValues] = useState([])
 | 
				
			||||||
 | 
					  const id = localStorage.getItem("id");
 | 
				
			||||||
 | 
					  const handleChangeCheckbox = (e) => {
 | 
				
			||||||
 | 
					    if (!e.target.checked) {
 | 
				
			||||||
 | 
					      setValues((prev) => [
 | 
				
			||||||
 | 
					        ...prev.filter((item) => item.response_body !== e.target.value)
 | 
				
			||||||
 | 
					      ]);
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    setValues((prev) => [
 | 
				
			||||||
 | 
					      ...prev, {
 | 
				
			||||||
 | 
					        user_id: id,
 | 
				
			||||||
 | 
					        user_questionnaire_uuid: uuid,
 | 
				
			||||||
 | 
					        question_id: questions[indexQuestion].id,
 | 
				
			||||||
 | 
					        response_body: e.target.value
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const handleFieldsForm = (e) => {
 | 
				
			||||||
 | 
					    setValues([{
 | 
				
			||||||
 | 
					      user_id: id,
 | 
				
			||||||
 | 
					      user_questionnaire_uuid: uuid,
 | 
				
			||||||
 | 
					      question_id: questions[indexQuestion].id,
 | 
				
			||||||
 | 
					      response_body: e.target.value
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    ]);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  const handleChange = (e) => {
 | 
				
			||||||
 | 
					    if (+questions[indexQuestion].question_type_id !== 3) {
 | 
				
			||||||
 | 
					      handleFieldsForm(e)
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    handleChangeCheckbox(e)
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  return {handleChange,values,setValues}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,9 +1,7 @@
 | 
				
			|||||||
import React, { useState } from "react";
 | 
					import React, { useEffect, useState } from "react";
 | 
				
			||||||
import { useSelector } from "react-redux";
 | 
					import { useSelector } from "react-redux";
 | 
				
			||||||
import { Link } from "react-router-dom";
 | 
					import { Link, useNavigate, useParams } from "react-router-dom";
 | 
				
			||||||
 | 
					 | 
				
			||||||
import { completedTestSelector } from "@redux/quizSlice";
 | 
					import { completedTestSelector } from "@redux/quizSlice";
 | 
				
			||||||
 | 
					 | 
				
			||||||
import { Footer } from "@components/Common/Footer/Footer";
 | 
					import { Footer } from "@components/Common/Footer/Footer";
 | 
				
			||||||
import { ProfileBreadcrumbs } from "@components/ProfileBreadcrumbs/ProfileBreadcrumbs";
 | 
					import { ProfileBreadcrumbs } from "@components/ProfileBreadcrumbs/ProfileBreadcrumbs";
 | 
				
			||||||
import { ProfileHeader } from "@components/ProfileHeader/ProfileHeader";
 | 
					import { ProfileHeader } from "@components/ProfileHeader/ProfileHeader";
 | 
				
			||||||
@@ -12,13 +10,32 @@ import { BlockCompletedTest } from "@components/features/quiz/BlockCompletedTest
 | 
				
			|||||||
import { CardIntroduction } from "@components/features/quiz/Card-introduction";
 | 
					import { CardIntroduction } from "@components/features/quiz/Card-introduction";
 | 
				
			||||||
import { QuizPassingInformation } from "@components/features/quiz/Quiz-passing-information";
 | 
					import { QuizPassingInformation } from "@components/features/quiz/Quiz-passing-information";
 | 
				
			||||||
import { TaskQuiz } from "@components/features/quiz/Task";
 | 
					import { TaskQuiz } from "@components/features/quiz/Task";
 | 
				
			||||||
 | 
					import { useTimer } from "react-timer-hook";
 | 
				
			||||||
 | 
					import moment from "moment";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const PassingTests = () => {
 | 
					export const PassingTests = () => {
 | 
				
			||||||
  const time = new Date();
 | 
					 | 
				
			||||||
  time.setSeconds(time.getSeconds() + 600); //600 - кол-во секунд для прохождения теста
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const [startTest, setStartTest] = useState(false);
 | 
					  const [startTest, setStartTest] = useState(false);
 | 
				
			||||||
 | 
					  const navigate = useNavigate()
 | 
				
			||||||
  const completedTest = useSelector(completedTestSelector);
 | 
					  const completedTest = useSelector(completedTestSelector);
 | 
				
			||||||
 | 
					  const { uuid } = useParams()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const timer = useTimer({
 | 
				
			||||||
 | 
					    expiryTimestamp: moment(),
 | 
				
			||||||
 | 
					    autoStart: false,
 | 
				
			||||||
 | 
					    onExpire: () => {
 | 
				
			||||||
 | 
					     navigate("/quiz")
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const onCloseWindow = (e) => {
 | 
				
			||||||
 | 
					    e.preventDefault();
 | 
				
			||||||
 | 
					    if(startTest){
 | 
				
			||||||
 | 
					      let confirmationMessage = "\o/";
 | 
				
			||||||
 | 
					      (e || window.e).returnValue = confirmationMessage;
 | 
				
			||||||
 | 
					      return confirmationMessage;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const introduction = [
 | 
					  const introduction = [
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -38,6 +55,23 @@ export const PassingTests = () => {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
  ];
 | 
					  ];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function onSwitchTab(e) {
 | 
				
			||||||
 | 
					    console.log(e,document.visibilityState);
 | 
				
			||||||
 | 
					    if (document.visibilityState === "hidden" && startTest) {
 | 
				
			||||||
 | 
					      alert("Убедительная просьба не покидать страницу и не переключаться. Рассчитывайте только на свои знания и умения!!!")
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  useEffect(()=>{
 | 
				
			||||||
 | 
					    window.addEventListener("beforeunload", onCloseWindow);
 | 
				
			||||||
 | 
					    window.addEventListener("visibilitychange", onSwitchTab);
 | 
				
			||||||
 | 
					    window.onblur = onSwitchTab
 | 
				
			||||||
 | 
					    return () => {
 | 
				
			||||||
 | 
					      window.removeEventListener("beforeunload", onCloseWindow);
 | 
				
			||||||
 | 
					      window.removeEventListener("visibilitychange", onSwitchTab);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }, [startTest])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
    <div className="passing-tests-page">
 | 
					    <div className="passing-tests-page">
 | 
				
			||||||
      <ProfileHeader />
 | 
					      <ProfileHeader />
 | 
				
			||||||
@@ -51,12 +85,13 @@ export const PassingTests = () => {
 | 
				
			|||||||
          ]}
 | 
					          ]}
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
        <div className="passing-tests-page__title main-title">
 | 
					        <div className="passing-tests-page__title main-title">
 | 
				
			||||||
          Тестирование в позиции Junior разработчик{" "}
 | 
					          Тестирование в позиции Junior разработчик
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div className="passing-tests-page__passing-information">
 | 
					        <div className="passing-tests-page__passing-information">
 | 
				
			||||||
          <QuizPassingInformation
 | 
					          <QuizPassingInformation
 | 
				
			||||||
            expiryTimestamp={time}
 | 
					            timer={timer}
 | 
				
			||||||
            setStartTest={setStartTest}
 | 
					            setStartTest={setStartTest}
 | 
				
			||||||
 | 
					            uuid={uuid}
 | 
				
			||||||
          />
 | 
					          />
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -68,7 +103,7 @@ export const PassingTests = () => {
 | 
				
			|||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
            )}
 | 
					            )}
 | 
				
			||||||
            {startTest ? (
 | 
					            {startTest ? (
 | 
				
			||||||
              <TaskQuiz />
 | 
					              <TaskQuiz timer={timer}/>
 | 
				
			||||||
            ) : (
 | 
					            ) : (
 | 
				
			||||||
              <div className="passing-tests-page__introduction">
 | 
					              <div className="passing-tests-page__introduction">
 | 
				
			||||||
                {introduction.map((item, i) => (
 | 
					                {introduction.map((item, i) => (
 | 
				
			||||||
@@ -98,6 +133,13 @@ export const PassingTests = () => {
 | 
				
			|||||||
        )}
 | 
					        )}
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <Footer />
 | 
					      <Footer />
 | 
				
			||||||
 | 
					      {/*<Prompt*/}
 | 
				
			||||||
 | 
					      {/*  when={showPrompt}*/}
 | 
				
			||||||
 | 
					      {/*  message="Unsaved changes detected, continue?"*/}
 | 
				
			||||||
 | 
					      {/*  beforeUnload={true}*/}
 | 
				
			||||||
 | 
					      {/*/>*/}
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  );
 | 
					  );
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,7 +27,7 @@ import BackEndImg from "assets/images/partnerProfile/personalBackEnd.svg";
 | 
				
			|||||||
import "./quiz-page.scss";
 | 
					import "./quiz-page.scss";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const QuizPage = () => {
 | 
					export const QuizPage = () => {
 | 
				
			||||||
  const questionnaires = useSelector(questionnairesSelector);
 | 
					  const [questionnaires,setQuestionnaires] = useState([]);
 | 
				
			||||||
  const dispatch = useDispatch();
 | 
					  const dispatch = useDispatch();
 | 
				
			||||||
  const [personalInfoItems] = useState([
 | 
					  const [personalInfoItems] = useState([
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@@ -36,7 +36,7 @@ export const QuizPage = () => {
 | 
				
			|||||||
      description:
 | 
					      description:
 | 
				
			||||||
        "Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript",
 | 
					        "Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript",
 | 
				
			||||||
      available: true,
 | 
					      available: true,
 | 
				
			||||||
      img: BackEndImg,
 | 
					      img: BackEndImg
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      title: "Frontend разработчики",
 | 
					      title: "Frontend разработчики",
 | 
				
			||||||
@@ -44,14 +44,14 @@ export const QuizPage = () => {
 | 
				
			|||||||
      description:
 | 
					      description:
 | 
				
			||||||
        "Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript",
 | 
					        "Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript",
 | 
				
			||||||
      available: true,
 | 
					      available: true,
 | 
				
			||||||
      img: FrontendImg,
 | 
					      img: FrontendImg
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      title: "Архитектура проектов",
 | 
					      title: "Архитектура проектов",
 | 
				
			||||||
      link: "/registration-candidate",
 | 
					      link: "/registration-candidate",
 | 
				
			||||||
      description: "Потоки данных ER ERP CRM CQRS UML BPMN",
 | 
					      description: "Потоки данных ER ERP CRM CQRS UML BPMN",
 | 
				
			||||||
      available: true,
 | 
					      available: true,
 | 
				
			||||||
      img: ArchitectureImg,
 | 
					      img: ArchitectureImg
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      title: "Дизайн проектов",
 | 
					      title: "Дизайн проектов",
 | 
				
			||||||
@@ -59,35 +59,35 @@ export const QuizPage = () => {
 | 
				
			|||||||
      description:
 | 
					      description:
 | 
				
			||||||
        "Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript",
 | 
					        "Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript",
 | 
				
			||||||
      available: true,
 | 
					      available: true,
 | 
				
			||||||
      img: DesignImg,
 | 
					      img: DesignImg
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      title: "Тестирование проектов",
 | 
					      title: "Тестирование проектов",
 | 
				
			||||||
      link: "/registration-candidate",
 | 
					      link: "/registration-candidate",
 | 
				
			||||||
      description: "SQL Postman TestRail Kibana Ручное тестирование",
 | 
					      description: "SQL Postman TestRail Kibana Ручное тестирование",
 | 
				
			||||||
      available: false,
 | 
					      available: false,
 | 
				
			||||||
      img: TestImg,
 | 
					      img: TestImg
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      title: "Администрирование проектов",
 | 
					      title: "Администрирование проектов",
 | 
				
			||||||
      link: "/registration-candidate",
 | 
					      link: "/registration-candidate",
 | 
				
			||||||
      description: "DevOps ELK Kubernetes Docker Bash Apache Oracle Git",
 | 
					      description: "DevOps ELK Kubernetes Docker Bash Apache Oracle Git",
 | 
				
			||||||
      available: false,
 | 
					      available: false,
 | 
				
			||||||
      img: AdminImg,
 | 
					      img: AdminImg
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      title: "Управление проектом",
 | 
					      title: "Управление проектом",
 | 
				
			||||||
      link: "/registration-candidate",
 | 
					      link: "/registration-candidate",
 | 
				
			||||||
      description: "Scrum Kanban Agile Miro CustDev",
 | 
					      description: "Scrum Kanban Agile Miro CustDev",
 | 
				
			||||||
      available: false,
 | 
					      available: false,
 | 
				
			||||||
      img: ManageImg,
 | 
					      img: ManageImg
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      title: "Копирайтинг проектов",
 | 
					      title: "Копирайтинг проектов",
 | 
				
			||||||
      link: "/registration-candidate",
 | 
					      link: "/registration-candidate",
 | 
				
			||||||
      description: "Теги Заголовок H1 Дескриптор Абзац Сценарий",
 | 
					      description: "Теги Заголовок H1 Дескриптор Абзац Сценарий",
 | 
				
			||||||
      available: false,
 | 
					      available: false,
 | 
				
			||||||
      img: CopyImg,
 | 
					      img: CopyImg
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      title: "Реклама и SMM",
 | 
					      title: "Реклама и SMM",
 | 
				
			||||||
@@ -95,16 +95,18 @@ export const QuizPage = () => {
 | 
				
			|||||||
      description:
 | 
					      description:
 | 
				
			||||||
        "Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript",
 | 
					        "Java PHP Python C# React Vue.js NodeJs Golang Ruby JavaScript",
 | 
				
			||||||
      available: false,
 | 
					      available: false,
 | 
				
			||||||
      img: SmmImg,
 | 
					      img: SmmImg
 | 
				
			||||||
    },
 | 
					    }
 | 
				
			||||||
  ]);
 | 
					  ]);
 | 
				
			||||||
  const userId = localStorage.getItem("id");
 | 
					  const userId = localStorage.getItem("id");
 | 
				
			||||||
  const [selectedCategory, setsetSelectedCategory] = useState(false);
 | 
					  const [selectedCategory, setSetSelectedCategory] = useState(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  useEffect(() => {
 | 
					  useEffect(() => {
 | 
				
			||||||
    apiRequest(
 | 
					    apiRequest(
 | 
				
			||||||
      `/user-questionnaire/questionnaires-list?user_id=${userId}`
 | 
					      `/user-questionnaire/questionnaires-list?user_id=${userId}`
 | 
				
			||||||
    ).then((res) => dispatch(setQuestionnaires(res)));
 | 
					    )
 | 
				
			||||||
 | 
					      .then(res => setQuestionnaires(res))
 | 
				
			||||||
 | 
					      .catch(e => console.log(e));
 | 
				
			||||||
  }, []);
 | 
					  }, []);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return (
 | 
					  return (
 | 
				
			||||||
@@ -115,7 +117,7 @@ export const QuizPage = () => {
 | 
				
			|||||||
        <ProfileBreadcrumbs
 | 
					        <ProfileBreadcrumbs
 | 
				
			||||||
          links={[
 | 
					          links={[
 | 
				
			||||||
            { name: "Главная", link: "/profile-candidate" },
 | 
					            { name: "Главная", link: "/profile-candidate" },
 | 
				
			||||||
            { name: "Тестирование", link: "/quiz" },
 | 
					            { name: "Тестирование", link: "/quiz" }
 | 
				
			||||||
          ]}
 | 
					          ]}
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
        <div className="quiz-page__title main-title">
 | 
					        <div className="quiz-page__title main-title">
 | 
				
			||||||
@@ -124,17 +126,15 @@ export const QuizPage = () => {
 | 
				
			|||||||
        {!selectedCategory && (
 | 
					        {!selectedCategory && (
 | 
				
			||||||
          <>
 | 
					          <>
 | 
				
			||||||
            <div className="quiz-page__specialization">
 | 
					            <div className="quiz-page__specialization">
 | 
				
			||||||
              <SelectedCategory setSelectedCategory={setsetSelectedCategory} />
 | 
					              <SelectedCategory setSelectedCategory={setSetSelectedCategory} />
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            <div className="quiz-page__block">Доступные тесты</div>
 | 
					            <div className="quiz-page__block">Доступные тесты</div>
 | 
				
			||||||
            <div className="quiz-page__cards-test">
 | 
					            <div className="quiz-page__cards-test">
 | 
				
			||||||
              {questionnaires.length ? (
 | 
					              {questionnaires.length ? (
 | 
				
			||||||
                questionnaires.map((item, index) => (
 | 
					                questionnaires.map((item, index) => (
 | 
				
			||||||
                  <CardAvailableTest
 | 
					                  <CardAvailableTest
 | 
				
			||||||
                    description={
 | 
					                    description={item.description}
 | 
				
			||||||
                      "Вы новичок с реальным опытом работы до 1 года, или без опыта"
 | 
					                    path={`quiz/test/${item.uuid}`}
 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    path={"quiz/test"}
 | 
					 | 
				
			||||||
                    status={item.status}
 | 
					                    status={item.status}
 | 
				
			||||||
                    title={item.questionnaire_title}
 | 
					                    title={item.questionnaire_title}
 | 
				
			||||||
                    passedTest={item.passedTest}
 | 
					                    passedTest={item.passedTest}
 | 
				
			||||||
@@ -151,7 +151,6 @@ export const QuizPage = () => {
 | 
				
			|||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
          </>
 | 
					          </>
 | 
				
			||||||
        )}
 | 
					        )}
 | 
				
			||||||
 | 
					 | 
				
			||||||
        {selectedCategory && (
 | 
					        {selectedCategory && (
 | 
				
			||||||
          <div className="quiz-page__categories-items">
 | 
					          <div className="quiz-page__categories-items">
 | 
				
			||||||
            {personalInfoItems.map((item, index) => {
 | 
					            {personalInfoItems.map((item, index) => {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,12 +32,11 @@ export const QuizReportPage = () => {
 | 
				
			|||||||
          ]}
 | 
					          ]}
 | 
				
			||||||
        />
 | 
					        />
 | 
				
			||||||
        <div className="quiz-report-page__title main-title">
 | 
					        <div className="quiz-report-page__title main-title">
 | 
				
			||||||
          Отчет по тестированию позиции Junior разработчик{" "}
 | 
					          Отчет по тестированию позиции Junior разработчик
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div className="quiz-report-page__report-quiz">
 | 
					        <div className="quiz-report-page__report-quiz">
 | 
				
			||||||
          <QuizReport />
 | 
					          <QuizReport />
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
 | 
					 | 
				
			||||||
        <AlertResult />
 | 
					        <AlertResult />
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <Footer />
 | 
					      <Footer />
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,107 +1,19 @@
 | 
				
			|||||||
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
 | 
					import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import { apiRequest } from "../api/request";
 | 
					import { apiRequest } from "@api/request";
 | 
				
			||||||
 | 
					import moment from "moment";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const initialState = {
 | 
					const initialState = {
 | 
				
			||||||
  answers: [
 | 
					  questions: null,
 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      id: "12",
 | 
					 | 
				
			||||||
      question_id: "7",
 | 
					 | 
				
			||||||
      answer_body:
 | 
					 | 
				
			||||||
        "Нsdf sfd fds sdf sf sfsdf sdfеск вsdffsdfsdf sf sdf sdfsdfsdfsdfdsjknsdkf dssdjf sdfbsdhf sd hjdsfv sdhjvар1 отв1 истина",
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      id: "23",
 | 
					 | 
				
			||||||
      question_id: "7",
 | 
					 | 
				
			||||||
      answer_body: "Неск вар1 отв1 истина",
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      id: "233",
 | 
					 | 
				
			||||||
      question_id: "7",
 | 
					 | 
				
			||||||
      answer_body: "lorem sdfdsf dfs sdf ",
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
  questionnaires: [],
 | 
					  questionnaires: [],
 | 
				
			||||||
  questions: [
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      id: "4",
 | 
					 | 
				
			||||||
      question_type_id: "3",
 | 
					 | 
				
			||||||
      question_body:
 | 
					 | 
				
			||||||
        "Для чего в Python используется встроенная функция enumerate()?",
 | 
					 | 
				
			||||||
      question_priority: null,
 | 
					 | 
				
			||||||
      next_question: null,
 | 
					 | 
				
			||||||
      time_limit: "00:22:00",
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      id: "24",
 | 
					 | 
				
			||||||
      question_type_id: "3",
 | 
					 | 
				
			||||||
      question_body: "Для чего в Python dfsf троенная функция enumerate()?",
 | 
					 | 
				
			||||||
      question_priority: null,
 | 
					 | 
				
			||||||
      next_question: null,
 | 
					 | 
				
			||||||
      time_limit: "00:22:00",
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      id: "41",
 | 
					 | 
				
			||||||
      question_type_id: "3",
 | 
					 | 
				
			||||||
      question_body: "Для чегоsdfsdfя функция enumerate()?",
 | 
					 | 
				
			||||||
      question_priority: null,
 | 
					 | 
				
			||||||
      next_question: null,
 | 
					 | 
				
			||||||
      time_limit: "00:22:00",
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
      id: "5",
 | 
					 | 
				
			||||||
      question_type_id: "2",
 | 
					 | 
				
			||||||
      question_body: "Один ответ2",
 | 
					 | 
				
			||||||
      question_priority: null,
 | 
					 | 
				
			||||||
      next_question: null,
 | 
					 | 
				
			||||||
      time_limit: "00:22:00",
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
  ],
 | 
					 | 
				
			||||||
  selectedTest: {
 | 
					 | 
				
			||||||
    user_id: 1,
 | 
					 | 
				
			||||||
    uuid: "d222f858-60fd-47fb-8731-dc9d5fc384c5",
 | 
					 | 
				
			||||||
    score: 11,
 | 
					 | 
				
			||||||
    status: 2,
 | 
					 | 
				
			||||||
    percent_correct_answers: 0.25,
 | 
					 | 
				
			||||||
    testing_date: "2022-03-17 11:14:22",
 | 
					 | 
				
			||||||
    questionnaire_title: "Кат1 Анкета 1 активна",
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  selectedAnswers: {},
 | 
					 | 
				
			||||||
  completedTest: false,
 | 
					  completedTest: false,
 | 
				
			||||||
 | 
					  selectedTest: {},
 | 
				
			||||||
  result: null,
 | 
					  result: null,
 | 
				
			||||||
  isLoading: false,
 | 
					 | 
				
			||||||
  dataQuestionnairesOfUser: [],
 | 
					 | 
				
			||||||
  passedTests: [],
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  userInfo: null,
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
export const setUserInfo = createAsyncThunk("userInfo", (id) =>
 | 
					 | 
				
			||||||
  apiRequest(`/profile/get-main-data?user_id=${id}`)
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const fetchUserAnswersMany = createAsyncThunk(
 | 
					export const fetchResultTest = createAsyncThunk(
 | 
				
			||||||
  "answersUserMany",
 | 
					  "result",
 | 
				
			||||||
  (checkedValues) =>
 | 
					  (uuid) =>
 | 
				
			||||||
    apiRequest("/user-response/set-responses", {
 | 
					 | 
				
			||||||
      method: "POST",
 | 
					 | 
				
			||||||
      data: { userResponses: checkedValues },
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const fetchUserAnswerOne = createAsyncThunk(
 | 
					 | 
				
			||||||
  "answersUserOne",
 | 
					 | 
				
			||||||
  (checkedValues) =>
 | 
					 | 
				
			||||||
    apiRequest("/user-response/set-response", {
 | 
					 | 
				
			||||||
      method: "POST",
 | 
					 | 
				
			||||||
      data: checkedValues[0],
 | 
					 | 
				
			||||||
    })
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const fetchGetAnswers = createAsyncThunk("answers", (question_id) =>
 | 
					 | 
				
			||||||
  apiRequest(`/answer/get-answers?question_id=${question_id}`)
 | 
					 | 
				
			||||||
);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export const fetchResultTest = createAsyncThunk("result", (uuid) =>
 | 
					 | 
				
			||||||
    apiRequest(
 | 
					    apiRequest(
 | 
				
			||||||
      `/user-questionnaire/questionnaire-completed?user_questionnaire_uuid=${uuid}`
 | 
					      `/user-questionnaire/questionnaire-completed?user_questionnaire_uuid=${uuid}`
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
@@ -111,41 +23,31 @@ export const quizSlice = createSlice({
 | 
				
			|||||||
  name: "quiz",
 | 
					  name: "quiz",
 | 
				
			||||||
  initialState,
 | 
					  initialState,
 | 
				
			||||||
  reducers: {
 | 
					  reducers: {
 | 
				
			||||||
    setQuestionnaires: (state, action) => {
 | 
					    setQuestions: (state, action) => {
 | 
				
			||||||
      state.questionnaires = action.payload;
 | 
					      state.questions = action.payload;
 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    setSelectedTest: (state, action) => {
 | 
					 | 
				
			||||||
      state.selectedTest = action.payload;
 | 
					 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    setCompleteTest: (state) => {
 | 
					    setCompleteTest: (state) => {
 | 
				
			||||||
      state.completedTest = true;
 | 
					      state.completedTest = true;
 | 
				
			||||||
    },
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  extraReducers: {
 | 
					  extraReducers: {
 | 
				
			||||||
    [setUserInfo.fulfilled]: (state, action) => {
 | 
					 | 
				
			||||||
      state.userInfo = action.payload;
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    [fetchGetAnswers.fulfilled]: (state, action) => {
 | 
					 | 
				
			||||||
      state.answer = action.payload;
 | 
					 | 
				
			||||||
    },
 | 
					 | 
				
			||||||
    [fetchResultTest.fulfilled]: (state, action) => {
 | 
					    [fetchResultTest.fulfilled]: (state, action) => {
 | 
				
			||||||
      state.result = action.payload;
 | 
					      state.result = action.payload;
 | 
				
			||||||
    },
 | 
					    }
 | 
				
			||||||
  },
 | 
					  }
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const { setQuestionnaires, setSelectedTest, setCompleteTest } =
 | 
					export const {
 | 
				
			||||||
  quizSlice.actions;
 | 
					  setQuestions,
 | 
				
			||||||
 | 
					} = quizSlice.actions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const answersSelector = (state) => state.quiz.answers;
 | 
					 | 
				
			||||||
export const questionnairesSelector = (state) => state.quiz.questionnaires;
 | 
					export const questionnairesSelector = (state) => state.quiz.questionnaires;
 | 
				
			||||||
export const selectedAnswersSelector = (state) => state.quiz.selectedAnswers;
 | 
					 | 
				
			||||||
export const questionsSelector = (state) => state.quiz.questions;
 | 
					export const questionsSelector = (state) => state.quiz.questions;
 | 
				
			||||||
export const completedTestSelector = (state) => state.quiz.completedTest;
 | 
					export const completedTestSelector = (state) => state.quiz.completedTest;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const selectResult = (state) => state.quiz.result;
 | 
					export const selectResult = (state) => state.quiz.result;
 | 
				
			||||||
export const selectedTest = (state) => state.quiz.selectedTest;
 | 
					export const selectedTest = (state) => state.quiz.selectedTest;
 | 
				
			||||||
export const selectPassedTests = (state) => state.quiz.passedTests;
 | 
					
 | 
				
			||||||
export const selectUserInfo = (state) => state.quiz.userInfo;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default quizSlice.reducer;
 | 
					export default quizSlice.reducer;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user