Удалил старые запросы к апи, переписал страницу тестов на новый конструктор запроса. Обновил библиотеки, в том числе реакт до последней версии, переписал устаревший код с библиотек.
This commit is contained in:
parent
f1628e5745
commit
c60e1b43d2
14314
package-lock.json
generated
14314
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
39
package.json
39
package.json
@ -28,53 +28,54 @@
|
|||||||
"identity-obj-proxy": "3.0.0",
|
"identity-obj-proxy": "3.0.0",
|
||||||
"moment": "^2.29.1",
|
"moment": "^2.29.1",
|
||||||
"prompts": "2.4.0",
|
"prompts": "2.4.0",
|
||||||
"react": "^17.0.2",
|
"react": "^18.2.0",
|
||||||
"react-app-polyfill": "^2.0.0",
|
"react-app-polyfill": "^2.0.0",
|
||||||
"react-bootstrap": "^1.6.0",
|
"react-bootstrap": "^1.6.0",
|
||||||
"react-dev-utils": "^11.0.3",
|
"react-dev-utils": "^12.0.1",
|
||||||
"react-dom": "^17.0.2",
|
"react-dom": "^18.2.0",
|
||||||
"react-inlinesvg": "^2.3.0",
|
"react-inlinesvg": "3.0.1",
|
||||||
"react-loader-spinner": "^4.0.0",
|
"react-loader-spinner": "^4.0.0",
|
||||||
"react-outside-click-handler": "^1.3.0",
|
"react-outside-click-handler": "^1.3.0",
|
||||||
"react-phone-input-2": "^2.14.0",
|
"react-phone-input-2": "^2.14.0",
|
||||||
"react-redux": "^7.2.4",
|
"react-redux": "^7.2.4",
|
||||||
"react-refresh": "^0.8.3",
|
|
||||||
"react-router": "latest",
|
"react-router": "latest",
|
||||||
"react-router-dom": "^6.2.1",
|
"react-router-dom": "^6.2.1",
|
||||||
"react-select": "^4.3.1",
|
"react-select": "^5.7.0",
|
||||||
"react-syntax-highlighter": "^15.4.5",
|
"react-syntax-highlighter": "^15.4.5",
|
||||||
"react-yandex-metrika": "^2.6.0",
|
"react-yandex-metrika": "^2.6.0",
|
||||||
"redux-devtools-extension": "^2.13.9",
|
"redux-devtools-extension": "^2.13.9",
|
||||||
"resolve": "1.18.1",
|
"resolve": "1.18.1",
|
||||||
"resolve-url-loader": "^3.1.2",
|
"resolve-url-loader": "^3.1.2",
|
||||||
"semver": "7.3.2",
|
"semver": "7.3.2",
|
||||||
"sweetalert2-react": "^0.8.3"
|
"sweetalert2": "^11.4.8"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.20.12",
|
"@babel/core": "^7.20.12",
|
||||||
"@babel/preset-env": "^7.20.2",
|
"@babel/preset-env": "^7.20.2",
|
||||||
|
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.10",
|
||||||
"babel-loader": "^9.1.2",
|
"babel-loader": "^9.1.2",
|
||||||
"copy-webpack-plugin": "^10.2.0",
|
"copy-webpack-plugin": "^10.2.0",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"css-loader": "^6.7.3",
|
"css-loader": "6.7.3",
|
||||||
"dotenv-webpack": "^7.0.3",
|
"dotenv-webpack": "^7.0.3",
|
||||||
"html-webpack-plugin": "latest",
|
"html-webpack-plugin": "5.5.0",
|
||||||
"mini-css-extract-plugin": "^2.7.2",
|
"mini-css-extract-plugin": "^2.7.2",
|
||||||
"node-sass": "^6.0.1",
|
"node-sass": "8.0.0",
|
||||||
"postcss": "^8.4.21",
|
"postcss": "^8.4.21",
|
||||||
"postcss-loader": "^6.2.1",
|
"postcss-loader": "^6.2.1",
|
||||||
"postcss-preset-env": "^7.8.3",
|
"postcss-preset-env": "^7.8.3",
|
||||||
"react-hot-loader": "^4.13.0",
|
"react-refresh": "^0.14.0",
|
||||||
"react-scripts": "5.0.1",
|
"react-scripts": "^5.0.1",
|
||||||
"sass": "^1.57.1",
|
"sass": "^1.58.0",
|
||||||
"sass-loader": "^12.6.0",
|
"sass-loader": "^13.2.0",
|
||||||
|
"sweetalert2-react-content": "^5.0.7",
|
||||||
"universal-cookie": "^4.0.4",
|
"universal-cookie": "^4.0.4",
|
||||||
"web-vitals": "^3.1.1",
|
"web-vitals": "^3.1.1",
|
||||||
"webpack": "latest",
|
"webpack": "5.75.0",
|
||||||
"webpack-bundle-analyzer": "latest",
|
"webpack-bundle-analyzer": "4.7.0",
|
||||||
"webpack-cli": "latest",
|
"webpack-cli": "^5.0.1",
|
||||||
"webpack-dev-server": "latest",
|
"webpack-dev-server": "4.11.1",
|
||||||
"webpack-merge": "latest"
|
"webpack-merge": "5.8.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "cross-env SERVE=true webpack -c config/webpack/prod.js",
|
"build": "cross-env SERVE=true webpack -c config/webpack/prod.js",
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
import React, {useEffect, useState} from 'react'
|
import React, {useEffect, useRef, useState} from 'react'
|
||||||
import {Link, useNavigate} from 'react-router-dom'
|
import {Link, useNavigate} from 'react-router-dom'
|
||||||
import {useDispatch, useSelector} from 'react-redux'
|
import {useDispatch, useSelector} from 'react-redux'
|
||||||
import {withSwalInstance} from 'sweetalert2-react'
|
|
||||||
import swal from 'sweetalert2'
|
|
||||||
|
|
||||||
import {Loader} from '../Loader/Loader'
|
import {Loader} from '../Loader/Loader'
|
||||||
import ErrorBoundary from "../../hoc/ErrorBoundary";
|
import ErrorBoundary from "../../hoc/ErrorBoundary";
|
||||||
@ -10,7 +8,6 @@ import ErrorBoundary from "../../hoc/ErrorBoundary";
|
|||||||
import {auth, selectAuth, setUserInfo} from '../../redux/outstaffingSlice'
|
import {auth, selectAuth, setUserInfo} from '../../redux/outstaffingSlice'
|
||||||
import {loading} from '../../redux/loaderSlice'
|
import {loading} from '../../redux/loaderSlice'
|
||||||
import {setRole} from '../../redux/roleSlice'
|
import {setRole} from '../../redux/roleSlice'
|
||||||
|
|
||||||
import {selectIsLoading} from '../../redux/loaderSlice'
|
import {selectIsLoading} from '../../redux/loaderSlice'
|
||||||
|
|
||||||
import {apiRequest} from "../../api/request";
|
import {apiRequest} from "../../api/request";
|
||||||
@ -19,12 +16,14 @@ import ellipse from '../../images/ellipse.png'
|
|||||||
|
|
||||||
import './authBox.scss'
|
import './authBox.scss'
|
||||||
|
|
||||||
const {useRef} = require("react");
|
import Swal from 'sweetalert2'
|
||||||
|
import withReactContent from 'sweetalert2-react-content'
|
||||||
|
|
||||||
|
const SweetAlert = withReactContent(Swal);
|
||||||
|
|
||||||
const SweetAlert = withSwalInstance(swal);
|
|
||||||
|
|
||||||
export const AuthBox = ({title, altTitle, roleChangeLink}) => {
|
export const AuthBox = ({title, altTitle, roleChangeLink}) => {
|
||||||
|
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const ref = useRef();
|
const ref = useRef();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@ -34,19 +33,32 @@ export const AuthBox = ({title, altTitle, roleChangeLink}) => {
|
|||||||
|
|
||||||
const [error, setError] = useState(null);
|
const [error, setError] = useState(null);
|
||||||
|
|
||||||
if (isAuth) {
|
const handleModalError = (error) => {
|
||||||
navigate('/')
|
SweetAlert.fire({
|
||||||
}
|
title: 'Ошибка',
|
||||||
|
text: error
|
||||||
|
});
|
||||||
|
|
||||||
useEffect(()=> {
|
setError(null)
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
if (!localStorage.getItem('auth_token')) {
|
if (!localStorage.getItem('auth_token')) {
|
||||||
dispatch(auth(false))
|
dispatch(auth(false))
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isAuth) {
|
||||||
|
navigate('/')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
const submitHandler = () => {
|
const submitHandler = () => {
|
||||||
|
|
||||||
let formData = new FormData(ref.current)
|
let formData = new FormData(ref.current);
|
||||||
if (!isLoading) {
|
if (!isLoading) {
|
||||||
dispatch(loading(true));
|
dispatch(loading(true));
|
||||||
apiRequest('/user/login',
|
apiRequest('/user/login',
|
||||||
@ -107,12 +119,17 @@ export const AuthBox = ({title, altTitle, roleChangeLink}) => {
|
|||||||
{error && (
|
{error && (
|
||||||
<div className='auth-box__form-error'>
|
<div className='auth-box__form-error'>
|
||||||
<ErrorBoundary>
|
<ErrorBoundary>
|
||||||
<SweetAlert
|
|
||||||
show={!!error}
|
|
||||||
title='Ошибка'
|
{
|
||||||
text={error}
|
handleModalError(error)
|
||||||
onConfirm={() => setError(null)}
|
}
|
||||||
/>
|
{/*<SweetAlert*/}
|
||||||
|
{/* show={!!error}*/}
|
||||||
|
{/* title='Ошибка'*/}
|
||||||
|
{/* text={error}*/}
|
||||||
|
{/* onConfirm={() => setError(null)}*/}
|
||||||
|
{/*/>*/}
|
||||||
</ErrorBoundary>
|
</ErrorBoundary>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -1,22 +1,23 @@
|
|||||||
import React, { useState } from 'react'
|
import React, {useEffect, useState} from 'react'
|
||||||
import {useParams, useNavigate} from 'react-router-dom'
|
import {useParams, useNavigate} from 'react-router-dom'
|
||||||
import { Loader } from '../Loader/Loader'
|
import {Loader} from '../Loader/Loader'
|
||||||
import PhoneInput from 'react-phone-input-2'
|
import PhoneInput from 'react-phone-input-2'
|
||||||
import 'react-phone-input-2/lib/style.css'
|
import 'react-phone-input-2/lib/style.css'
|
||||||
import './form.scss'
|
import './form.scss'
|
||||||
|
|
||||||
import { withSwalInstance } from 'sweetalert2-react'
|
|
||||||
import swal from 'sweetalert2'
|
|
||||||
import {apiRequest} from "../../api/request";
|
import {apiRequest} from "../../api/request";
|
||||||
|
|
||||||
|
import Swal from 'sweetalert2'
|
||||||
|
import withReactContent from 'sweetalert2-react-content'
|
||||||
|
|
||||||
const SweetAlert = withSwalInstance(swal);
|
const SweetAlert = withReactContent(Swal);
|
||||||
|
|
||||||
const Form = () => {
|
const Form = () => {
|
||||||
|
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const urlParams = useParams();
|
const urlParams = useParams();
|
||||||
|
|
||||||
const [status, setStatus] = useState(null);
|
const [status, setStatus] = useState(null);
|
||||||
const [data, setData] = useState({
|
const [data, setData] = useState({
|
||||||
email: '',
|
email: '',
|
||||||
@ -25,9 +26,29 @@ const Form = () => {
|
|||||||
});
|
});
|
||||||
const [isFetching, setIsFetching] = useState(false);
|
const [isFetching, setIsFetching] = useState(false);
|
||||||
|
|
||||||
|
const handleModal = (status) => {
|
||||||
|
SweetAlert.fire({
|
||||||
|
text: status !== 200 || 201
|
||||||
|
? 'Какие-то неполадки =('
|
||||||
|
: 'Форма отправлена',
|
||||||
|
preConfirm: () =>
|
||||||
|
status !== 200 || 201 ? () => {
|
||||||
|
setStatus(null)
|
||||||
|
} : () => {
|
||||||
|
setStatus(null);
|
||||||
|
navigate(`/candidate/${urlParams.id}`)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (status) {
|
||||||
|
handleModal(status)
|
||||||
|
}
|
||||||
|
}, [status]);
|
||||||
|
|
||||||
const handleChange = (e) => {
|
const handleChange = (e) => {
|
||||||
const { id, value } = e.target;
|
const {id, value} = e.target;
|
||||||
|
|
||||||
setData((prev) => ({
|
setData((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
@ -41,11 +62,11 @@ const Form = () => {
|
|||||||
setIsFetching(true);
|
setIsFetching(true);
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('profile_id', urlParams.id);
|
formData.append('profile_id', urlParams.id);
|
||||||
formData.append('email', data.email);
|
formData.append('Email', data.email);
|
||||||
formData.append('phone', data.phone);
|
formData.append('phone', data.phone);
|
||||||
formData.append('comment', data.comment);
|
formData.append('comment', data.comment);
|
||||||
|
|
||||||
apiRequest('/interview-request/create-interview-request',{
|
apiRequest('/interview-request/create-interview-request', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
params: {
|
params: {
|
||||||
profile_id: urlParams.id,
|
profile_id: urlParams.id,
|
||||||
@ -59,49 +80,28 @@ const Form = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
|
||||||
{status && (
|
|
||||||
<SweetAlert
|
|
||||||
show={!!status}
|
|
||||||
text={
|
|
||||||
status.errors
|
|
||||||
? status.errors[Object.keys(status.errors)[0]]
|
|
||||||
: 'Форма отправлена'
|
|
||||||
}
|
|
||||||
onConfirm={
|
|
||||||
status.errors
|
|
||||||
? () => {
|
|
||||||
setStatus(null)
|
|
||||||
}
|
|
||||||
: () => {
|
|
||||||
setStatus(null);
|
|
||||||
navigate(`/candidate/${urlParams.id}`)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
<div className='row'>
|
<div className='row'>
|
||||||
<div className='col-sm-12'>
|
<div className='col-sm-12'>
|
||||||
<form className='form' id='test'>
|
<form className='form' id='test'>
|
||||||
<label htmlFor='email'>Емейл:</label>
|
<label htmlFor='email'>Емейл:</label>
|
||||||
<input
|
<input
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
id='email'
|
id='email'
|
||||||
name='Email'
|
name='Email'
|
||||||
type='email'
|
type='email'
|
||||||
placeholder='Емейл'
|
placeholder='Емейл'
|
||||||
value={data.email}
|
value={data.email}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<label htmlFor='phone'>Номер телефона:</label>
|
<label htmlFor='phone'>Номер телефона:</label>
|
||||||
<PhoneInput
|
<PhoneInput
|
||||||
id='phone'
|
id='phone'
|
||||||
name='Phone'
|
name='Phone'
|
||||||
country={'ru'}
|
country={'ru'}
|
||||||
value={data.phone}
|
value={data.phone}
|
||||||
onChange={(e) =>
|
onChange={(e) =>
|
||||||
handleChange({ target: { value: e, id: 'phone' } })
|
handleChange({target: {value: e, id: 'phone'}})
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
{/* <input
|
{/* <input
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
@ -113,22 +113,21 @@ const Form = () => {
|
|||||||
/> */}
|
/> */}
|
||||||
|
|
||||||
<textarea
|
<textarea
|
||||||
onChange={handleChange}
|
onChange={handleChange}
|
||||||
id='comment'
|
id='comment'
|
||||||
rows='5'
|
rows='5'
|
||||||
cols='40'
|
cols='40'
|
||||||
name='Comment'
|
name='Comment'
|
||||||
placeholder='Оставьте комментарий'
|
placeholder='Оставьте комментарий'
|
||||||
value={data.comment}
|
value={data.comment}
|
||||||
></textarea>
|
></textarea>
|
||||||
|
|
||||||
<button onClick={handleSubmit} className='form__btn' type='submit'>
|
<button onClick={handleSubmit} className='form__btn' type='submit'>
|
||||||
{isFetching ? <Loader /> : 'Отправить'}
|
{isFetching ? <Loader/> : 'Отправить'}
|
||||||
</button>
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ import {Link} from 'react-router-dom'
|
|||||||
import './quiz.scss'
|
import './quiz.scss'
|
||||||
import {useSelector} from "react-redux";
|
import {useSelector} from "react-redux";
|
||||||
import {selectedTest, selectUserInfo} from "../../../redux/quizSlice";
|
import {selectedTest, selectUserInfo} from "../../../redux/quizSlice";
|
||||||
|
import {urlForLocal} from "../../../helper";
|
||||||
|
|
||||||
|
|
||||||
export const HeaderPageTestsQuiz = ({isVisibilityButton}) => {
|
export const HeaderPageTestsQuiz = ({isVisibilityButton}) => {
|
||||||
@ -14,7 +15,7 @@ export const HeaderPageTestsQuiz = ({isVisibilityButton}) => {
|
|||||||
<div className="header-quiz__container">
|
<div className="header-quiz__container">
|
||||||
<div className="header-quiz__body">
|
<div className="header-quiz__body">
|
||||||
<div className="header-quiz__avatar">
|
<div className="header-quiz__avatar">
|
||||||
{userInfo.photo && <img src={userInfo.photo} alt={userInfo.photo}/>}
|
{userInfo.photo && <img src={urlForLocal(userInfo.photo)} alt={userInfo.photo}/>}
|
||||||
</div>
|
</div>
|
||||||
<div className="header-quiz__description">
|
<div className="header-quiz__description">
|
||||||
<div className="header-quiz__title-test title">{test.questionnaire_title}</div>
|
<div className="header-quiz__title-test title">{test.questionnaire_title}</div>
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import React, {useEffect} from 'react'
|
import React, {useEffect} from 'react'
|
||||||
import {useDispatch, useSelector} from 'react-redux'
|
import {useDispatch, useSelector} from 'react-redux'
|
||||||
import {selectUserInfo, setQuestionnairesList, setUserInfo} from "../../../redux/quizSlice";
|
import {selectUserInfo, setQuestionnairesList, setUserInfo} from "../../../redux/quizSlice";
|
||||||
import './quiz.scss'
|
|
||||||
import {apiRequest} from "../../../api/request";
|
import {apiRequest} from "../../../api/request";
|
||||||
|
import {urlForLocal} from "../../../helper";
|
||||||
|
import './quiz.scss'
|
||||||
|
|
||||||
export const HeaderQuiz = ({header}) => {
|
export const HeaderQuiz = ({header}) => {
|
||||||
|
|
||||||
@ -13,12 +14,12 @@ export const HeaderQuiz = ({header}) => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
dispatch(setUserInfo(userId))
|
dispatch(setUserInfo(userId))
|
||||||
}, [dispatch]);
|
}, [userId, dispatch]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
apiRequest(`/user-questionnaire/questionnaires-list?user_id=${userId}`)
|
apiRequest(`/user-questionnaire/questionnaires-list?user_id=${userId}`)
|
||||||
.then(res => dispatch(setQuestionnairesList(res)))
|
.then(res => dispatch(setQuestionnairesList(res)))
|
||||||
}, [dispatch]);
|
}, [userId, dispatch]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@ -30,7 +31,7 @@ export const HeaderQuiz = ({header}) => {
|
|||||||
{header && <h2 className={'header-quiz__title-main'}>Добрый день, {userInfo.fio}</h2>}
|
{header && <h2 className={'header-quiz__title-main'}>Добрый день, {userInfo.fio}</h2>}
|
||||||
<div className="header-quiz__body header-quiz__body_interjacent">
|
<div className="header-quiz__body header-quiz__body_interjacent">
|
||||||
<div className="header-quiz__avatar">
|
<div className="header-quiz__avatar">
|
||||||
<img src={userInfo.photo} alt={userInfo.photo}/>
|
<img src={urlForLocal(userInfo.photo)} alt={userInfo.photo}/>
|
||||||
</div>
|
</div>
|
||||||
<div className="header-quiz__name-user">{userInfo.fio}</div>
|
<div className="header-quiz__name-user">{userInfo.fio}</div>
|
||||||
<div className="header-quiz__title">{userInfo.position_name}</div>
|
<div className="header-quiz__title">{userInfo.position_name}</div>
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import {Link} from 'react-router-dom'
|
import {Link} from 'react-router-dom'
|
||||||
import calendarImage from './../../../images/calendar.svg'
|
import calendarImage from './../../../images/calendar.svg'
|
||||||
import './quiz.scss'
|
|
||||||
import {useDispatch} from "react-redux";
|
import {useDispatch} from "react-redux";
|
||||||
import {setSelectedTest} from "../../../redux/quizSlice";
|
import {setSelectedTest} from "../../../redux/quizSlice";
|
||||||
|
import {urlForLocal} from "../../../helper";
|
||||||
|
import './quiz.scss'
|
||||||
|
|
||||||
export const MyTestsQuiz = ({listTests}) => {
|
export const MyTestsQuiz = ({listTests}) => {
|
||||||
|
|
||||||
@ -46,7 +47,7 @@ export const MyTestsQuiz = ({listTests}) => {
|
|||||||
</h3>
|
</h3>
|
||||||
<div className="item-test__body test-data">
|
<div className="item-test__body test-data">
|
||||||
<div className="test-data__calendar ">
|
<div className="test-data__calendar ">
|
||||||
<img src={calendarImage} alt=""/>
|
<img src={urlForLocal(calendarImage)} alt=""/>
|
||||||
{item.testing_date}
|
{item.testing_date}
|
||||||
</div>
|
</div>
|
||||||
<div className="test-data__hr"></div>
|
<div className="test-data__hr"></div>
|
||||||
|
@ -1,11 +0,0 @@
|
|||||||
import React from 'react';
|
|
||||||
import { LogoutButton } from '../components/LogoutButton/LogoutButton';
|
|
||||||
|
|
||||||
export const WithLogout = (props) => {
|
|
||||||
return (
|
|
||||||
<div className='container'>
|
|
||||||
{props.children}
|
|
||||||
<LogoutButton />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
};
|
|
18
src/index.js
18
src/index.js
@ -1,14 +1,14 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import ReactDOM from 'react-dom'
|
import ReactDOM from 'react-dom/client'
|
||||||
import { store } from './store/store'
|
import {store} from './store/store'
|
||||||
import { Provider } from 'react-redux'
|
import {Provider} from 'react-redux'
|
||||||
import App from './App'
|
import App from './App'
|
||||||
|
|
||||||
import './index.css'
|
import './index.css'
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.createRoot(document.getElementById("root"))
|
||||||
<Provider store={store}>
|
.render(
|
||||||
<App />
|
<Provider store={store}>
|
||||||
</Provider>,
|
<App/>
|
||||||
document.getElementById('root')
|
</Provider>,
|
||||||
)
|
);
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
import React from 'react'
|
import React, {useEffect} from 'react'
|
||||||
import {useDispatch, useSelector} from 'react-redux'
|
import {useDispatch, useSelector} from 'react-redux'
|
||||||
import {useParams, useNavigate} from 'react-router-dom'
|
import {useParams, useNavigate} from 'react-router-dom'
|
||||||
import SVG from 'react-inlinesvg'
|
import SVG from 'react-inlinesvg'
|
||||||
|
|
||||||
import {WithLogout} from '../../hoc/withLogout'
|
|
||||||
|
|
||||||
import Form from '../../components/Form/Form'
|
import Form from '../../components/Form/Form'
|
||||||
import {Footer} from '../../components/Footer/Footer'
|
import {Footer} from '../../components/Footer/Footer'
|
||||||
|
import {LogoutButton} from "../../components/LogoutButton/LogoutButton";
|
||||||
|
|
||||||
|
|
||||||
import arrow from '../../images/right-arrow.png'
|
import arrow from '../../images/right-arrow.png'
|
||||||
import rectangle from '../../images/rectangle_secondPage.png'
|
import rectangle from '../../images/rectangle_secondPage.png'
|
||||||
@ -16,12 +16,10 @@ import {LEVELS, SKILLS} from '../../constants/constants'
|
|||||||
|
|
||||||
import {currentCandidate, selectCurrentCandidate} from '../../redux/outstaffingSlice'
|
import {currentCandidate, selectCurrentCandidate} from '../../redux/outstaffingSlice'
|
||||||
|
|
||||||
import './formPage.scss'
|
|
||||||
import {apiRequest} from "../../api/request";
|
import {apiRequest} from "../../api/request";
|
||||||
import {LogoutButton} from "../../components/LogoutButton/LogoutButton";
|
import {urlForLocal} from "../../helper";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
import './formPage.scss'
|
||||||
|
|
||||||
const FormPage = () => {
|
const FormPage = () => {
|
||||||
const params = useParams();
|
const params = useParams();
|
||||||
@ -29,23 +27,22 @@ const FormPage = () => {
|
|||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const candidate = useSelector(selectCurrentCandidate);
|
const candidate = useSelector(selectCurrentCandidate);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const goBack = () => {
|
const goBack = () => {
|
||||||
navigate(-1)
|
navigate(-1)
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!candidate.id) {
|
useEffect(()=> {
|
||||||
apiRequest('/profile', {
|
if (!candidate.id) {
|
||||||
params: Number(params.id)
|
apiRequest('/profile', {
|
||||||
})
|
params: Number(params.id)
|
||||||
.then((el) => dispatch(currentCandidate(el)))
|
})
|
||||||
}
|
.then((el) => dispatch(currentCandidate(el)))
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='container'>
|
<div className='container'>
|
||||||
|
|
||||||
|
|
||||||
<div className='form-page'>
|
<div className='form-page'>
|
||||||
<div className='form-page__back'>
|
<div className='form-page__back'>
|
||||||
<div className='form-page__arrow' onClick={goBack}>
|
<div className='form-page__arrow' onClick={goBack}>
|
||||||
@ -60,7 +57,7 @@ const FormPage = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className='form-page__candidate'>
|
<div className='form-page__candidate'>
|
||||||
<div className='form-page__avatar'>
|
<div className='form-page__avatar'>
|
||||||
<img src={candidate.photo} alt='candidate avatar'/>
|
{candidate.photo && <img src={urlForLocal(candidate.photo)} alt='candidate avatar'/>}
|
||||||
</div>
|
</div>
|
||||||
<div className='form-page__candidate-info'>
|
<div className='form-page__candidate-info'>
|
||||||
<div className='form-page__position'>
|
<div className='form-page__position'>
|
||||||
|
@ -3,15 +3,18 @@ import {HeaderPageTestsQuiz} from '../../components/features/quiz/HeaderPageTest
|
|||||||
import {TaskQuiz} from '../../components/features/quiz/Task'
|
import {TaskQuiz} from '../../components/features/quiz/Task'
|
||||||
import {useSelector} from "react-redux";
|
import {useSelector} from "react-redux";
|
||||||
import {selectedTest} from "../../redux/quizSlice";
|
import {selectedTest} from "../../redux/quizSlice";
|
||||||
import React from "react";
|
import React, {useEffect} from "react";
|
||||||
|
|
||||||
export const QuizTestPage = () => {
|
export const QuizTestPage = () => {
|
||||||
let navigate = useNavigate()
|
let navigate = useNavigate();
|
||||||
const test = useSelector(selectedTest)
|
const test = useSelector(selectedTest);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!test) {
|
||||||
|
navigate('/quiz')
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
if (!test) {
|
|
||||||
navigate('/quiz')
|
|
||||||
}
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<HeaderPageTestsQuiz isVisibilityButton={false}/>
|
<HeaderPageTestsQuiz isVisibilityButton={false}/>
|
||||||
|
@ -1,111 +1,71 @@
|
|||||||
import {createAsyncThunk, createSlice} from '@reduxjs/toolkit';
|
import {createAsyncThunk, createSlice} from '@reduxjs/toolkit';
|
||||||
import {fetchGet} from './../server/server'
|
|
||||||
import axios from "axios";
|
import {apiRequest} from "../api/request";
|
||||||
|
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
// questions: [],
|
// questions: [],
|
||||||
answer: [],
|
answer: [],
|
||||||
result: null,
|
result: null,
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
dataQuestionnairesOfUser: [],
|
dataQuestionnairesOfUser: [],
|
||||||
passedTests: [],
|
passedTests: [],
|
||||||
selectedTest: null,
|
selectedTest: null,
|
||||||
userInfo: null
|
userInfo: null
|
||||||
};
|
};
|
||||||
export const setUserInfo = createAsyncThunk(
|
export const setUserInfo = createAsyncThunk(
|
||||||
'userInfo',
|
'userInfo',
|
||||||
async (id) => {
|
(id) =>
|
||||||
try{
|
apiRequest(`/profile/get-main-data?user_id=${id}`)
|
||||||
return await fetchGet({
|
|
||||||
link: `${process.env.REACT_APP_API_URL}/api/profile/get-main-data?user_id=${id}`,
|
|
||||||
Origin: `${process.env.REACT_APP_BASE_URL}`,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}catch (e) {
|
|
||||||
console.log(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
export const fetchUserAnswersMany = createAsyncThunk(
|
export const fetchUserAnswersMany = createAsyncThunk(
|
||||||
'answersUserMany',
|
'answersUserMany',
|
||||||
async (checkedValues) => {
|
(checkedValues) =>
|
||||||
try{
|
apiRequest('/user-response/set-responses', {method: 'POST', data: {"userResponses": checkedValues}})
|
||||||
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(
|
export const fetchUserAnswerOne = createAsyncThunk(
|
||||||
'answersUserOne',
|
'answersUserOne',
|
||||||
async (checkedValues) => {
|
(checkedValues) =>
|
||||||
try{
|
apiRequest('/user-response/set-response', {method: 'POST', data: checkedValues[0]})
|
||||||
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(
|
export const fetchGetAnswers = createAsyncThunk(
|
||||||
'answers',
|
'answers',
|
||||||
async (question_id) => {
|
(question_id) =>
|
||||||
return await fetchGet({
|
apiRequest(`/answer/get-answers?question_id=${question_id}`)
|
||||||
link: `${process.env.REACT_APP_API_URL}/api/answer/get-answers?question_id=${question_id}`,
|
|
||||||
Origin: `${process.env.REACT_APP_BASE_URL}`,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
export const fetchResultTest = createAsyncThunk(
|
export const fetchResultTest = createAsyncThunk(
|
||||||
'result',
|
'result',
|
||||||
async (uuid) => {
|
(uuid) =>
|
||||||
return await fetchGet({
|
apiRequest(`/user-questionnaire/questionnaire-completed?user_questionnaire_uuid=${uuid}`)
|
||||||
link: `${process.env.REACT_APP_API_URL}/api/user-questionnaire/questionnaire-completed?user_questionnaire_uuid=${uuid}`,
|
|
||||||
Origin: `${process.env.REACT_APP_BASE_URL}`,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
export const quizSlice = createSlice({
|
export const quizSlice = createSlice({
|
||||||
name: 'quiz',
|
name: 'quiz',
|
||||||
initialState,
|
initialState,
|
||||||
reducers: {
|
reducers: {
|
||||||
setQuestionnairesList: (state, action) => {
|
setQuestionnairesList: (state, action) => {
|
||||||
state.dataQuestionnairesOfUser = action.payload;
|
state.dataQuestionnairesOfUser = action.payload;
|
||||||
state.passedTests = action.payload.filter(item => item.status === 2)
|
state.passedTests = action.payload.filter(item => item.status === 2)
|
||||||
},
|
},
|
||||||
setSelectedTest: (state, action) => {
|
setSelectedTest: (state, action) => {
|
||||||
state.selectedTest = action.payload
|
state.selectedTest = action.payload
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
extraReducers: {
|
extraReducers: {
|
||||||
[setUserInfo.fulfilled]: (state, action) => {
|
[setUserInfo.fulfilled]: (state, action) => {
|
||||||
state.userInfo = action.payload;
|
state.userInfo = action.payload;
|
||||||
},
|
},
|
||||||
[fetchGetAnswers.fulfilled]: (state, action) => {
|
[fetchGetAnswers.fulfilled]: (state, action) => {
|
||||||
state.answer = action.payload;
|
state.answer = action.payload;
|
||||||
},
|
},
|
||||||
[fetchResultTest.fulfilled]: (state, action) => {
|
[fetchResultTest.fulfilled]: (state, action) => {
|
||||||
state.result = action.payload;
|
state.result = action.payload;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export const {setQuestionnairesList, setSelectedTest} = quizSlice.actions;
|
export const {setQuestionnairesList, setSelectedTest} = quizSlice.actions;
|
||||||
|
@ -1,22 +0,0 @@
|
|||||||
export const withAuthRedirect =
|
|
||||||
(actionCall) =>
|
|
||||||
({ link, params, history, role, logout, body }) => {
|
|
||||||
// const linkWithParams = params
|
|
||||||
// ? `${link}?${new URLSearchParams(params)}`
|
|
||||||
// : link;
|
|
||||||
// return actionCall(linkWithParams, body)
|
|
||||||
// .then((res) => {
|
|
||||||
// if (res.status && res.status === 401) {
|
|
||||||
// localStorage.clear();
|
|
||||||
// logout && logout();
|
|
||||||
// history.push(role === 'ROLE_DEV' ? '/authdev' : '/auth')
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return res
|
|
||||||
// })
|
|
||||||
// .catch((err) => {
|
|
||||||
// localStorage.clear();
|
|
||||||
// logout && logout();
|
|
||||||
// history.push(role === 'ROLE_DEV' ? '/authdev' : '/auth')
|
|
||||||
// })
|
|
||||||
};
|
|
@ -1,18 +0,0 @@
|
|||||||
import { withAuthRedirect } from './authRedirect'
|
|
||||||
|
|
||||||
|
|
||||||
export const fetchGet = withAuthRedirect(async (link) => {
|
|
||||||
try {
|
|
||||||
const response = await fetch(link, {
|
|
||||||
method: 'GET',
|
|
||||||
headers: {
|
|
||||||
Authorization: `Bearer ${localStorage.getItem('auth_token')}`
|
|
||||||
}
|
|
||||||
});
|
|
||||||
let data = await response.json();
|
|
||||||
|
|
||||||
return data
|
|
||||||
} catch (error) {
|
|
||||||
console.log('Query error', error)
|
|
||||||
}
|
|
||||||
});
|
|
Loading…
Reference in New Issue
Block a user