Merge pull request #33 from apuc/authentication

logout fixes with role redirect
This commit is contained in:
kavalar 2021-08-20 18:02:54 +03:00 committed by GitHub
commit 5b0c1a17f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 89 additions and 29 deletions

View File

@ -14,6 +14,7 @@ import { fetchAuth } from '../../server/server'
import { selectAuth } from '../../redux/outstaffingSlice';
import { selectIsLoading } from '../../redux/loaderSlice';
import { setRole } from '../../redux/roleSlice';
import { Redirect, Link } from 'react-router-dom';
import { Loader } from '../Loader/Loader'
@ -71,8 +72,6 @@ const AuthForDevelopers = () => {
onChange={(e) => setPassword(e.target.value)}
/>
{ error && <div className={style.form__error}>
<SweetAlert
show={!!error}
@ -94,6 +93,7 @@ const AuthForDevelopers = () => {
dispatch: ()=> {
dispatch(auth(true))
dispatch(loading(false))
dispatch(setRole('ROLE_DEV'))
},
catchError: () => {
setError('Некорректные данные для входа')

View File

@ -18,6 +18,7 @@ import { fetchAuth } from '../../server/server'
import { useSelector } from 'react-redux'
import { selectAuth } from '../../redux/outstaffingSlice';
import { selectIsLoading } from '../../redux/loaderSlice';
import { setRole } from '../../redux/roleSlice';
import { Redirect, Link } from 'react-router-dom';
import { Loader } from '../Loader/Loader'
@ -90,6 +91,7 @@ const AuthForPartners = () => {
dispatch: ()=> {
dispatch(auth(true))
dispatch(loading(false))
dispatch(setRole('ROLE_PARTNER'))
},
catchError: () => {
setError('Некорректные данные для входа')

View File

@ -13,18 +13,20 @@ import { fetchItemsForId } from '../../server/server';
import { Footer } from '../Footer/Footer';
import './candidate.css';
import { getRole } from '../../redux/roleSlice';
const Candidate = () => {
const history = useHistory();
const { id: candidateId } = useParams();
const dispatch = useDispatch();
const role = useSelector(getRole);
useEffect(() => {
window.scrollTo(0, 0)
}, [])
useEffect(() => {
fetchItemsForId(`${process.env.REACT_APP_API_URL}/api/profile/`, Number(candidateId)).then((el) =>
fetchItemsForId({ link: `${process.env.REACT_APP_API_URL}/api/profile/`, index:Number(candidateId), history, role }).then((el) =>
dispatch(currentCandidate(el))
);
}, [dispatch, candidateId]);

View File

@ -2,21 +2,24 @@ import React, { useEffect, useState } from 'react';
import style from './Description.module.css';
import male from '../../images/medium_male.png';
import rectangle from '../../images/rectangle_secondPage.png';
import { Link } from 'react-router-dom';
import { Link, useHistory } from 'react-router-dom';
import { LEVELS, SKILLS } from '../constants/constants';
import { selectProfiles, selectFilteredCandidates, selectItems } from '../../redux/outstaffingSlice';
import { useSelector } from 'react-redux';
import { fetchProfile } from '../../server/server';
import { Loader } from '../Loader/Loader';
import { getRole } from '../../redux/roleSlice';
const Description = ({ onLoadMore, isLoadingMore }) => {
const history = useHistory();
const role = useSelector(getRole)
const candidatesListArr = useSelector(selectProfiles);
const itemsArr = useSelector(selectItems);
const filteredListArr = useSelector(selectFilteredCandidates);
const [allCandidates, getAllCandidates] = useState([]);
useEffect(() => {
fetchProfile(`${process.env.REACT_APP_API_URL}/api/profile?limit=`, 1000).then((p) => getAllCandidates(p));
fetchProfile({ link: `${process.env.REACT_APP_API_URL}/api/profile?limit=`, index: 1000, history, role }).then((p) => getAllCandidates(p));
}, []);
if(!filteredListArr) {

View File

@ -8,10 +8,14 @@ import './form.css';
import { withSwalInstance } from 'sweetalert2-react';
import swal from 'sweetalert2';
import { useSelector } from 'react-redux';
import { getRole } from '../../redux/roleSlice';
const SweetAlert = withSwalInstance(swal);
const Form = () => {
const history = useHistory();
const role = useSelector(getRole);
const urlParams = useParams();
const [status, setStatus] = useState(null);
const [data, setData] = useState({
@ -20,8 +24,6 @@ const Form = () => {
comment: '',
});
const history = useHistory();
const handleChange = (e) => {
const { id, value } = e.target;
@ -40,10 +42,10 @@ const Form = () => {
formData.append('phone', data.phone);
formData.append('comment', data.comment);
fetchForm(`${process.env.REACT_APP_API_URL}/api/profile/add-to-interview`, {
fetchForm({ link: `${process.env.REACT_APP_API_URL}/api/profile/add-to-interview`, index: {
profile_id: urlParams.id,
...data,
}).then( (res)=> res.json()
}, history, role }).then( (res)=> res.json()
.then( resJSON => setStatus(resJSON))
)
};

View File

@ -1,25 +1,29 @@
import React, { useState, useEffect } from 'react';
import { useDispatch } from 'react-redux';
import { useDispatch, useSelector } from 'react-redux';
import Outstaffing from '../Outstaffing/Outstaffing';
import Description from '../Description/Description';
import { fetchProfile, fetchSkills } from '../../server/server';
import { profiles, tags } from '../../redux/outstaffingSlice';
import { getRole } from '../../redux/roleSlice';
import { Footer } from '../Footer/Footer';
import { useHistory } from 'react-router-dom';
const Home = () => {
const history = useHistory()
const [isLoadingMore, setIsLoadingMore] = useState(false);
const [index, setIndex] = useState(4);
const dispatch = useDispatch();
const role = useSelector(getRole)
useEffect(() => {
setIsLoadingMore(true);
fetchProfile(`${process.env.REACT_APP_API_URL}/api/profile?limit=`, index).then((profileArr) => {
fetchProfile({ link:`${process.env.REACT_APP_API_URL}/api/profile?limit=`, index, history, role}).then((profileArr) => {
dispatch(profiles(profileArr));
setIsLoadingMore(false);
});
fetchSkills(`${process.env.REACT_APP_API_URL}/api/skills/skills-on-main-page`).then((skills) => {
fetchSkills({ link: `${process.env.REACT_APP_API_URL}/api/skills/skills-on-main-page`, history, role}).then((skills) => {
const keys = Object.keys(skills);
const values = Object.values(skills);

View File

@ -1,16 +1,28 @@
import React, { useState } from 'react';
import { useDispatch } from 'react-redux';
import { useHistory } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { Loader } from '../Loader/Loader';
import { auth } from '../../redux/outstaffingSlice';
import { getRole } from '../../redux/roleSlice';
import './logoutButton.css'
export const LogoutButton = () => {
const [isLoggingOut, setIsLoggingOut] = useState(false);
const dispatch = useDispatch();
const userRole = useSelector(getRole);
const history = useHistory();
return (
<div className='logout-button'>
<button onClick={()=>{setIsLoggingOut(true); localStorage.clear(); dispatch(auth(false)); setIsLoggingOut(false); }}>
<button onClick={()=>{
setIsLoggingOut(true);
localStorage.clear();
dispatch(auth(false));
setIsLoggingOut(false);
history.push(userRole === 'ROLE_DEV' ? '/authdev' : '/auth')
}}>
{
isLoggingOut ? <Loader /> : 'Выйти'
} </button>

View File

@ -6,18 +6,19 @@ import { fetchItemsForId } from '../../server/server';
import style from './Outstaffing.module.css';
import { fetchProfile } from '../../server/server';
import { useHistory } from 'react-router-dom';
import { getRole } from '../../redux/roleSlice';
const handlePositionClick = ({dispatch, positionId, isSelected, onSelect}) => {
const handlePositionClick = ({dispatch, positionId, isSelected, onSelect, history, role}) => {
if(isSelected) {
fetchProfile(`${process.env.REACT_APP_API_URL}/api/profile?limit=`, 4).then((profileArr) => {
fetchProfile({ link: `${process.env.REACT_APP_API_URL}/api/profile?limit=`, index: 4, history, role }).then((profileArr) => {
dispatch(filteredCandidates(profileArr));
dispatch(selectedItems([]));
onSelect(positionId);
}
);
} else {
fetchItemsForId(`${process.env.REACT_APP_API_URL}/api/profile?position_id=`, positionId).then((el) => {
fetchItemsForId({ link: `${process.env.REACT_APP_API_URL}/api/profile?position_id=`, index: positionId, history, role, }).then((el) => {
dispatch(filteredCandidates(el));
dispatch(selectedItems([]));
onSelect(positionId);
@ -27,6 +28,8 @@ const handlePositionClick = ({dispatch, positionId, isSelected, onSelect}) => {
};
const OutstaffingBlock = ({ dataTags = [], selected, img, header, positionId, isSelected, onSelect }) => {
const history = useHistory();
const role = useSelector(getRole);
const dispatch = useDispatch();
@ -57,7 +60,7 @@ const OutstaffingBlock = ({ dataTags = [], selected, img, header, positionId, is
}}
>
<div className={`${style.outstaffing__box} ${isSelected?style.outstaffing__box__selected:''}`} >
<div className={`${style.outstaffing__box__img} ${selected ? style.border : ''}`} onClick={()=>handlePositionClick({dispatch, positionId, isSelected, onSelect})}>
<div className={`${style.outstaffing__box__img} ${selected ? style.border : ''}`} onClick={()=>handlePositionClick({dispatch, positionId, isSelected, onSelect, history, role})}>
<h3>{header}</h3>
<img className={classes} src={img} alt="img" />
</div>

View File

@ -5,8 +5,12 @@ import { Loader } from '../Loader/Loader';
import style from './TagSelect.module.css';
import { selectedItems, selectItems, selectTags, filteredCandidates, setPositionId } from '../../redux/outstaffingSlice';
import { fetchItemsForId } 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();
@ -20,7 +24,7 @@ const TagSelect = () => {
dispatch(setPositionId(null));
const filterItemsId = itemsArr.map((item) => item.id).join();
fetchItemsForId(`${process.env.REACT_APP_API_URL}/api/profile?skills=`, filterItemsId).then((el) => {
fetchItemsForId({ link: `${process.env.REACT_APP_API_URL}/api/profile?skills=`, index: filterItemsId, history, role, }).then((el) => {
dispatch(filteredCandidates(el))
setSearchLoading(false)
});

View File

@ -84,7 +84,6 @@
}
@media (max-width: 575.98px) {
.candidateSidebar__info__btn,
.candidateSidebar__info__l,
.candidateSidebar__arrows {
display: none;

View File

@ -1,6 +1,6 @@
import React from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useHistory, useParams, } from 'react-router-dom';
import { useHistory, useParams, Link } from 'react-router-dom';
import { currentCandidate, selectCurrentCandidate } from '../redux/outstaffingSlice';
import SVG from 'react-inlinesvg';
import { WithLogout } from '../hoc/withLogout';
@ -14,6 +14,7 @@ import rectangle from '../images/rectangle_secondPage.png';
import telegramIcon from '../images/telegram-icon.svg';
import './formPage.scss';
import { getRole } from '../redux/roleSlice';
const goBack = (history) => {
history.goBack();
@ -23,10 +24,11 @@ const FormPage = () => {
const params = useParams();
const history = useHistory();
const dispatch = useDispatch();
const candidate = useSelector(selectCurrentCandidate)
const candidate = useSelector(selectCurrentCandidate);
const role = useSelector(getRole);
if(!candidate.id) {
fetchItemsForId(`${process.env.REACT_APP_API_URL}/api/profile/`, Number(params.id)).then((el) =>
fetchItemsForId({ link: `${process.env.REACT_APP_API_URL}/api/profile/`, index: Number(params.id), history, role, }).then((el) =>
dispatch(currentCandidate(el))
);
}
@ -67,7 +69,7 @@ const FormPage = () => {
<div className='form-page__telegram'>
<div className='form-page__telegram-text'>Заявка на собеседование через телеграм</div>
<div className='form-page__telegram-icon'>
<SVG src={telegramIcon} />
<a href='https://t.me/st0kir' target='_blank'><SVG src={telegramIcon} /></a>
</div>
</div>
</div>

21
src/redux/roleSlice.js Normal file
View File

@ -0,0 +1,21 @@
import { createSlice } from '@reduxjs/toolkit';
const initialState = {
role: null,
};
export const roleSlice = createSlice({
name: 'role',
initialState,
reducers: {
setRole: (state, action) => {
state.role = action.payload;
},
},
});
export const { setRole } = roleSlice.actions;
export const getRole = (state) => state.role.role;
export default roleSlice.reducer;

View File

@ -1,11 +1,15 @@
export const withAuthRedirect = actionCall => (link, index) => {
export const withAuthRedirect = actionCall => ({link, index, history, role}) => {
return actionCall(link, index)
.then(res => {
if(res.status && res.status == 401) {
localStorage.clear();
history.push(role === 'ROLE_DEV' ? '/authdev' : '/auth')
}
return res;
})
.catch(err => localStorage.clear())
.catch(err => {
localStorage.clear();
history.push(role === 'ROLE_DEV' ? '/authdev' : '/auth');
})
}

View File

@ -1,10 +1,12 @@
import { configureStore } from '@reduxjs/toolkit';
import outstaffingReducer from '../redux/outstaffingSlice';
import loaderReducer from '../redux/loaderSlice';
import roleReducer from '../redux/roleSlice';
export const store = configureStore({
reducer: {
outstaffing: outstaffingReducer,
loader: loaderReducer,
role: roleReducer
},
});