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": {
|
"abab": {
|
||||||
"version": "1.0.4",
|
"version": "1.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz",
|
||||||
|
@ -2669,6 +2704,11 @@
|
||||||
"cssom": "0.3.x"
|
"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": {
|
"currently-unhandled": {
|
||||||
"version": "0.4.1",
|
"version": "0.4.1",
|
||||||
"resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
|
||||||
|
@ -8639,6 +8679,26 @@
|
||||||
"schedule": "^0.3.0"
|
"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": {
|
"react-dev-utils": {
|
||||||
"version": "5.0.2",
|
"version": "5.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/react-dev-utils/-/react-dev-utils-5.0.2.tgz",
|
"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",
|
"resolved": "https://registry.npmjs.org/react-icons/-/react-icons-3.0.5.tgz",
|
||||||
"integrity": "sha512-gNOTMhB3QCFsDnBkO0psdcz84BjprjT95pX6SSJ9pNARQozTsBqOKeVl+uw8zMIBGGDX9GpdY9TflnRjiX4z1A=="
|
"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": {
|
"react-lifecycles-compat": {
|
||||||
"version": "3.0.4",
|
"version": "3.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
|
"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"
|
"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": {
|
"universalify": {
|
||||||
"version": "0.1.2",
|
"version": "0.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
"axios": "^0.18.0",
|
"axios": "^0.18.0",
|
||||||
"bootstrap": "^4.1.3",
|
"bootstrap": "^4.1.3",
|
||||||
"react": "^16.5.0",
|
"react": "^16.5.0",
|
||||||
|
"react-cookie": "^3.0.4",
|
||||||
"react-dom": "^16.5.0",
|
"react-dom": "^16.5.0",
|
||||||
"react-icons": "^3.0.5",
|
"react-icons": "^3.0.5",
|
||||||
"react-router-dom": "^4.3.1",
|
"react-router-dom": "^4.3.1",
|
||||||
|
@ -14,7 +15,7 @@
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"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",
|
"test": "react-scripts test --env=jsdom",
|
||||||
"eject": "react-scripts eject"
|
"eject": "react-scripts eject"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
||||||
|
axios.defaults.headers.common['Access-Control-Allow-Origin'] = '*';
|
||||||
|
|
||||||
export function setDefaults(params) {
|
export function setDefaults(params) {
|
||||||
axios.defaults.headers.common.Authorization = params.Authorization;
|
axios.defaults.headers.common.Authorization = params.Authorization;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function setAuthorization(Authorization) {
|
||||||
|
axios.defaults.headers.common.Authorization = Authorization;
|
||||||
|
}
|
||||||
|
|
||||||
export default axios.create({
|
export default axios.create({
|
||||||
baseURL: 'https://api.cfa.darkou.fr/api/',
|
baseURL: 'https://api.cfa.darkou.fr/api/',
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,6 +9,7 @@ import Vegetable from './Vegetable';
|
||||||
|
|
||||||
import requireAuth from './requireAuth';
|
import requireAuth from './requireAuth';
|
||||||
import Login from './Login';
|
import Login from './Login';
|
||||||
|
import Logout from './Logout';
|
||||||
|
|
||||||
import './App.css';
|
import './App.css';
|
||||||
|
|
||||||
|
@ -19,6 +20,7 @@ class App extends Component {
|
||||||
<Router>
|
<Router>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route exact path="/" component={requireAuth(Login, false)} />
|
<Route exact path="/" component={requireAuth(Login, false)} />
|
||||||
|
<Route exact path="/LogOut" component={Logout} />
|
||||||
<Route exact path="/categories" component={requireAuth(Categories)} />
|
<Route exact path="/categories" component={requireAuth(Categories)} />
|
||||||
<Route exact path="/categories/:categoryId" component={requireAuth(Category)} />
|
<Route exact path="/categories/:categoryId" component={requireAuth(Category)} />
|
||||||
<Route exact path="/categories/:categoryId/vegetables/:vegetableId" component={requireAuth(Vegetable)} />
|
<Route exact path="/categories/:categoryId/vegetables/:vegetableId" component={requireAuth(Vegetable)} />
|
||||||
|
|
|
@ -9,6 +9,7 @@ import {
|
||||||
} from 'reactstrap';
|
} from 'reactstrap';
|
||||||
import { FaTrashAlt, FaPlus } from 'react-icons/fa';
|
import { FaTrashAlt, FaPlus } from 'react-icons/fa';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
import Navigation from './Navigation';
|
||||||
import Header from './Header';
|
import Header from './Header';
|
||||||
import API from './Api';
|
import API from './Api';
|
||||||
|
|
||||||
|
@ -81,48 +82,51 @@ class Categories extends Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Container>
|
<div>
|
||||||
<Header />
|
<Header />
|
||||||
<Table>
|
<Container>
|
||||||
<thead>
|
<Navigation />
|
||||||
<tr>
|
<Table>
|
||||||
<th>#</th>
|
<thead>
|
||||||
<th>Nom</th>
|
<tr>
|
||||||
<th>Nom d'éléments</th>
|
<th>#</th>
|
||||||
<th>Action</th>
|
<th>Nom</th>
|
||||||
</tr>
|
<th>Nom d'éléments</th>
|
||||||
</thead>
|
<th>Action</th>
|
||||||
<tbody>
|
|
||||||
{this.state.Categories.map((item, key) => (
|
|
||||||
<tr key={key}>
|
|
||||||
<th scope="row"><Link to={`/categories/${item.id}`}>{item.id}</Link></th>
|
|
||||||
<td>{item.name}</td>
|
|
||||||
<td>{item.Vegetables !== undefined ? item.Vegetables.length : 0 }</td>
|
|
||||||
<td>
|
|
||||||
{' '}
|
|
||||||
<Button color="danger" onClick={() => this.deleteCategory(item)}><FaTrashAlt /></Button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
</thead>
|
||||||
</tbody>
|
<tbody>
|
||||||
</Table>
|
{this.state.Categories.map((item, key) => (
|
||||||
<Form inline onSubmit={this.addCategory}>
|
<tr key={key}>
|
||||||
<FormGroup className="mb-8 mr-sm-8 mb-sm-0">
|
<th scope="row"><Link to={`/categories/${item.id}`}>{item.id}</Link></th>
|
||||||
<Input
|
<td>{item.name}</td>
|
||||||
type="text"
|
<td>{item.Vegetables !== undefined ? item.Vegetables.length : 0 }</td>
|
||||||
name="name"
|
<td>
|
||||||
value={this.state.name}
|
{' '}
|
||||||
placeholder="Nouvelle catégorie"
|
<Button color="danger" onClick={() => this.deleteCategory(item)}><FaTrashAlt /></Button>
|
||||||
onChange={this.handleChange}
|
</td>
|
||||||
/>
|
</tr>
|
||||||
</FormGroup>
|
))}
|
||||||
<Button color="primary">
|
</tbody>
|
||||||
<FaPlus />
|
</Table>
|
||||||
{' '}
|
<Form inline onSubmit={this.addCategory}>
|
||||||
Ajouter
|
<FormGroup className="mb-8 mr-sm-8 mb-sm-0">
|
||||||
</Button>
|
<Input
|
||||||
</Form>
|
type="text"
|
||||||
</Container>
|
name="name"
|
||||||
|
value={this.state.name}
|
||||||
|
placeholder="Nouvelle catégorie"
|
||||||
|
onChange={this.handleChange}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
<Button color="primary">
|
||||||
|
<FaPlus />
|
||||||
|
{' '}
|
||||||
|
Ajouter
|
||||||
|
</Button>
|
||||||
|
</Form>
|
||||||
|
</Container>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
112
src/Category.js
112
src/Category.js
|
@ -9,6 +9,7 @@ import {
|
||||||
} from 'reactstrap';
|
} from 'reactstrap';
|
||||||
import { FaTrashAlt, FaPlus, FaEdit } from 'react-icons/fa';
|
import { FaTrashAlt, FaPlus, FaEdit } from 'react-icons/fa';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
import Navigation from './Navigation';
|
||||||
import Header from './Header';
|
import Header from './Header';
|
||||||
import API from './Api';
|
import API from './Api';
|
||||||
|
|
||||||
|
@ -111,61 +112,64 @@ class Category extends Component {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<Container>
|
<div>
|
||||||
<Header categoryId={this.state.categoryId} categoryName={this.state.Category.name} />
|
<Header />
|
||||||
<Form inline onSubmit={this.updateCategory} style={{ marginBottom: '16px' }}>
|
<Container>
|
||||||
<FormGroup className="mb-8 mr-sm-8 mb-sm-0">
|
<Navigation categoryId={this.state.categoryId} categoryName={this.state.Category.name} />
|
||||||
<Input
|
<Form inline onSubmit={this.updateCategory} style={{ marginBottom: '16px' }}>
|
||||||
type="text"
|
<FormGroup className="mb-8 mr-sm-8 mb-sm-0">
|
||||||
name="categoryName"
|
<Input
|
||||||
value={this.state.categoryName}
|
type="text"
|
||||||
placeholder="Changez le nom de la catégorie"
|
name="categoryName"
|
||||||
onChange={this.handleChange}
|
value={this.state.categoryName}
|
||||||
/>
|
placeholder="Changez le nom de la catégorie"
|
||||||
</FormGroup>
|
onChange={this.handleChange}
|
||||||
<Button color="primary">
|
/>
|
||||||
<FaEdit />
|
</FormGroup>
|
||||||
{' '}
|
<Button color="primary">
|
||||||
Mettre à jour
|
<FaEdit />
|
||||||
</Button>
|
{' '}
|
||||||
</Form>
|
Mettre à jour
|
||||||
<Table>
|
</Button>
|
||||||
<thead>
|
</Form>
|
||||||
<tr>
|
<Table>
|
||||||
<th>#</th>
|
<thead>
|
||||||
<th>Nom</th>
|
<tr>
|
||||||
<th>Action</th>
|
<th>#</th>
|
||||||
</tr>
|
<th>Nom</th>
|
||||||
</thead>
|
<th>Action</th>
|
||||||
<tbody>
|
|
||||||
{this.state.Category.Vegetables && this.state.Category.Vegetables.map((item, key) => (
|
|
||||||
<tr key={key}>
|
|
||||||
<th scope="row"><Link to={`/categories/${this.state.Category.id}/vegetables/${item.id}`}>{item.id}</Link></th>
|
|
||||||
<td>{item.name}</td>
|
|
||||||
<td>
|
|
||||||
{' '}
|
|
||||||
<Button color="danger" onClick={() => this.deleteVegetable(item, key)}><FaTrashAlt /></Button>
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
))}
|
</thead>
|
||||||
</tbody>
|
<tbody>
|
||||||
</Table>
|
{this.state.Category.Vegetables && this.state.Category.Vegetables.map((item, key) => (
|
||||||
<Form inline onSubmit={this.addVegetable}>
|
<tr key={key}>
|
||||||
<FormGroup className="mb-8 mr-sm-8 mb-sm-0">
|
<th scope="row"><Link to={`/categories/${this.state.Category.id}/vegetables/${item.id}`}>{item.id}</Link></th>
|
||||||
<Input
|
<td>{item.name}</td>
|
||||||
type="text"
|
<td>
|
||||||
name="name"
|
{' '}
|
||||||
placeholder="Nouveau végétal"
|
<Button color="danger" onClick={() => this.deleteVegetable(item, key)}><FaTrashAlt /></Button>
|
||||||
onChange={this.handleChange}
|
</td>
|
||||||
/>
|
</tr>
|
||||||
</FormGroup>
|
))}
|
||||||
<Button color="primary">
|
</tbody>
|
||||||
<FaPlus />
|
</Table>
|
||||||
{' '}
|
<Form inline onSubmit={this.addVegetable}>
|
||||||
Ajouter
|
<FormGroup className="mb-8 mr-sm-8 mb-sm-0">
|
||||||
</Button>
|
<Input
|
||||||
</Form>
|
type="text"
|
||||||
</Container>
|
name="name"
|
||||||
|
placeholder="Nouveau végétal"
|
||||||
|
onChange={this.handleChange}
|
||||||
|
/>
|
||||||
|
</FormGroup>
|
||||||
|
<Button color="primary">
|
||||||
|
<FaPlus />
|
||||||
|
{' '}
|
||||||
|
Ajouter
|
||||||
|
</Button>
|
||||||
|
</Form>
|
||||||
|
</Container>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,77 +1,51 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Breadcrumb, BreadcrumbItem } from 'reactstrap';
|
|
||||||
import { Link } from 'react-router-dom';
|
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) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
const Breadcrumb = [];
|
this.toggle = this.toggle.bind(this);
|
||||||
|
|
||||||
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 = {
|
this.state = {
|
||||||
Breadcrumb,
|
isOpen: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(props) {
|
toggle() {
|
||||||
if (props.categoryName) {
|
this.setState({
|
||||||
const Breadcrumb = this.state.Breadcrumb;
|
isOpen: !this.state.isOpen,
|
||||||
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() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Breadcrumb>
|
<Navbar color="light" light expand="md">
|
||||||
{ this.state.Breadcrumb.map((item, key) => (
|
<NavbarBrand>RodiVert</NavbarBrand>
|
||||||
item.active === true
|
<NavbarToggler onClick={this.toggle} />
|
||||||
? (
|
<Collapse isOpen={this.state.isOpen} navbar>
|
||||||
<BreadcrumbItem key={key} active>
|
<Nav className="ml-auto" navbar>
|
||||||
{item.name}
|
<NavItem>
|
||||||
</BreadcrumbItem>
|
<NavLink tag={Link} to="/LogOut">
|
||||||
)
|
<FaSignOutAlt />
|
||||||
: (
|
{' '}
|
||||||
<BreadcrumbItem key={key}>
|
Déconnexion
|
||||||
<Link to={item.path}>{item.name}</Link>
|
</NavLink>
|
||||||
</BreadcrumbItem>
|
</NavItem>
|
||||||
)
|
</Nav>
|
||||||
))}
|
</Collapse>
|
||||||
</Breadcrumb>
|
</Navbar>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Header;
|
|
||||||
|
|
11
src/Login.js
11
src/Login.js
|
@ -10,7 +10,8 @@ import {
|
||||||
Alert,
|
Alert,
|
||||||
} from 'reactstrap';
|
} from 'reactstrap';
|
||||||
import { FaSignInAlt } from 'react-icons/fa';
|
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 {
|
class Login extends Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
|
@ -37,9 +38,11 @@ class Login extends Component {
|
||||||
})
|
})
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
setDefaults({
|
const cookies = new Cookies();
|
||||||
Authorization: `Basic ${new Buffer(`${this.state.email}:${this.state.password}`).toString('base64')}`,
|
const Authorization = `Basic ${new Buffer(`${this.state.email}:${this.state.password}`).toString('base64')}`;
|
||||||
});
|
|
||||||
|
cookies.set('cfa_bo', Authorization);
|
||||||
|
setAuthorization(Authorization);
|
||||||
this.setState({ message: '' });
|
this.setState({ message: '' });
|
||||||
this.props.history.push('/categories');
|
this.props.history.push('/categories');
|
||||||
} else {
|
} 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;
|
188
src/Vegetable.js
188
src/Vegetable.js
|
@ -10,6 +10,7 @@ import {
|
||||||
Input,
|
Input,
|
||||||
} from 'reactstrap';
|
} from 'reactstrap';
|
||||||
import { FaEdit, FaMapMarkerAlt } from 'react-icons/fa';
|
import { FaEdit, FaMapMarkerAlt } from 'react-icons/fa';
|
||||||
|
import Navigation from './Navigation';
|
||||||
import Header from './Header';
|
import Header from './Header';
|
||||||
import API from './Api';
|
import API from './Api';
|
||||||
|
|
||||||
|
@ -161,100 +162,103 @@ class Vegetable extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container className="Vegetable">
|
<div>
|
||||||
<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} />
|
<Header />
|
||||||
<Form onSubmit={this.updateVegetable}>
|
<Container className="Vegetable">
|
||||||
<Row>
|
<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} />
|
||||||
<Col xs={12} sm={4}>
|
<Form onSubmit={this.updateVegetable}>
|
||||||
<FormGroup row>
|
<Row>
|
||||||
<Label for="name" sm={4}>Nom</Label>
|
<Col xs={12} sm={4}>
|
||||||
<Col sm={8}>
|
<FormGroup row>
|
||||||
<Input
|
<Label for="name" sm={4}>Nom</Label>
|
||||||
type="text"
|
<Col sm={8}>
|
||||||
name="name"
|
<Input
|
||||||
id="name"
|
type="text"
|
||||||
value={this.state.Vegetable.name}
|
name="name"
|
||||||
placeholder="Nom"
|
id="name"
|
||||||
onChange={this.handleChange}
|
value={this.state.Vegetable.name}
|
||||||
/>
|
placeholder="Nom"
|
||||||
</Col>
|
onChange={this.handleChange}
|
||||||
</FormGroup>
|
/>
|
||||||
<FormGroup row>
|
</Col>
|
||||||
<Label for="description" sm={4}>Description</Label>
|
</FormGroup>
|
||||||
<Col sm={8}>
|
<FormGroup row>
|
||||||
<Input
|
<Label for="description" sm={4}>Description</Label>
|
||||||
type="textarea"
|
<Col sm={8}>
|
||||||
name="description"
|
<Input
|
||||||
id="description"
|
type="textarea"
|
||||||
value={this.state.Vegetable.description}
|
name="description"
|
||||||
placeholder="Description"
|
id="description"
|
||||||
onChange={this.handleChange}
|
value={this.state.Vegetable.description}
|
||||||
/>
|
placeholder="Description"
|
||||||
</Col>
|
onChange={this.handleChange}
|
||||||
</FormGroup>
|
/>
|
||||||
<FormGroup row>
|
</Col>
|
||||||
<Label for="lat" sm={4}>Latitude (%)</Label>
|
</FormGroup>
|
||||||
<Col sm={8}>
|
<FormGroup row>
|
||||||
<Input
|
<Label for="lat" sm={4}>Latitude (%)</Label>
|
||||||
type="number"
|
<Col sm={8}>
|
||||||
min="0"
|
<Input
|
||||||
max="100"
|
type="number"
|
||||||
step="1"
|
min="0"
|
||||||
name="lat"
|
max="100"
|
||||||
id="lat"
|
step="1"
|
||||||
value={this.state.Vegetable.lat}
|
name="lat"
|
||||||
placeholder="Latitude"
|
id="lat"
|
||||||
onChange={this.handleChange}
|
value={this.state.Vegetable.lat}
|
||||||
/>
|
placeholder="Latitude"
|
||||||
</Col>
|
onChange={this.handleChange}
|
||||||
</FormGroup>
|
/>
|
||||||
<FormGroup row>
|
</Col>
|
||||||
<Label for="lng" sm={4}>Longitude (%)</Label>
|
</FormGroup>
|
||||||
<Col sm={8}>
|
<FormGroup row>
|
||||||
<Input
|
<Label for="lng" sm={4}>Longitude (%)</Label>
|
||||||
type="number"
|
<Col sm={8}>
|
||||||
min="0"
|
<Input
|
||||||
max="100"
|
type="number"
|
||||||
step="1"
|
min="0"
|
||||||
name="lng"
|
max="100"
|
||||||
id="lng"
|
step="1"
|
||||||
value={this.state.Vegetable.lng}
|
name="lng"
|
||||||
placeholder="Longitude"
|
id="lng"
|
||||||
onChange={this.handleChange}
|
value={this.state.Vegetable.lng}
|
||||||
/>
|
placeholder="Longitude"
|
||||||
</Col>
|
onChange={this.handleChange}
|
||||||
</FormGroup>
|
/>
|
||||||
<FormGroup row>
|
</Col>
|
||||||
<Label for="mainPicture" sm={4}>Photo principale</Label>
|
</FormGroup>
|
||||||
<Col sm={8}>
|
<FormGroup row>
|
||||||
<Input
|
<Label for="mainPicture" sm={4}>Photo principale</Label>
|
||||||
type="file"
|
<Col sm={8}>
|
||||||
id="mainPicture"
|
<Input
|
||||||
onChange={e => this.onImageChange(e)}
|
type="file"
|
||||||
/>
|
id="mainPicture"
|
||||||
</Col>
|
onChange={e => this.onImageChange(e)}
|
||||||
</FormGroup>
|
/>
|
||||||
<div className="imgPreview">
|
</Col>
|
||||||
{$imagePreview}
|
</FormGroup>
|
||||||
</div>
|
<div className="imgPreview">
|
||||||
|
{$imagePreview}
|
||||||
</Col>
|
|
||||||
<Col xs={12} sm={8}>
|
|
||||||
<div id="MapContainer">
|
|
||||||
<div className="map" style={{ width: this.state.Map.width, height: this.state.Map.height }}>
|
|
||||||
<div className="mapMarker" style={{ left: `calc(${this.state.Vegetable.lat}% - 16px)`, top: `calc(${this.state.Vegetable.lng}% - 16px)` }}><FaMapMarkerAlt /></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</Col>
|
|
||||||
</Row>
|
|
||||||
|
|
||||||
<Button color="primary" style={{ marginTop: '16px' }}>
|
</Col>
|
||||||
<FaEdit />
|
<Col xs={12} sm={8}>
|
||||||
{' '}
|
<div id="MapContainer">
|
||||||
Mettre à jour
|
<div className="map" style={{ width: this.state.Map.width, height: this.state.Map.height }}>
|
||||||
</Button>
|
<div className="mapMarker" style={{ left: `calc(${this.state.Vegetable.lat}% - 16px)`, top: `calc(${this.state.Vegetable.lng}% - 16px)` }}><FaMapMarkerAlt /></div>
|
||||||
</Form>
|
</div>
|
||||||
</Container>
|
</div>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
|
||||||
|
<Button color="primary" style={{ marginTop: '16px' }}>
|
||||||
|
<FaEdit />
|
||||||
|
{' '}
|
||||||
|
Mettre à jour
|
||||||
|
</Button>
|
||||||
|
</Form>
|
||||||
|
</Container>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,19 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
|
import { Cookies } from 'react-cookie';
|
||||||
import App from './App';
|
import App from './App';
|
||||||
import registerServiceWorker from './registerServiceWorker';
|
import registerServiceWorker from './registerServiceWorker';
|
||||||
|
import { setAuthorization } from './Api';
|
||||||
|
|
||||||
import './index.css';
|
import './index.css';
|
||||||
import 'bootstrap/dist/css/bootstrap.min.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'));
|
ReactDOM.render(<App />, document.getElementById('root'));
|
||||||
registerServiceWorker();
|
registerServiceWorker();
|
||||||
|
|
Loading…
Reference in a new issue