Merge pull request #12 from apuc/authentication

Authentication
This commit is contained in:
kavalar 2021-08-11 16:05:56 +03:00 committed by GitHub
commit fffd254e43
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 141 additions and 82 deletions

View File

@ -67,27 +67,30 @@ const AuthForDevelopers = () => {
onChange={(e) => setPassword(e.target.value)} onChange={(e) => setPassword(e.target.value)}
/> />
<button <div className={style.form__buttons}>
className={style.form__btn} <button
onClick={!isLoading ? (e) => { className={style.form__btn}
e.preventDefault(); onClick={!isLoading ? (e) => {
dispatch(loading(true)) e.preventDefault();
fetchAuth({ dispatch(loading(true))
username, fetchAuth({
password, username,
dispatch: ()=> { password,
dispatch(auth(true)) dispatch: ()=> {
dispatch(loading(false)) dispatch(auth(true))
} dispatch(loading(false))
}) }
} : ()=>{}} })
> } : ()=>{}}
{ isLoading ? <Loader /> : 'Войти' } >
</button> { isLoading ? <Loader /> : 'Войти' }
</button>
<button className={`${style.form__btn__partners} ${style.auth__link}`}>
<Link to='/auth'>Для партнёров</Link>
</button>
</div>
<button className={`${style.form__btn__partners} ${style.auth__link}`}>
<Link to='/auth'>Для партнёров</Link>
</button>
</form> </form>
</div> </div>
</div> </div>

View File

@ -132,8 +132,14 @@
outline: none; outline: none;
} }
.form__buttons {
display: flex;
justify-content: start;
align-items: center;
}
.form__btn { .form__btn {
width: 288px; width: 268px;
height: 75px; height: 75px;
box-shadow: 6px 5px 20px rgba(82, 151, 34, 0.21); box-shadow: 6px 5px 20px rgba(82, 151, 34, 0.21);
border-radius: 38px; border-radius: 38px;
@ -154,6 +160,7 @@
line-height: 71.88px; line-height: 71.88px;
text-align: center; text-align: center;
border: 2px solid #6aaf5c; border: 2px solid #6aaf5c;
margin-right: 1.5rem;
} }
.form__btn:hover .loader * { .form__btn:hover .loader * {
@ -169,7 +176,7 @@
} }
.form__btn__partners { .form__btn__partners {
width: 288px; width: 268px;
height: 75px; height: 75px;
border-radius: 38px; border-radius: 38px;
background-color: #ffffff; background-color: #ffffff;
@ -432,7 +439,6 @@
.auth__link { .auth__link {
display: block; display: block;
margin-top: 1.3rem;
} }
@ -442,3 +448,14 @@
height: 100%; height: 100%;
color: #fff; color: #fff;
} }
@media (max-width: 766px) {
.form__buttons {
flex-direction: column;
}
.form__btn {
margin: 0;
margin-bottom: 1.5rem;
}
}

View File

