fixs, Убрал стейты для формы авторизации, переписал на форм дату
This commit is contained in:
parent
50f33071bb
commit
5c8a8160bd
@ -1,13 +0,0 @@
|
||||
import axios from 'axios';
|
||||
import {getToken, urlHasParams} from "../helper";
|
||||
import {useLogout} from "./useLogout";
|
||||
|
||||
|
||||
|
||||
export const useRequest = () => {
|
||||
|
||||
|
||||
|
||||
|
||||
return {apiRequest}
|
||||
};
|
@ -5,7 +5,7 @@ import {withSwalInstance} from 'sweetalert2-react'
|
||||
import swal from 'sweetalert2'
|
||||
|
||||
import {Loader} from '../Loader/Loader'
|
||||
import ErrorBoundary from "../../HOC/ErrorBoundary";
|
||||
import ErrorBoundary from "../../hoc/ErrorBoundary";
|
||||
|
||||
import {auth, selectAuth, setUserInfo} from '../../redux/outstaffingSlice'
|
||||
import {loading} from '../../redux/loaderSlice'
|
||||
@ -19,20 +19,19 @@ import ellipse from '../../images/ellipse.png'
|
||||
|
||||
import './authBox.scss'
|
||||
|
||||
const {useRef} = require("react");
|
||||
|
||||
|
||||
const SweetAlert = withSwalInstance(swal);
|
||||
|
||||
export const AuthBox = ({title, altTitle, roleChangeLink}) => {
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const ref = useRef();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const isAuth = useSelector(selectAuth);
|
||||
const isLoading = useSelector(selectIsLoading);
|
||||
|
||||
|
||||
const [username, setUsername] = useState('');
|
||||
const [password, setPassword] = useState('');
|
||||
const [error, setError] = useState(null);
|
||||
|
||||
if (isAuth) {
|
||||
@ -47,15 +46,13 @@ export const AuthBox = ({title, altTitle, roleChangeLink}) => {
|
||||
|
||||
const submitHandler = () => {
|
||||
|
||||
let formData = new FormData(ref.current)
|
||||
if (!isLoading) {
|
||||
dispatch(loading(true));
|
||||
apiRequest('/user/login',
|
||||
{
|
||||
method: 'POST',
|
||||
data: JSON.stringify({
|
||||
username,
|
||||
password
|
||||
})
|
||||
data: formData
|
||||
}).then((res) => {
|
||||
|
||||
if (!res.access_token) {
|
||||
@ -90,23 +87,21 @@ export const AuthBox = ({title, altTitle, roleChangeLink}) => {
|
||||
<img src={ellipse} alt=''/>
|
||||
<span>{title}</span>
|
||||
</div>
|
||||
<form className='auth-box__form'>
|
||||
<form ref={ref} className='auth-box__form'>
|
||||
<label htmlFor='login'>Ваш логин:</label>
|
||||
<input
|
||||
id='login'
|
||||
type='text'
|
||||
name='username'
|
||||
placeholder='Логин'
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
/>
|
||||
|
||||
<label htmlFor='password'>Пароль:</label>
|
||||
<input
|
||||
id='password'
|
||||
type='password'
|
||||
name='password'
|
||||
placeholder='Пароль'
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
/>
|
||||
|
||||
{error && (
|
||||
|
@ -12,6 +12,7 @@ import {selectCurrentCandidate} from '../../redux/outstaffingSlice'
|
||||
import rectangle from '../../images/rectangle_secondPage.png'
|
||||
|
||||
import './calendar.scss'
|
||||
import {urlForLocal} from "../../helper";
|
||||
|
||||
|
||||
const Calendar = () => {
|
||||
@ -42,7 +43,7 @@ const Calendar = () => {
|
||||
</div>
|
||||
<div className='col-12 col-xl-12 d-flex justify-content-between align-items-center flex-column flex-sm-row'>
|
||||
<div className='calendar__info'>
|
||||
<img className='calendar__info-img' src={photo} alt='img'/>
|
||||
{photo && <img className='calendar__info-img' src={urlForLocal(photo)} alt='img'/>}
|
||||
<h3 className='calendar__info-name'>{abbreviatedName}</h3>
|
||||
</div>
|
||||
<div className='calendar__title'>
|
||||
|
@ -1,10 +1,11 @@
|
||||
import React from 'react'
|
||||
import { Link } from 'react-router-dom'
|
||||
import { Achievement } from '../Achievement/Achievement'
|
||||
import {Link} from 'react-router-dom'
|
||||
import {Achievement} from '../Achievement/Achievement'
|
||||
|
||||
import { LEVELS, SKILLS } from '../../constants/constants'
|
||||
import {LEVELS, SKILLS} from '../../constants/constants'
|
||||
|
||||
import './candidateSidebar.scss'
|
||||
import {urlForLocal} from "../../helper";
|
||||
|
||||
const getYearsString = (years) => {
|
||||
let yearsString;
|
||||
@ -20,60 +21,58 @@ const getYearsString = (years) => {
|
||||
return `${years} ${yearsString}`
|
||||
};
|
||||
|
||||
const CandidateSidebar = ({ candidate, setActiveSnippet, activeSnippet }) => {
|
||||
const userId = localStorage.getItem('id') ;
|
||||
const CandidateSidebar = ({candidate, setActiveSnippet, activeSnippet}) => {
|
||||
const userId = localStorage.getItem('id');
|
||||
const showSnippet = () => {
|
||||
setActiveSnippet((prev)=>!prev)
|
||||
setActiveSnippet((prev) => !prev)
|
||||
};
|
||||
|
||||
return (
|
||||
<div className='candidate-sidebar'>
|
||||
<div className='candidate-sidebar__info'>
|
||||
<div className='candidate-sidebar__position'>
|
||||
<h2>
|
||||
{candidate.specification} {SKILLS[candidate.position_id]},{' '}
|
||||
{LEVELS[candidate.level]}{' '}
|
||||
</h2>
|
||||
<div className='candidate-sidebar'>
|
||||
<div className='candidate-sidebar__info'>
|
||||
<div className='candidate-sidebar__position'>
|
||||
<h2>
|
||||
{candidate.specification} {SKILLS[candidate.position_id]},{' '}
|
||||
{LEVELS[candidate.level]}{' '}
|
||||
</h2>
|
||||
</div>
|
||||
{candidate.photo && <img src={urlForLocal(candidate.photo)} alt=''/>}
|
||||
{candidate && candidate.years_of_exp && (
|
||||
<>
|
||||
<p className='candidate-sidebar__experience-title'>Опыт работы</p>
|
||||
<p className='candidate-sidebar__experience'>
|
||||
{getYearsString(candidate.years_of_exp)}
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
<Link to={`/candidate/${candidate.id}/form`}>
|
||||
<button className='candidate-sidebar__select'>
|
||||
Выбрать к собеседованию
|
||||
</button>
|
||||
</Link>
|
||||
{userId && (
|
||||
<>
|
||||
<Link to={`/${candidate.id}/calendar`}>
|
||||
<button className='candidate-sidebar__select'>
|
||||
Отчёты
|
||||
</button>
|
||||
</Link>
|
||||
<button
|
||||
className='candidate-sidebar__select'
|
||||
onClick={showSnippet}
|
||||
>
|
||||
{activeSnippet ? "Показать" : "Скрыть"}
|
||||
</button>
|
||||
<div className='candidate-sidebar__achievements'>
|
||||
{candidate &&
|
||||
candidate.achievements &&
|
||||
candidate.achievements.map((item) => {
|
||||
return <Achievement key={item.id} achievement={item.achievement}/>
|
||||
})}
|
||||
</div>
|
||||
</>)}
|
||||
</div>
|
||||
<img src={candidate.photo} alt='' />
|
||||
{candidate && candidate.years_of_exp && (
|
||||
<>
|
||||
<p className='candidate-sidebar__experience-title'>Опыт работы</p>
|
||||
<p className='candidate-sidebar__experience'>
|
||||
{getYearsString(candidate.years_of_exp)}
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
<Link to={`/candidate/${candidate.id}/form`}>
|
||||
<button className='candidate-sidebar__select'>
|
||||
Выбрать к собеседованию
|
||||
</button>
|
||||
</Link>
|
||||
{userId && (
|
||||
<>
|
||||
<Link to={`/${candidate.id}/calendar`}>
|
||||
<button className='candidate-sidebar__select'>
|
||||
Отчёты
|
||||
</button>
|
||||
</Link>
|
||||
{/* <Link to={`/candidate/${candidate.id}/code`}> */}
|
||||
<button
|
||||
className='candidate-sidebar__select'
|
||||
onClick={showSnippet}
|
||||
>
|
||||
{activeSnippet ? "Показать": "Скрыть"}
|
||||
</button>
|
||||
{/* </Link> */}
|
||||
<div className='candidate-sidebar__achievements'>
|
||||
{candidate &&
|
||||
candidate.achievements &&
|
||||
candidate.achievements.map((item) => {
|
||||
return <Achievement key={item.id} achievement={item.achievement} />
|
||||
})}
|
||||
</div>
|
||||
</>)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
};
|
||||
|
||||
|
@ -2,11 +2,10 @@ import React from 'react'
|
||||
import {useSelector} from 'react-redux'
|
||||
import {Link} from 'react-router-dom'
|
||||
|
||||
import {Loader} from '../Loader/Loader'
|
||||
import ErrorBoundary from "../../HOC/ErrorBoundary";
|
||||
import ErrorBoundary from "../../hoc/ErrorBoundary";
|
||||
|
||||
import {LEVELS, SKILLS} from '../../constants/constants'
|
||||
import {selectProfiles, selectFilteredCandidates,} from '../../redux/outstaffingSlice'
|
||||
import {selectProfiles} from '../../redux/outstaffingSlice'
|
||||
|
||||
import {urlForLocal} from '../../helper'
|
||||
|
||||
@ -19,105 +18,17 @@ import './description.scss'
|
||||
const Description = ({onLoadMore, isLoadingMore}) => {
|
||||
|
||||
const candidatesListArr = useSelector(selectProfiles);
|
||||
const filteredListArr = useSelector(selectFilteredCandidates);
|
||||
|
||||
|
||||
|
||||
if (!filteredListArr) {
|
||||
return (
|
||||
<section className='description'>
|
||||
<div className='container'>
|
||||
<div className='description__wrapper'>
|
||||
<ErrorBoundary>
|
||||
{candidatesListArr && Array.isArray(candidatesListArr) && candidatesListArr.length > 0 ? (
|
||||
candidatesListArr.map((el) => (
|
||||
<div className='row' key={el.id}>
|
||||
<div className='col-2 col-xs-12'>
|
||||
{el.photo && <img className='description__img' src={urlForLocal(el.photo)} alt=''/>}
|
||||
</div>
|
||||
<div className='col-12 col-xl-6'>
|
||||
<h3 className='description__title'>
|
||||
<Link to={`/candidate/${el.id}`}>
|
||||
{el.specification} {SKILLS[el.position_id]},{' '}
|
||||
{LEVELS[el.level]}{' '}
|
||||
</Link>
|
||||
</h3>
|
||||
|
||||
{el.vc_text_short ? (
|
||||
<div className='description__text'>
|
||||
{el.vc_text_short}
|
||||
</div>
|
||||
) : (
|
||||
<p className='description__text-secondary'>
|
||||
Описание отсутствует...
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
<div className='col-12 col-xl-4'>
|
||||
<Link to={`/candidate/${el.id}`}>
|
||||
<button className='description__button'>
|
||||
Подробное резюме
|
||||
</button>
|
||||
</Link>
|
||||
</div>
|
||||
<div className='col-xl-2'></div>
|
||||
<div className='col-12 col-xl-6'>
|
||||
<ul className='description__list'>
|
||||
{Array.isArray(el?.skillValues) && el.skillValues.map((e) => (
|
||||
<li key={e.id} className='description__list-item'>
|
||||
{e.skill.name}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<img
|
||||
className='description__rectangle'
|
||||
src={rectangle}
|
||||
alt=''
|
||||
/>
|
||||
</div>
|
||||
<div className='col-xl-4'></div>
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
<div className='description__empty'>
|
||||
{isLoadingMore
|
||||
? 'В данный момент в категории нет свободных специалистов'
|
||||
: 'Загрузка...'}
|
||||
</div>
|
||||
)}
|
||||
</ErrorBoundary>
|
||||
</div>
|
||||
|
||||
<div className='row'>
|
||||
<div className='col-12'>
|
||||
<div className='description__footer'>
|
||||
<div className='description__footer-btn'>
|
||||
<button onClick={() => onLoadMore(2)}>
|
||||
{isLoadingMore ? (
|
||||
<Loader width={40} height={40}/>
|
||||
) : (
|
||||
'Загрузить еще'
|
||||
)}{' '}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<section className='description'>
|
||||
<div className='container'>
|
||||
<div className='description__wrapper'>
|
||||
<ErrorBoundary>
|
||||
{filteredListArr && Array.isArray(filteredListArr) && filteredListArr.length > 0
|
||||
? filteredListArr.map((el) => (
|
||||
{candidatesListArr && Array.isArray(candidatesListArr) && candidatesListArr.length > 0
|
||||
? candidatesListArr.map((el) => (
|
||||
<div className='row' key={el.id}>
|
||||
<div className='col-2'>
|
||||
<img className='description__img' src={()=>urlForLocal(el?.photo)} alt=''/>
|
||||
{el.photo && <img className='description__img' src={urlForLocal(el.photo)} alt=''/>}
|
||||
</div>
|
||||
<div className='col-12 col-xl-6'>
|
||||
<h3 className='description__title'>
|
||||
@ -217,10 +128,9 @@ const Description = ({onLoadMore, isLoadingMore}) => {
|
||||
<div className='col-12'>
|
||||
<div className='description__footer'>
|
||||
<div className='description__footer-btn'>
|
||||
{candidatesListArr &&
|
||||
filteredListArr.length === 0 ? (
|
||||
{candidatesListArr && (
|
||||
<button onClick={() => onLoadMore(2)}>Загрузить еще</button>
|
||||
) : null}
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,25 +1,28 @@
|
||||
import React, {useState} from 'react'
|
||||
import {useNavigate} from 'react-router-dom'
|
||||
import {useDispatch, useSelector} from 'react-redux'
|
||||
import {useSelector} from 'react-redux'
|
||||
import {useLogout} from "../../hooks/useLogout";
|
||||
|
||||
import {Loader} from '../Loader/Loader'
|
||||
import {auth} from '../../redux/outstaffingSlice'
|
||||
|
||||
import {getRole} from '../../redux/roleSlice'
|
||||
|
||||
import './logoutButton.scss'
|
||||
|
||||
|
||||
export const LogoutButton = () => {
|
||||
const [isLoggingOut, setIsLoggingOut] = useState(false);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const userRole = useSelector(getRole);
|
||||
const navigate = useNavigate();
|
||||
const {logout} = useLogout();
|
||||
|
||||
return (
|
||||
<button
|
||||
className='logout-button'
|
||||
onClick={() => {
|
||||
setIsLoggingOut(true);
|
||||
localStorage.clear();
|
||||
dispatch(auth(false));
|
||||
logout();
|
||||
setIsLoggingOut(false);
|
||||
navigate(userRole === 'ROLE_DEV' ? '/authdev' : '/auth')
|
||||
}}
|
||||
|
@ -4,7 +4,7 @@ import {useDispatch, useSelector} from 'react-redux'
|
||||
import {
|
||||
selectItems,
|
||||
selectedItems,
|
||||
filteredCandidates,
|
||||
profiles,
|
||||
} from '../../redux/outstaffingSlice'
|
||||
|
||||
import {apiRequest} from "../../api/request";
|
||||
@ -22,9 +22,11 @@ const handlePositionClick = (
|
||||
}) => {
|
||||
if (isSelected) {
|
||||
apiRequest('/profile', {
|
||||
params: {limit: 1000},
|
||||
params: {
|
||||
limit: 1000
|
||||
},
|
||||
}).then((profileArr) => {
|
||||
dispatch(filteredCandidates(profileArr));
|
||||
dispatch(profiles(profileArr));
|
||||
dispatch(selectedItems([]));
|
||||
onSelect(positionId)
|
||||
})
|
||||
@ -32,9 +34,10 @@ const handlePositionClick = (
|
||||
apiRequest('/profile', {
|
||||
params: {
|
||||
limit: '1000',
|
||||
position_id: positionId},
|
||||
}).then((el) => {
|
||||
dispatch(filteredCandidates(el));
|
||||
position_id: positionId
|
||||
},
|
||||
}).then((res) => {
|
||||
dispatch(profiles(res));
|
||||
dispatch(selectedItems([]));
|
||||
onSelect(positionId)
|
||||
})
|
||||
|
@ -7,7 +7,7 @@ import {
|
||||
selectedItems,
|
||||
selectItems,
|
||||
selectTags,
|
||||
filteredCandidates,
|
||||
profiles,
|
||||
setPositionId
|
||||
} from '../../redux/outstaffingSlice'
|
||||
|
||||
@ -33,8 +33,8 @@ const TagSelect = () => {
|
||||
|
||||
apiRequest('/profile', {
|
||||
params: {...params, limit: 1000},
|
||||
}).then((el) => {
|
||||
dispatch(filteredCandidates(el));
|
||||
}).then((res) => {
|
||||
dispatch(profiles(res));
|
||||
setSearchLoading(false)
|
||||
})
|
||||
|
||||
|
@ -5,7 +5,6 @@ import {useEffect, useState} from "react";
|
||||
import {useSelector} from "react-redux";
|
||||
import {selectedTest} from "../../../redux/quizSlice";
|
||||
|
||||
import {useRequest} from "../../../HOOks/useRequest";
|
||||
import {apiRequest} from "../../../api/request";
|
||||
|
||||
export const Instruction = () => {
|
||||
|
@ -1,7 +1,6 @@
|
||||
import React, {useEffect, useState} from 'react';
|
||||
import {useDispatch, useSelector} from "react-redux";
|
||||
import {fetchResultTest, selectedTest, selectResult} from "../../../redux/quizSlice";
|
||||
import {useRequest} from "../../../HOOks/useRequest";
|
||||
import {apiRequest} from "../../../api/request";
|
||||
|
||||
|
||||
|
@ -2,7 +2,6 @@ import React, {useEffect, useState} from 'react'
|
||||
import {useNavigate} from "react-router-dom"
|
||||
import {useSelector, useDispatch} from 'react-redux'
|
||||
|
||||
import {useRequest} from "../../../HOOks/useRequest";
|
||||
import {Progressbar} from './ProgressbarQuiz'
|
||||
import {GetOptionTask} from './GetOptionTask'
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React from 'react'
|
||||
import React, {useEffect} from 'react'
|
||||
|
||||
import { AuthBox } from '../../components/AuthBox/AuthBox'
|
||||
|
||||
@ -20,10 +20,14 @@ const AuthForDevelopers = () => {
|
||||
|
||||
const isAuth = useSelector(selectAuth);
|
||||
let navigate = useNavigate();
|
||||
const getToken = localStorage.getItem('auth_token')
|
||||
|
||||
useEffect(()=> {
|
||||
if (isAuth || getToken) {
|
||||
navigate('/profile')
|
||||
}
|
||||
}, [getToken]);
|
||||
|
||||
if (isAuth) {
|
||||
navigate('/profile')
|
||||
}
|
||||
|
||||
return (
|
||||
<section className='auth-developers'>
|
||||
|
@ -1,4 +1,4 @@
|
||||
import React from 'react'
|
||||
import React, {useEffect} from 'react'
|
||||
import arrow from '../../images/arrow__login_page.png'
|
||||
import medium from '../../images/medium_male_big.png'
|
||||
import cross from '../../images/cross.png'
|
||||
@ -18,9 +18,14 @@ const AuthForPartners = () => {
|
||||
const isAuth = useSelector(selectAuth);
|
||||
let navigate = useNavigate();
|
||||
|
||||
if (isAuth) {
|
||||
navigate('/')
|
||||
}
|
||||
const getToken = localStorage.getItem('auth_token')
|
||||
|
||||
useEffect(()=> {
|
||||
if (isAuth || getToken) {
|
||||
navigate('/')
|
||||
}
|
||||
}, [getToken]);
|
||||
|
||||
|
||||
return (
|
||||
<section className='auth-partners'>
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { WithLogout } from '../HOC/withLogout';
|
||||
import { WithLogout } from '../hoc/withLogout';
|
||||
import Calendar from '../components/Calendar/Calendar';
|
||||
|
||||
const CalendarPage = () => {
|
||||
|
@ -3,8 +3,7 @@ import {useDispatch, useSelector} from 'react-redux'
|
||||
import {useParams, useNavigate} from 'react-router-dom'
|
||||
import SVG from 'react-inlinesvg'
|
||||
|
||||
import {useRequest} from "../../HOOks/useRequest";
|
||||
import {WithLogout} from '../../HOC/withLogout'
|
||||
import {WithLogout} from '../../hoc/withLogout'
|
||||
|
||||
import Form from '../../components/Form/Form'
|
||||
import {Footer} from '../../components/Footer/Footer'
|
||||
|
@ -7,8 +7,6 @@ import {Footer} from '../../components/Footer/Footer'
|
||||
|
||||
import {profiles, tags} from '../../redux/outstaffingSlice'
|
||||
|
||||
import {useRequest} from "../../HOOks/useRequest";
|
||||
import {LogoutButton} from "../../components/LogoutButton/LogoutButton";
|
||||
import {Header} from "../../components/Header/Header";
|
||||
import {apiRequest} from "../../api/request";
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
import React from 'react'
|
||||
import { WithLogout } from '../../HOC/withLogout'
|
||||
import arrowLeft from '../../images/right-arrow.png'
|
||||
|
||||
import SVG from 'react-inlinesvg'
|
||||
|
@ -5,8 +5,6 @@ import {getProfileInfo} from "../../redux/outstaffingSlice";
|
||||
import {Footer} from '../../components/Footer/Footer'
|
||||
import {transformHtml, urlForLocal} from "../../helper";
|
||||
|
||||
import {useRequest} from "../../HOOks/useRequest";
|
||||
|
||||
import arrow from "../../images/right-arrow.png";
|
||||
import rightArrow from "../../images/arrowRight.png"
|
||||
import gitImgItem from "../../images/gitItemImg.png"
|
||||
|
Loading…
Reference in New Issue
Block a user