quiz #3
@ -106,8 +106,8 @@ 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/:uuid" element={<QuizReportPage />} />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
<Route exact path="profile">
|
<Route exact path="profile">
|
||||||
|
@ -36,6 +36,10 @@ export const Navigation = () => {
|
|||||||
path: "/payouts",
|
path: "/payouts",
|
||||||
name: "Выплаты",
|
name: "Выплаты",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: "/quiz",
|
||||||
|
name: "Тесты",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: "/settings",
|
path: "/settings",
|
||||||
name: "Настройки",
|
name: "Настройки",
|
||||||
@ -91,7 +95,11 @@ export const Navigation = () => {
|
|||||||
<nav className="profileHeader__nav">
|
<nav className="profileHeader__nav">
|
||||||
{navInfo[user].map((link, index) => {
|
{navInfo[user].map((link, index) => {
|
||||||
return (
|
return (
|
||||||
<NavLink key={index} end to={`/profile${link.path}`}>
|
<NavLink
|
||||||
|
key={index}
|
||||||
|
end
|
||||||
|
to={link.path === "/quiz" ? link.path : `/profile${link.path}`}
|
||||||
|
>
|
||||||
{link.name}
|
{link.name}
|
||||||
</NavLink>
|
</NavLink>
|
||||||
);
|
);
|
||||||
|
@ -2,7 +2,7 @@ import React from "react";
|
|||||||
|
|
||||||
import suucessIcon from "assets/images/quiz/success.png";
|
import suucessIcon from "assets/images/quiz/success.png";
|
||||||
|
|
||||||
export const AlertResult = () => {
|
export const AlertResult = ({ info }) => {
|
||||||
const successTest = false;
|
const successTest = false;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -17,7 +17,7 @@ export const AlertResult = () => {
|
|||||||
className="alert-result__text"
|
className="alert-result__text"
|
||||||
style={{ color: successTest ? "#52B709" : "#5B6871" }}
|
style={{ color: successTest ? "#52B709" : "#5B6871" }}
|
||||||
>
|
>
|
||||||
Благодарим Вас за прохождение теста "Junior разработчик". Ваши
|
Благодарим Вас за прохождение теста "{info.questionnaire_title}". Ваши
|
||||||
результаты проверены, готовы пригласить Вас в команду
|
результаты проверены, готовы пригласить Вас в команду
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -5,16 +5,19 @@ 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={status === 2 ? `/quiz/report/${path}` : `/quiz/test/${path}`}
|
||||||
|
aria-disabled={true}
|
||||||
className="card-available-test__container"
|
className="card-available-test__container"
|
||||||
style={{
|
style={
|
||||||
opacity: passedTest ? 0.3 : 1,
|
{
|
||||||
pointerEvents: passedTest ? "none" : "all",
|
// opacity: status !== 1 ? 0.3 : 1,
|
||||||
}}
|
// pointerEvents: status !== 1 ? "none" : "all",
|
||||||
|
}
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<div className="card-available-test__top-head">
|
<div className="card-available-test__top-head">
|
||||||
<StarRating />
|
<StarRating />
|
||||||
@ -27,11 +30,10 @@ 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/${path}`}>Отчет по тесту</Link>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
@ -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" key={id}>
|
||||||
<div className="form-task__group">
|
<input
|
||||||
<textarea
|
className="form-task__check"
|
||||||
className="form-task__field"
|
type={+type === 3 ? "checkbox" : "radio"}
|
||||||
value={inputValue}
|
value={answer_body}
|
||||||
onChange={handleChange}
|
name={+type === 3 ? "checkbox" : "radio"}
|
||||||
/>
|
id={id}
|
||||||
</div>
|
onChange={handleChange}
|
||||||
);
|
/>
|
||||||
case "3":
|
<label htmlFor={id}>{answer_body}</label>
|
||||||
return (
|
</div>
|
||||||
<div className="form-task__group" key={answer.id}>
|
);
|
||||||
<input
|
|
||||||
className="form-task__check"
|
|
||||||
type="checkbox"
|
|
||||||
value={answer.answer_body}
|
|
||||||
id={answer.id}
|
|
||||||
onChange={handleChange}
|
|
||||||
/>
|
|
||||||
<label htmlFor={answer.id}>{answer.answer_body}</label>
|
|
||||||
</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,15 +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>
|
||||||
{userInfo?.status === 500 ? (
|
{userInfo?.status === 500 ? (
|
||||||
|
@ -1,36 +1,71 @@
|
|||||||
|
import moment from "moment";
|
||||||
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 { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
import { completedTestSelector } from "@redux/quizSlice";
|
import { setQuestions } from "@redux/quizSlice";
|
||||||
|
|
||||||
|
import { apiRequest } from "@api/request";
|
||||||
|
|
||||||
|
import { useNotification } from "@hooks/useNotification";
|
||||||
|
|
||||||
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";
|
||||||
|
|
||||||
export const QuizPassingInformation = ({ expiryTimestamp, setStartTest }) => {
|
export const QuizPassingInformation = ({ setStartTest, uuid, timer }) => {
|
||||||
const { seconds, minutes, isRunning, start, restart } = useTimer({
|
const { restart, pause, hours, minutes, seconds, isRunning } = timer;
|
||||||
expiryTimestamp,
|
const navigate = useNavigate();
|
||||||
autoStart: false,
|
const { showNotification } = useNotification();
|
||||||
onExpire: () => {
|
const dispatch = useDispatch();
|
||||||
console.warn("onExpire called");
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const completedTest = useSelector(completedTestSelector);
|
|
||||||
|
|
||||||
const startTesting = () => {
|
const startTesting = () => {
|
||||||
setStartTest(true);
|
apiRequest(`/question/get-questions?uuid=${uuid}`)
|
||||||
start();
|
.then((res) => {
|
||||||
|
if (res.status === 400) {
|
||||||
|
dispatch(setQuestions(null));
|
||||||
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: res?.message || "",
|
||||||
|
type: "error",
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
dispatch(setQuestions(res));
|
||||||
|
setStartTest(true);
|
||||||
|
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));
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
const checkTest = () =>
|
||||||
if (completedTest) {
|
apiRequest(
|
||||||
const time = new Date();
|
`user-questionnaire/questionnaire-completed?user_questionnaire_uuid=${uuid}`
|
||||||
time.setSeconds(time.getSeconds() + 0); //600 - кол-во секунд для прохождения теста
|
);
|
||||||
restart(time, false);
|
|
||||||
}
|
const completeTest = () =>
|
||||||
}, [completedTest]);
|
apiRequest("/user-questionnaire/questionnaire-completed", {
|
||||||
|
method: "POST",
|
||||||
|
});
|
||||||
|
|
||||||
|
const finishQuiz = async () => {
|
||||||
|
Promise.all([checkTest, completeTest])
|
||||||
|
.then(function () {
|
||||||
|
pause();
|
||||||
|
})
|
||||||
|
.catch((e) => {
|
||||||
|
console.log(e);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="quiz-passing-information">
|
<div className="quiz-passing-information">
|
||||||
@ -48,32 +83,38 @@ export const QuizPassingInformation = ({ expiryTimestamp, setStartTest }) => {
|
|||||||
разработчик
|
разработчик
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="quiz-passing-information__timer timer-quiz">
|
{isRunning && (
|
||||||
<div className="quiz-passing-information__icon">
|
<div className="quiz-passing-information__timer timer-quiz">
|
||||||
<img src={timer} alt="" />
|
<div className="quiz-passing-information__icon">
|
||||||
|
<img src={iconTomer} alt="" />
|
||||||
|
</div>
|
||||||
|
<div className="quiz-passing-information__text">
|
||||||
|
Время на прохождение теста:
|
||||||
|
<br />
|
||||||
|
<span>
|
||||||
|
{hours.toString().padStart(2, "0") +
|
||||||
|
":" +
|
||||||
|
minutes.toString().padStart(2, "0") +
|
||||||
|
":" +
|
||||||
|
seconds.toString().padStart(2, "0")}
|
||||||
|
секунд
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="quiz-passing-information__text">
|
)}
|
||||||
{completedTest ? "Время вышло" : "Время на прохождение теста:"}{" "}
|
{!isRunning && (
|
||||||
<br />
|
<div className="quiz-passing-information__attempt">
|
||||||
<span>
|
<div className="quiz-passing-information__icon">
|
||||||
{minutes.toString().padStart(2, "0") +
|
<img src={accempt} alt="" />
|
||||||
":" +
|
</div>
|
||||||
seconds.toString().padStart(2, "0")}{" "}
|
<div className="quiz-passing-information__text">
|
||||||
секунд
|
Попыток прохождения: <br />
|
||||||
</span>
|
<span>1 попытка</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
)}
|
||||||
<div className="quiz-passing-information__attempt">
|
|
||||||
<div className="quiz-passing-information__icon">
|
|
||||||
<img src={accempt} alt="" />
|
|
||||||
</div>
|
|
||||||
<div className="quiz-passing-information__text">
|
|
||||||
Попыток прохождения: <br />
|
|
||||||
<span>1 попытка</span>
|
|
||||||
</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 +123,15 @@ 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>
|
||||||
);
|
);
|
||||||
|
@ -2,7 +2,13 @@ import React from "react";
|
|||||||
|
|
||||||
import StarRating from "@components/StarRating/StarRating";
|
import StarRating from "@components/StarRating/StarRating";
|
||||||
|
|
||||||
export const QuizReport = () => {
|
export const QuizReport = ({ info }) => {
|
||||||
|
function correctAnswers() {
|
||||||
|
return info.number_questions * info.percent_correct_answers;
|
||||||
|
}
|
||||||
|
function correctWrongAnswers() {
|
||||||
|
return info.number_questions * (1 - info.percent_correct_answers);
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<div className="report">
|
<div className="report">
|
||||||
<div className="report__row">
|
<div className="report__row">
|
||||||
@ -13,16 +19,18 @@ export const QuizReport = () => {
|
|||||||
countActiveStars={0.5}
|
countActiveStars={0.5}
|
||||||
size={61}
|
size={61}
|
||||||
/>
|
/>
|
||||||
<div className="report__job-title">
|
<div className="report__job-title">{info.questionnaire_title}</div>
|
||||||
Junior <br /> разработчик
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="report__column">
|
<div className="report__column">
|
||||||
<div className="report__value">22</div>
|
<div className="report__value">
|
||||||
|
{Boolean(correctAnswers()) ? correctAnswers() : 0}
|
||||||
|
</div>
|
||||||
<div className="report__text">Правильных ответов</div>
|
<div className="report__text">Правильных ответов</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="report__column">
|
<div className="report__column">
|
||||||
<div className="report__value report__value_false">02</div>
|
<div className="report__value report__value_false">
|
||||||
|
{Boolean(correctWrongAnswers()) ? correctWrongAnswers() : 0}
|
||||||
|
</div>
|
||||||
<div className="report__text">Не правильных ответов</div>
|
<div className="report__text">Не правильных ответов</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="report__column">
|
<div className="report__column">
|
||||||
|
@ -1,148 +1,158 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import moment from "moment";
|
||||||
import { useDispatch, useSelector } from "react-redux";
|
import React, { useState } from "react";
|
||||||
|
import { useSelector } from "react-redux";
|
||||||
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
|
|
||||||
import {
|
import { questionsSelector } from "@redux/quizSlice";
|
||||||
answersSelector,
|
|
||||||
fetchGetAnswers, // fetchUserAnswerOne,
|
|
||||||
// fetchUserAnswersMany,
|
|
||||||
questionsSelector,
|
|
||||||
selectedTest, // setAnswers,
|
|
||||||
setCompleteTest,
|
|
||||||
} from "@redux/quizSlice";
|
|
||||||
|
|
||||||
import { apiRequest } from "@api/request";
|
import { apiRequest } from "@api/request";
|
||||||
|
|
||||||
|
import { useHandlerFieldTest } from "@hooks/useHandlerFieldTest";
|
||||||
|
import { useNotification } from "@hooks/useNotification";
|
||||||
|
|
||||||
|
import { Loader } from "@components/Common/Loader/Loader";
|
||||||
|
|
||||||
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";
|
||||||
|
|
||||||
export const TaskQuiz = () => {
|
export const TaskQuiz = ({ timer }) => {
|
||||||
const dispatch = useDispatch();
|
const navigate = useNavigate();
|
||||||
|
const { restart } = timer;
|
||||||
const answers = useSelector(answersSelector);
|
const { uuid } = useParams();
|
||||||
|
const userId = localStorage.getItem("id");
|
||||||
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] = useState(false);
|
||||||
//const [stripValue, setStripValue] = useState(0);
|
const { showNotification } = useNotification();
|
||||||
const [inputValue, setInputValue] = useState("");
|
|
||||||
|
|
||||||
const id = localStorage.getItem("id");
|
const { userResponses, handleChange } = useHandlerFieldTest({
|
||||||
|
questions,
|
||||||
useEffect(() => {
|
indexQuestion: index,
|
||||||
// fetch('https://itguild.info/api/user-questionnaire/questionnaires-list?user_id=110').then(response => response.json())
|
});
|
||||||
// .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 (!userResponses[index]) {
|
||||||
alert("Вы не ответили на вопрос");
|
alert("Вы не ответили на вопрос");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//отправка ответов на сервер
|
// setLoadingSendAnswers(true);
|
||||||
if (questions[index].question_type_id != 3) {
|
// .finally(() => setLoadingSendAnswers(false));
|
||||||
//dispatch(fetchUserAnswerOne(checkedValues));
|
|
||||||
} else {
|
|
||||||
console.log(checkedValues);
|
|
||||||
// dispatch(fetchUserAnswersMany(checkedValues));
|
|
||||||
}
|
|
||||||
|
|
||||||
//Проверка на окончание теста
|
// отправка ответов на сервер
|
||||||
if (!(index < questions.length - 1)) {
|
if (questions.length === userResponses.length) {
|
||||||
dispatch(setCompleteTest());
|
await apiRequest(`/user-response/set-responses`, {
|
||||||
return;
|
method: "POST",
|
||||||
}
|
data: {
|
||||||
|
user_id: userId,
|
||||||
dispatch(fetchGetAnswers(questions[index + 1].id));
|
user_questionnaire_uuid: uuid,
|
||||||
setIndex((prev) => prev + 1);
|
userResponses: JSON.stringify(userResponses),
|
||||||
setCheckedValues([]);
|
|
||||||
setInputValue("");
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleChange = (e) => {
|
|
||||||
const checked = e.target.checked;
|
|
||||||
|
|
||||||
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,
|
|
||||||
},
|
},
|
||||||
]);
|
}).then(() => {
|
||||||
return;
|
showNotification({
|
||||||
|
show: true,
|
||||||
|
text: "Тест успешно пройден",
|
||||||
|
type: "success",
|
||||||
|
});
|
||||||
|
navigate("/quiz");
|
||||||
|
// if (String(res?.status)[0] !== "2") {
|
||||||
|
// showNotification({
|
||||||
|
// show: true,
|
||||||
|
// text: res?.message || "",
|
||||||
|
// type: "error",
|
||||||
|
// });
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
});
|
||||||
|
// .catch((e) => {
|
||||||
|
// showNotification({
|
||||||
|
// show: true,
|
||||||
|
// text: e?.message || "",
|
||||||
|
// type: "error",
|
||||||
|
// });
|
||||||
|
// })
|
||||||
}
|
}
|
||||||
|
|
||||||
checked
|
//установка таймера на вопрос если он существует
|
||||||
? setCheckedValues((prev) => [
|
if (questions[index + 1]?.time_limit !== "00:00:00") setValueTimer();
|
||||||
...prev,
|
|
||||||
{
|
// переход на следующий вопрос
|
||||||
user_id: id,
|
setIndex((prev) => (questions[prev + 1] ? prev + 1 : prev));
|
||||||
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 complete = (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
};
|
||||||
|
|
||||||
|
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")
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
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
|
||||||
{answers.map((answer) => (
|
className="task__form form-task"
|
||||||
<GetOptionTask
|
onSubmit={
|
||||||
key={answer.id}
|
index !== questions.length - 1 ? nextQuestion : complete
|
||||||
type={questions[index].question_type_id}
|
}
|
||||||
handleChange={handleChange}
|
>
|
||||||
answer={answer}
|
{questions[index].question_type_id === 1 ? (
|
||||||
/>
|
<div className="form-task__group">
|
||||||
))}
|
<textarea
|
||||||
|
className="form-task__field"
|
||||||
|
onChange={handleChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
questions[index]?.answers?.map((answer) => (
|
||||||
|
<GetOptionTask
|
||||||
|
key={answer.id}
|
||||||
|
type={questions[index].question_type_id}
|
||||||
|
handleChange={handleChange}
|
||||||
|
answer={answer}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
)}
|
||||||
<div className="form-task__buttons">
|
<div className="form-task__buttons">
|
||||||
{/* {
|
<button
|
||||||
index != 0 && <button type='submit' className='form-task__btn quiz-btn quiz-btn_back'
|
onClick={nextQuestion}
|
||||||
onClick={prevQuestion}>Назад</button>
|
// disabled={isLoadingSendAnswers}
|
||||||
} */}
|
className="form-task__btn quiz-btn"
|
||||||
{index != questions.length && (
|
>
|
||||||
<button
|
{isLoadingSendAnswers ? (
|
||||||
onClick={nextQuestion}
|
<Loader width={25} height={25} />
|
||||||
className="form-task__btn quiz-btn"
|
) : index !== questions.length - 1 ? (
|
||||||
>
|
"Далее"
|
||||||
Далее
|
) : (
|
||||||
</button>
|
"Завершить"
|
||||||
)}
|
)}
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
) : (
|
||||||
|
<h1>ОШибка</h1>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
32
src/hooks/useHandlerFieldTest.js
Normal file
32
src/hooks/useHandlerFieldTest.js
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
export const useHandlerFieldTest = ({ questions, indexQuestion }) => {
|
||||||
|
const [userResponses, setUserResponses] = useState([]);
|
||||||
|
const handleChangeCheckbox = (e) => {
|
||||||
|
setUserResponses((prev) => [
|
||||||
|
...prev.filter(
|
||||||
|
(item) => item.question_id !== questions[indexQuestion].id
|
||||||
|
),
|
||||||
|
{
|
||||||
|
question_id: questions[indexQuestion].id,
|
||||||
|
response_body: e.target.value,
|
||||||
|
answer_id: e.target.id ? e.target.id : questions[indexQuestion].id,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
};
|
||||||
|
|
||||||
|
// const handleFieldsForm = (e) => {
|
||||||
|
// setValues([
|
||||||
|
// {
|
||||||
|
// user_id: id,
|
||||||
|
// user_questionnaire_uuid: uuid,
|
||||||
|
// question_id: questions[indexQuestion].id,
|
||||||
|
// response_body: e.target.value,
|
||||||
|
// },
|
||||||
|
// ]);
|
||||||
|
// };
|
||||||
|
const handleChange = (e) => {
|
||||||
|
handleChangeCheckbox(e);
|
||||||
|
};
|
||||||
|
return { handleChange, userResponses };
|
||||||
|
};
|
@ -1,24 +1,43 @@
|
|||||||
import React, { useState } from "react";
|
import moment from "moment";
|
||||||
|
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 { useTimer } from "react-timer-hook";
|
||||||
|
|
||||||
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 { Navigation } from "@components/Navigation/Navigation";
|
||||||
import { ProfileBreadcrumbs } from "@components/ProfileBreadcrumbs/ProfileBreadcrumbs";
|
import { ProfileBreadcrumbs } from "@components/ProfileBreadcrumbs/ProfileBreadcrumbs";
|
||||||
import { ProfileHeader } from "@components/ProfileHeader/ProfileHeader";
|
import { ProfileHeader } from "@components/ProfileHeader/ProfileHeader";
|
||||||
import { HeadBottom } from "@components/features/Candidate-lk/HeadBottom";
|
// import { HeadBottom } from "@components/features/Candidate-lk/HeadBottom";
|
||||||
import { BlockCompletedTest } from "@components/features/quiz/BlockCompletedTest";
|
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";
|
||||||
|
|
||||||
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,10 +57,30 @@ 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 />
|
||||||
<HeadBottom />
|
<Navigation />
|
||||||
|
{/*<HeadBottom />*/}
|
||||||
<div className="passing-tests-page__container">
|
<div className="passing-tests-page__container">
|
||||||
<ProfileBreadcrumbs
|
<ProfileBreadcrumbs
|
||||||
links={[
|
links={[
|
||||||
@ -51,12 +90,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 +108,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 +138,11 @@ export const PassingTests = () => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<Footer />
|
<Footer />
|
||||||
|
{/*<Prompt*/}
|
||||||
|
{/* when={showPrompt}*/}
|
||||||
|
{/* message="Unsaved changes detected, continue?"*/}
|
||||||
|
{/* beforeUnload={true}*/}
|
||||||
|
{/*/>*/}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -2,15 +2,15 @@ import React, { useEffect, useState } from "react";
|
|||||||
import { useDispatch, useSelector } from "react-redux";
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
import { questionnairesSelector, setQuestionnaires } from "@redux/quizSlice";
|
// import { questionnairesSelector, setQuestionnaires } from "@redux/quizSlice";
|
||||||
|
|
||||||
import { apiRequest } from "@api/request";
|
import { apiRequest } from "@api/request";
|
||||||
|
|
||||||
import CategoriesItem from "@components/CategoriesItem/CategoriesItem";
|
import CategoriesItem from "@components/CategoriesItem/CategoriesItem";
|
||||||
import { Footer } from "@components/Common/Footer/Footer";
|
import { Footer } from "@components/Common/Footer/Footer";
|
||||||
|
import { Navigation } from "@components/Navigation/Navigation";
|
||||||
import { ProfileBreadcrumbs } from "@components/ProfileBreadcrumbs/ProfileBreadcrumbs";
|
import { ProfileBreadcrumbs } from "@components/ProfileBreadcrumbs/ProfileBreadcrumbs";
|
||||||
import { ProfileHeader } from "@components/ProfileHeader/ProfileHeader";
|
import { ProfileHeader } from "@components/ProfileHeader/ProfileHeader";
|
||||||
import { HeadBottom } from "@components/features/Candidate-lk/HeadBottom";
|
// import { HeadBottom } from "@components/features/Candidate-lk/HeadBottom";
|
||||||
import { CardAvailableTest } from "@components/features/quiz/CardAviableTest";
|
import { CardAvailableTest } from "@components/features/quiz/CardAviableTest";
|
||||||
import { SelectedCategory } from "@components/features/quiz/SelectedCategory";
|
import { SelectedCategory } from "@components/features/quiz/SelectedCategory";
|
||||||
|
|
||||||
@ -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([
|
||||||
{
|
{
|
||||||
@ -99,18 +99,19 @@ export const QuizPage = () => {
|
|||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
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) => setQuestionnaires(res))
|
||||||
).then((res) => dispatch(setQuestionnaires(res)));
|
.catch((e) => console.log(e));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="quiz-page">
|
<div className="quiz-page">
|
||||||
<ProfileHeader />
|
<ProfileHeader />
|
||||||
<HeadBottom />
|
<Navigation />
|
||||||
|
{/*<HeadBottom />*/}
|
||||||
<div className="quiz-page__container">
|
<div className="quiz-page__container">
|
||||||
<ProfileBreadcrumbs
|
<ProfileBreadcrumbs
|
||||||
links={[
|
links={[
|
||||||
@ -124,17 +125,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={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 +150,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) => {
|
||||||
|
@ -1,28 +1,43 @@
|
|||||||
import React from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate, useParams } from "react-router-dom";
|
||||||
|
|
||||||
import { selectedTest } from "@redux/quizSlice";
|
import { selectedTest } from "@redux/quizSlice";
|
||||||
|
|
||||||
|
import { apiRequest } from "@api/request";
|
||||||
|
|
||||||
import { Footer } from "@components/Common/Footer/Footer";
|
import { Footer } from "@components/Common/Footer/Footer";
|
||||||
|
import { Navigation } from "@components/Navigation/Navigation";
|
||||||
import { ProfileBreadcrumbs } from "@components/ProfileBreadcrumbs/ProfileBreadcrumbs";
|
import { ProfileBreadcrumbs } from "@components/ProfileBreadcrumbs/ProfileBreadcrumbs";
|
||||||
import { ProfileHeader } from "@components/ProfileHeader/ProfileHeader";
|
import { ProfileHeader } from "@components/ProfileHeader/ProfileHeader";
|
||||||
import { HeadBottom } from "@components/features/Candidate-lk/HeadBottom";
|
// import { HeadBottom } from "@components/features/Candidate-lk/HeadBottom";
|
||||||
import { AlertResult } from "@components/features/quiz/AlertResult";
|
import { AlertResult } from "@components/features/quiz/AlertResult";
|
||||||
import { QuizReport } from "@components/features/quiz/QuizReport";
|
import { QuizReport } from "@components/features/quiz/QuizReport";
|
||||||
|
|
||||||
export const QuizReportPage = () => {
|
export const QuizReportPage = () => {
|
||||||
const test = useSelector(selectedTest);
|
const test = useSelector(selectedTest);
|
||||||
|
const params = useParams();
|
||||||
|
|
||||||
let navigate = useNavigate();
|
let navigate = useNavigate();
|
||||||
if (!test) {
|
if (!test) {
|
||||||
navigate("/quiz");
|
navigate("/quiz");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
apiRequest(
|
||||||
|
`/user-questionnaire/questionnaire-completed?user_questionnaire_uuid=${params.uuid}`
|
||||||
|
).then((res) => {
|
||||||
|
setTestInfo(res);
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const [testInfo, setTestInfo] = useState({});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="quiz-report-page">
|
<div className="quiz-report-page">
|
||||||
<ProfileHeader />
|
<ProfileHeader />
|
||||||
<HeadBottom />
|
<Navigation />
|
||||||
|
{/*<HeadBottom />*/}
|
||||||
<div className="quiz-report-page__container">
|
<div className="quiz-report-page__container">
|
||||||
<ProfileBreadcrumbs
|
<ProfileBreadcrumbs
|
||||||
links={[
|
links={[
|
||||||
@ -32,13 +47,12 @@ export const QuizReportPage = () => {
|
|||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
<div className="quiz-report-page__title main-title">
|
<div className="quiz-report-page__title main-title">
|
||||||
Отчет по тестированию позиции Junior разработчик{" "}
|
Отчет по тестированию позиции {testInfo.questionnaire_title}
|
||||||
</div>
|
</div>
|
||||||
<div className="quiz-report-page__report-quiz">
|
<div className="quiz-report-page__report-quiz">
|
||||||
<QuizReport />
|
<QuizReport info={testInfo} />
|
||||||
</div>
|
</div>
|
||||||
|
<AlertResult info={testInfo} />
|
||||||
<AlertResult />
|
|
||||||
</div>
|
</div>
|
||||||
<Footer />
|
<Footer />
|
||||||
</div>
|
</div>
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
&__container {
|
&__container {
|
||||||
max-width: 1160px;
|
max-width: 1160px;
|
||||||
margin: 0 auto 42px auto;
|
margin: 23px auto 42px auto;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0 15px;
|
padding: 0 15px;
|
||||||
@ -68,7 +68,7 @@
|
|||||||
}
|
}
|
||||||
&__container {
|
&__container {
|
||||||
max-width: 1160px;
|
max-width: 1160px;
|
||||||
margin: 0 auto 42px auto;
|
margin: 23px auto 42px auto;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0 15px;
|
padding: 0 15px;
|
||||||
@ -90,7 +90,7 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
&__container {
|
&__container {
|
||||||
max-width: 1160px;
|
max-width: 1160px;
|
||||||
margin: 0 auto 42px auto;
|
margin: 23px auto 42px auto;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0 15px;
|
padding: 0 15px;
|
||||||
@ -125,7 +125,7 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
&__container {
|
&__container {
|
||||||
max-width: 1160px;
|
max-width: 1160px;
|
||||||
margin: 0 auto 42px auto;
|
margin: 23px auto 42px auto;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0 15px;
|
padding: 0 15px;
|
||||||
|
@ -1,105 +1,15 @@
|
|||||||
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
|
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
|
||||||
|
import moment from "moment";
|
||||||
|
|
||||||
import { apiRequest } from "../api/request";
|
import { apiRequest } from "@api/request";
|
||||||
|
|
||||||
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(
|
|
||||||
"answersUserMany",
|
|
||||||
(checkedValues) =>
|
|
||||||
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) =>
|
export const fetchResultTest = createAsyncThunk("result", (uuid) =>
|
||||||
apiRequest(
|
apiRequest(
|
||||||
@ -111,41 +21,27 @@ 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 { setQuestions } = quizSlice.actions;
|
||||||
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;
|
||||||
|
Loading…
Reference in New Issue
Block a user