Persistent session
This commit is contained in:
parent
c4f0a9ea62
commit
84c5fe0a6c
12 changed files with 432 additions and 249 deletions
76
package-lock.json
generated
76
package-lock.json
generated
|
@ -37,6 +37,41 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"@types/cookie": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.3.1.tgz",
|
||||
"integrity": "sha512-64Uv+8bTRVZHlbB8eXQgMP9HguxPgnOOIYrQpwHWrtLDrtcG/lILKhUl7bV65NSOIJ9dXGYD7skQFXzhL8tk1A=="
|
||||
},
|
||||
"@types/hoist-non-react-statics": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.0.1.tgz",
|
||||
"integrity": "sha512-3wTz66vV+WatOAjMST+hKCmo01KYPFgnsu+QeLcn0FuwPCoymX6aj1a4RvFCdVsfh2m0hfTPhE/zTv4M28ho1Q==",
|
||||
"requires": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"@types/object-assign": {
|
||||
"version": "4.0.30",
|
||||
"resolved": "https://registry.npmjs.org/@types/object-assign/-/object-assign-4.0.30.tgz",
|
||||
"integrity": "sha1-iUk3HVqZ9Dge4PHfCpt6GH4H5lI="
|
||||
},
|
||||
"@types/prop-types": {
|
||||
"version": "15.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.5.5.tgz",
|
||||
"integrity": "sha512-mOrlCEdwX3seT3n0AXNt4KNPAZZxcsABUHwBgFXOt+nvFUXkxCAO6UBJHPrDxWEa2KDMil86355fjo8jbZ+K0Q==",
|
||||
"requires": {
|
||||
"@types/react": "*"
|
||||
}
|
||||
},
|
||||
"@types/react": {
|
||||
"version": "16.4.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.4.13.tgz",
|
||||
"integrity": "sha512-a2Z7UmwnAzZ23bTHV6on141S8vvSC7MEJGG85R5/VG80ybzkt5QJqNzlaJ0Y6OX1dncrXFW8B0vWPIx7QuOUqA==",
|
||||
"requires": {
|
||||
"@types/prop-types": "*",
|
||||
"csstype": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"abab": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz",
|
||||
|
@ -2669,6 +2704,11 @@
|
|||
"cssom": "0.3.x"
|
||||
}
|
||||
},
|
||||
"csstype": {
|
||||
"version": "2.5.6",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.5.6.tgz",
|
||||
"integrity": "sha512-tKPyhy0FmfYD2KQYXD5GzkvAYLYj96cMLXr648CKGd3wBe0QqoPipImjGiLze9c8leJK8J3n7ap90tpk3E6HGQ=="
|
||||
},
|
||||
"currently-unhandled": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
|
||||
|
@ -8639,6 +8679,26 @@
|
|||
"schedule": "^0.3.0"
|
||||
}
|
||||
},
|
||||
"react-cookie": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/react-cookie/-/react-cookie-3.0.4.tgz",
|
||||
"integrity": "sha512-WNf1LifcjRQfg/QEDYQkey78XNJ46/k+lhoKrTK1Iv1jiqInl5jmjRBnEqDJ32HhgeL0iJAsJrEC+o+LkJ/O9Q==",
|
||||
"requires": {
|
||||
"@types/hoist-non-react-statics": "^3.0.1",
|
||||
"hoist-non-react-statics": "^3.0.0",
|
||||
"universal-cookie": "^3.0.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"hoist-non-react-statics": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.0.1.tgz",
|
||||
"integrity": "sha512-1kXwPsOi0OGQIZNVMPvgWJ9tSnGMiMfJdihqEzrPEXlHOBh9AAHXX/QYmAJTXztnz/K+PQ8ryCb4eGaN6HlGbQ==",
|
||||
"requires": {
|
||||
"react-is": "^16.3.2"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"react-dev-utils": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-5.0.2.tgz",
|
||||
|
@ -8685,6 +8745,11 @@
|
|||
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-3.0.5.tgz",
|
||||
"integrity": "sha512-gNOTMhB3QCFsDnBkO0psdcz84BjprjT95pX6SSJ9pNARQozTsBqOKeVl+uw8zMIBGGDX9GpdY9TflnRjiX4z1A=="
|
||||
},
|
||||
"react-is": {
|
||||
"version": "16.5.0",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.5.0.tgz",
|
||||
"integrity": "sha512-kpkCGLsChXTEQJVmowQqHpCjHKJFwB4SIChYaaaiAkq8OtE2aBg5pQe8/xnFlGmz9KmMx1H4oQRUyxP7qC9v5A=="
|
||||
},
|
||||
"react-lifecycles-compat": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
|
||||
|
@ -10599,6 +10664,17 @@
|
|||
"crypto-random-string": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"universal-cookie": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/universal-cookie/-/universal-cookie-3.0.4.tgz",
|
||||
"integrity": "sha512-3rhx6RAIuRmCWJttnbgzMrp2TbHhUmgQ2GrpY/US03Siv5T28iXr2qYw1m3YqmluBxEyrvZaloVemkLSId+Oyg==",
|
||||
"requires": {
|
||||
"@types/cookie": "^0.3.1",
|
||||
"@types/object-assign": "^4.0.30",
|
||||
"cookie": "^0.3.1",
|
||||
"object-assign": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"universalify": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
"axios": "^0.18.0",
|
||||
"bootstrap": "^4.1.3",
|
||||
"react": "^16.5.0",
|
||||
"react-cookie": "^3.0.4",
|
||||
"react-dom": "^16.5.0",
|
||||
"react-icons": "^3.0.5",
|
||||
"react-router-dom": "^4.3.1",
|
||||
|
@ -14,7 +15,7 @@
|
|||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"build": "react-scripts build && ssh guarda 'rm -r www/darkou.fr/cfa/bo/static' && scp -r build/* guarda:www/darkou.fr/cfa/bo",
|
||||
"test": "react-scripts test --env=jsdom",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
import axios from 'axios';
|
||||
|
||||
axios.defaults.headers.common['Access-Control-Allow-Origin'] = '*';
|
||||
|
||||
export function setDefaults(params) {
|
||||
axios.defaults.headers.common.Authorization = params.Authorization;
|
||||
}
|
||||
|
||||
export function setAuthorization(Authorization) {
|
||||
axios.defaults.headers.common.Authorization = Authorization;
|
||||
}
|
||||
|
||||
export default axios.create({
|
||||
baseURL: 'https://api.cfa.darkou.fr/api/',
|
||||
});
|
||||
|
|
|
@ -9,6 +9,7 @@ import Vegetable from './Vegetable';
|
|||
|
||||
import requireAuth from './requireAuth';
|
||||
import Login from './Login';
|
||||
import Logout from './Logout';
|
||||
|
||||
import './App.css';
|
||||
|
||||
|
@ -19,6 +20,7 @@ class App extends Component {
|
|||
<Router>
|
||||
<Switch>
|
||||
<Route exact path="/" component={requireAuth(Login, false)} />
|
||||
<Route exact path="/LogOut" component={Logout} />
|
||||
<Route exact path="/categories" component={requireAuth(Categories)} />
|
||||
<Route exact path="/categories/:categoryId" component={requireAuth(Category)} />
|
||||
<Route exact path="/categories/:categoryId/vegetables/:vegetableId" component={requireAuth(Vegetable)} />
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
} from 'reactstrap';
|
||||
import { FaTrashAlt, FaPlus } from 'react-icons/fa';
|
||||
import { Link } from 'react-router-dom';
|
||||
import Navigation from './Navigation';
|
||||
import Header from './Header';
|
||||
import API from './Api';
|
||||
|
||||
|
@ -81,8 +82,10 @@ class Categories extends Component {
|
|||
|
||||
render() {
|
||||
return (
|
||||
<Container>
|
||||
<div>
|
||||
<Header />
|
||||
<Container>
|
||||
<Navigation />
|
||||
<Table>
|
||||
<thead>
|
||||
<tr>
|
||||
|
@ -119,10 +122,11 @@ class Categories extends Component {
|
|||
<Button color="primary">
|
||||
<FaPlus />
|
||||
{' '}
|
||||
Ajouter
|
||||
Ajouter
|
||||
</Button>
|
||||
</Form>
|
||||
</Container>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import {
|
|||
} from 'reactstrap';
|
||||
import { FaTrashAlt, FaPlus, FaEdit } from 'react-icons/fa';
|
||||
import { Link } from 'react-router-dom';
|
||||
import Navigation from './Navigation';
|
||||
import Header from './Header';
|
||||
import API from './Api';
|
||||
|
||||
|
@ -111,8 +112,10 @@ class Category extends Component {
|
|||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<Header />
|
||||
<Container>
|
||||
<Header categoryId={this.state.categoryId} categoryName={this.state.Category.name} />
|
||||
<Navigation categoryId={this.state.categoryId} categoryName={this.state.Category.name} />
|
||||
<Form inline onSubmit={this.updateCategory} style={{ marginBottom: '16px' }}>
|
||||
<FormGroup className="mb-8 mr-sm-8 mb-sm-0">
|
||||
<Input
|
||||
|
@ -126,7 +129,7 @@ class Category extends Component {
|
|||
<Button color="primary">
|
||||
<FaEdit />
|
||||
{' '}
|
||||
Mettre à jour
|
||||
Mettre à jour
|
||||
</Button>
|
||||
</Form>
|
||||
<Table>
|
||||
|
@ -162,10 +165,11 @@ Mettre à jour
|
|||
<Button color="primary">
|
||||
<FaPlus />
|
||||
{' '}
|
||||
Ajouter
|
||||
Ajouter
|
||||
</Button>
|
||||
</Form>
|
||||
</Container>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,77 +1,51 @@
|
|||
import React from 'react';
|
||||
import { Breadcrumb, BreadcrumbItem } from 'reactstrap';
|
||||
import { Link } from 'react-router-dom';
|
||||
import API from './Api';
|
||||
import {
|
||||
Collapse,
|
||||
Navbar,
|
||||
NavbarToggler,
|
||||
NavbarBrand,
|
||||
Nav,
|
||||
NavItem,
|
||||
NavLink,
|
||||
} from 'reactstrap';
|
||||
import { FaSignOutAlt } from 'react-icons/fa';
|
||||
|
||||
class Header extends React.Component {
|
||||
export default class Example extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
const Breadcrumb = [];
|
||||
|
||||
if (API.defaults.headers.common.Authorization !== undefined) {
|
||||
Breadcrumb.push({
|
||||
name: 'Catégories',
|
||||
path: '/categories',
|
||||
active: !this.props.categoryId,
|
||||
});
|
||||
|
||||
if (this.props.categoryId) {
|
||||
Breadcrumb.push({
|
||||
name: this.props.categoryId,
|
||||
path: `/categories/${this.props.categoryId}`,
|
||||
active: !this.props.vegetableId,
|
||||
});
|
||||
|
||||
if (this.props.vegetableId) {
|
||||
Breadcrumb.push({
|
||||
name: this.props.vegetableId,
|
||||
path: `/categories/${this.props.categoryId}/vegetal/${this.props.vegetableId}`,
|
||||
active: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.toggle = this.toggle.bind(this);
|
||||
this.state = {
|
||||
Breadcrumb,
|
||||
isOpen: false,
|
||||
};
|
||||
}
|
||||
|
||||
componentWillReceiveProps(props) {
|
||||
if (props.categoryName) {
|
||||
const Breadcrumb = this.state.Breadcrumb;
|
||||
Breadcrumb[1].name = props.categoryName;
|
||||
this.setState({ Breadcrumb });
|
||||
}
|
||||
if (props.vegetableName) {
|
||||
const Breadcrumb = this.state.Breadcrumb;
|
||||
Breadcrumb[2].name = props.vegetableName;
|
||||
this.setState({ Breadcrumb });
|
||||
}
|
||||
toggle() {
|
||||
this.setState({
|
||||
isOpen: !this.state.isOpen,
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<Breadcrumb>
|
||||
{ this.state.Breadcrumb.map((item, key) => (
|
||||
item.active === true
|
||||
? (
|
||||
<BreadcrumbItem key={key} active>
|
||||
{item.name}
|
||||
</BreadcrumbItem>
|
||||
)
|
||||
: (
|
||||
<BreadcrumbItem key={key}>
|
||||
<Link to={item.path}>{item.name}</Link>
|
||||
</BreadcrumbItem>
|
||||
)
|
||||
))}
|
||||
</Breadcrumb>
|
||||
<Navbar color="light" light expand="md">
|
||||
<NavbarBrand>RodiVert</NavbarBrand>
|
||||
<NavbarToggler onClick={this.toggle} />
|
||||
<Collapse isOpen={this.state.isOpen} navbar>
|
||||
<Nav className="ml-auto" navbar>
|
||||
<NavItem>
|
||||
<NavLink tag={Link} to="/LogOut">
|
||||
<FaSignOutAlt />
|
||||
{' '}
|
||||
Déconnexion
|
||||
</NavLink>
|
||||
</NavItem>
|
||||
</Nav>
|
||||
</Collapse>
|
||||
</Navbar>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Header;
|
||||
|
|
11
src/Login.js
11
src/Login.js
|
@ -10,7 +10,8 @@ import {
|
|||
Alert,
|
||||
} from 'reactstrap';
|
||||
import { FaSignInAlt } from 'react-icons/fa';
|
||||
import API, { setDefaults } from './Api';
|
||||
import { Cookies } from 'react-cookie';
|
||||
import API, { setAuthorization } from './Api';
|
||||
|
||||
class Login extends Component {
|
||||
constructor(props) {
|
||||
|
@ -37,9 +38,11 @@ class Login extends Component {
|
|||
})
|
||||
.then((response) => {
|
||||
if (response.status === 200) {
|
||||
setDefaults({
|
||||
Authorization: `Basic ${new Buffer(`${this.state.email}:${this.state.password}`).toString('base64')}`,
|
||||
});
|
||||
const cookies = new Cookies();
|
||||
const Authorization = `Basic ${new Buffer(`${this.state.email}:${this.state.password}`).toString('base64')}`;
|
||||
|
||||
cookies.set('cfa_bo', Authorization);
|
||||
setAuthorization(Authorization);
|
||||
this.setState({ message: '' });
|
||||
this.props.history.push('/categories');
|
||||
} else {
|
||||
|
|
23
src/Logout.js
Normal file
23
src/Logout.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
import { Component } from 'react';
|
||||
import { Cookies } from 'react-cookie';
|
||||
import { setAuthorization } from './Api';
|
||||
|
||||
class Logout extends Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
const cookies = new Cookies();
|
||||
|
||||
setAuthorization(null);
|
||||
cookies.remove('cfa_bo');
|
||||
|
||||
this.props.history.push('/');
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
'Bye !'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Logout;
|
77
src/Navigation.js
Normal file
77
src/Navigation.js
Normal file
|
@ -0,0 +1,77 @@
|
|||
import React from 'react';
|
||||
import { Breadcrumb, BreadcrumbItem } from 'reactstrap';
|
||||
import { Link } from 'react-router-dom';
|
||||
import API from './Api';
|
||||
|
||||
class Navigation extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
const Breadcrumb = [];
|
||||
|
||||
if (API.defaults.headers.common.Authorization !== undefined) {
|
||||
Breadcrumb.push({
|
||||
name: 'Catégories',
|
||||
path: '/categories',
|
||||
active: !this.props.categoryId,
|
||||
});
|
||||
|
||||
if (this.props.categoryId) {
|
||||
Breadcrumb.push({
|
||||
name: this.props.categoryId,
|
||||
path: `/categories/${this.props.categoryId}`,
|
||||
active: !this.props.vegetableId,
|
||||
});
|
||||
|
||||
if (this.props.vegetableId) {
|
||||
Breadcrumb.push({
|
||||
name: this.props.vegetableId,
|
||||
path: `/categories/${this.props.categoryId}/vegetal/${this.props.vegetableId}`,
|
||||
active: true,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.state = {
|
||||
Breadcrumb,
|
||||
};
|
||||
}
|
||||
|
||||
componentWillReceiveProps(props) {
|
||||
if (props.categoryName) {
|
||||
const Breadcrumb = this.state.Breadcrumb;
|
||||
Breadcrumb[1].name = props.categoryName;
|
||||
this.setState({ Breadcrumb });
|
||||
}
|
||||
if (props.vegetableName) {
|
||||
const Breadcrumb = this.state.Breadcrumb;
|
||||
Breadcrumb[2].name = props.vegetableName;
|
||||
this.setState({ Breadcrumb });
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<Breadcrumb>
|
||||
{ this.state.Breadcrumb.map((item, key) => (
|
||||
item.active === true
|
||||
? (
|
||||
<BreadcrumbItem key={key} active>
|
||||
{item.name}
|
||||
</BreadcrumbItem>
|
||||
)
|
||||
: (
|
||||
<BreadcrumbItem key={key}>
|
||||
<Link to={item.path}>{item.name}</Link>
|
||||
</BreadcrumbItem>
|
||||
)
|
||||
))}
|
||||
</Breadcrumb>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Navigation;
|
|
@ -10,6 +10,7 @@ import {
|
|||
Input,
|
||||
} from 'reactstrap';
|
||||
import { FaEdit, FaMapMarkerAlt } from 'react-icons/fa';
|
||||
import Navigation from './Navigation';
|
||||
import Header from './Header';
|
||||
import API from './Api';
|
||||
|
||||
|
@ -161,8 +162,10 @@ class Vegetable extends Component {
|
|||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Header />
|
||||
<Container className="Vegetable">
|
||||
<Header categoryId={this.state.Vegetable.Type ? this.state.Vegetable.Type.id : 1} categoryName={this.state.Vegetable.Type ? this.state.Vegetable.Type.name : null} vegetableId={this.state.Vegetable.id || 1} vegetableName={this.state.Vegetable.name} />
|
||||
<Navigation categoryId={this.state.Vegetable.Type ? this.state.Vegetable.Type.id : 1} categoryName={this.state.Vegetable.Type ? this.state.Vegetable.Type.name : null} vegetableId={this.state.Vegetable.id || 1} vegetableName={this.state.Vegetable.name} />
|
||||
<Form onSubmit={this.updateVegetable}>
|
||||
<Row>
|
||||
<Col xs={12} sm={4}>
|
||||
|
@ -251,10 +254,11 @@ class Vegetable extends Component {
|
|||
<Button color="primary" style={{ marginTop: '16px' }}>
|
||||
<FaEdit />
|
||||
{' '}
|
||||
Mettre à jour
|
||||
Mettre à jour
|
||||
</Button>
|
||||
</Form>
|
||||
</Container>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,19 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { Cookies } from 'react-cookie';
|
||||
import App from './App';
|
||||
import registerServiceWorker from './registerServiceWorker';
|
||||
import { setAuthorization } from './Api';
|
||||
|
||||
import './index.css';
|
||||
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||
|
||||
const cookies = new Cookies();
|
||||
const auth = cookies.get('cfa_bo');
|
||||
|
||||
if (auth) {
|
||||
setAuthorization(auth);
|
||||
}
|
||||
|
||||
ReactDOM.render(<App />, document.getElementById('root'));
|
||||
registerServiceWorker();
|
||||
|
|
Loading…
Reference in a new issue