quiz page
This commit is contained in:
parent
d4ec833a31
commit
f7367dbdf2
38
src/components/features/quiz/GetOptionTask.js
Normal file
38
src/components/features/quiz/GetOptionTask.js
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
export const GetOptionTask = ({type, answer, handleChange, inputValue}) => {
|
||||||
|
switch (type) {
|
||||||
|
case "3":
|
||||||
|
return (
|
||||||
|
<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>
|
||||||
|
)
|
||||||
|
case "2":
|
||||||
|
case "4":
|
||||||
|
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>
|
||||||
|
)
|
||||||
|
case "1":
|
||||||
|
return (
|
||||||
|
<div className="form-task__group">
|
||||||
|
<textarea className='form-task__field' value={inputValue}
|
||||||
|
onChange={handleChange}/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
default:
|
||||||
|
return (
|
||||||
|
<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>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
30
src/components/features/quiz/HeaderPageTests.js
Normal file
30
src/components/features/quiz/HeaderPageTests.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
import {Link} from 'react-router-dom'
|
||||||
|
import './quiz.scss'
|
||||||
|
import {useSelector} from "react-redux";
|
||||||
|
import {selectedTest, selectUserInfo} from "../../../redux/quizSlice";
|
||||||
|
|
||||||
|
|
||||||
|
export const HeaderPageTestsQuiz = ({isVisibilityButton}) => {
|
||||||
|
|
||||||
|
const test = useSelector(selectedTest)
|
||||||
|
const userInfo = useSelector(selectUserInfo);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="header-quiz">
|
||||||
|
<div className="header-quiz__container">
|
||||||
|
<div className="header-quiz__body">
|
||||||
|
<div className="header-quiz__avatar">
|
||||||
|
{userInfo.photo && <img src={userInfo.photo} alt={userInfo.photo}/>}
|
||||||
|
</div>
|
||||||
|
<div className="header-quiz__description">
|
||||||
|
<div className="header-quiz__title-test title">{test.questionnaire_title}</div>
|
||||||
|
<div className="header-quiz__subtitle subtitle">Тест на основе выступление
|
||||||
|
"{test.questionnaire_title}" {userInfo.fio}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{isVisibilityButton &&
|
||||||
|
<Link to={'/quiz-instruction'} className='quiz-btn quiz-btn_restriction'>Пройти</Link>}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
48
src/components/features/quiz/HeaderQuiz.js
Normal file
48
src/components/features/quiz/HeaderQuiz.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import {useEffect} from 'react'
|
||||||
|
import {useDispatch} from 'react-redux'
|
||||||
|
import {useSelector} from 'react-redux'
|
||||||
|
import {fetchGet} from '../../../server/server'
|
||||||
|
import './quiz.scss'
|
||||||
|
import {selectUserInfo, setQuestionnairesList, setUserInfo,} from "../../../redux/quizSlice";
|
||||||
|
|
||||||
|
export const HeaderQuiz = ({header}) => {
|
||||||
|
|
||||||
|
const dispatch = useDispatch()
|
||||||
|
const userId = localStorage.getItem('id');
|
||||||
|
const userInfo = useSelector(selectUserInfo);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
dispatch(setUserInfo(userId))
|
||||||
|
}, [dispatch])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetchGet({
|
||||||
|
link: `${process.env.REACT_APP_API_URL}/api/user-questionnaire/questionnaires-list?user_id=${userId}`,
|
||||||
|
Origin: `${process.env.REACT_APP_BASE_URL}`,
|
||||||
|
}
|
||||||
|
).then(response => {
|
||||||
|
dispatch(setQuestionnairesList(response))
|
||||||
|
})
|
||||||
|
}, [dispatch])
|
||||||
|
|
||||||
|
console.log('render header quiz')
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="header-quiz">
|
||||||
|
<div className="header-quiz__container">
|
||||||
|
{!userInfo ? <h2>Loading...</h2> :
|
||||||
|
<>
|
||||||
|
{header && <h2 className={'header-quiz__title-main'}>Добрый день, {userInfo.fio}</h2>}
|
||||||
|
<div className="header-quiz__body header-quiz__body_interjacent">
|
||||||
|
<div className="header-quiz__avatar">
|
||||||
|
<img src={userInfo.photo} alt={userInfo.photo}/>
|
||||||
|
</div>
|
||||||
|
<div className="header-quiz__name-user">{userInfo.fio}</div>
|
||||||
|
<div className="header-quiz__title">{userInfo.position_name}</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
48
src/components/features/quiz/Instructions.js
Normal file
48
src/components/features/quiz/Instructions.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
import {Link} from 'react-router-dom'
|
||||||
|
import {CodeSnippetlighter} from '../../../pages/CodeSnippetPage'
|
||||||
|
import comment from './../../../images/comment.jpg'
|
||||||
|
import './quiz.scss'
|
||||||
|
import {useEffect, useState} from "react";
|
||||||
|
import {useSelector} from "react-redux";
|
||||||
|
import {selectedTest} from "../../../redux/quizSlice";
|
||||||
|
import {fetchGet} from "../../../server/server";
|
||||||
|
|
||||||
|
export const Instruction = () => {
|
||||||
|
|
||||||
|
const [countQuestions, setCountQuestions] = useState()
|
||||||
|
const test = useSelector(selectedTest)
|
||||||
|
|
||||||
|
useEffect(async () => {
|
||||||
|
|
||||||
|
const response = await fetchGet({
|
||||||
|
link: `${process.env.REACT_APP_API_URL}/api/user-questionnaire/get-question-number?user_questionnaire_uuid=${test.uuid}`,
|
||||||
|
Origin: `${process.env.REACT_APP_BASE_URL}`,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
setCountQuestions(response.question_number)
|
||||||
|
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="instruction">
|
||||||
|
<div className="instruction__container">
|
||||||
|
<h3 className="instruction__title quiz-title_h3">Инструкция к тесту</h3>
|
||||||
|
<div className="instruction__text">
|
||||||
|
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempoLorem ipsum dolor sit
|
||||||
|
amet,Lo
|
||||||
|
rem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempo consectetur adipisicing e
|
||||||
|
lit, sed do eiusmod tempo
|
||||||
|
</div>
|
||||||
|
<Link to="/quiz-test" className='instruction__btn quiz-btn quiz-btn_restriction'>Далее</Link>
|
||||||
|
<div className="instruction__info">
|
||||||
|
<div className="instruction__icon">
|
||||||
|
<img src={comment} alt=""/>
|
||||||
|
</div>
|
||||||
|
<div className="instruction__text instruction__text_info">Количество вопросов в
|
||||||
|
тесте: <span>{countQuestions}</span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
73
src/components/features/quiz/MyTestsQuiz.js
Normal file
73
src/components/features/quiz/MyTestsQuiz.js
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import {Link} from 'react-router-dom'
|
||||||
|
import calendarImage from './../../../images/calendar.svg'
|
||||||
|
import './quiz.scss'
|
||||||
|
import {useDispatch} from "react-redux";
|
||||||
|
import {setSelectedTest} from "../../../redux/quizSlice";
|
||||||
|
|
||||||
|
export const MyTestsQuiz = ({listTests}) => {
|
||||||
|
|
||||||
|
const formationEndingOfScore = (score) => {
|
||||||
|
const lastNumber = score % 10
|
||||||
|
if(score === 11 ||score === 12 ||score === 13 ||score === 14 ){
|
||||||
|
return 'баллов'
|
||||||
|
}else if(lastNumber === 2 || lastNumber === 3 || lastNumber === 4 ){
|
||||||
|
return 'балла'
|
||||||
|
}else if(lastNumber === 1){
|
||||||
|
return 'балл'
|
||||||
|
}else{
|
||||||
|
return 'баллов'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const dispatch = useDispatch()
|
||||||
|
const recordSelectedTest = (item) => dispatch(setSelectedTest(item))
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="my-tests">
|
||||||
|
<div className="my-tests__container">
|
||||||
|
<div className="my-tests__title">Мои тесты</div>
|
||||||
|
<div className="my-tests__items">
|
||||||
|
{listTests.map(item => {
|
||||||
|
switch (item.status) {
|
||||||
|
case 1:
|
||||||
|
return <article className="my-tests__item item-test" key={item.questionnaire_title}>
|
||||||
|
<h3 className="item-test__name-test">
|
||||||
|
{item.questionnaire_title}
|
||||||
|
</h3>
|
||||||
|
<div className="item-test__body test-data">
|
||||||
|
<Link to={'/quiz-interjacent'} className='quiz-btn'
|
||||||
|
onClick={() => recordSelectedTest(item)}>Пройти</Link>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
case 2:
|
||||||
|
return <article className="my-tests__item item-test" key={item.questionnaire_title}>
|
||||||
|
<h3 className="item-test__name-test">
|
||||||
|
{item.questionnaire_title}
|
||||||
|
</h3>
|
||||||
|
<div className="item-test__body test-data">
|
||||||
|
<div className="test-data__calendar ">
|
||||||
|
<img src={calendarImage} alt=""/>
|
||||||
|
{item.testing_date}
|
||||||
|
</div>
|
||||||
|
<div className="test-data__hr"></div>
|
||||||
|
<div className="test-data__score quiz-text">{item.score} {formationEndingOfScore(item.score)}</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
case 3:
|
||||||
|
return <article className="my-tests__item item-test" key={item.questionnaire_title}>
|
||||||
|
<h3 className="item-test__name-test">
|
||||||
|
{item.questionnaire_title}
|
||||||
|
</h3>
|
||||||
|
<div className="item-test__body test-data">
|
||||||
|
<div className='quiz-btn'>На проверке</div>
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
18
src/components/features/quiz/ProgressbarQuiz.js
Normal file
18
src/components/features/quiz/ProgressbarQuiz.js
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
import { Link } from 'react-router-dom'
|
||||||
|
import avatar from './../../../images/medium_male.png'
|
||||||
|
import './quiz.scss'
|
||||||
|
|
||||||
|
export const Progressbar = ({indexQuestion, width}) => {
|
||||||
|
return (
|
||||||
|
<div className="progressbar">
|
||||||
|
<div className="progressbar__body">
|
||||||
|
<div className="progressbar__value">
|
||||||
|
{indexQuestion}
|
||||||
|
</div>
|
||||||
|
<div className="progressbar__strip" >
|
||||||
|
<div style={{width: width+'%'}}></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
0
src/components/features/quiz/Results.js
Normal file
0
src/components/features/quiz/Results.js
Normal file
152
src/components/features/quiz/Task.js
Normal file
152
src/components/features/quiz/Task.js
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
import React, {useEffect} from 'react'
|
||||||
|
import {useHistory} from "react-router"
|
||||||
|
import {CodeSnippetlighter} from '../../../pages/CodeSnippetPage'
|
||||||
|
import './quiz.scss'
|
||||||
|
import {useDispatch} from 'react-redux'
|
||||||
|
import {useState} from 'react'
|
||||||
|
import {
|
||||||
|
fetchGetAnswers,
|
||||||
|
selectAnswer,
|
||||||
|
selectedTest
|
||||||
|
} from '../../../redux/quizSlice'
|
||||||
|
import {useSelector} from 'react-redux'
|
||||||
|
import {Progressbar} from './ProgressbarQuiz'
|
||||||
|
import {fetchUserAnswersMany, fetchUserAnswerOne} from './../../../redux/quizSlice'
|
||||||
|
import {GetOptionTask} from './GetOptionTask'
|
||||||
|
import {fetchGet} from "../../../server/server";
|
||||||
|
|
||||||
|
|
||||||
|
export const TaskQuiz = () => {
|
||||||
|
|
||||||
|
const history = useHistory();
|
||||||
|
const dispatch = useDispatch()
|
||||||
|
const listAnswers = useSelector(selectAnswer)
|
||||||
|
const dataTest = useSelector(selectedTest)
|
||||||
|
const [index, setIndex] = useState(0);
|
||||||
|
const [checkedValues, setCheckedValues] = useState([])
|
||||||
|
const [stripValue, setStripValue] = useState(0);
|
||||||
|
const [inputValue, setInputValue] = useState('')
|
||||||
|
const id = localStorage.getItem('id');
|
||||||
|
const [questions, setQuestions] = useState([])
|
||||||
|
|
||||||
|
console.log("render task");
|
||||||
|
|
||||||
|
useEffect(async () => {
|
||||||
|
const response = await fetchGet({
|
||||||
|
link: `${process.env.REACT_APP_API_URL}/api/question/get-questions?uuid=${dataTest.uuid}`,
|
||||||
|
Origin: `${process.env.REACT_APP_BASE_URL}`,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
setQuestions(response)
|
||||||
|
dispatch(fetchGetAnswers(response[0].id))
|
||||||
|
setStripValue((+index + 1) * 100 / response.length)
|
||||||
|
}, [dispatch])
|
||||||
|
|
||||||
|
|
||||||
|
const nextQuestion = async (e) => {
|
||||||
|
e.preventDefault()
|
||||||
|
|
||||||
|
//Проверка на валидацию ответов
|
||||||
|
if (checkedValues.length || inputValue) {
|
||||||
|
switch (questions[index].question_type_id) {
|
||||||
|
case '3':
|
||||||
|
// await dispatch(fetchUserAnswersMany(checkedValues))
|
||||||
|
break;
|
||||||
|
case '2':
|
||||||
|
case '1':
|
||||||
|
case '4':
|
||||||
|
// await dispatch(fetchUserAnswerOne(checkedValues))
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Проверка на существование следующего запроса
|
||||||
|
if (index < questions.length - 1) {
|
||||||
|
await dispatch(fetchGetAnswers(questions[index + 1].id))
|
||||||
|
setIndex(prev => prev >= questions.length - 1 ? prev : prev + 1)
|
||||||
|
setStripValue((prev => prev + (100 / questions.length)))
|
||||||
|
setCheckedValues([]);
|
||||||
|
setInputValue('')
|
||||||
|
} else {
|
||||||
|
history.push(`/quiz-result`)
|
||||||
|
// alert("Тест пройден!")
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
alert("Вы не ответили на вопрос")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleChange = (e) => {
|
||||||
|
const checked = e.target.checked;
|
||||||
|
switch (questions[index].question_type_id) {
|
||||||
|
case '3':
|
||||||
|
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)])
|
||||||
|
break
|
||||||
|
case '1':
|
||||||
|
case '2':
|
||||||
|
case '4':
|
||||||
|
setCheckedValues([{
|
||||||
|
user_id: id,
|
||||||
|
user_questionnaire_uuid: dataTest.uuid,
|
||||||
|
question_id: questions[index].id,
|
||||||
|
response_body: e.target.value
|
||||||
|
}])
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.StrictMode>
|
||||||
|
<Progressbar indexQuestion={index + 1} width={stripValue}/>
|
||||||
|
<div className="task">
|
||||||
|
{!questions.length || !stripValue || !listAnswers.length ?
|
||||||
|
<h1 className={'_container'} style={{display: "block"}}>Loading....</h1>
|
||||||
|
:
|
||||||
|
<div className="task__container">
|
||||||
|
<div className="task__code code">
|
||||||
|
{/* <CodeSnippetlighter /> */}
|
||||||
|
</div>
|
||||||
|
<h3 className="task__title quiz-title_h3">{questions[index].question_body}</h3>
|
||||||
|
<div className="task__body">
|
||||||
|
<form className='task__form form-task'>
|
||||||
|
{
|
||||||
|
questions[index].question_type_id === 1 ?
|
||||||
|
<GetOptionTask
|
||||||
|
type={1}
|
||||||
|
inputValue={checkedValues.length ? checkedValues[0].response_body : ''}
|
||||||
|
handleChange={handleChange}
|
||||||
|
/>
|
||||||
|
:
|
||||||
|
listAnswers.map((answer) => (
|
||||||
|
<GetOptionTask
|
||||||
|
key={answer.id}
|
||||||
|
type={questions[index].question_type_id}
|
||||||
|
handleChange={handleChange}
|
||||||
|
answer={answer}
|
||||||
|
/>
|
||||||
|
))
|
||||||
|
|
||||||
|
}
|
||||||
|
<div className="form-task__buttons">
|
||||||
|
{questions.length !== index + 1 &&
|
||||||
|
<button type='submit' className='quiz-btn'
|
||||||
|
onClick={(e) => nextQuestion(e)}>Далее</button>}
|
||||||
|
{questions.length === index + 1 && <button onClick={(e) => nextQuestion(e)}
|
||||||
|
className='quiz-btn quiz-btn_dark-green'>Завершить</button>}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</React.StrictMode>
|
||||||
|
)
|
||||||
|
}
|
45
src/components/features/quiz/functions.scss
Normal file
45
src/components/features/quiz/functions.scss
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
|
||||||
|
//перевод в %
|
||||||
|
@function prc($pxOne, $pxTwo) {
|
||||||
|
$result: math.div($pxOne, $pxTwo) * 100%;
|
||||||
|
@return $result;
|
||||||
|
}
|
||||||
|
//перевод в rem
|
||||||
|
@function rem($px) {
|
||||||
|
$result: math.div($px, 8) + rem;
|
||||||
|
@return $result;
|
||||||
|
}
|
||||||
|
//перевод в em
|
||||||
|
@function em($px, $size:16) {
|
||||||
|
$result: math.div($px, $size) + em;
|
||||||
|
@return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//адаптивное свойство
|
||||||
|
@mixin adaptiv-value($property, $startSize, $minSize, $type) {
|
||||||
|
$addSize: $startSize - $minSize;
|
||||||
|
@if $type == 1 {
|
||||||
|
//только если меньше контейнера, присутствует ограничение
|
||||||
|
#{$property}: $startSize+px;
|
||||||
|
@media (max-width: em($maxWidthContainer)) {
|
||||||
|
#{$property}: calc(
|
||||||
|
#{$minSize+px} + #{$addSize} *
|
||||||
|
((100vw - 320px) / #{$maxWidthContainer - 320})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} @else if $type == 2 {
|
||||||
|
//только если больше контейнера, min-width
|
||||||
|
#{$property}: rem($startSize);
|
||||||
|
@media (min-width: #{$maxWidthContainer + px}) {
|
||||||
|
#{$property}: calc(
|
||||||
|
#{rem($minSize)} + #{$addSize} * ((100vw - 320px) / #{$maxWidth - 320})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} @else {
|
||||||
|
//всегда на всех экранах
|
||||||
|
#{$property}: calc(
|
||||||
|
#{rem($minSize)} + #{$addSize} * ((100vw - 320px) / #{$maxWidth - 320})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
402
src/components/features/quiz/quiz.scss
Normal file
402
src/components/features/quiz/quiz.scss
Normal file
@ -0,0 +1,402 @@
|
|||||||
|
@use 'sass:math';
|
||||||
|
@import 'functions.scss';
|
||||||
|
|
||||||
|
$maxWidthContainer: 1123;
|
||||||
|
|
||||||
|
._container{
|
||||||
|
max-width: 1123px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.quiz-text{
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: math.div(30, 20);
|
||||||
|
}
|
||||||
|
.title{
|
||||||
|
color: #282828;
|
||||||
|
font-family: "GT Eesti Pro Display";
|
||||||
|
font-size: 33px;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: math.div(48, 33);
|
||||||
|
letter-spacing: 0.56px;
|
||||||
|
}
|
||||||
|
.subtitle{
|
||||||
|
color: #373936;
|
||||||
|
font-family: "GT Eesti Pro Display";
|
||||||
|
font-size: 20px;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: math.div(25, 20);
|
||||||
|
}
|
||||||
|
.quiz-btn{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
box-shadow: 6px 5px 20px rgba(82, 151, 34, 0.21);
|
||||||
|
border-radius: 23px;
|
||||||
|
color: #ffffff;
|
||||||
|
outline: none;
|
||||||
|
border: 2px solid #52b709;
|
||||||
|
background: #52b709;
|
||||||
|
transition: 0 all ease 0.8s;
|
||||||
|
padding: 14px 38px;
|
||||||
|
line-height: 1;
|
||||||
|
font-family: "Muller Extra Bold";
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 16px;
|
||||||
|
text-decoration: none;
|
||||||
|
&:hover{
|
||||||
|
text-decoration: none;
|
||||||
|
color: #52b709;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
&_dark-green{
|
||||||
|
background-color: #1a310c;
|
||||||
|
border: 2px solid #1a310c;
|
||||||
|
&:hover{
|
||||||
|
text-decoration: none;
|
||||||
|
color: #1a310c;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&_restriction{
|
||||||
|
max-width: 131px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.quiz-title_h3{
|
||||||
|
color: #000000;
|
||||||
|
font-family: "GT Eesti Pro Display";
|
||||||
|
font-size: 25px;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: math.div(30, 25);
|
||||||
|
}
|
||||||
|
//=============================================
|
||||||
|
.header-quiz{
|
||||||
|
@include adaptiv-value("padding-top", 48, 30, 1);
|
||||||
|
@include adaptiv-value("padding-bottom", 85, 30, 1);
|
||||||
|
&__container{
|
||||||
|
max-width: $maxWidthContainer+px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
&__title-main{
|
||||||
|
font-family: "GT Eesti Pro Display";
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
@include adaptiv-value("margin-bottom", 80, 30, 1);
|
||||||
|
}
|
||||||
|
&__body{
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
row-gap: 30px;
|
||||||
|
margin-bottom: 39px;
|
||||||
|
}
|
||||||
|
&__body_interjacent{
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
&__description{
|
||||||
|
max-width: 576px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
&__avatar{
|
||||||
|
position: relative;
|
||||||
|
display: block;
|
||||||
|
flex: 0 0 133px;
|
||||||
|
min-height: 133px;
|
||||||
|
margin-right: 31px;
|
||||||
|
img{
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&__name-user{
|
||||||
|
color: #000000;
|
||||||
|
font-family: "GT Eesti Pro Display";
|
||||||
|
font-size: 16px;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: math.div(30, 20);
|
||||||
|
margin-right: 70px;
|
||||||
|
}
|
||||||
|
&__title{
|
||||||
|
color: #000000;
|
||||||
|
font-family: "GT Eesti Pro Display";
|
||||||
|
@include adaptiv-value("font-size", 25, 16, 1);
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: math.div(36, 25);
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::before{
|
||||||
|
position: absolute;
|
||||||
|
content: "";
|
||||||
|
width: prc(316, 370);
|
||||||
|
height: 5px;
|
||||||
|
border-radius: 3px;
|
||||||
|
background-color: #54b611;
|
||||||
|
bottom: -26px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.my-tests{
|
||||||
|
font-family: "GT Eesti Pro Display";
|
||||||
|
// @include adaptiv-value("padding-top", 85, 30, 1);
|
||||||
|
// @include adaptiv-value("padding-bottom", 85, 30, 1);
|
||||||
|
&__container{
|
||||||
|
max-width: $maxWidthContainer+px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
&__title{
|
||||||
|
color: #000000;
|
||||||
|
font-size: 25px;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: math.div(30, 25);
|
||||||
|
@include adaptiv-value("margin-bottom", 80, 30, 1);
|
||||||
|
}
|
||||||
|
&__items{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
margin: 0 -41px -42px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.item-test{
|
||||||
|
flex: 0 1 50%;
|
||||||
|
padding: 0 41px;
|
||||||
|
margin: 0 0 42px 0;
|
||||||
|
@media (max-width: 760px) {
|
||||||
|
flex: 0 1 100%;
|
||||||
|
}
|
||||||
|
&__name-test{
|
||||||
|
color: #373936;
|
||||||
|
margin-bottom: 29px;
|
||||||
|
|
||||||
|
}
|
||||||
|
.active{
|
||||||
|
color: #54b611;
|
||||||
|
}
|
||||||
|
&__body{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.test-data{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
&__calendar{
|
||||||
|
padding: 13px 21px;
|
||||||
|
box-shadow: 0 0 59px rgba(44, 44, 44, 0.05);
|
||||||
|
border-radius: 5px;
|
||||||
|
border: 1px solid #c4c4c4;
|
||||||
|
background-color: #f0f7e0;
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 13px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-right: 17px;
|
||||||
|
img{
|
||||||
|
display: block;
|
||||||
|
margin-right: 11px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
&__hr{
|
||||||
|
width: 28px;
|
||||||
|
height: 5px;
|
||||||
|
border-radius: 3px;
|
||||||
|
background-color: #54b611;
|
||||||
|
margin-right: 26px;
|
||||||
|
}
|
||||||
|
&__select{
|
||||||
|
max-width: 131px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.progressbar{
|
||||||
|
max-width: $maxWidthContainer+px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 10px;
|
||||||
|
&__body{
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
&__value{
|
||||||
|
flex: 0 0 39px;
|
||||||
|
height: 39px;
|
||||||
|
background-color: #5cb42b;
|
||||||
|
border-radius: 50%;
|
||||||
|
color: #fff;
|
||||||
|
letter-spacing: 1.1px;
|
||||||
|
font-size: 16px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
// flex: 1 1 auto;
|
||||||
|
margin-right: 19px;
|
||||||
|
}
|
||||||
|
&__strip{
|
||||||
|
flex: 1 1 auto;
|
||||||
|
height: 19px;
|
||||||
|
|
||||||
|
div{
|
||||||
|
border-radius: 10px;
|
||||||
|
height: 100%;
|
||||||
|
background-color: #5cb42b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.task{
|
||||||
|
@include adaptiv-value("padding-top", 35, 10, 1);
|
||||||
|
&__container{
|
||||||
|
max-width: $maxWidthContainer+px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
&__title{
|
||||||
|
margin-bottom: 39px;
|
||||||
|
}
|
||||||
|
&__form{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-task{
|
||||||
|
&__field{
|
||||||
|
padding: 10px 15px;
|
||||||
|
font-size: 17px;
|
||||||
|
font-family: 'GT Eesti Pro Display';
|
||||||
|
letter-spacing: 0.3px;
|
||||||
|
outline: none;
|
||||||
|
border: 1px solid #52b709;
|
||||||
|
width: 100%;
|
||||||
|
resize: vertical;
|
||||||
|
}
|
||||||
|
&__check {
|
||||||
|
padding: 0;
|
||||||
|
height: initial;
|
||||||
|
width: initial;
|
||||||
|
margin-bottom: 0;
|
||||||
|
display: none;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
&__buttons{
|
||||||
|
display: flex;
|
||||||
|
gap: 56px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
@include adaptiv-value("margin-top", 60, 30, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-task__group{
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
margin-bottom: 15px;
|
||||||
|
|
||||||
|
label {
|
||||||
|
color: #373936;
|
||||||
|
font-family: "GT Eesti Pro Display";
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 300;
|
||||||
|
line-height: math.div(28,18);
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
&:before {
|
||||||
|
content:'';
|
||||||
|
-webkit-appearance: none;
|
||||||
|
background-color: transparent;
|
||||||
|
border: 2px solid #52b709;
|
||||||
|
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05), inset 0px -15px 10px -12px rgba(0, 0, 0, 0.05);
|
||||||
|
padding: 11px;
|
||||||
|
display: inline-block;
|
||||||
|
position: relative;
|
||||||
|
vertical-align: middle;
|
||||||
|
cursor: pointer;
|
||||||
|
margin-right: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input[type="radio"] + label:before{
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
input:checked + label:before{
|
||||||
|
background: #52b709;
|
||||||
|
}
|
||||||
|
input:checked + label:after {
|
||||||
|
|
||||||
|
content: "";
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: 6px;
|
||||||
|
left: 9px;
|
||||||
|
width: 7px;
|
||||||
|
height: 14px;
|
||||||
|
border: solid #fff;
|
||||||
|
border-width: 0 2px 2px 0;
|
||||||
|
transform: rotate(45deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.instruction{
|
||||||
|
&__container{
|
||||||
|
max-width: $maxWidthContainer+px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 0 10px;
|
||||||
|
}
|
||||||
|
&__title{
|
||||||
|
@include adaptiv-value("margin-bottom", 62, 20, 1);
|
||||||
|
}
|
||||||
|
&__text{
|
||||||
|
color: #373936;
|
||||||
|
font-family: "GT Eesti Pro Display";
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 300;
|
||||||
|
line-height: math.div(28, 18);
|
||||||
|
@include adaptiv-value("margin-bottom", 50, 20, 1);
|
||||||
|
span{
|
||||||
|
color: #54b611;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
&_info{
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&__info{
|
||||||
|
display: flex;
|
||||||
|
gap: 24px;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
&__icon{
|
||||||
|
width: 36px;
|
||||||
|
height: 33px;
|
||||||
|
}
|
||||||
|
&__btn{
|
||||||
|
margin-bottom: 34px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.result{
|
||||||
|
font-family: "GT Eesti Pro Display";
|
||||||
|
&__body{
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
&__text{
|
||||||
|
font-size: 24px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
&__score{
|
||||||
|
color: #5cb42b;
|
||||||
|
}
|
||||||
|
}
|
23
src/pages/quiz/InstructionPage.js
Normal file
23
src/pages/quiz/InstructionPage.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import {Redirect} from "react-router-dom"
|
||||||
|
import { HeaderPageTestsQuiz } from "../../components/features/quiz/HeaderPageTests"
|
||||||
|
import { Instruction } from "../../components/features/quiz/Instructions"
|
||||||
|
import React from "react";
|
||||||
|
import {useSelector} from "react-redux";
|
||||||
|
import {selectedTest} from "../../redux/quizSlice";
|
||||||
|
|
||||||
|
|
||||||
|
export const InstructionPage = () => {
|
||||||
|
|
||||||
|
const test = useSelector(selectedTest)
|
||||||
|
|
||||||
|
if(!test){
|
||||||
|
return <Redirect to={'/quiz'} />
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<HeaderPageTestsQuiz isVisibilityButton={false}/>
|
||||||
|
<Instruction />
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
24
src/pages/quiz/InterjacentPage.js
Normal file
24
src/pages/quiz/InterjacentPage.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import {Redirect} from "react-router-dom"
|
||||||
|
import {HeaderPageTestsQuiz} from "../../components/features/quiz/HeaderPageTests"
|
||||||
|
import {MyTestsQuiz} from "../../components/features/quiz/MyTestsQuiz"
|
||||||
|
import {useSelector} from "react-redux";
|
||||||
|
import {selectedTest, selectPassedTests} from "../../redux/quizSlice";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
|
||||||
|
export const InterjacentPage = () => {
|
||||||
|
|
||||||
|
const test = useSelector(selectedTest)
|
||||||
|
const passedTests = useSelector(selectPassedTests)
|
||||||
|
|
||||||
|
if (!test) {
|
||||||
|
return <Redirect to={'/quiz'}/>
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<HeaderPageTestsQuiz isVisibilityButton={true}/>
|
||||||
|
<MyTestsQuiz listTests={passedTests}/>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
17
src/pages/quiz/QuizPage.js
Normal file
17
src/pages/quiz/QuizPage.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import React from 'react'
|
||||||
|
import {HeaderQuiz} from "../../components/features/quiz/HeaderQuiz"
|
||||||
|
import {MyTestsQuiz} from "../../components/features/quiz/MyTestsQuiz"
|
||||||
|
import {useSelector} from "react-redux";
|
||||||
|
import {selectQuestionnairesOfUser} from "../../redux/quizSlice";
|
||||||
|
|
||||||
|
export const QuizPage = () => {
|
||||||
|
|
||||||
|
const allTests = useSelector(selectQuestionnairesOfUser)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<HeaderQuiz header={true}/>
|
||||||
|
<MyTestsQuiz listTests={allTests}/>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
22
src/pages/quiz/QuizTestPage.js
Normal file
22
src/pages/quiz/QuizTestPage.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import {Link, Redirect} from 'react-router-dom'
|
||||||
|
import {HeaderPageTestsQuiz} from '../../components/features/quiz/HeaderPageTests'
|
||||||
|
import {Progressbar} from '../../components/features/quiz/ProgressbarQuiz'
|
||||||
|
import {TaskQuiz} from '../../components/features/quiz/Task'
|
||||||
|
import {useSelector} from "react-redux";
|
||||||
|
import {selectedTest} from "../../redux/quizSlice";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
export const QuizTestPage = () => {
|
||||||
|
|
||||||
|
const test = useSelector(selectedTest)
|
||||||
|
|
||||||
|
if (!test) {
|
||||||
|
return <Redirect to={'/quiz'}/>
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<HeaderPageTestsQuiz isVisibilityButton={false}/>
|
||||||
|
<TaskQuiz/>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
0
src/pages/quiz/ResultPage.js
Normal file
0
src/pages/quiz/ResultPage.js
Normal file
137
src/redux/quizSlice.js
Normal file
137
src/redux/quizSlice.js
Normal file
@ -0,0 +1,137 @@
|
|||||||
|
import {createAsyncThunk, createSlice} from '@reduxjs/toolkit';
|
||||||
|
import {fetchGet, fetchPost} from './../server/server'
|
||||||
|
import axios from "axios";
|
||||||
|
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
// questions: [],
|
||||||
|
answer: [],
|
||||||
|
result: null,
|
||||||
|
isLoading: false,
|
||||||
|
dataQuestionnairesOfUser: [],
|
||||||
|
passedTests: [],
|
||||||
|
selectedTest: null,
|
||||||
|
userInfo: null
|
||||||
|
};
|
||||||
|
export const setUserInfo = createAsyncThunk(
|
||||||
|
'userInfo',
|
||||||
|
async (id) => {
|
||||||
|
try{
|
||||||
|
const response = await fetchGet({
|
||||||
|
link: `${process.env.REACT_APP_API_URL}/api/user-card/get-user-card?user_id=${id}`,
|
||||||
|
Origin: `${process.env.REACT_APP_BASE_URL}`,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return response
|
||||||
|
}catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export const fetchUserAnswersMany = createAsyncThunk(
|
||||||
|
'answersUserMany',
|
||||||
|
async (checkedValues) => {
|
||||||
|
try{
|
||||||
|
const response = await axios.post(`${process.env.REACT_APP_API_URL}/api/user-response/set-responses`,
|
||||||
|
{"userResponses": checkedValues}, {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${localStorage.getItem('auth_token')}`,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return response.data
|
||||||
|
}catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
export const fetchUserAnswerOne = createAsyncThunk(
|
||||||
|
'answersUserOne',
|
||||||
|
async (checkedValues) => {
|
||||||
|
try{
|
||||||
|
const response = await axios.post(`${process.env.REACT_APP_API_URL}/api/user-response/set-response`,
|
||||||
|
checkedValues[0], {
|
||||||
|
headers: {
|
||||||
|
Authorization: `Bearer ${localStorage.getItem('auth_token')}`,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return response.data
|
||||||
|
}catch (e) {
|
||||||
|
console.log(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
export const fetchGetAnswers = createAsyncThunk(
|
||||||
|
'answers',
|
||||||
|
async (question_id) => {
|
||||||
|
const resp = await fetchGet({
|
||||||
|
link: `${process.env.REACT_APP_API_URL}/api/answer/get-answers?question_id=${question_id}`,
|
||||||
|
Origin: `${process.env.REACT_APP_BASE_URL}`,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return resp
|
||||||
|
}
|
||||||
|
)
|
||||||
|
// export const fetchGetQuestion = createAsyncThunk(
|
||||||
|
// 'questions',
|
||||||
|
// async (uuid) => {
|
||||||
|
// const resp = await fetchGet({
|
||||||
|
// link: `${process.env.REACT_APP_API_URL}/api/question/get-questions?uuid=${uuid}`,
|
||||||
|
// Origin: `${process.env.REACT_APP_BASE_URL}`,
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
// return resp
|
||||||
|
// }
|
||||||
|
// )
|
||||||
|
export const fetchResultTest = createAsyncThunk(
|
||||||
|
'result',
|
||||||
|
async (uuid) => {
|
||||||
|
const resp = await fetchGet({
|
||||||
|
link: `${process.env.REACT_APP_API_URL}/api/user-questionnaire/questionnaire-completed?user_questionnaire_uuid=${uuid}`,
|
||||||
|
Origin: `${process.env.REACT_APP_BASE_URL}`,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return resp
|
||||||
|
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
export const quizSlice = createSlice({
|
||||||
|
name: 'quiz',
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
setQuestionnairesList: (state, action) => {
|
||||||
|
state.dataQuestionnairesOfUser = action.payload
|
||||||
|
state.passedTests = action.payload.filter(item=>item.status === 2)
|
||||||
|
},
|
||||||
|
setSelectedTest: (state, action) => {
|
||||||
|
state.selectedTest = action.payload
|
||||||
|
},
|
||||||
|
},
|
||||||
|
extraReducers: {
|
||||||
|
[setUserInfo.fulfilled]: (state, action) => {
|
||||||
|
state.userInfo = action.payload;
|
||||||
|
},
|
||||||
|
[fetchGetAnswers.fulfilled]: (state, action) => {
|
||||||
|
state.answer = action.payload;
|
||||||
|
},
|
||||||
|
[fetchResultTest.fulfilled]: (state, action) => {
|
||||||
|
state.result = action.payload;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const {setQuestionnairesList, setSelectedTest} = quizSlice.actions;
|
||||||
|
|
||||||
|
// export const selectQuestions = (state) => state.quiz.questions;
|
||||||
|
export const selectAnswer = (state) => state.quiz.answer;
|
||||||
|
export const selectQuestionnairesOfUser = (state) => state.quiz.dataQuestionnairesOfUser;
|
||||||
|
export const selectResult = (state) => state.quiz.result;
|
||||||
|
export const selectIsLoading = (state) => state.quiz.isLoading;
|
||||||
|
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;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user