import Cookies from "js-cookie"; import React, { Component } from "react"; import Geocode from "react-geocode"; import Autocomplete from "react-google-autocomplete"; import { GoogleMap, InfoWindow, Marker, withGoogleMap, withScriptjs, } from "react-google-maps"; import { GoogleMapsAPI } from "./client-config"; Geocode.setApiKey(GoogleMapsAPI); Geocode.enableDebug(); class Map extends Component { constructor(props) { super(props); this.state = { address: "", city: "", area: "", state: "", mapPosition: { lat: this.props.center.lat, lng: this.props.center.lng, }, markerPosition: { lat: this.props.center.lat, lng: this.props.center.lng, }, }; } /** * Get the current address from the default map position and set those values in the state */ componentDidMount() { Geocode.fromLatLng( this.state.mapPosition.lat, this.state.mapPosition.lng, ).then( (response) => { const address = response.results[0].formatted_address; const addressArray = response.results[0].address_components; const city = this.getCity(addressArray); const area = this.getArea(addressArray); const state = this.getState(addressArray); console.log("city", city, area, state); this.setState({ address: address || "", area: area || "", city: city || "", state: state || "", }); }, (error) => { console.error(error); }, ); } /** * Component should only update ( meaning re-render ), when the user selects the address, or drags the pin * * @param nextProps * @param nextState * @return {boolean} */ shouldComponentUpdate(nextProps, nextState) { if ( this.state.markerPosition.lat !== this.props.center.lat || this.state.address !== nextState.address || this.state.city !== nextState.city || this.state.area !== nextState.area || this.state.state !== nextState.state ) { return true; } if (this.props.center.lat == nextProps.center.lat) { return false; } } /** * Get the city and set the city input value to the one selected * * @param addressArray * @return {string} */ getCity = (addressArray) => { let city = ""; for (const element of addressArray) { if ( element.types[0] && element.types[0] == "administrative_area_level_2" ) { city = element.long_name; return city; } } }; /** * Get the area and set the area input value to the one selected * * @param addressArray * @return {string} */ getArea = (addressArray) => { let area = ""; for (const element of addressArray) { if (element.types[0]) { for (let j = 0; j < element.types.length; j++) { if ( element.types[j] == "sublocality_level_1" || element.types[j] == "locality" ) { area = element.long_name; return area; } } } } }; /** * Get the address and set the address input value to the one selected * * @param addressArray * @return {string} */ getState = (addressArray) => { let state = ""; for (let i = 0; i < addressArray.length; i++) { for (const element of addressArray) { if ( element.types[0] && element.types[0] == "administrative_area_level_1" ) { state = element.long_name; return state; } } } }; /** * And function for city,state and address input * @param event */ onChange = (event) => { this.setState({ [event.target.name]: event.target.value, }); }; /** * This Event triggers when the marker window is closed * * @param event */ onInfoWindowClose = () => {}; /** * When the marker is dragged you get the lat and long using the functions available from event object. * Use geocode to get the address, city, area and state from the lat and lng positions. * And then set those values in the state. * * @param event */ onMarkerDragEnd = (event) => { const newLat = event.latLng.lat(); const newLng = event.latLng.lng(); Geocode.fromLatLng(newLat, newLng).then( (response) => { const address = response.results[0].formatted_address; const addressArray = response.results[0].address_components; const city = this.getCity(addressArray); const area = this.getArea(addressArray); const state = this.getState(addressArray); this.setState({ address: address || "", area: area || "", city: city || "", state: state || "", markerPosition: { lat: newLat, lng: newLng, }, mapPosition: { lat: newLat, lng: newLng, }, }); Cookies.set("map_lat", `${newLat}`, { expires: 1 }); Cookies.set("map_long", `${newLng}`, { expires: 1 }); $(".input-location-schedule").val(address); }, (error) => { console.error(error); }, ); }; /** * When the user types an address in the search box * @param place */ onPlaceSelected = (place) => { console.log("plc", place); const address = place.formatted_address; const addressArray = place.address_components; const city = this.getCity(addressArray); const area = this.getArea(addressArray); const state = this.getState(addressArray); const latValue = place.geometry.location.lat(); const lngValue = place.geometry.location.lng(); // Set these values in the state. this.setState({ address: address || "", area: area || "", city: city || "", state: state || "", markerPosition: { lat: latValue, lng: lngValue, }, mapPosition: { lat: latValue, lng: lngValue, }, }); Cookies.set("map_lat", `${latValue}`, { expires: 1 }); Cookies.set("map_long", `${lngValue}`, { expires: 1 }); $(".input-location-schedule").val(address); }; render() { const AsyncMap = withScriptjs( withGoogleMap(() => ( {/* InfoWindow on top of marker */}
{this.state.address}
{/* Marker */} {/* For Auto complete Search Box */}
)), ); let map; if (this.props.center.lat == undefined) { map = (
); } else { map = (
{/*
*/} } containerElement={
} mapElement={
} />
); } return map; } } export default Map;