import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { compose, withStateHandlers } from 'recompose'; import { withScriptjs, withGoogleMap, GoogleMap, Marker, InfoWindow } from 'react-google-maps'; import { MarkerClusterer } from 'react-google-maps/lib/components/addons/MarkerClusterer'; // Custom Components import LayerMapSwitches from './LayerMapSwitches'; // Helpers import GOOGLE_MAPS_API from '../utils/constants'; import Client from '../utils/feathers'; // Images import MerchantPin from '../assets/img/map/merchant_pin.png'; import AmbassadorPin from '../assets/img/map/ambassador_pin.png'; /** * This object is used for type checking the props of the component. */ const propTypes = { ambassadors: PropTypes.array, merchants: PropTypes.array, mapCenter: PropTypes.object, mapZoom: PropTypes.number, // Fix google maps modal problem showControls: PropTypes.bool }; /** * This object sets default values to the optional props. */ const defaultProps = { mapCenter: { lat: -22.9068, lng: -43.1729 }, mapZoom: 12, googleMapURL: `https://maps.googleapis.com/maps/api/js?key=${GOOGLE_MAPS_API}&v=3.exp&libraries=geometry,drawing,places`, loadingElement:
, containerElement:
, mapElement:
, // Fix google maps modal problem showControls: true, }; defaultProps['markers'] = [ defaultProps.mapCenter ]; /** * Map that support Merchant Layer Markers and Ambassadors Layer Markers. */ const CustomLayerMap = compose( withStateHandlers(() => ({ isOpenObj: {}, isOpenAmbassadorObj:{} }), { onToggleOpen: ({ isOpenObj }) => (index) => { const openObj = isOpenObj; openObj[index] = !openObj[index]; return openObj; }, onToggleAmbassadorOpen: ({ isOpenAmbassadorObj }) => (index) => { const openObj = isOpenAmbassadorObj; openObj[index] = !openObj[index]; return openObj; } }), withScriptjs, withGoogleMap )(props => {props.ambassadors.map( (marker, index) => ( marker.withInfo ? ( props.onToggleOpen(index)} > {props.isOpenObj[index] && props.onToggleOpen(index)}>
{marker.infoTitle}

{marker.infoDescription}
}
) : ( ) ))}
{props.merchants.map( (marker, index) => ( marker.withInfo ? ( props.onToggleAmbassadorOpen(index)} > {props.isOpenAmbassadorObj[index] && props.onToggleAmbassadorOpen(index)}>
{marker.infoTitle}

{marker.infoDescription}
}
) : ( ) ))}
); // Type checking the props of the component CustomLayerMap.propTypes = propTypes; // Assign default values to the optional props CustomLayerMap.defaultProps = defaultProps; /** * This object is used for type checking the props of the component. */ const propTypesLayerMap = { ambassadorsLayer: PropTypes.bool, merchantsLayer: PropTypes.bool, showControls: PropTypes.bool, mapHeight: PropTypes.string }; class LayerMap extends Component { constructor(props) { super(props); this.state = { ambassadors: [], merchants: [], ambassadorLayer: this.props.ambassadorsLayer, merchantLayer: this.props.merchantsLayer }; } /** * @description Lifecycle event handler called just after the App loads into the DOM. */ UNSAFE_componentWillMount() { this.getAmbassadors(); this.getMerchants(); } /** * @description Get the ambassadors list from the web service. * @param {string} id - Merchant ID. */ getAmbassadors = () => { const app = this; const ambassadors = Client.service('api/v1/ambassadors'); this.setState({loading: true}); ambassadors.find().then( (results) => { const markers = results.data.map(ambassador => { const marker = { lat: ambassador.lat, lng: ambassador.lon, withInfo: true, infoTitle: ambassador.nickname, infoDescription: `${ambassador.city} - ${ambassador.country}`, }; return marker; }); // Once both return, update the state app.setState({ ambassadors: markers, loading: false }); }).catch( error => { app.setState({responseError: error.message, loading: false}); }); }; /** * @description Get the merchants list from the web service. * @param {string} id - Merchant ID. */ getMerchants = () => { const app = this; const merchants = Client.service('api/v1/merchants'); this.setState({loading: true}); merchants.find().then( (results) => { const markers = results.data.map(merchant => { const marker = { lat: merchant.lat, lng: merchant.lon, withInfo: true, infoTitle: merchant.name, infoDescription: `${merchant.address}, ${merchant.city} - ${merchant.country}`, }; return marker; }); // Once both return, update the state app.setState({ merchants: markers, loading: false }); }).catch( error => { app.setState({responseError: error.message, loading: false}); }); }; handleLayerChange = name => event => { this.setState({ [name]: event.target.checked }); // Update any time changes this.getAmbassadors(); this.getMerchants(); }; render() { // create an array with marker components return (
{!this.props.showControls ? ( ) : (
)} } containerElement={
} mapElement={
} />
); } } // Type checking the props of the component LayerMap.propTypes = propTypesLayerMap; export default LayerMap;