Переписываю спорные решения
This commit is contained in:
@ -1,94 +0,0 @@
|
||||
import React from 'react'
|
||||
|
||||
import { AuthBox } from '../AuthBox/AuthBox'
|
||||
|
||||
import { useSelector } from 'react-redux'
|
||||
import arrow from '../../images/arrow__login_page.png'
|
||||
import authImg from '../../images/auth_img.png'
|
||||
import cross from '../../images/cross.png'
|
||||
import text from '../../images/Body_Text.png'
|
||||
import vector from '../../images/Vector_Smart_Object.png'
|
||||
|
||||
import { selectAuth } from '../../redux/outstaffingSlice'
|
||||
import { Redirect } from 'react-router-dom'
|
||||
import { Footer } from '../Footer/Footer'
|
||||
|
||||
import './authForDevelopers.scss'
|
||||
|
||||
const AuthForDevelopers = () => {
|
||||
const isAuth = useSelector(selectAuth)
|
||||
|
||||
if (isAuth) {
|
||||
return <Redirect to='/profile' />
|
||||
}
|
||||
|
||||
return (
|
||||
<section className='auth-developers'>
|
||||
<div className='auth-developers__background'>
|
||||
<img className='auth-developers__vector' src={vector} alt='' />
|
||||
<img
|
||||
className='auth-developers__vector-black'
|
||||
src={'./images/Vector_Smart_Object_black.png'}
|
||||
alt=''
|
||||
/>
|
||||
<div className='container'>
|
||||
<div className='row'>
|
||||
<div className='col-12 col-xl-6'>
|
||||
<div className='auth-developers__box'>
|
||||
<AuthBox
|
||||
title='Для разработчиков'
|
||||
altTitle='Для партнёров'
|
||||
roleChangeLink='/auth'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className='col-xl-2'>
|
||||
<img className='auth-developers__arrow' src={arrow} alt='' />
|
||||
</div>
|
||||
<div className='col-12 col-xl-4'>
|
||||
<div className='auth-developers__info'>
|
||||
<div className='auth-developers__info-box'>
|
||||
<img src={authImg} alt='' />
|
||||
<h3>
|
||||
Управление
|
||||
<br /> командой
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
<div className='auth-developers__info-container'>
|
||||
<div className='auth-developers__info-img'>
|
||||
<div>
|
||||
<img className='cross' src={cross} alt='' />
|
||||
</div>
|
||||
<div>
|
||||
{/* <img className='auth-specialists} src={specialists} alt="" /> */}
|
||||
<p className='auth-developers__specialists'>
|
||||
20 Специалистов
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul className='auth-developers__info-list'>
|
||||
<li className='auth-developers__info-item'>
|
||||
Рабочее
|
||||
<br />
|
||||
пространство
|
||||
</li>
|
||||
<li className='auth-info__list-item'>
|
||||
Управление задачами
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<img className='auth-developers__img-text' src={text} alt='' />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
export default AuthForDevelopers
|
@ -1,86 +0,0 @@
|
||||
import React from 'react'
|
||||
import arrow from '../../images/arrow__login_page.png'
|
||||
import medium from '../../images/medium_male_big.png'
|
||||
import cross from '../../images/cross.png'
|
||||
import text from '../../images/Body_Text.png'
|
||||
import vector from '../../images/Vector_Smart_Object.png'
|
||||
import vectorBlack from '../../images/Vector_Smart_Object_black.png'
|
||||
import { useSelector } from 'react-redux'
|
||||
import { selectAuth } from '../../redux/outstaffingSlice'
|
||||
import { Redirect } from 'react-router-dom'
|
||||
|
||||
import { Footer } from '../Footer/Footer'
|
||||
import { AuthBox } from '../AuthBox/AuthBox'
|
||||
|
||||
import './authForPartners.scss'
|
||||
|
||||
const AuthForPartners = () => {
|
||||
const isAuth = useSelector(selectAuth)
|
||||
|
||||
if (isAuth) {
|
||||
return <Redirect to='/' />
|
||||
}
|
||||
|
||||
return (
|
||||
<section className='auth-partners'>
|
||||
<div className='auth-partners__background'>
|
||||
<img className='auth-partners__vector' src={vector} alt='' />
|
||||
<img className='auth-partners__vector-black' src={vectorBlack} alt='' />
|
||||
<div className='container'>
|
||||
<div className='row'>
|
||||
<div className='col-12 col-xl-6'>
|
||||
<div className='auth-partners__box'>
|
||||
<AuthBox
|
||||
title='Для партнёров'
|
||||
altTitle='Для разработчиков'
|
||||
roleChangeLink='/authdev'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className='col-xl-2'>
|
||||
<img className='auth-partners__arrow' src={arrow} alt='' />
|
||||
</div>
|
||||
<div className='col-12 col-xl-4'>
|
||||
<div className='auth-partners__info'>
|
||||
<div className='auth-partners__info-box'>
|
||||
<img src={medium} alt='' />
|
||||
<h3>
|
||||
Frontend разработчик,
|
||||
<br /> Middle
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
<div className='auth-partners__info-container'>
|
||||
<div className='auth-partners__info-img'>
|
||||
<div>
|
||||
<img className='cross' src={cross} alt='' />
|
||||
</div>
|
||||
<div>
|
||||
{/* <img className='auth-specialists} src={specialists} alt="" /> */}
|
||||
<p className='auth-partners__specialists'>
|
||||
20 Специалистов
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<ul className='auth-partners__info-list'>
|
||||
<li className='auth-partners__info-item'>Ruby on Rails</li>
|
||||
<li className='auth-partners__info-item'>PHP</li>
|
||||
<li className='auth-partners__info-item'>Python</li>
|
||||
<li className='auth-partners__info-item'>Vue.js</li>
|
||||
<li className='auth-partners__info-item'>React. JS</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<img className='auth-partners__img-text' src={text} alt='' />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Footer />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
export default AuthForPartners
|
@ -1,207 +0,0 @@
|
||||
.auth-developers {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.auth-developers__background {
|
||||
background-color: #f1f1f1;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.auth-developers__vector,
|
||||
.auth-developers__vector-black {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.auth-developers__vector {
|
||||
top: -720px;
|
||||
left: -320px;
|
||||
}
|
||||
|
||||
.auth-developers__vector-black {
|
||||
top: 460px;
|
||||
right: -224px;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.auth-developers__vector,
|
||||
.auth-developers__vector-black {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* .form__error {
|
||||
font-size: 16px;
|
||||
color: #b21;
|
||||
margin-left: 45px;
|
||||
} */
|
||||
|
||||
.auth-developers__arrow {
|
||||
margin-top: 360px;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.auth-developers__arrow {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.auth-developers__info {
|
||||
background-color: #e1fccf;
|
||||
margin-top: 70px;
|
||||
max-width: 310px;
|
||||
padding-top: 30px;
|
||||
position: relative;
|
||||
padding-bottom: 310px;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.auth-developers__info {
|
||||
max-width: 380px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 375.98px) {
|
||||
.auth-developers__info {
|
||||
max-width: 340px;
|
||||
}
|
||||
}
|
||||
|
||||
.auth-developers__info-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.auth-developers__info-box {
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.auth-developers__info-box > img {
|
||||
width: 150px;
|
||||
height: 150px;
|
||||
margin-left: -84px;
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.auth-developers__info-box > img {
|
||||
margin-left: 0px;
|
||||
margin-right: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.auth-developers__info-box > h3 {
|
||||
font-family: 'GT Eesti Pro Display';
|
||||
font-size: 2em;
|
||||
font-weight: 100;
|
||||
font-style: normal;
|
||||
letter-spacing: normal;
|
||||
line-height: 36px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.auth-developers__info-box > h3 {
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.auth-developers__info-container {
|
||||
display: flex;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.auth-developers__info-img {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
margin-top: 28px;
|
||||
margin-left: -40px;
|
||||
}
|
||||
|
||||
.auth-developers__info-img > div > img {
|
||||
margin-bottom: 100px;
|
||||
}
|
||||
|
||||
.auth-developers__specialists {
|
||||
font-family: 'GT Eesti Pro Display';
|
||||
font-size: 1.8em;
|
||||
font-weight: 100;
|
||||
font-style: normal;
|
||||
letter-spacing: normal;
|
||||
line-height: 26.12px;
|
||||
text-align: left;
|
||||
transform: rotate(-90deg);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
.auth-developers__info-list {
|
||||
list-style: none;
|
||||
margin-top: 110px;
|
||||
position: absolute;
|
||||
left: 34px;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.auth-developers__info-list {
|
||||
left: 34px;
|
||||
}
|
||||
}
|
||||
|
||||
.auth-developers__info-item {
|
||||
color: #1f1f1f;
|
||||
font-family: 'GT Eesti Pro Display';
|
||||
font-size: 2.6em;
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
letter-spacing: normal;
|
||||
line-height: 56.95px;
|
||||
text-align: left;
|
||||
text-decoration: underline;
|
||||
text-transform: uppercase;
|
||||
margin-bottom: 34px;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.auth-developers__info-item {
|
||||
font-size: 2.6em;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
}
|
||||
|
||||
.auth-developers__img-text {
|
||||
position: absolute;
|
||||
right: -68px;
|
||||
bottom: -84px;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.auth-developers__img-text {
|
||||
right: 0px;
|
||||
bottom: -40px;
|
||||
}
|
||||
}
|
||||
|
||||
.auth-developers__auth-link {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.auth-developers__auth-link a {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@media (max-width: 766px) {
|
||||
.auth-developers__form-buttons {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.auth-developers__form-btn {
|
||||
margin: 0;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
}
|
@ -1,288 +0,0 @@
|
||||
.auth-partners {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.auth-partners__background {
|
||||
background-color: #f1f1f1;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.auth-partners__vector,
|
||||
.auth-partners__vector-black {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.auth-partners__vector {
|
||||
top: -720px;
|
||||
left: -320px;
|
||||
}
|
||||
|
||||
.auth-partners__vector-black {
|
||||
top: 460px;
|
||||
right: -224px;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.auth-partners__vector,
|
||||
.auth-partners__vector-black {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.auth-partners__arrow {
|
||||
margin-top: 360px;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.auth-partners__arrow {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.auth-partners__info {
|
||||
background-color: #e1fccf;
|
||||
margin-top: 70px;
|
||||
max-width: 310px;
|
||||
padding-top: 30px;
|
||||
position: relative;
|
||||
padding-bottom: 310px;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.auth-partners__info {
|
||||
max-width: 380px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 375.98px) {
|
||||
.auth-partners__info {
|
||||
max-width: 340px;
|
||||
}
|
||||
}
|
||||
|
||||
.auth-partners__info-box {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.auth-partners__info-box {
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
||||
.auth-partners__info-box > img {
|
||||
width: 165px;
|
||||
height: 165px;
|
||||
margin-left: -84px;
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.auth-partners__info-box > img {
|
||||
margin-left: 0px;
|
||||
margin-right: 0px;
|
||||
}
|
||||
}
|
||||
|
||||
.auth-partners__info-box > h3 {
|
||||
font-family: 'GT Eesti Pro Display';
|
||||
font-size: 2em;
|
||||
font-weight: 100;
|
||||
font-style: normal;
|
||||
letter-spacing: normal;
|
||||
line-height: 36px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.auth-partners__info-box > h3 {
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.auth-partners__info-container {
|
||||
display: flex;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.auth-partners__info-img {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
margin-top: 28px;
|
||||
margin-left: -40px;
|
||||
}
|
||||
|
||||
.auth-partners__info-img > div > img {
|
||||
margin-bottom: 100px;
|
||||
}
|
||||
|
||||
.auth-partners__specialists {
|
||||
font-family: 'GT Eesti Pro Display';
|
||||
font-size: 1.8em;
|
||||
font-weight: 100;
|
||||
font-style: normal;
|
||||
letter-spacing: normal;
|
||||
line-height: 26.12px;
|
||||
text-align: left;
|
||||
transform: rotate(-90deg);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
/* .specialists {
|
||||
margin-left: 26px;
|
||||
} */
|
||||
|
||||
.auth-partners__info-list {
|
||||
list-style: none;
|
||||
margin-top: 110px;
|
||||
position: absolute;
|
||||
right: -70px;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.auth-partners__info-list {
|
||||
left: 34px;
|
||||
}
|
||||
}
|
||||
|
||||
.auth-partners__info-item {
|
||||
color: #1f1f1f;
|
||||
font-family: 'GT Eesti Pro Display';
|
||||
font-size: 4em;
|
||||
font-weight: 700;
|
||||
font-style: normal;
|
||||
letter-spacing: normal;
|
||||
line-height: 56.95px;
|
||||
text-align: left;
|
||||
text-decoration: underline;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.auth-partners__info-item {
|
||||
font-size: 2.6em;
|
||||
}
|
||||
}
|
||||
|
||||
.auth-partners__img-text {
|
||||
position: absolute;
|
||||
right: -68px;
|
||||
bottom: -84px;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.auth-partners__img-text {
|
||||
right: 0px;
|
||||
bottom: -40px;
|
||||
}
|
||||
}
|
||||
|
||||
.auth-partners__footer--left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 60px;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.auth-partners__footer--left {
|
||||
margin-top: 120px;
|
||||
}
|
||||
}
|
||||
|
||||
.auth-partners__footer__sp {
|
||||
padding: 0 100px 0 34px;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.auth-partners__footer__sp {
|
||||
padding: 0;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.auth-partners__footer--left > div > span {
|
||||
color: #18586e;
|
||||
font-family: 'GT Eesti Pro Display';
|
||||
font-size: 1.6em;
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
letter-spacing: normal;
|
||||
line-height: 16.81px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.auth-partners__footer--left > div > span {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
}
|
||||
|
||||
.auth-partners__footer-icon {
|
||||
text-align: end;
|
||||
}
|
||||
|
||||
.auth-partners__footer-icon > img {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.auth-partners__footer-icon > img {
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.auth-partners__footer--right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: left;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.auth-partners__footer--right {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
}
|
||||
.auth-partners__phone {
|
||||
color: #003b65;
|
||||
font-family: 'CeraPro';
|
||||
font-size: 2.1em;
|
||||
letter-spacing: normal;
|
||||
line-height: 25px;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.auth-partners__working-hours {
|
||||
color: #003b65;
|
||||
font-family: 'CeraPro';
|
||||
font-size: 1.2em;
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
letter-spacing: normal;
|
||||
line-height: normal;
|
||||
margin-left: 24px;
|
||||
}
|
||||
|
||||
.auth-partners__auth-link {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.auth-partners__auth-link a {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
@media (max-width: 766px) {
|
||||
.auth-partners__form-buttons {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.auth-partners__form-btn {
|
||||
margin: 0;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
}
|
@ -1,107 +1,129 @@
|
||||
import React, { useState } from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import React, {useState} from 'react'
|
||||
import {Link} from 'react-router-dom'
|
||||
import {useDispatch, useSelector} from 'react-redux'
|
||||
import {withSwalInstance} from 'sweetalert2-react'
|
||||
import swal from 'sweetalert2'
|
||||
|
||||
import {Loader} from '../Loader/Loader'
|
||||
|
||||
import {auth, setUserInfo} from '../../redux/outstaffingSlice'
|
||||
import {loading} from '../../redux/loaderSlice'
|
||||
import {setRole} from '../../redux/roleSlice'
|
||||
|
||||
import {selectIsLoading} from '../../redux/loaderSlice'
|
||||
|
||||
import { auth, setUserInfo } from '../../redux/outstaffingSlice'
|
||||
import { loading } from '../../redux/loaderSlice'
|
||||
import ellipse from '../../images/ellipse.png'
|
||||
|
||||
import { Loader } from '../Loader/Loader'
|
||||
|
||||
import { fetchAuth } from '../../server/server'
|
||||
import { setRole } from '../../redux/roleSlice'
|
||||
import { selectIsLoading } from '../../redux/loaderSlice'
|
||||
|
||||
import './authBox.scss'
|
||||
import {useRequest} from "../../hooks/useRequest";
|
||||
|
||||
import { withSwalInstance } from 'sweetalert2-react'
|
||||
import swal from 'sweetalert2'
|
||||
const SweetAlert = withSwalInstance(swal)
|
||||
|
||||
export const AuthBox = ({ title, altTitle, roleChangeLink }) => {
|
||||
const dispatch = useDispatch()
|
||||
const SweetAlert = withSwalInstance(swal);
|
||||
|
||||
const isLoading = useSelector(selectIsLoading)
|
||||
export const AuthBox = ({title, altTitle, roleChangeLink}) => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const [username, setUsername] = useState('')
|
||||
const [password, setPassword] = useState('')
|
||||
const [error, setError] = useState(null)
|
||||
const {apiRequest} = useRequest();
|
||||
|
||||
const isLoading = useSelector(selectIsLoading);
|
||||
|
||||
const [username, setUsername] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [error, setError] = useState(null);
|
||||
|
||||
const submitHandler = () => {
|
||||
|
||||
if (!isLoading) {
|
||||
dispatch(loading(true));
|
||||
apiRequest('/user/login',
|
||||
{
|
||||
method: 'POST',
|
||||
data: JSON.stringify({
|
||||
username,
|
||||
password
|
||||
})
|
||||
}).then((res) => {
|
||||
|
||||
if (!res.access_token) {
|
||||
|
||||
setError('Некорректные данные для входа');
|
||||
dispatch(loading(false))
|
||||
|
||||
} else {
|
||||
|
||||
localStorage.setItem('auth_token', res.access_token);
|
||||
localStorage.setItem('id', res.id);
|
||||
localStorage.setItem('cardId', res.card_id);
|
||||
localStorage.setItem(
|
||||
'access_token_expired_at',
|
||||
res.access_token_expired_at
|
||||
);
|
||||
dispatch(auth(true));
|
||||
dispatch(setUserInfo(res));
|
||||
dispatch(loading(false));
|
||||
dispatch(setRole('ROLE_PARTNER'))
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='auth-box'>
|
||||
<h2 className='auth-box__header'>
|
||||
Войти в <span>систему</span>
|
||||
</h2>
|
||||
<div className='auth-box__title'>
|
||||
<img src={ellipse} alt='' />
|
||||
<span>{title}</span>
|
||||
</div>
|
||||
<form className='auth-box__form'>
|
||||
<label htmlFor='login'>Ваш логин:</label>
|
||||
<input
|
||||
id='login'
|
||||
type='text'
|
||||
placeholder='Логин'
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
/>
|
||||
|
||||
<label htmlFor='password'>Пароль:</label>
|
||||
<input
|
||||
id='password'
|
||||
type='password'
|
||||
placeholder='Пароль'
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
/>
|
||||
|
||||
{error && (
|
||||
<div className='auth-box__form-error'>
|
||||
<SweetAlert
|
||||
show={!!error}
|
||||
title='Ошибка'
|
||||
text={error}
|
||||
onConfirm={() => setError(null)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className='auth-box__form-buttons'>
|
||||
<button
|
||||
className='auth-box__form-btn'
|
||||
onClick={
|
||||
!isLoading
|
||||
? (e) => {
|
||||
e.preventDefault()
|
||||
dispatch(loading(true))
|
||||
fetchAuth({
|
||||
username,
|
||||
password,
|
||||
dispatch: (resJSON) => {
|
||||
dispatch(auth(true))
|
||||
dispatch(setUserInfo(resJSON))
|
||||
dispatch(loading(false))
|
||||
dispatch(setRole('ROLE_PARTNER'))
|
||||
},
|
||||
catchError: () => {
|
||||
setError('Некорректные данные для входа')
|
||||
dispatch(loading(false))
|
||||
}
|
||||
})
|
||||
}
|
||||
: () => {}
|
||||
}
|
||||
>
|
||||
{isLoading ? <Loader /> : 'Войти'}
|
||||
</button>
|
||||
|
||||
<Link to={roleChangeLink}>
|
||||
<button className='auth-box__form-btn--role auth-box__auth-link'>
|
||||
{altTitle}
|
||||
</button>
|
||||
</Link>
|
||||
<div className='auth-box'>
|
||||
<h2 className='auth-box__header'>
|
||||
Войти в <span>систему</span>
|
||||
</h2>
|
||||
<div className='auth-box__title'>
|
||||
<img src={ellipse} alt=''/>
|
||||
<span>{title}</span>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<form className='auth-box__form'>
|
||||
<label htmlFor='login'>Ваш логин:</label>
|
||||
<input
|
||||
id='login'
|
||||
type='text'
|
||||
placeholder='Логин'
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
/>
|
||||
|
||||
<label htmlFor='password'>Пароль:</label>
|
||||
<input
|
||||
id='password'
|
||||
type='password'
|
||||
placeholder='Пароль'
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
/>
|
||||
|
||||
{error && (
|
||||
<div className='auth-box__form-error'>
|
||||
<SweetAlert
|
||||
show={!!error}
|
||||
title='Ошибка'
|
||||
text={error}
|
||||
onConfirm={() => setError(null)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className='auth-box__form-buttons'>
|
||||
<button
|
||||
className='auth-box__form-btn'
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
submitHandler()
|
||||
}}
|
||||
>
|
||||
{isLoading ? <Loader/> : 'Войти'}
|
||||
</button>
|
||||
|
||||
<Link to={roleChangeLink}>
|
||||
<button className='auth-box__form-btn--role auth-box__auth-link'>
|
||||
{altTitle}
|
||||
</button>
|
||||
</Link>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, {useEffect} from 'react'
|
||||
import {useHistory, useParams, Link} from 'react-router-dom'
|
||||
import {useParams, Link, useNavigate} from 'react-router-dom'
|
||||
import {useSelector, useDispatch} from 'react-redux'
|
||||
import {
|
||||
currentCandidate,
|
||||
@ -22,8 +22,8 @@ import {Footer} from '../Footer/Footer'
|
||||
import './candidate.scss'
|
||||
|
||||
const Candidate = () => {
|
||||
const history = useHistory();
|
||||
const {id: candidateId} = useParams();
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
const role = useSelector(getRole);
|
||||
const [activeSnippet, setActiveSnippet] = useState(true);
|
||||
@ -36,7 +36,6 @@ const Candidate = () => {
|
||||
fetchGet({
|
||||
link: `${process.env.REACT_APP_API_URL}/api/profile/${candidateId}`,
|
||||
params: Number(candidateId),
|
||||
history,
|
||||
role,
|
||||
logout: () => dispatch(auth(false))
|
||||
}).then((el) => dispatch(currentCandidate(el)))
|
||||
@ -97,7 +96,7 @@ const Candidate = () => {
|
||||
<div className='row'>
|
||||
<div className='col-12 candidate__header'>
|
||||
|
||||
<div className='candidate__arrow' onClick={() => history.push('/')}>
|
||||
<div className='candidate__arrow' onClick={() => navigate('/')}>
|
||||
<div className='candidate__arrow-img'>
|
||||
<img src={arrow} alt=''/>
|
||||
</div>
|
||||
|
@ -1,43 +1,42 @@
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import male from '../../images/medium_male.png'
|
||||
import rectangle from '../../images/rectangle_secondPage.png'
|
||||
import { Link, useHistory } from 'react-router-dom'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { LEVELS, SKILLS } from '../constants/constants'
|
||||
import {
|
||||
selectProfiles,
|
||||
selectFilteredCandidates,
|
||||
selectItems,
|
||||
auth
|
||||
} from '../../redux/outstaffingSlice'
|
||||
import { useSelector, useDispatch } from 'react-redux'
|
||||
import { fetchGet } from '../../server/server'
|
||||
|
||||
import { Loader } from '../Loader/Loader'
|
||||
import { getRole } from '../../redux/roleSlice'
|
||||
|
||||
import './description.scss'
|
||||
import {useRequest} from "../../hooks/useRequest";
|
||||
|
||||
const Description = ({ onLoadMore, isLoadingMore }) => {
|
||||
const dispatch = useDispatch()
|
||||
const [isLoaded, setIsLoaded] = useState(false)
|
||||
const history = useHistory()
|
||||
const role = useSelector(getRole)
|
||||
const candidatesListArr = useSelector(selectProfiles)
|
||||
const itemsArr = useSelector(selectItems)
|
||||
const filteredListArr = useSelector(selectFilteredCandidates)
|
||||
const [allCandidates, getAllCandidates] = useState([])
|
||||
const dispatch = useDispatch();
|
||||
const {apiRequest} = useRequest();
|
||||
const [isLoaded, setIsLoaded] = useState(false);
|
||||
const role = useSelector(getRole);
|
||||
const candidatesListArr = useSelector(selectProfiles);
|
||||
const itemsArr = useSelector(selectItems);
|
||||
const filteredListArr = useSelector(selectFilteredCandidates);
|
||||
const [allCandidates, getAllCandidates] = useState([]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchGet({
|
||||
link: `${process.env.REACT_APP_API_URL}/api/profile?limit=`,
|
||||
params: 1000,
|
||||
history,
|
||||
role,
|
||||
logout: () => dispatch(auth(false))
|
||||
}).then((p) => {
|
||||
getAllCandidates(p)
|
||||
setIsLoaded(true)
|
||||
})
|
||||
}, [])
|
||||
// useEffect(() => {
|
||||
// apiRequest('/profile?limit=',{
|
||||
// params: 1000,
|
||||
//
|
||||
// role,
|
||||
// logout: () => dispatch(auth(false))
|
||||
// }).then((p) => {
|
||||
// getAllCandidates(p);
|
||||
// setIsLoaded(true)
|
||||
// })
|
||||
// }, []);
|
||||
|
||||
if (!filteredListArr) {
|
||||
return (
|
||||
@ -242,6 +241,6 @@ const Description = ({ onLoadMore, isLoadingMore }) => {
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
export default Description
|
||||
|
@ -1,7 +1,7 @@
|
||||
import React, { useState } from 'react'
|
||||
import { fetchPost } from '../../server/server'
|
||||
import { auth } from '../../redux/outstaffingSlice'
|
||||
import { useHistory, useParams, Redirect } from 'react-router-dom'
|
||||
import {useParams, useNavigate} from 'react-router-dom'
|
||||
import { Loader } from '../Loader/Loader'
|
||||
import PhoneInput from 'react-phone-input-2'
|
||||
import 'react-phone-input-2/lib/style.css'
|
||||
@ -16,7 +16,7 @@ const SweetAlert = withSwalInstance(swal)
|
||||
|
||||
const Form = () => {
|
||||
const dispatch = useDispatch()
|
||||
const history = useHistory()
|
||||
const navigate = useNavigate()
|
||||
const role = useSelector(getRole)
|
||||
const urlParams = useParams()
|
||||
const [status, setStatus] = useState(null)
|
||||
@ -52,7 +52,7 @@ const Form = () => {
|
||||
profile_id: urlParams.id,
|
||||
...data
|
||||
},
|
||||
history,
|
||||
|
||||
role,
|
||||
logout: () => dispatch(auth(false))
|
||||
}).then((res) =>
|
||||
@ -79,8 +79,8 @@ const Form = () => {
|
||||
setStatus(null)
|
||||
}
|
||||
: () => {
|
||||
setStatus(null)
|
||||
history.push(`/candidate/${urlParams.id}`)
|
||||
setStatus(null);
|
||||
navigate(`/candidate/${urlParams.id}`)
|
||||
}
|
||||
}
|
||||
/>
|
||||
|
@ -1,66 +1,72 @@
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { useDispatch, useSelector } from 'react-redux'
|
||||
import React, {useState, useEffect} from 'react'
|
||||
import {useDispatch, useSelector} from 'react-redux'
|
||||
|
||||
import Outstaffing from '../Outstaffing/Outstaffing'
|
||||
import Description from '../Description/Description'
|
||||
import { fetchGet } from '../../server/server'
|
||||
import { profiles, tags, auth } from '../../redux/outstaffingSlice'
|
||||
import { getRole } from '../../redux/roleSlice'
|
||||
import { Footer } from '../Footer/Footer'
|
||||
import { useHistory } from 'react-router-dom'
|
||||
import {Footer} from '../Footer/Footer'
|
||||
|
||||
|
||||
import {profiles, tags, auth} from '../../redux/outstaffingSlice'
|
||||
import {getRole} from '../../redux/roleSlice'
|
||||
|
||||
import {useRequest} from "../../hooks/useRequest";
|
||||
|
||||
|
||||
const Home = () => {
|
||||
const history = useHistory()
|
||||
const [isLoadingMore, setIsLoadingMore] = useState(false)
|
||||
const [index, setIndex] = useState(4)
|
||||
|
||||
const dispatch = useDispatch()
|
||||
const role = useSelector(getRole)
|
||||
const [isLoadingMore, setIsLoadingMore] = useState(false);
|
||||
const [index, setIndex] = useState(4);
|
||||
|
||||
const dispatch = useDispatch();
|
||||
const role = useSelector(getRole);
|
||||
|
||||
const {apiRequest} = useRequest();
|
||||
|
||||
useEffect(() => {
|
||||
setIsLoadingMore(true)
|
||||
fetchGet({
|
||||
link: `${process.env.REACT_APP_API_URL}/api/profile?limit=`,
|
||||
params: index,
|
||||
history,
|
||||
setIsLoadingMore(true);
|
||||
apiRequest('/profile',{
|
||||
//Корс блокирует все фильтры в гет параметрах
|
||||
// params: {"get-document-list": 1000},
|
||||
role,
|
||||
logout: () => dispatch(auth(false))
|
||||
// logout: () => dispatch(auth(false))
|
||||
}).then((profileArr) => {
|
||||
dispatch(profiles(profileArr))
|
||||
setIsLoadingMore(false)
|
||||
})
|
||||
|
||||
fetchGet({
|
||||
link: `${process.env.REACT_APP_API_URL}/api/skills/skills-on-main-page`,
|
||||
history,
|
||||
dispatch(profiles(profileArr));
|
||||
setIsLoadingMore(false)
|
||||
});
|
||||
|
||||
apiRequest('/skills/skills-on-main-page',{
|
||||
|
||||
role,
|
||||
logout: () => dispatch(auth(false))
|
||||
// logout: () => dispatch(auth(false))
|
||||
}).then((skills) => {
|
||||
if (!skills) {
|
||||
return []
|
||||
}
|
||||
const keys = Object.keys(skills)
|
||||
const values = Object.values(skills)
|
||||
|
||||
const keys = Object.keys(skills);
|
||||
const values = Object.values(skills);
|
||||
|
||||
const tempTags = values.map((value, index) =>
|
||||
value.map((val) => {
|
||||
return { id: val.id, value: val.tags, name: keys[index] }
|
||||
})
|
||||
)
|
||||
value.map((val) => {
|
||||
return {id: val.id, value: val.tags, name: keys[index]}
|
||||
})
|
||||
);
|
||||
dispatch(tags(tempTags))
|
||||
})
|
||||
}, [dispatch, index])
|
||||
}, [dispatch, index]);
|
||||
|
||||
const loadMore = (count) => {
|
||||
setIndex((prev) => prev + count)
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Outstaffing />
|
||||
<Description onLoadMore={loadMore} isLoadingMore={isLoadingMore} />
|
||||
<Footer />
|
||||
</>
|
||||
<>
|
||||
<Outstaffing/>
|
||||
<Description onLoadMore={loadMore} isLoadingMore={isLoadingMore}/>
|
||||
<Footer/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
export default Home
|
||||
|
@ -1,5 +1,6 @@
|
||||
import SVGLoader from 'react-loader-spinner'
|
||||
import './loader.scss'
|
||||
import React from "react";
|
||||
|
||||
export const Loader = ({ width = 50, height = 50 }) => {
|
||||
return (
|
||||
@ -7,4 +8,4 @@ export const Loader = ({ width = 50, height = 50 }) => {
|
||||
<SVGLoader type='Circles' color='#fff' height={height} width={width} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
};
|
||||
|
@ -1,5 +1,5 @@
|
||||
import React, {useState} from 'react'
|
||||
import {useHistory} from 'react-router-dom'
|
||||
import {useNavigate} from 'react-router-dom'
|
||||
import {useDispatch, useSelector} from 'react-redux'
|
||||
import {Loader} from '../Loader/Loader'
|
||||
import {auth} from '../../redux/outstaffingSlice'
|
||||
@ -11,7 +11,7 @@ export const LogoutButton = () => {
|
||||
const [isLoggingOut, setIsLoggingOut] = useState(false);
|
||||
const dispatch = useDispatch();
|
||||
const userRole = useSelector(getRole);
|
||||
const history = useHistory();
|
||||
const navigate = useNavigate();
|
||||
|
||||
return (
|
||||
<div className='logout-button'>
|
||||
@ -21,7 +21,7 @@ export const LogoutButton = () => {
|
||||
localStorage.clear();
|
||||
dispatch(auth(false));
|
||||
setIsLoggingOut(false);
|
||||
history.push(userRole === 'ROLE_DEV' ? '/authdev' : '/auth')
|
||||
navigate(userRole === 'ROLE_DEV' ? '/authdev' : '/auth')
|
||||
}}
|
||||
>
|
||||
{isLoggingOut ? <Loader/> : 'Выйти'}{' '}
|
||||
|
@ -21,18 +21,18 @@ const createSelectPositionHandler =
|
||||
} else {
|
||||
dispatch(setPositionId(id))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const Outstaffing = () => {
|
||||
const dispatch = useDispatch()
|
||||
const positionId = useSelector(getPositionId)
|
||||
const tagsArr = useSelector(selectTags)
|
||||
const dispatch = useDispatch();
|
||||
const positionId = useSelector(getPositionId);
|
||||
const tagsArr = useSelector(selectTags);
|
||||
|
||||
const onSelectPosition = createSelectPositionHandler({
|
||||
positionId,
|
||||
setPositionId,
|
||||
dispatch
|
||||
})
|
||||
});
|
||||
return (
|
||||
<>
|
||||
<section className='outstaffing'>
|
||||
@ -91,6 +91,6 @@ const Outstaffing = () => {
|
||||
<TagSelect />
|
||||
</>
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
export default Outstaffing
|
||||
|
@ -9,7 +9,7 @@ import {
|
||||
} from '../../redux/outstaffingSlice'
|
||||
|
||||
import { fetchGet } from '../../server/server'
|
||||
import { useHistory } from 'react-router-dom'
|
||||
|
||||
import { getRole } from '../../redux/roleSlice'
|
||||
|
||||
import './outstaffingBlock.scss'
|
||||
@ -19,35 +19,32 @@ const handlePositionClick = ({
|
||||
positionId,
|
||||
isSelected,
|
||||
onSelect,
|
||||
history,
|
||||
role
|
||||
}) => {
|
||||
if (isSelected) {
|
||||
fetchGet({
|
||||
link: `${process.env.REACT_APP_API_URL}/api/profile?limit=`,
|
||||
params: 4,
|
||||
history,
|
||||
role,
|
||||
logout: () => dispatch(auth(false))
|
||||
}).then((profileArr) => {
|
||||
dispatch(filteredCandidates(profileArr))
|
||||
dispatch(selectedItems([]))
|
||||
dispatch(filteredCandidates(profileArr));
|
||||
dispatch(selectedItems([]));
|
||||
onSelect(positionId)
|
||||
})
|
||||
} else {
|
||||
fetchGet({
|
||||
link: `${process.env.REACT_APP_API_URL}/api/profile?position_id=`,
|
||||
params: positionId,
|
||||
history,
|
||||
role,
|
||||
logout: () => dispatch(auth(false))
|
||||
}).then((el) => {
|
||||
dispatch(filteredCandidates(el))
|
||||
dispatch(selectedItems([]))
|
||||
dispatch(filteredCandidates(el));
|
||||
dispatch(selectedItems([]));
|
||||
onSelect(positionId)
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const OutstaffingBlock = ({
|
||||
dataTags = [],
|
||||
@ -58,20 +55,20 @@ const OutstaffingBlock = ({
|
||||
isSelected,
|
||||
onSelect
|
||||
}) => {
|
||||
const history = useHistory()
|
||||
const role = useSelector(getRole)
|
||||
|
||||
const dispatch = useDispatch()
|
||||
const role = useSelector(getRole);
|
||||
|
||||
const itemsArr = useSelector(selectItems)
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const itemsArr = useSelector(selectItems);
|
||||
|
||||
const handleBlockClick = (item, id) => {
|
||||
if (!itemsArr.find((el) => item === el.value)) {
|
||||
dispatch(selectedItems([...itemsArr, { id, value: item, label: item }]))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let classes
|
||||
let classes;
|
||||
|
||||
dataTags.forEach((el) => {
|
||||
if (el.name === 'skills_back') {
|
||||
@ -81,7 +78,7 @@ const OutstaffingBlock = ({
|
||||
} else if (el.name === 'skills_front') {
|
||||
classes = 'front'
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
return (
|
||||
<OutsideClickHandler
|
||||
@ -104,7 +101,6 @@ const OutstaffingBlock = ({
|
||||
positionId,
|
||||
isSelected,
|
||||
onSelect,
|
||||
history,
|
||||
role
|
||||
})
|
||||
}
|
||||
@ -136,6 +132,6 @@ const OutstaffingBlock = ({
|
||||
</div>
|
||||
</OutsideClickHandler>
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
export default OutstaffingBlock
|
||||
|
@ -1,59 +0,0 @@
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import {auth, getProfileInfo, setProfileInfo} from "../../redux/outstaffingSlice";
|
||||
import {useDispatch, useSelector} from "react-redux";
|
||||
import {Loader} from '../Loader/Loader'
|
||||
import {getRole} from "../../redux/roleSlice";
|
||||
import {useHistory, NavLink} from "react-router-dom";
|
||||
import {fetchGet} from "../../server/server";
|
||||
|
||||
import './profileHeader.scss'
|
||||
|
||||
export const ProfileHeader = () => {
|
||||
const [isLoggingOut, setIsLoggingOut] = useState(false);
|
||||
const dispatch = useDispatch();
|
||||
const userRole = useSelector(getRole);
|
||||
const profileInfo = useSelector(getProfileInfo)
|
||||
const history = useHistory();
|
||||
|
||||
useEffect(() => {
|
||||
fetchGet({
|
||||
link: `${process.env.REACT_APP_API_URL}/api/profile/${localStorage.getItem('cardId')}`,
|
||||
}).then((profileInfo) => {
|
||||
dispatch(setProfileInfo(profileInfo))
|
||||
})
|
||||
}, [])
|
||||
return(
|
||||
<header className='profileHeader'>
|
||||
<div className='profileHeader__head'>
|
||||
<div className='profileHeader__container'>
|
||||
<h2 className='profileHeader__title'>itguild.<span>для разработчиков</span></h2>
|
||||
<button onClick={() => {
|
||||
setIsLoggingOut(true);
|
||||
localStorage.clear();
|
||||
dispatch(auth(false));
|
||||
setIsLoggingOut(false);
|
||||
history.push(userRole === 'ROLE_DEV' ? '/authdev' : '/auth')
|
||||
}}
|
||||
className='profileHeader__logout'>
|
||||
{isLoggingOut ? <Loader/> : 'Выйти'}{' '}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className='profileHeader__info'>
|
||||
<div className='profileHeader__container'>
|
||||
<nav className='profileHeader__nav'>
|
||||
<NavLink to={'/summary'}>Резюме</NavLink>
|
||||
<NavLink to={'/profile'}>Отчетность</NavLink>
|
||||
<a>Трекер</a>
|
||||
<a>Выплаты</a>
|
||||
<a>Настройки</a>
|
||||
</nav>
|
||||
<div className='profileHeader__personalInfo'>
|
||||
<h3 className='profileHeader__personalInfoName'>{profileInfo.fio}</h3>
|
||||
<img src={profileInfo.photo} className='profileHeader__personalInfoAvatar' />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
)
|
||||
}
|
@ -1,120 +0,0 @@
|
||||
.profile {
|
||||
background: #F1F1F1;
|
||||
height: 100%;
|
||||
min-height: 100vh;
|
||||
font-family: 'LabGrotesque', sans-serif;
|
||||
|
||||
&__title {
|
||||
font-weight: 700;
|
||||
font-size: 22px;
|
||||
line-height: 32px;
|
||||
color: #000000;
|
||||
span {
|
||||
color: #52B709;
|
||||
}
|
||||
|
||||
@media (max-width: 560px) {
|
||||
font-size: 17px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
&__info {
|
||||
min-height: 128px;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
margin-top: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 130px 0 45px;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
&__items {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
margin-top: 30px;
|
||||
row-gap: 25px;
|
||||
column-gap: 35px;
|
||||
|
||||
@media (max-width: 1175px) {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.item {
|
||||
max-width: 353px;
|
||||
width: 100%;
|
||||
padding: 35px 45px 15px 30px;
|
||||
background: #FFFFFF;
|
||||
border-radius: 12px;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
|
||||
@media (max-width: 1175px) {
|
||||
width: 48%;
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
@media (max-width: 925px) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&__about {
|
||||
display: flex;
|
||||
column-gap: 20px;
|
||||
align-items: center;
|
||||
margin-bottom: 30px;
|
||||
|
||||
h3 {
|
||||
color: #000000;
|
||||
font-weight: 500;
|
||||
font-size: 18px;
|
||||
line-height: 22px;
|
||||
max-width: 125px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
|
||||
p {
|
||||
font-weight: 700;
|
||||
font-size: 12px;
|
||||
line-height: 20px;
|
||||
color: #000000;
|
||||
margin-bottom: 0;
|
||||
|
||||
span {
|
||||
color: #52B709;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
&Link {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
background: #DDEEC6;
|
||||
border-radius: 50px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1160px;
|
||||
margin-top: 23px;
|
||||
|
||||
@media (max-width: 570px) {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: 70px;
|
||||
}
|
||||
}
|
@ -1,379 +0,0 @@
|
||||
.summary {
|
||||
background: #F1F1F1;
|
||||
height: 100%;
|
||||
min-height: 100vh;
|
||||
font-family: 'LabGrotesque', sans-serif;
|
||||
//
|
||||
//&__container {
|
||||
// max-width: 1160px;
|
||||
// padding: 0 10px;
|
||||
// margin: 20px auto;
|
||||
// position: relative;
|
||||
// display: flex;
|
||||
// flex-direction: column;
|
||||
//}
|
||||
|
||||
&__content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
&__title {
|
||||
font-weight: 700;
|
||||
font-size: 22px;
|
||||
line-height: 32px;
|
||||
margin-bottom: 0;
|
||||
|
||||
span {
|
||||
color: #52B709;
|
||||
}
|
||||
}
|
||||
|
||||
&__back {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
column-gap: 30px;
|
||||
margin-top: 20px;
|
||||
cursor: pointer;
|
||||
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
font-size: 14px;
|
||||
line-height: 32px;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
&__info {
|
||||
min-height: 128px;
|
||||
background: white;
|
||||
border-radius: 12px;
|
||||
margin-top: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 130px 0 45px;
|
||||
justify-content: space-between;
|
||||
|
||||
@media (max-width: 930px) {
|
||||
padding: 0 40px;
|
||||
}
|
||||
|
||||
@media (max-width: 690px) {
|
||||
padding: 0 20px;
|
||||
min-height: 80px;
|
||||
}
|
||||
}
|
||||
|
||||
&__person {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
column-gap: 45px;
|
||||
|
||||
@media (max-width: 690px) {
|
||||
column-gap: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
&__avatar {
|
||||
width: 88px;
|
||||
height: 88px;
|
||||
border-radius: 100px;
|
||||
|
||||
@media (max-width: 690px) {
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
min-width: 44px;
|
||||
min-height: 44px;
|
||||
}
|
||||
}
|
||||
|
||||
&__name {
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
line-height: 32px;
|
||||
position: relative;
|
||||
|
||||
@media (max-width: 690px) {
|
||||
font-size: 14px;
|
||||
margin-right: 10px;
|
||||
line-height: 15px;
|
||||
}
|
||||
|
||||
&:after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
background: #52B709;
|
||||
border-radius: 12px;
|
||||
width: 70%;
|
||||
height: 8px;
|
||||
bottom: -14px;
|
||||
left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
&__git {
|
||||
background: #52B709;
|
||||
border-radius: 44px;
|
||||
width: 177px;
|
||||
height: 50px;
|
||||
font-weight: 500;
|
||||
font-size: 16px;
|
||||
line-height: 32px;
|
||||
color: white;
|
||||
border: none;
|
||||
|
||||
@media (max-width: 690px) {
|
||||
width: 120px;
|
||||
}
|
||||
}
|
||||
|
||||
&__skills {
|
||||
background: #FFFFFF;
|
||||
border-radius: 12px;
|
||||
margin-top: 35px;
|
||||
}
|
||||
|
||||
&__sections__head {
|
||||
display: flex;
|
||||
min-height: 69px;
|
||||
background: #E1FCCF;
|
||||
border-radius: 12px 12px 0px 0px;
|
||||
align-items: center;
|
||||
padding: 0 35px 0 50px;
|
||||
justify-content: space-between;
|
||||
|
||||
@media (max-width: 550px) {
|
||||
padding: 0 15px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-style: normal;
|
||||
font-size: 18px;
|
||||
line-height: 32px;
|
||||
|
||||
@media (max-width: 660px) {
|
||||
line-height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
button {
|
||||
background: #FFFFFF;
|
||||
border-radius: 44px;
|
||||
padding: 10px 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border: none;
|
||||
height: 42px;
|
||||
font-weight: 500;
|
||||
font-size: 14px;
|
||||
line-height: 32px;
|
||||
white-space: nowrap;
|
||||
|
||||
@media (max-width: 520px) {
|
||||
font-size: 12px;
|
||||
padding: 10px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.skills__section {
|
||||
&__items {
|
||||
padding: 25px 35px 25px 50px;
|
||||
|
||||
@media (max-width: 550px) {
|
||||
padding: 15px 15px 20px;
|
||||
}
|
||||
|
||||
&__wrapper {
|
||||
max-width: 630px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
column-gap: 5px;
|
||||
|
||||
.skill_item {
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
line-height: 32px;
|
||||
white-space: nowrap;
|
||||
text-transform: uppercase;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__experience {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
row-gap: 20px;
|
||||
margin-top: 30px;
|
||||
|
||||
.experience {
|
||||
&__block {
|
||||
background: #FFFFFF;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
&__content {
|
||||
padding: 15px 35px 15px 50px;
|
||||
|
||||
@media (max-width: 550px) {
|
||||
padding: 15px 15px 20px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-weight: 700;
|
||||
font-size: 16px;
|
||||
line-height: 32px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
p {
|
||||
font-weight: 400;
|
||||
font-size: 16px;
|
||||
line-height: 32px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__sectionGit {
|
||||
margin-top: 25px;
|
||||
|
||||
&Items {
|
||||
margin-top: 25px;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
row-gap: 20px;
|
||||
column-gap: 25px;
|
||||
justify-content: space-between;
|
||||
|
||||
.gitItem {
|
||||
width: 48%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
background: #FFFFFF;
|
||||
border-radius: 12px;
|
||||
padding: 35px 30px 30px 45px;
|
||||
|
||||
@media (max-width: 825px) {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
@media (max-width: 470px) {
|
||||
padding: 15px;
|
||||
}
|
||||
|
||||
&__info {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-width: 350px;
|
||||
width: 100%;
|
||||
|
||||
@media (max-width: 825px) {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
&__about {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
column-gap: 15px;
|
||||
}
|
||||
|
||||
&__name {
|
||||
h4 {
|
||||
font-weight: 700;
|
||||
font-size: 18px;
|
||||
line-height: 32px;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
p {
|
||||
font-weight: 300;
|
||||
font-size: 16px;
|
||||
line-height: 32px;
|
||||
margin-bottom: 0;
|
||||
white-space: nowrap;
|
||||
max-width: 300px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
@media (max-width: 1040px) {
|
||||
max-width: 250px;
|
||||
}
|
||||
|
||||
@media (max-width: 890px) {
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
@media (max-width: 825px) {
|
||||
max-width: 500px;
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
max-width: 250px;
|
||||
}
|
||||
|
||||
@media (max-width: 470px) {
|
||||
max-width: 200px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__specification {
|
||||
margin-top: 30px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 10px;
|
||||
column-gap: 25px;
|
||||
|
||||
@media (max-width: 470px) {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
span {
|
||||
background: #D4F123;
|
||||
border-radius: 12px;
|
||||
max-width: 260px;
|
||||
width: 100%;
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
p {
|
||||
margin-bottom: 0;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
line-height: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__link {
|
||||
border-radius: 50%;
|
||||
background: #DDEEC6;
|
||||
min-width: 48px;
|
||||
height: 48px;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
footer {
|
||||
margin-top: 70px;
|
||||
}
|
||||
|
||||
.container {
|
||||
max-width: 1160px;
|
||||
margin-top: 23px;
|
||||
|
||||
@media (max-width: 570px) {
|
||||
margin-top: 0;
|
||||
}
|
||||
}
|
||||
}
|
71
src/components/ProfileHeader/ProfileHeader.js
Normal file
71
src/components/ProfileHeader/ProfileHeader.js
Normal file
@ -0,0 +1,71 @@
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import {useNavigate, NavLink} from "react-router-dom";
|
||||
import {useDispatch, useSelector} from "react-redux";
|
||||
|
||||
import {Loader} from '../Loader/Loader'
|
||||
|
||||
import {auth, getProfileInfo, setProfileInfo} from "../../redux/outstaffingSlice";
|
||||
import {getRole} from "../../redux/roleSlice";
|
||||
|
||||
|
||||
|
||||
import './profileHeader.scss'
|
||||
import {useRequest} from "../../hooks/useRequest";
|
||||
|
||||
|
||||
export const ProfileHeader = () => {
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const {apiRequest} = useRequest();
|
||||
|
||||
const userRole = useSelector(getRole);
|
||||
const profileInfo = useSelector(getProfileInfo);
|
||||
|
||||
const [isLoggingOut, setIsLoggingOut] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
apiRequest(`/api/profile/${localStorage.getItem('cardId')}`)
|
||||
.then((profileInfo) =>
|
||||
dispatch(setProfileInfo(profileInfo))
|
||||
);
|
||||
|
||||
}, [dispatch]);
|
||||
|
||||
const handler = () => {
|
||||
setIsLoggingOut(true);
|
||||
localStorage.clear();
|
||||
dispatch(auth(false));
|
||||
setIsLoggingOut(false);
|
||||
navigate(userRole === 'ROLE_DEV' ? '/authdev' : '/auth')
|
||||
};
|
||||
|
||||
return (
|
||||
<header className='profileHeader'>
|
||||
<div className='profileHeader__head'>
|
||||
<div className='profileHeader__container'>
|
||||
<h2 className='profileHeader__title'>itguild.<span>для разработчиков</span></h2>
|
||||
<button onClick={handler} className='profileHeader__logout'>
|
||||
{isLoggingOut ? <Loader/> : 'Выйти'}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className='profileHeader__info'>
|
||||
<div className='profileHeader__container'>
|
||||
<nav className='profileHeader__nav'>
|
||||
<NavLink to={'/summary'}>Резюме</NavLink>
|
||||
<NavLink to={'/profile'}>Отчетность</NavLink>
|
||||
<NavLink to={'/profile'}>Трекер</NavLink>
|
||||
<NavLink to={'/profile'}>Выплаты</NavLink>
|
||||
<NavLink to={'/profile'}>Настройки</NavLink>
|
||||
</nav>
|
||||
|
||||
<div className='profileHeader__personalInfo'>
|
||||
<h3 className='profileHeader__personalInfoName'>{profileInfo.fio}</h3>
|
||||
<img src={profileInfo.photo} className='profileHeader__personalInfoAvatar' alt='avatar'/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
)
|
||||
};
|
@ -8,16 +8,16 @@ export const ProtectedRoute = ({ component: Component, ...rest }) => {
|
||||
const existingToken = localStorage.getItem('auth_token')
|
||||
const expiresAt = localStorage.getItem('access_token_expired_at')
|
||||
|
||||
const isTokenAlive = (existingToken && expiresAt && new Date(expiresAt).getTime() > (new Date()).getTime());
|
||||
|
||||
const isTokenAlive = !isAuth && (existingToken && expiresAt && new Date(expiresAt).getTime() > (new Date()).getTime());
|
||||
|
||||
return (
|
||||
<Route
|
||||
{...rest}
|
||||
render={props =>
|
||||
( isAuth || isTokenAlive) ? (
|
||||
// ( isAuth || isTokenAlive) ? (
|
||||
<Component {...props} />
|
||||
) : <Redirect to='/auth' />
|
||||
// ) : <Redirect to='/auth' />
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
@ -1,7 +1,7 @@
|
||||
import React, {useState} from 'react'
|
||||
import {useSelector, useDispatch} from 'react-redux'
|
||||
import {fetchPost} from '../../server/server'
|
||||
import {useHistory, useParams, Redirect, Link} from 'react-router-dom'
|
||||
import {useNavigate, useParams, Redirect, Link} from 'react-router-dom'
|
||||
import {Loader} from '../Loader/Loader'
|
||||
import {auth} from '../../redux/outstaffingSlice'
|
||||
import {getReportDate} from '../../redux/reportSlice'
|
||||
@ -28,7 +28,7 @@ const getCreatedDate = (day) => {
|
||||
|
||||
const ReportForm = () => {
|
||||
const dispatch = useDispatch();
|
||||
const history = useHistory();
|
||||
const navigate = useNavigate();
|
||||
const reportDate = useSelector(getReportDate);
|
||||
const role = useSelector(getRole);
|
||||
|
||||
@ -153,7 +153,6 @@ const ReportForm = () => {
|
||||
<button className='report-form__footer-btn' onClick={() => {
|
||||
fetchPost({
|
||||
link: `${process.env.REACT_APP_API_URL}/api/reports/create`,
|
||||
history,
|
||||
role,
|
||||
body: {
|
||||
tasks: inputs,
|
||||
|
@ -12,38 +12,37 @@ import {
|
||||
auth
|
||||
} from '../../redux/outstaffingSlice'
|
||||
import { fetchGet } from '../../server/server'
|
||||
import { useHistory } from 'react-router-dom'
|
||||
|
||||
import { getRole } from '../../redux/roleSlice'
|
||||
|
||||
const TagSelect = () => {
|
||||
const history = useHistory
|
||||
const role = useSelector(getRole)
|
||||
const [searchLoading, setSearchLoading] = useState(false)
|
||||
const dispatch = useDispatch()
|
||||
|
||||
const itemsArr = useSelector(selectItems)
|
||||
const role = useSelector(getRole);
|
||||
const [searchLoading, setSearchLoading] = useState(false);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const tagsArr = useSelector(selectTags)
|
||||
const itemsArr = useSelector(selectItems);
|
||||
|
||||
const tagsArr = useSelector(selectTags);
|
||||
|
||||
const handleSubmit = ({ dispatch, setSearchLoading }) => {
|
||||
setSearchLoading(true)
|
||||
setSearchLoading(true);
|
||||
|
||||
dispatch(setPositionId(null))
|
||||
const filterItemsId = itemsArr.map((item) => item.id).join()
|
||||
dispatch(setPositionId(null));
|
||||
const filterItemsId = itemsArr.map((item) => item.id).join();
|
||||
|
||||
fetchGet({
|
||||
link: `${process.env.REACT_APP_API_URL}/api/profile?skills=`,
|
||||
params: filterItemsId,
|
||||
history,
|
||||
role,
|
||||
logout: () => dispatch(auth(false))
|
||||
}).then((el) => {
|
||||
dispatch(filteredCandidates(el))
|
||||
dispatch(filteredCandidates(el));
|
||||
setSearchLoading(false)
|
||||
})
|
||||
|
||||
// dispatch(selectedItems([]));
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -85,6 +84,6 @@ const TagSelect = () => {
|
||||
</section>
|
||||
</>
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
export default TagSelect
|
||||
|
@ -5,20 +5,20 @@ import {fetchGet} from "../../../server/server";
|
||||
|
||||
|
||||
export const Results = () => {
|
||||
const result = useSelector(selectResult)
|
||||
const test = useSelector(selectedTest)
|
||||
const [maxScore, setMaxScore] = useState('')
|
||||
const dispatch = useDispatch()
|
||||
const result = useSelector(selectResult);
|
||||
const test = useSelector(selectedTest);
|
||||
const [maxScore, setMaxScore] = useState('');
|
||||
const dispatch = useDispatch();
|
||||
|
||||
useEffect(async () => {
|
||||
dispatch(fetchResultTest(test.uuid))
|
||||
dispatch(fetchResultTest(test.uuid));
|
||||
const response = await fetchGet({
|
||||
link: `${process.env.REACT_APP_API_URL}/api/user-questionnaire/get-points-number?user_questionnaire_uuid=${test.uuid}`,
|
||||
Origin: `${process.env.REACT_APP_BASE_URL}`,
|
||||
}
|
||||
)
|
||||
);
|
||||
setMaxScore(response.sum_point)
|
||||
}, [])
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className={'result _container'}>
|
||||
|
@ -1,59 +1,62 @@
|
||||
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 React, {useEffect, useState} from 'react'
|
||||
import { useNavigate} from "react-router-dom"
|
||||
import {useSelector, useDispatch} from 'react-redux'
|
||||
|
||||
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 {fetchUserAnswersMany, fetchUserAnswerOne} from './../../../redux/quizSlice'
|
||||
|
||||
import {fetchGet} from "../../../server/server";
|
||||
|
||||
import './quiz.scss'
|
||||
|
||||
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([])
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
|
||||
useEffect(async () => {
|
||||
const response = await fetchGet({
|
||||
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 [questions, setQuestions] = useState([]);
|
||||
|
||||
const id = localStorage.getItem('id');
|
||||
|
||||
useEffect( () => {
|
||||
const response = 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))
|
||||
);
|
||||
setQuestions(response);
|
||||
dispatch(fetchGetAnswers(response[0].id));
|
||||
setStripValue((+index + 1) * 100 / response.length)
|
||||
}, [dispatch])
|
||||
|
||||
}, [dispatch]);
|
||||
|
||||
const nextQuestion = async (e) => {
|
||||
e.preventDefault()
|
||||
e.preventDefault();
|
||||
|
||||
//Проверка на валидацию ответов
|
||||
if (checkedValues.length || inputValue) {
|
||||
switch (questions[index].question_type_id) {
|
||||
case '3':
|
||||
dispatch(fetchUserAnswersMany(checkedValues))
|
||||
dispatch(fetchUserAnswersMany(checkedValues));
|
||||
break;
|
||||
case '2':
|
||||
case '1':
|
||||
case '4':
|
||||
dispatch(fetchUserAnswerOne(checkedValues))
|
||||
dispatch(fetchUserAnswerOne(checkedValues));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
@ -61,20 +64,20 @@ export const TaskQuiz = () => {
|
||||
|
||||
//Проверка на существование следующего запроса
|
||||
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)))
|
||||
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`)
|
||||
navigate(`/quiz-result`);
|
||||
alert("Тест пройден!")
|
||||
}
|
||||
|
||||
} else {
|
||||
alert("Вы не ответили на вопрос")
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const handleChange = (e) => {
|
||||
const checked = e.target.checked;
|
||||
@ -86,8 +89,8 @@ export const TaskQuiz = () => {
|
||||
question_id: questions[index].id,
|
||||
response_body: e.target.value
|
||||
}]) :
|
||||
setCheckedValues(prev => [...prev.filter(item => item.response_body !== e.target.value)])
|
||||
break
|
||||
setCheckedValues(prev => [...prev.filter(item => item.response_body !== e.target.value)]);
|
||||
break;
|
||||
case '1':
|
||||
case '2':
|
||||
case '4':
|
||||
@ -146,4 +149,4 @@ export const TaskQuiz = () => {
|
||||
</div>
|
||||
</React.StrictMode>
|
||||
)
|
||||
}
|
||||
};
|
||||
|
Reference in New Issue
Block a user