@ -62,6 +62,7 @@ const AuthForPartners = () => {
onChange={(e) => setPassword(e.target.value)} onChange={(e) => setPassword(e.target.value)}
/> />
<div className={style.form__buttons}>
<button <button
className={style.form__btn} className={style.form__btn}
onClick={!isLoading ? (e) => { onClick={!isLoading ? (e) => {
@ -83,6 +84,7 @@ const AuthForPartners = () => {
<button className={`${style.form__btn__dev} ${style.auth__link}`}> <button className={`${style.form__btn__dev} ${style.auth__link}`}>
<Link to='/authdev'>Для разработчиков</Link> <Link to='/authdev'>Для разработчиков</Link>
</button> </button>
</div>
</form> </form>
</div> </div>
</div> </div>

View File

@ -132,8 +132,14 @@
outline: none; outline: none;
} }
.form__buttons {
display: flex;
justify-content: start;
align-items: center;
}
.form__btn { .form__btn {
width: 288px; width: 268px;
height: 75px; height: 75px;
box-shadow: 6px 5px 20px rgba(82, 151, 34, 0.21); box-shadow: 6px 5px 20px rgba(82, 151, 34, 0.21);
border-radius: 38px; border-radius: 38px;
@ -154,6 +160,7 @@
line-height: 71.88px; line-height: 71.88px;
text-align: center; text-align: center;
border: 2px solid #6aaf5c; border: 2px solid #6aaf5c;
margin-right: 1.5rem;
} }
.form__btn:hover { .form__btn:hover {
@ -166,7 +173,7 @@
.form__btn__dev { .form__btn__dev {
width: 288px; width: 268px;
height: 75px; height: 75px;
border-radius: 38px; border-radius: 38px;
background-color: #ffffff; background-color: #ffffff;
@ -430,7 +437,6 @@
.auth__link { .auth__link {
display: block; display: block;
margin-top: 1.3rem;
} }
.auth__link a { .auth__link a {
@ -439,3 +445,14 @@
height: 100%; height: 100%;
color: #fff; color: #fff;
} }
@media (max-width: 766px) {
.form__buttons {
flex-direction: column;
}
.form__btn {
margin: 0;
margin-bottom: 1.5rem;
}
}

View File

@ -4,12 +4,13 @@ import male from '../../images/medium_male.png';
import rectangle from '../../images/rectangle_secondPage.png'; import rectangle from '../../images/rectangle_secondPage.png';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { LEVELS, SKILLS } from '../constants/constants'; import { LEVELS, SKILLS } from '../constants/constants';
import { selectProfiles, selectFilteredCandidates } from '../../redux/outstaffingSlice'; import { selectProfiles, selectFilteredCandidates, selectItems } from '../../redux/outstaffingSlice';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import { fetchProfile } from '../../server/server'; import { fetchProfile } from '../../server/server';
const Description = ({ onLoadMore }) => { const Description = ({ onLoadMore }) => {
const candidatesListArr = useSelector(selectProfiles); const candidatesListArr = useSelector(selectProfiles);
const itemsArr = useSelector(selectItems);
const filteredListArr = useSelector(selectFilteredCandidates); const filteredListArr = useSelector(selectFilteredCandidates);
const [allCandidates, getAllCandidates] = useState([]); const [allCandidates, getAllCandidates] = useState([]);
@ -17,60 +18,69 @@ const Description = ({ onLoadMore }) => {
fetchProfile(`${process.env.REACT_APP_API_URL}/api/profile?limit=`, 1000).then((p) => getAllCandidates(p)); fetchProfile(`${process.env.REACT_APP_API_URL}/api/profile?limit=`, 1000).then((p) => getAllCandidates(p));
}, []); }, []);
console.log('render',filteredListArr, itemsArr)
if(!filteredListArr) {
return (
<section className={style.description}>
<div className="container">
<div className={style.description__wrapper}>
{
candidatesListArr.map((el) => (
<div className="row" key={el.id}>
<div className="col-2">
<img className={style.description__img} src={male} alt="" />
</div>
<div className="col-12 col-xl-6">
<h3 className={style.description__title}>
{SKILLS[el.position_id]}, {LEVELS[el.level]}
</h3>
{el.vc_text_short ? (
<div className={style.description__text}>{el.vc_text_short}</div>
) : (
<p className={style.description__textSecondary}>Описание отсутствует...</p>
)}
</div>
<div className="col-12 col-xl-4">
<Link to={`/candidate/${el.id}`}>
<button className={style.description__button}>Подробное резюме</button>
</Link>
</div>
<div className="col-xl-2"></div>
<div className="col-12 col-xl-6">
<ul className={style.description__list}>
{el.skillValues.map((e) => (
<li key={e.id} className={style.description__list__item}>
{e.skill.name}
</li>
))}
</ul>
<img className={style.description__rectangle} src={rectangle} alt="" />
</div>
<div className="col-xl-4"></div>
</div>
))}
</div>
</div>
</section>
);
}
return ( return (
<section className={style.description}> <section className={style.description}>
<div className="container"> <div className="container">
<div className={style.description__wrapper}> <div className={style.description__wrapper}>
{filteredListArr {filteredListArr
? (filteredListArr.length > 0 ? filteredListArr.map((el) => (
? <></>
: filteredListArr.map((el) => (
<div className="row" key={el.id}>
<div className="col-2">
<img className={style.description__img} src={male} alt="" />
</div>
<div className="col-12 col-xl-6">
<h3 className={style.description__title}>
<Link to={`/candidate/${el.id}`}>
{SKILLS[el.position_id]}, {LEVELS[el.level]}
</Link>
</h3>
{el.vc_text_short ? (
<div className={style.description__text}>{el.vc_text_short}</div>
) : (
<p className={style.description__textSecondary}>Описание отсутствует...</p>
)}
</div>
<div className="col-12 col-xl-4">
<Link to={`/candidate/${el.id}`}>
<button className={style.description__button}>Подробное резюме</button>
</Link>
</div>
<div className="col-xl-2"></div>
<div className="col-12 col-xl-6">
<ul className={style.description__list}>
{el.skillValues.map((e) => (
<li key={e.id} className={style.description__list__item}>
{e.skill.name}
</li>
))}
</ul>
<img className={style.description__rectangle} src={rectangle} alt="" />
</div>
<div className="col-xl-4"></div>
</div>
)))
: 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={style.description__img} src={male} alt="" /> <img className={style.description__img} src={male} alt="" />
</div> </div>
<div className="col-12 col-xl-6"> <div className="col-12 col-xl-6">
<h3 className={style.description__title}> <h3 className={style.description__title}>
<Link to={`/candidate/${el.id}`}> {SKILLS[el.position_id]}, {LEVELS[el.level]}
{SKILLS[el.position_id]}, {LEVELS[el.level]}
</Link>
</h3> </h3>
{el.vc_text_short ? ( {el.vc_text_short ? (
@ -97,14 +107,15 @@ const Description = ({ onLoadMore }) => {
</div> </div>
<div className="col-xl-4"></div> <div className="col-xl-4"></div>
</div> </div>
))} ))
: filteredListArr.length && filteredListArr.length === 0 && <></> }
</div> </div>
<div className="row"> <div className="row">
<div className="col-12"> <div className="col-12">
<div className={style.description__footer}> <div className={style.description__footer}>
<div className={style.description__footer__btn}> <div className={style.description__footer__btn}>
{candidatesListArr.length !== allCandidates.length && filteredListArr.length === 0 ? ( {(candidatesListArr.length !== allCandidates.length && filteredListArr.length > 0) || filteredListArr===null ? (
<button onClick={() => onLoadMore(2)}>Загрузить еще</button> <button onClick={() => onLoadMore(2)}>Загрузить еще</button>
) : null} ) : null}
</div> </div>

View File

@ -1,7 +1,7 @@
.logout-button { .logout-button {
position: fixed; position: fixed;
top: 2rem; top: 70px;
right: 3.5rem; right: 2.5rem;
z-index: 100; z-index: 100;
} }
@ -10,21 +10,30 @@
justify-content: center; justify-content: center;
align-items: center; align-items: center;
margin: 0; margin: 0;
padding: 1rem 2rem; width: 131px;
border-radius: 20px; height: 40px;
border-radius: 10px;
font-family: 'Muller';
font-size: 1.6em;
letter-spacing: 0.8px;
background-color: #6aaf5c; background-color: #6aaf5c;
color: #ffffff; color: #ffffff;
border: 2px solid #6aaf5c; border: 3px solid #6aaf5c;
font-family: 'Muller'; font-family: 'Muller';
font-size: 2em;
letter-spacing: normal;
text-align: center; text-align: center;
} }
.logout-button:hover button { .logout-button:hover button {
background-color: #ffffff; background-color: #ffffff;
color: #6aaf5c; color: #6aaf5c;
border: 2px solid #6aaf5c; border: 3px solid #6aaf5c;
box-shadow: 3px 2px 5px rgba(82, 151, 34, 0.21); box-shadow: 3px 2px 5px rgba(82, 151, 34, 0.21);
transition: .3s; transition: .3s;
} }
@media (max-width: 1198px) {
.logout-button {
top: 16px;
}
}

View File

@ -3,7 +3,7 @@ import { createSlice } from '@reduxjs/toolkit';
const initialState = { const initialState = {
tags: [], tags: [],
profiles: [], profiles: [],
filteredCandidates: [], filteredCandidates:null,
selectedItems: [], selectedItems: [],
currentCandidate: {}, currentCandidate: {},
auth: false, auth: false,