Merge pull request #9 from apuc/authentication
logout, hover transition and small fixes
This commit is contained in:
commit
d58b7b62d3
8
package-lock.json
generated
8
package-lock.json
generated
@ -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",
|
||||
|
@ -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",
|
||||
|
@ -1,19 +1,19 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
|
||||
<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"
|
||||
/>
|
||||
<meta name="description" content="Web site created using create-react-app" />
|
||||
|
||||
<title>React App</title>
|
||||
</head>
|
||||
<body>
|
||||
<title>Outstaffing</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||
<div id="root"></div>
|
||||
|
||||
</body>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -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>
|
||||
|
@ -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) {
|
||||
|
@ -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>
|
||||
|
@ -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) {
|
||||
|
@ -29,7 +29,9 @@ const Description = ({ onLoadMore }) => {
|
||||
</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 ? (
|
||||
@ -64,7 +66,9 @@ const Description = ({ onLoadMore }) => {
|
||||
</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 ? (
|
||||
|
@ -53,6 +53,10 @@
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
.description__title {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
@media (max-width: 575.98px) {
|
||||
.description__title {
|
||||
text-align: center;
|
||||
|
14
src/components/Loader/Loader.js
Normal file
14
src/components/Loader/Loader.js
Normal 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>
|
||||
);
|
||||
}
|
14
src/components/LogoutButton/LogoutButton.js
Normal file
14
src/components/LogoutButton/LogoutButton.js
Normal 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>
|
||||
)
|
||||
}
|
30
src/components/LogoutButton/logoutButton.css
Normal file
30
src/components/LogoutButton/logoutButton.css
Normal 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
9
src/hoc/withLogout.js
Normal file
@ -0,0 +1,9 @@
|
||||
import React from 'react';
|
||||
import { LogoutButton } from '../components/LogoutButton/LogoutButton';
|
||||
|
||||
export const WithLogout = (props) => {
|
||||
return <>
|
||||
<LogoutButton />
|
||||
{props.children}
|
||||
</>
|
||||
}
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
21
src/redux/loaderSlice.js
Normal 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;
|
@ -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,
|
||||
},
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user