Merge pull request #9 from apuc/authentication

logout, hover transition and small fixes
This commit is contained in:
kavalar 2021-08-09 15:19:38 +03:00 committed by GitHub
commit d58b7b62d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 218 additions and 39 deletions

8
package-lock.json generated
View File

@ -12735,6 +12735,14 @@
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
},
"react-loader-spinner": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/react-loader-spinner/-/react-loader-spinner-4.0.0.tgz",
"integrity": "sha512-RU2vpEej6G4ECei0h3q6bgLU10of9Lw5O+4AwF/mtkrX5oY20Sh/AxoPJ7etbrs/7Q3u4jN5qwCwGLRKCHpk6g==",
"requires": {
"prop-types": "^15.7.2"
}
},
"react-overlays": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/react-overlays/-/react-overlays-5.0.1.tgz",

View File

@ -16,6 +16,7 @@
"react": "^17.0.2",
"react-bootstrap": "^1.6.0",
"react-dom": "^17.0.2",
"react-loader-spinner": "^4.0.0",
"react-redux": "^7.2.4",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",

View File

@ -1,19 +1,19 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Web site created using create-react-app" />
</body>
</html>
<title>Outstaffing</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>

View File

@ -1,6 +1,7 @@
import React, { useState } from 'react'
import { useDispatch } from 'react-redux'
import { useDispatch, useSelector } from 'react-redux'
import { auth } from '../../redux/outstaffingSlice'
import { loading } from '../../redux/loaderSlice'
import style from './AuthForDevelopers.module.css'
import ellipse from '../../images/ellipse.png'
import arrow from '../../images/arrow__login_page.png'
@ -14,13 +15,15 @@ import vector from '../../images/Vector_Smart_Object.png'
import vectorBlack from '../../images/Vector_Smart_Object_black.png'
import { fetchAuth } from '../../server/server'
import { useSelector } from 'react-redux'
import { selectAuth } from '../../redux/outstaffingSlice';
import { selectIsLoading } from '../../redux/loaderSlice';
import { Redirect, Link } from 'react-router-dom';
import { Loader } from '../Loader/Loader'
const AuthForDevelopers = () => {
const dispatch = useDispatch()
const isAuth = useSelector(selectAuth)
const isLoading = useSelector(selectIsLoading)
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
@ -66,19 +69,23 @@ const AuthForDevelopers = () => {
<button
className={style.form__btn}
onClick={(e) => {
onClick={!isLoading ? (e) => {
e.preventDefault();
dispatch(loading(true))
fetchAuth({
username,
password,
dispatch: ()=> dispatch(auth(true))
dispatch: ()=> {
dispatch(auth(true))
dispatch(loading(false))
}
})
}}
} : ()=>{}}
>
Войти
{ isLoading ? <Loader /> : 'Войти' }
</button>
<button className={`${style.form__btn} ${style.auth__link}`}>
<button className={`${style.form__btn__partners} ${style.auth__link}`}>
<Link to='/auth'>Для партнёров</Link>
</button>
</form>

View File

@ -153,6 +153,32 @@
letter-spacing: normal;
line-height: 71.88px;
text-align: center;
border: 2px solid #6aaf5c;
}
.form__btn:hover {
background-image: none;
background-color: #ffffff;
border: 2px solid #6aaf5c;
color: #6aaf5c !important;
transition: .3s;
}
.form__btn__partners {
width: 288px;
height: 75px;
border-radius: 38px;
background-color: #ffffff;
border: 2px solid #6aaf5c;
font-family: 'Muller';
font-size: 2em;
letter-spacing: normal;
line-height: 71.88px;
text-align: center;
}
.form__btn__partners a {
color: #6aaf5c !important;
}
@media (max-width: 575.98px) {

View File

@ -1,6 +1,7 @@
import React, { useState } from 'react';
import { useDispatch } from 'react-redux';
import { auth } from '../../redux/outstaffingSlice';
import { loading } from '../../redux/loaderSlice'
import style from './AuthForPartners.module.css';
import ellipse from '../../images/ellipse.png';
import arrow from '../../images/arrow__login_page.png';
@ -16,12 +17,15 @@ import { fetchAuth } from '../../server/server'
import { useSelector } from 'react-redux'
import { selectAuth } from '../../redux/outstaffingSlice';
import { selectIsLoading } from '../../redux/loaderSlice';
import { Redirect, Link } from 'react-router-dom';
import { Loader } from '../Loader/Loader'
const AuthForPartners = () => {
const dispatch = useDispatch()
const isAuth = useSelector(selectAuth)
const isLoading = useSelector(selectIsLoading)
console.log('iL',isLoading);
const [username, setUsername] = useState('')
const [password, setPassword] = useState('')
@ -58,20 +62,25 @@ const AuthForPartners = () => {
onChange={(e) => setPassword(e.target.value)}
/>
<button className={style.form__btn}
onClick={(e) => {
<button
className={style.form__btn}
onClick={!isLoading ? (e) => {
e.preventDefault();
dispatch(loading(true))
fetchAuth({
username,
password,
dispatch: ()=> dispatch(auth(true))
dispatch: ()=> {
dispatch(auth(true))
dispatch(loading(false))
}
})
}
}>
Войти
} : ()=>{}}
>
{ isLoading ? <Loader /> : 'Войти' }
</button>
<button className={`${style.form__btn} ${style.auth__link}`}>
<button className={`${style.form__btn__dev} ${style.auth__link}`}>
<Link to='/authdev'>Для разработчиков</Link>
</button>
</form>

View File

@ -153,6 +153,33 @@
letter-spacing: normal;
line-height: 71.88px;
text-align: center;
border: 2px solid #6aaf5c;
}
.form__btn:hover {
background-image: none;
background-color: #ffffff;
border: 2px solid #6aaf5c;
color: #6aaf5c !important;
transition: .3s;
}
.form__btn__dev {
width: 288px;
height: 75px;
border-radius: 38px;
background-color: #ffffff;
border: 2px solid #6aaf5c;
font-family: 'Muller';
font-size: 2em;
letter-spacing: normal;
line-height: 71.88px;
text-align: center;
}
.form__btn__dev a {
color: #6aaf5c !important;
}
@media (max-width: 575.98px) {

View File

@ -29,7 +29,9 @@ const Description = ({ onLoadMore }) => {
</div>
<div className="col-12 col-xl-6">
<h3 className={style.description__title}>
{SKILLS[el.position_id]}, {LEVELS[el.level]}
<Link to={`/candidate/${el.id}`}>
{SKILLS[el.position_id]}, {LEVELS[el.level]}
</Link>
</h3>
{el.vc_text_short ? (
@ -64,7 +66,9 @@ const Description = ({ onLoadMore }) => {
</div>
<div className="col-12 col-xl-6">
<h3 className={style.description__title}>
{SKILLS[el.position_id]}, {LEVELS[el.level]}
<Link to={`/candidate/${el.id}`}>
{SKILLS[el.position_id]}, {LEVELS[el.level]}
</Link>
</h3>
{el.vc_text_short ? (

View File

@ -53,6 +53,10 @@
margin-bottom: 10px;
}
.description__title {
color: #333;
}
@media (max-width: 575.98px) {
.description__title {
text-align: center;

View File

@ -0,0 +1,14 @@
import SVGLoader from "react-loader-spinner";
export const Loader = () => {
return (
<div className='loader'>
<SVGLoader
type="Circles"
color="#fff"
height={50}
width={50}
timeout={3000}
/>
</div>
);
}

View File

@ -0,0 +1,14 @@
import React from 'react';
import { useDispatch } from 'react-redux';
import { auth } from '../../redux/outstaffingSlice';
import './logoutButton.css'
export const LogoutButton = () => {
const dispatch = useDispatch();
return (
<div className='logout-button' onClick={()=>{localStorage.clear(); dispatch(auth(false));}}>
<button>Выйти</button>
</div>
)
}

View File

@ -0,0 +1,30 @@
.logout-button {
position: fixed;
top: 2rem;
right: 3.5rem;
z-index: 100;
}
.logout-button button {
display: flex;
justify-content: center;
align-items: center;
margin: 0;
padding: 1rem 2rem;
border-radius: 20px;
background-color: #6aaf5c;
color: #ffffff;
border: 2px solid #6aaf5c;
font-family: 'Muller';
font-size: 2em;
letter-spacing: normal;
text-align: center;
}
.logout-button:hover button {
background-color: #ffffff;
color: #6aaf5c;
border: 2px solid #6aaf5c;
box-shadow: 3px 2px 5px rgba(82, 151, 34, 0.21);
transition: .3s;
}

9
src/hoc/withLogout.js Normal file
View File

@ -0,0 +1,9 @@
import React from 'react';
import { LogoutButton } from '../components/LogoutButton/LogoutButton';
export const WithLogout = (props) => {
return <>
<LogoutButton />
{props.children}
</>
}

View File

@ -1,8 +1,9 @@
import React from 'react';
import { WithLogout } from '../hoc/withLogout';
import Calendar from '../components/Calendar/Calendar';
const CalendarPage = () => {
return <Calendar />;
return <WithLogout><Calendar /></WithLogout>;
};
export default CalendarPage;

View File

@ -1,7 +1,7 @@
import React from 'react';
import { WithLogout } from '../hoc/withLogout';
import Candidate from '../components/Candidate/Candidate';
const CandidatePage = () => <Candidate />;
const CandidatePage = () => <WithLogout><Candidate /></WithLogout>;
export default CandidatePage;

View File

@ -1,6 +1,7 @@
import React from 'react';
import { WithLogout } from '../hoc/withLogout';
import Form from '../components/Form/Form';
const FormPage = () => <Form />;
const FormPage = () => <WithLogout><Form /></WithLogout>;
export default FormPage;

View File

@ -1,7 +1,7 @@
import React from 'react';
import { WithLogout } from '../hoc/withLogout';
import Home from '../components/Home/Home';
const HomePage = () => <Home />;
const HomePage = () => <WithLogout><Home /></WithLogout>;
export default HomePage;

View File

@ -1,6 +1,7 @@
import React from 'react';
import { WithLogout } from '../hoc/withLogout';
import ReportForm from '../components/ReportForm/ReportForm';
const ReportFormPage = () => <ReportForm />;
const ReportFormPage = () => <WithLogout><ReportForm /></WithLogout>;
export default ReportFormPage;

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

@ -0,0 +1,21 @@
import { createSlice } from '@reduxjs/toolkit';
const initialState = {
isLoading: false,
};
export const loaderSlice = createSlice({
name: 'loader',
initialState,
reducers: {
loading: (state, action) => {
state.isLoading = action.payload;
},
},
});
export const { loading } = loaderSlice.actions;
export const selectIsLoading = (state) => state.loader.isLoading;
export default loaderSlice.reducer;

View File

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