178 lines
4.1 KiB
JavaScript
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;
|