Updated structure and added Vegetables page
This commit is contained in:
parent
773ef7e859
commit
9f29edb00e
12 changed files with 371 additions and 224 deletions
|
@ -4,9 +4,9 @@ import {
|
|||
BrowserRouter as Router, Route,
|
||||
Switch,
|
||||
} from 'react-router-dom';
|
||||
import Map from './Map';
|
||||
import Home from './Home';
|
||||
import Vegetables from './Vegetables';
|
||||
import Map from '../Routes/Map';
|
||||
import Home from '../Routes/Home';
|
||||
import Vegetables from '../Routes/Vegetables';
|
||||
|
||||
class App extends Component {
|
||||
constructor(props) {
|
||||
|
@ -43,8 +43,7 @@ class App extends Component {
|
|||
<Switch>
|
||||
<Route exact path="/" component={Home} />
|
||||
<Route exact path="/carte" component={Map} />
|
||||
<Route exact path="/vegetaux" component={Vegetables} />
|
||||
<Route exact path="/vegetaux/:id-:slug" component={Vegetables} />
|
||||
<Route exact path="/vegetaux/:typeId-:typeSlug" component={Vegetables} />
|
||||
</Switch>
|
||||
</Router>
|
||||
</div>
|
120
src/Components/Map.js
Normal file
120
src/Components/Map.js
Normal file
|
@ -0,0 +1,120 @@
|
|||
import React from 'react';
|
||||
import {
|
||||
Row,
|
||||
Col,
|
||||
Tooltip
|
||||
} from 'reactstrap';
|
||||
import {
|
||||
FaMapMarkerAlt
|
||||
} from 'react-icons/fa';
|
||||
import {
|
||||
Link
|
||||
} from 'react-router-dom';
|
||||
import strToSlug from '../StrToSlug'
|
||||
|
||||
import '../css/Map.css'
|
||||
|
||||
const MapDimensions = {
|
||||
width: 734,
|
||||
height: 530,
|
||||
};
|
||||
|
||||
export default class Map extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
selectedType: this.props.selectedType,
|
||||
selectedVegetable: this.props.selectedVegetable,
|
||||
Map: {
|
||||
width: '20px',
|
||||
height: '20px',
|
||||
},
|
||||
tooltipOpen: false
|
||||
}
|
||||
|
||||
this.selectVegetable = this.selectVegetable.bind(this);
|
||||
this.setMap = this.setMap.bind(this);
|
||||
this.toggle = this.toggle.bind(this);
|
||||
}
|
||||
|
||||
componentWillReceiveProps(newProps) {
|
||||
this.setState(prevState => ({
|
||||
...prevState,
|
||||
selectedType: newProps.selectedType,
|
||||
selectedVegetable: newProps.selectedVegetable
|
||||
}));
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener('resize', this.setMap);
|
||||
this.setMap();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener('resize', this.setMap);
|
||||
}
|
||||
|
||||
setMap() {
|
||||
const width = document.getElementById('MapContainer').clientWidth;
|
||||
let MapWidth = MapDimensions.width;
|
||||
let MapHeight = MapDimensions.height;
|
||||
|
||||
if (width < MapDimensions.width) {
|
||||
MapWidth = width;
|
||||
MapHeight = Math.round(MapDimensions.height * MapWidth / MapDimensions.width);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
Map: {
|
||||
width: MapWidth,
|
||||
height: MapHeight,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
selectVegetable(vegetable) {
|
||||
this.setState({
|
||||
selectedVegetable: vegetable
|
||||
})
|
||||
this.props.selectVegetable(vegetable)
|
||||
}
|
||||
|
||||
toggle(id) {
|
||||
this.setState(prevState => ({
|
||||
tooltipOpen: prevState.tooltipOpen === id ? false : id
|
||||
}));
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Row className="with-margin">
|
||||
<Col className="with-border with-background">
|
||||
<div id="MapContainer">
|
||||
<div className="map" style={{ width: this.state.Map.width, height: this.state.Map.height }}>
|
||||
{
|
||||
this.state.selectedType &&
|
||||
this.state.selectedType.Vegetables &&
|
||||
this.state.selectedType.Vegetables.map((vegetable, key) =>
|
||||
(
|
||||
<Link to={`/vegetaux/${this.state.selectedType.id}-${strToSlug(this.state.selectedType.name)}/${vegetable.id}-${strToSlug(vegetable.name)}`}
|
||||
key={key}
|
||||
className={`mapMarker ${this.state.selectedVegetable && this.state.selectedVegetable.id === vegetable.id ? 'selected' : ''}`}
|
||||
style={{ left: `calc(${vegetable.lat}% - 16px)`, top: `calc(${vegetable.lng}% - 16px)` }}
|
||||
onMouseOver={(e) => this.selectVegetable(vegetable)}
|
||||
>
|
||||
<Tooltip placement='top' isOpen={this.state.tooltipOpen === vegetable.id} target={'Tooltip-' + vegetable.id} toggle={() => this.toggle(vegetable.id)}>
|
||||
{vegetable.name}
|
||||
</Tooltip>
|
||||
<FaMapMarkerAlt id={'Tooltip-' + vegetable.id} />
|
||||
</Link>
|
||||
)
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
);
|
||||
}
|
||||
}
|
56
src/Components/Vegetables.js
Normal file
56
src/Components/Vegetables.js
Normal file
|
@ -0,0 +1,56 @@
|
|||
import React from 'react';
|
||||
import {
|
||||
ListGroup,
|
||||
ListGroupItem
|
||||
} from 'reactstrap';
|
||||
import {
|
||||
Link
|
||||
} from 'react-router-dom';
|
||||
import strToSlug from '../StrToSlug'
|
||||
|
||||
import '../css/Vegetables.css'
|
||||
|
||||
export default class Map extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
selectedType: this.props.selectedType,
|
||||
selectedVegetable: this.props.selectVegetable
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(newProps) {
|
||||
this.setState(newProps);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
|
||||
<div className="with-margin">
|
||||
<div className=" with-border with-background">
|
||||
<ListGroup className='vegetables--types--group'>
|
||||
{
|
||||
this.state.selectedType &&
|
||||
this.state.selectedType.Vegetables &&
|
||||
this.state.selectedType.Vegetables.map((vegetable, key) =>
|
||||
(
|
||||
<ListGroupItem
|
||||
key={key}
|
||||
className={this.state.selectedVegetable.id === vegetable.id ? "selected" : "null"}
|
||||
onMouseOver={(e) => this.props.selectVegetable(vegetable)}
|
||||
>
|
||||
<Link to={`/vegetaux/${this.state.selectedType.id}-${strToSlug(this.state.selectedType.name)}/${vegetable.id}-${strToSlug(vegetable.name)}`}>
|
||||
{vegetable.name}
|
||||
</Link>
|
||||
|
||||
</ListGroupItem>
|
||||
)
|
||||
)
|
||||
}
|
||||
</ListGroup>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -7,7 +7,7 @@ import {
|
|||
|
||||
import '../css/Home.css';
|
||||
|
||||
export default class Home extends React.Component {
|
||||
export default class RouterHome extends React.Component {
|
||||
|
||||
render() {
|
||||
return (
|
108
src/Routes/Map.js
Normal file
108
src/Routes/Map.js
Normal file
|
@ -0,0 +1,108 @@
|
|||
import React from 'react';
|
||||
import {
|
||||
Container,
|
||||
Row,
|
||||
Col,
|
||||
ListGroup,
|
||||
ListGroupItem,
|
||||
Badge
|
||||
} from 'reactstrap';
|
||||
import Api from '../Components/Api';
|
||||
import {
|
||||
NotificationContainer,
|
||||
NotificationManager
|
||||
} from 'react-notifications';
|
||||
import MapItem from '../Components/Map'
|
||||
import Vegetables from '../Components/Vegetables'
|
||||
|
||||
export default class RouterMap extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
types: [],
|
||||
vegetables: [],
|
||||
selectedType: {},
|
||||
selectedVegetable: {}
|
||||
}
|
||||
|
||||
this.getVegetablesTypes = this.getVegetablesTypes.bind(this);
|
||||
this.selectType = this.selectType.bind(this);
|
||||
this.selectVegetable = this.selectVegetable.bind(this);
|
||||
|
||||
this.getVegetablesTypes();
|
||||
}
|
||||
|
||||
getVegetablesTypes() {
|
||||
Api.get('types')
|
||||
.then(res => {
|
||||
this.setState({
|
||||
types: res.data.rows
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
NotificationManager.error('Erreur lors de la récupération des catégories');
|
||||
})
|
||||
}
|
||||
|
||||
selectType(type) {
|
||||
this.setState({
|
||||
selectedType: type
|
||||
});
|
||||
}
|
||||
|
||||
selectVegetable(vegetable) {
|
||||
this.setState({
|
||||
selectedVegetable: vegetable
|
||||
})
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Container>
|
||||
<NotificationContainer />
|
||||
<Row>
|
||||
|
||||
<Col xs="12" sm="8">
|
||||
<MapItem
|
||||
selectedType={this.state.selectedType}
|
||||
selectedVegetable={this.state.selectedVegetable}
|
||||
selectVegetable={this.selectVegetable}
|
||||
/>
|
||||
</Col>
|
||||
<Col xs="12" sm="4">
|
||||
<Row>
|
||||
<Col xs="6" sm="12">
|
||||
<div className="with-margin">
|
||||
<div className=" with-border with-background">
|
||||
<ListGroup className='vegetables--types--group'>
|
||||
{
|
||||
this.state.types.map((type, key) =>
|
||||
(
|
||||
<ListGroupItem
|
||||
key={key}
|
||||
className={this.state.selectedType.id === type.id ? "selected" : "null"} onClick={(e) => this.selectType(type)}>
|
||||
{type.name}
|
||||
<Badge pill>{type.Vegetables.length}</Badge>
|
||||
</ListGroupItem>
|
||||
)
|
||||
)
|
||||
}
|
||||
</ListGroup>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
<Col xs="6" sm="12">
|
||||
<Vegetables
|
||||
selectedType={this.state.selectedType}
|
||||
selectedVegetable={this.state.selectedVegetable}
|
||||
selectVegetable={this.selectVegetable}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
</Row >
|
||||
</Container >
|
||||
);
|
||||
}
|
||||
}
|
78
src/Routes/Vegetables.js
Normal file
78
src/Routes/Vegetables.js
Normal file
|
@ -0,0 +1,78 @@
|
|||
import React from 'react';
|
||||
import {
|
||||
Container,
|
||||
Row,
|
||||
Col
|
||||
} from 'reactstrap';
|
||||
import Api from '../Components/Api';
|
||||
import {
|
||||
NotificationContainer,
|
||||
NotificationManager
|
||||
} from 'react-notifications';
|
||||
import MapItem from '../Components/Map'
|
||||
import VegetablesList from '../Components/Vegetables'
|
||||
|
||||
export default class RouterVegetables extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
typeId: props.match.params.typeId,
|
||||
selectedType: {},
|
||||
selectedVegetable: {}
|
||||
}
|
||||
|
||||
this.getItem = this.getItem.bind(this);
|
||||
this.selectVegetable = this.selectVegetable.bind(this);
|
||||
|
||||
this.getItem();
|
||||
}
|
||||
|
||||
selectVegetable(vegetable) {
|
||||
this.setState({
|
||||
selectedVegetable: vegetable
|
||||
})
|
||||
}
|
||||
|
||||
getItem() {
|
||||
Api.get(`/types/${this.state.typeId}`)
|
||||
.then(res => {
|
||||
this.setState({
|
||||
selectedType: res.data
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
NotificationManager.error('Erreur lors de la récupération des végétaux');
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Container>
|
||||
<NotificationContainer />
|
||||
<Row>
|
||||
|
||||
<Col xs="12" sm="8">
|
||||
<MapItem
|
||||
selectedType={this.state.selectedType}
|
||||
selectedVegetable={this.state.selectedVegetable}
|
||||
selectVegetable={this.selectVegetable}
|
||||
/>
|
||||
</Col>
|
||||
<Col xs="12" sm="4">
|
||||
<Row>
|
||||
<Col xs="6" sm="12">
|
||||
<VegetablesList
|
||||
selectedType={this.state.selectedType}
|
||||
selectedVegetable={this.state.selectedVegetable}
|
||||
selectVegetable={this.selectVegetable}
|
||||
/>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
</Row >
|
||||
</Container >
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,206 +0,0 @@
|
|||
import React from 'react';
|
||||
import {
|
||||
Container,
|
||||
Row,
|
||||
Col,
|
||||
ListGroup,
|
||||
ListGroupItem,
|
||||
Badge,
|
||||
Tooltip
|
||||
} from 'reactstrap';
|
||||
import Api from './Api';
|
||||
import {
|
||||
FaMapMarkerAlt
|
||||
} from 'react-icons/fa';
|
||||
import {
|
||||
NotificationContainer,
|
||||
NotificationManager
|
||||
} from 'react-notifications';
|
||||
import {
|
||||
Link
|
||||
} from 'react-router-dom';
|
||||
import strToSlug from '../StrToSlug'
|
||||
|
||||
import '../css/Map.css'
|
||||
|
||||
const MapDimensions = {
|
||||
width: 734,
|
||||
height: 530,
|
||||
};
|
||||
|
||||
export default class Map extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
types: [],
|
||||
vegetables: [],
|
||||
selectedType: {},
|
||||
selectedVegetable: {},
|
||||
Map: {
|
||||
width: '20px',
|
||||
height: '20px',
|
||||
},
|
||||
tooltipOpen: false
|
||||
}
|
||||
|
||||
this.getVegetablesTypes = this.getVegetablesTypes.bind(this);
|
||||
this.selectType = this.selectType.bind(this);
|
||||
this.selectVegetable = this.selectVegetable.bind(this);
|
||||
this.setMap = this.setMap.bind(this);
|
||||
this.toggle = this.toggle.bind(this);
|
||||
|
||||
this.getVegetablesTypes();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener('resize', this.setMap);
|
||||
this.setMap();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener('resize', this.setMap);
|
||||
}
|
||||
|
||||
setMap() {
|
||||
const width = document.getElementById('MapContainer').clientWidth;
|
||||
let MapWidth = MapDimensions.width;
|
||||
let MapHeight = MapDimensions.height;
|
||||
|
||||
if (width < MapDimensions.width) {
|
||||
MapWidth = width;
|
||||
MapHeight = Math.round(MapDimensions.height * MapWidth / MapDimensions.width);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
Map: {
|
||||
width: MapWidth,
|
||||
height: MapHeight,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
getVegetablesTypes() {
|
||||
Api.get('types')
|
||||
.then(res => {
|
||||
this.setState({
|
||||
types: res.data.rows
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
NotificationManager.error('Erreur lors de la récupération des catégories');
|
||||
})
|
||||
}
|
||||
|
||||
getVegetable(id) {
|
||||
Api.get(`types/${id}`)
|
||||
.then(res => {
|
||||
this.setState({
|
||||
vegetables: res.data
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
NotificationManager.error('Erreur lors de la récupération des végétaux');
|
||||
})
|
||||
}
|
||||
|
||||
selectType(type) {
|
||||
this.setState({
|
||||
selectedType: type
|
||||
});
|
||||
}
|
||||
|
||||
selectVegetable(vegetable) {
|
||||
this.setState({
|
||||
selectedVegetable: vegetable
|
||||
})
|
||||
}
|
||||
|
||||
toggle(id) {
|
||||
this.setState(prevState => ({
|
||||
tooltipOpen: prevState.tooltipOpen === id ? false : id
|
||||
}));
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Container>
|
||||
<NotificationContainer />
|
||||
<Row>
|
||||
<Col xs="12" sm="8">
|
||||
<Row className="with-margin">
|
||||
<Col className="with-border with-background">
|
||||
<div id="MapContainer">
|
||||
<div className="map" style={{ width: this.state.Map.width, height: this.state.Map.height }}>
|
||||
{
|
||||
this.state.selectedType &&
|
||||
this.state.selectedType.Vegetables &&
|
||||
this.state.selectedType.Vegetables.map((vegetable, key) =>
|
||||
(
|
||||
<Link to={`/vegetaux/${this.state.selectedType.id}-${strToSlug(this.state.selectedType.name)}/${vegetable.id}-${strToSlug(vegetable.name)}`}
|
||||
key={key}
|
||||
className={`mapMarker ${this.state.selectedVegetable && this.state.selectedVegetable.id === vegetable.id ? 'selected' : ''}`}
|
||||
style={{ left: `calc(${vegetable.lat}% - 16px)`, top: `calc(${vegetable.lng}% - 16px)` }}
|
||||
onMouseOver={(e) => this.selectVegetable(vegetable)}
|
||||
>
|
||||
<Tooltip placement='top' isOpen={this.state.tooltipOpen === vegetable.id} target={'Tooltip-' + vegetable.id} toggle={() => this.toggle(vegetable.id)}>
|
||||
{vegetable.name}
|
||||
</Tooltip>
|
||||
<FaMapMarkerAlt id={'Tooltip-' + vegetable.id} />
|
||||
</Link>
|
||||
)
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
<Col xs="12" sm="4">
|
||||
<Row>
|
||||
<Col xs="6" sm="12">
|
||||
<div className="with-margin">
|
||||
<div className=" with-border with-background">
|
||||
<ListGroup className='vegetables--types--group'>
|
||||
{
|
||||
this.state.types.map((type, key) =>
|
||||
(
|
||||
<ListGroupItem
|
||||
key={key}
|
||||
className={this.state.selectedType.id === type.id ? "selected" : "null"} onClick={(e) => this.selectType(type)}>
|
||||
{type.name}
|
||||
<Badge pill>{type.Vegetables.length}</Badge>
|
||||
</ListGroupItem>
|
||||
)
|
||||
)
|
||||
}
|
||||
</ListGroup>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
<Col xs="6" sm="12">
|
||||
<div className="with-margin">
|
||||
<div className=" with-border with-background">
|
||||
<ListGroup className='vegetables--types--group'>
|
||||
{
|
||||
this.state.selectedType &&
|
||||
this.state.selectedType.Vegetables &&
|
||||
this.state.selectedType.Vegetables.map((vegetable, key) =>
|
||||
(
|
||||
<ListGroupItem key={key} className={this.state.selectedVegetable.id === vegetable.id ? "selected" : "null"} onMouseOver={(e) => this.selectVegetable(vegetable)}>
|
||||
{vegetable.name}
|
||||
</ListGroupItem>
|
||||
)
|
||||
)
|
||||
}
|
||||
</ListGroup>
|
||||
</div>
|
||||
</div>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
import React from 'react';
|
||||
|
||||
export default class Vegetables extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
3
src/css/Vegetables.css
Normal file
3
src/css/Vegetables.css
Normal file
|
@ -0,0 +1,3 @@
|
|||
.vegetables--types--group.list-group a {
|
||||
color: #212529;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
import React from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import App from './components/App';
|
||||
import App from './Components/App';
|
||||
import * as serviceWorker from './serviceWorker';
|
||||
|
||||
import 'react-notifications/lib/notifications.css';
|
||||
|
|
Loading…
Reference in a new issue