front/src/Components/Map.js
2019-04-13 13:59:58 +02:00

178 lines
4.1 KiB
JavaScript

import React from 'react';
import PropTypes from 'prop-types';
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,
};
class Map extends React.Component {
constructor(props) {
super(props);
const {
selectedType,
selectedVegetable,
} = this.props;
this.state = {
selectedType,
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);
}
componentDidMount() {
window.addEventListener('resize', this.setMap);
this.setMap();
}
componentWillReceiveProps(newProps) {
const {
selectedType,
selectedVegetable,
} = this.state;
if (newProps.selectedType !== selectedType
|| newProps.selectedVegetable !== selectedVegetable
) {
this.setState(prevState => ({
...prevState,
selectedType: newProps.selectedType,
selectedVegetable: newProps.selectedVegetable,
}), this.setMap);
}
}
componentWillUnmount() {
window.removeEventListener('resize', this.setMap);
}
setMap() {
const {
setHeight,
} = this.props;
const width = document.getElementById('MapContainer').clientWidth;
let MapWidth = MapDimensions.width;
let MapHeight = MapDimensions.height;
MapWidth = width;
MapHeight = Math.round(MapDimensions.height * MapWidth / MapDimensions.width);
if (setHeight) {
setHeight(MapHeight);
}
this.setState({
map: {
width: MapWidth,
height: MapHeight,
},
});
}
selectVegetable(vegetable) {
this.setState({
selectedVegetable: vegetable,
});
const {
selectVegetable,
} = this.props;
selectVegetable(vegetable);
}
toggle(id) {
this.setState(prevState => ({
tooltipOpen: prevState.tooltipOpen === id ? false : id,
}));
}
createLink(vegetable) {
const {
selectedType,
} = this.state;
let url = '/vegetaux/';
if (vegetable.Type) {
url += `${vegetable.Type.id}-${strToSlug(vegetable.Type.name)}`;
} else {
url += `${selectedType.id}-${strToSlug(selectedType.name)}`;
}
url += `/${vegetable.id}-${strToSlug(vegetable.name)}`;
return url;
}
render() {
const {
map,
selectedType,
selectedVegetable,
tooltipOpen,
} = this.state;
return (
<Row className="with-margin">
<Col className="with-border with-background">
<div id="MapContainer">
<div className="map" style={{ width: map.width, height: map.height }}>
{
selectedType
&& selectedType.Vegetables
&& selectedType.Vegetables.map(vegetable => (
<Link
to={this.createLink(vegetable)}
key={vegetable.id}
className={`mapMarker ${selectedVegetable && selectedVegetable.id === vegetable.id ? 'selected' : ''}`}
style={{ left: `calc(${vegetable.lat}% - 16px)`, top: `calc(${vegetable.lng}% - 16px)` }}
onMouseOver={() => this.selectVegetable(vegetable)}
onFocus={() => { }}
>
<Tooltip placement="top" isOpen={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>
);
}
}
Map.propTypes = {
selectedType: PropTypes.shape().isRequired,
selectedVegetable: PropTypes.shape().isRequired,
setHeight: PropTypes.func.isRequired,
selectVegetable: PropTypes.func.isRequired,
};
export default Map;