fixs, Убрал стейты для формы авторизации, переписал на форм дату

This commit is contained in:
Дмитрий Савенко 2023-01-25 16:50:36 +03:00
parent 50f33071bb
commit 5c8a8160bd
21 changed files with 107 additions and 209 deletions

View File

@ -1,13 +0,0 @@
import axios from 'axios';
import {getToken, urlHasParams} from "../helper";
import {useLogout} from "./useLogout";
export const useRequest = () => {
return {apiRequest}
};

View File

@ -5,7 +5,7 @@ import {withSwalInstance} from 'sweetalert2-react'
import swal from 'sweetalert2' import swal from 'sweetalert2'
import {Loader} from '../Loader/Loader' import {Loader} from '../Loader/Loader'
import ErrorBoundary from "../../HOC/ErrorBoundary"; 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'
@ -19,20 +19,19 @@ import ellipse from '../../images/ellipse.png'
import './authBox.scss' import './authBox.scss'
const {useRef} = require("react");
const SweetAlert = withSwalInstance(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 navigate = useNavigate(); const navigate = useNavigate();
const isAuth = useSelector(selectAuth); const isAuth = useSelector(selectAuth);
const isLoading = useSelector(selectIsLoading); const isLoading = useSelector(selectIsLoading);
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState(null); const [error, setError] = useState(null);
if (isAuth) { if (isAuth) {
@ -47,15 +46,13 @@ export const AuthBox = ({title, altTitle, roleChangeLink}) => {
const submitHandler = () => { const submitHandler = () => {
let formData = new FormData(ref.current)
if (!isLoading) { if (!isLoading) {
dispatch(loading(true)); dispatch(loading(true));
apiRequest('/user/login', apiRequest('/user/login',
{ {
method: 'POST', method: 'POST',
data: JSON.stringify({ data: formData
username,
password
})
}).then((res) => { }).then((res) => {
if (!res.access_token) { if (!res.access_token) {
@ -90,23 +87,21 @@ export const AuthBox = ({title, altTitle, roleChangeLink}) => {
<img src={ellipse} alt=''/> <img src={ellipse} alt=''/>
<span>{title}</span> <span>{title}</span>
</div> </div>
<form className='auth-box__form'> <form ref={ref} className='auth-box__form'>
<label htmlFor='login'>Ваш логин:</label> <label htmlFor='login'>Ваш логин:</label>
<input <input
id='login' id='login'
type='text' type='text'
name='username'
placeholder='Логин' placeholder='Логин'
value={username}
onChange={(e) => setUsername(e.target.value)}
/> />
<label htmlFor='password'>Пароль:</label> <label htmlFor='password'>Пароль:</label>
<input <input
id='password' id='password'
type='password' type='password'
name='password'
placeholder='Пароль' placeholder='Пароль'
value={password}
onChange={(e) => setPassword(e.target.value)}
/> />
{error && ( {error && (

View File

@ -12,6 +12,7 @@ import {selectCurrentCandidate} from '../../redux/outstaffingSlice'
import rectangle from '../../images/rectangle_secondPage.png' import rectangle from '../../images/rectangle_secondPage.png'
import './calendar.scss' import './calendar.scss'
import {urlForLocal} from "../../helper";
const Calendar = () => { const Calendar = () => {
@ -42,7 +43,7 @@ const Calendar = () => {
</div> </div>
<div className='col-12 col-xl-12 d-flex justify-content-between align-items-center flex-column flex-sm-row'> <div className='col-12 col-xl-12 d-flex justify-content-between align-items-center flex-column flex-sm-row'>
<div className='calendar__info'> <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> <h3 className='calendar__info-name'>{abbreviatedName}</h3>
</div> </div>
<div className='calendar__title'> <div className='calendar__title'>

View File

@ -1,10 +1,11 @@
import React from 'react' import React from 'react'
import { Link } from 'react-router-dom' import {Link} from 'react-router-dom'
import { Achievement } from '../Achievement/Achievement' import {Achievement} from '../Achievement/Achievement'
import { LEVELS, SKILLS } from '../../constants/constants' import {LEVELS, SKILLS} from '../../constants/constants'
import './candidateSidebar.scss' import './candidateSidebar.scss'
import {urlForLocal} from "../../helper";
const getYearsString = (years) => { const getYearsString = (years) => {
let yearsString; let yearsString;
@ -20,60 +21,58 @@ const getYearsString = (years) => {
return `${years} ${yearsString}` return `${years} ${yearsString}`
}; };
const CandidateSidebar = ({ candidate, setActiveSnippet, activeSnippet }) => { const CandidateSidebar = ({candidate, setActiveSnippet, activeSnippet}) => {
const userId = localStorage.getItem('id') ; const userId = localStorage.getItem('id');
const showSnippet = () => { const showSnippet = () => {
setActiveSnippet((prev)=>!prev) setActiveSnippet((prev) => !prev)
}; };
return ( return (
<div className='candidate-sidebar'> <div className='candidate-sidebar'>
<div className='candidate-sidebar__info'> <div className='candidate-sidebar__info'>
<div className='candidate-sidebar__position'> <div className='candidate-sidebar__position'>
<h2> <h2>
{candidate.specification} {SKILLS[candidate.position_id]},{' '} {candidate.specification} {SKILLS[candidate.position_id]},{' '}
{LEVELS[candidate.level]}{' '} {LEVELS[candidate.level]}{' '}
</h2> </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> </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>
</div>
) )
}; };

View File

@ -2,11 +2,10 @@ import React from 'react'
import {useSelector} from 'react-redux' import {useSelector} from 'react-redux'
import {Link} from 'react-router-dom' 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 {LEVELS, SKILLS} from '../../constants/constants'
import {selectProfiles, selectFilteredCandidates,} from '../../redux/outstaffingSlice' import {selectProfiles} from '../../redux/outstaffingSlice'
import {urlForLocal} from '../../helper' import {urlForLocal} from '../../helper'
@ -19,105 +18,17 @@ import './description.scss'
const Description = ({onLoadMore, isLoadingMore}) => { const Description = ({onLoadMore, isLoadingMore}) => {
const candidatesListArr = useSelector(selectProfiles); 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 ( return (
<section className='description'> <section className='description'>
<div className='container'> <div className='container'>
<div className='description__wrapper'> <div className='description__wrapper'>
<ErrorBoundary> <ErrorBoundary>
{filteredListArr && Array.isArray(filteredListArr) && filteredListArr.length > 0 {candidatesListArr && Array.isArray(candidatesListArr) && candidatesListArr.length > 0
? filteredListArr.map((el) => ( ? candidatesListArr.map((el) => (
<div className='row' key={el.id}> <div className='row' key={el.id}>
<div className='col-2'> <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>
<div className='col-12 col-xl-6'> <div className='col-12 col-xl-6'>
<h3 className='description__title'> <h3 className='description__title'>
@ -217,10 +128,9 @@ const Description = ({onLoadMore, isLoadingMore}) => {
<div className='col-12'> <div className='col-12'>
<div className='description__footer'> <div className='description__footer'>
<div className='description__footer-btn'> <div className='description__footer-btn'>
{candidatesListArr && {candidatesListArr && (
filteredListArr.length === 0 ? (
<button onClick={() => onLoadMore(2)}>Загрузить еще</button> <button onClick={() => onLoadMore(2)}>Загрузить еще</button>
) : null} )}
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,25 +1,28 @@
import React, {useState} from 'react' import React, {useState} from 'react'
import {useNavigate} from 'react-router-dom' 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 {Loader} from '../Loader/Loader'
import {auth} from '../../redux/outstaffingSlice'
import {getRole} from '../../redux/roleSlice' import {getRole} from '../../redux/roleSlice'
import './logoutButton.scss' import './logoutButton.scss'
export const LogoutButton = () => { export const LogoutButton = () => {
const [isLoggingOut, setIsLoggingOut] = useState(false); const [isLoggingOut, setIsLoggingOut] = useState(false);
const dispatch = useDispatch();
const userRole = useSelector(getRole); const userRole = useSelector(getRole);
const navigate = useNavigate(); const navigate = useNavigate();
const {logout} = useLogout();
return ( return (
<button <button
className='logout-button' className='logout-button'
onClick={() => { onClick={() => {
setIsLoggingOut(true); setIsLoggingOut(true);
localStorage.clear(); logout();
dispatch(auth(false));
setIsLoggingOut(false); setIsLoggingOut(false);
navigate(userRole === 'ROLE_DEV' ? '/authdev' : '/auth') navigate(userRole === 'ROLE_DEV' ? '/authdev' : '/auth')
}} }}

View File

@ -4,7 +4,7 @@ import {useDispatch, useSelector} from 'react-redux'
import { import {
selectItems, selectItems,
selectedItems, selectedItems,
filteredCandidates, profiles,
} from '../../redux/outstaffingSlice' } from '../../redux/outstaffingSlice'
import {apiRequest} from "../../api/request"; import {apiRequest} from "../../api/request";
@ -22,9 +22,11 @@ const handlePositionClick = (
}) => { }) => {
if (isSelected) { if (isSelected) {
apiRequest('/profile', { apiRequest('/profile', {
params: {limit: 1000}, params: {
limit: 1000
},
}).then((profileArr) => { }).then((profileArr) => {
dispatch(filteredCandidates(profileArr)); dispatch(profiles(profileArr));
dispatch(selectedItems([])); dispatch(selectedItems([]));
onSelect(positionId) onSelect(positionId)
}) })
@ -32,9 +34,10 @@ const handlePositionClick = (
apiRequest('/profile', { apiRequest('/profile', {
params: { params: {
limit: '1000', limit: '1000',
position_id: positionId}, position_id: positionId
}).then((el) => { },
dispatch(filteredCandidates(el)); }).then((res) => {
dispatch(profiles(res));
dispatch(selectedItems([])); dispatch(selectedItems([]));
onSelect(positionId) onSelect(positionId)
}) })

View File

@ -7,7 +7,7 @@ import {
selectedItems, selectedItems,
selectItems, selectItems,
selectTags, selectTags,
filteredCandidates, profiles,
setPositionId setPositionId
} from '../../redux/outstaffingSlice' } from '../../redux/outstaffingSlice'
@ -33,8 +33,8 @@ const TagSelect = () => {
apiRequest('/profile', { apiRequest('/profile', {
params: {...params, limit: 1000}, params: {...params, limit: 1000},
}).then((el) => { }).then((res) => {
dispatch(filteredCandidates(el)); dispatch(profiles(res));
setSearchLoading(false) setSearchLoading(false)
}) })

View File

@ -5,7 +5,6 @@ import {useEffect, useState} from "react";
import {useSelector} from "react-redux"; import {useSelector} from "react-redux";
import {selectedTest} from "../../../redux/quizSlice"; import {selectedTest} from "../../../redux/quizSlice";
import {useRequest} from "../../../HOOks/useRequest";
import {apiRequest} from "../../../api/request"; import {apiRequest} from "../../../api/request";
export const Instruction = () => { export const Instruction = () => {

View File

@ -1,7 +1,6 @@
import React, {useEffect, useState} from 'react'; import React, {useEffect, useState} from 'react';
import {useDispatch, useSelector} from "react-redux"; import {useDispatch, useSelector} from "react-redux";
import {fetchResultTest, selectedTest, selectResult} from "../../../redux/quizSlice"; import {fetchResultTest, selectedTest, selectResult} from "../../../redux/quizSlice";
import {useRequest} from "../../../HOOks/useRequest";
import {apiRequest} from "../../../api/request"; import {apiRequest} from "../../../api/request";

View File

@ -2,7 +2,6 @@ import React, {useEffect, useState} from 'react'
import {useNavigate} from "react-router-dom" import {useNavigate} from "react-router-dom"
import {useSelector, useDispatch} from 'react-redux' import {useSelector, useDispatch} from 'react-redux'
import {useRequest} from "../../../HOOks/useRequest";
import {Progressbar} from './ProgressbarQuiz' import {Progressbar} from './ProgressbarQuiz'
import {GetOptionTask} from './GetOptionTask' import {GetOptionTask} from './GetOptionTask'

View File

@ -1,4 +1,4 @@
import React from 'react' import React, {useEffect} from 'react'
import { AuthBox } from '../../components/AuthBox/AuthBox' import { AuthBox } from '../../components/AuthBox/AuthBox'
@ -20,10 +20,14 @@ const AuthForDevelopers = () => {
const isAuth = useSelector(selectAuth); const isAuth = useSelector(selectAuth);
let navigate = useNavigate(); let navigate = useNavigate();
const getToken = localStorage.getItem('auth_token')
useEffect(()=> {
if (isAuth || getToken) {
navigate('/profile')
}
}, [getToken]);
if (isAuth) {
navigate('/profile')
}
return ( return (
<section className='auth-developers'> <section className='auth-developers'>

View File

@ -1,4 +1,4 @@
import React from 'react' import React, {useEffect} from 'react'
import arrow from '../../images/arrow__login_page.png' import arrow from '../../images/arrow__login_page.png'
import medium from '../../images/medium_male_big.png' import medium from '../../images/medium_male_big.png'
import cross from '../../images/cross.png' import cross from '../../images/cross.png'
@ -18,9 +18,14 @@ const AuthForPartners = () => {
const isAuth = useSelector(selectAuth); const isAuth = useSelector(selectAuth);
let navigate = useNavigate(); let navigate = useNavigate();
if (isAuth) { const getToken = localStorage.getItem('auth_token')
navigate('/')
} useEffect(()=> {
if (isAuth || getToken) {
navigate('/')
}
}, [getToken]);
return ( return (
<section className='auth-partners'> <section className='auth-partners'>

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import { WithLogout } from '../HOC/withLogout'; import { WithLogout } from '../hoc/withLogout';
import Calendar from '../components/Calendar/Calendar'; import Calendar from '../components/Calendar/Calendar';
const CalendarPage = () => { const CalendarPage = () => {

View File

@ -3,8 +3,7 @@ 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 {useRequest} from "../../HOOks/useRequest"; import {WithLogout} from '../../hoc/withLogout'
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'

View File

@ -7,8 +7,6 @@ import {Footer} from '../../components/Footer/Footer'
import {profiles, tags} from '../../redux/outstaffingSlice' import {profiles, tags} from '../../redux/outstaffingSlice'
import {useRequest} from "../../HOOks/useRequest";
import {LogoutButton} from "../../components/LogoutButton/LogoutButton";
import {Header} from "../../components/Header/Header"; import {Header} from "../../components/Header/Header";
import {apiRequest} from "../../api/request"; import {apiRequest} from "../../api/request";

View File

@ -1,5 +1,4 @@
import React from 'react' import React from 'react'
import { WithLogout } from '../../HOC/withLogout'
import arrowLeft from '../../images/right-arrow.png' import arrowLeft from '../../images/right-arrow.png'
import SVG from 'react-inlinesvg' import SVG from 'react-inlinesvg'

View File

@ -5,8 +5,6 @@ import {getProfileInfo} from "../../redux/outstaffingSlice";
import {Footer} from '../../components/Footer/Footer' import {Footer} from '../../components/Footer/Footer'
import {transformHtml, urlForLocal} from "../../helper"; import {transformHtml, urlForLocal} from "../../helper";
import {useRequest} from "../../HOOks/useRequest";
import arrow from "../../images/right-arrow.png"; import arrow from "../../images/right-arrow.png";
import rightArrow from "../../images/arrowRight.png" import rightArrow from "../../images/arrowRight.png"
import gitImgItem from "../../images/gitItemImg.png" import gitImgItem from "../../images/gitItemImg.png"