kontenhumas-fe/components/maps/Map copy.js

366 lines
9.2 KiB
JavaScript

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(() => (
<GoogleMap
google={this.props.google}
defaultZoom={this.props.zoom}
defaultCenter={{
lat: this.state.mapPosition.lat,
lng: this.state.mapPosition.lng,
}}
>
<Autocomplete
style={{
width: "100%",
height: "40px",
paddingLeft: "16px",
marginTop: "2px",
marginBottom: "500px",
}}
onPlaceSelected={this.onPlaceSelected}
options={{
types: ["geocode"],
}}
/>
{/* InfoWindow on top of marker */}
<InfoWindow
onClose={this.onInfoWindowClose}
position={{
lat: this.state.markerPosition.lat + 0.0018,
lng: this.state.markerPosition.lng,
}}
>
<div>
<span
style={{
padding: 0,
margin: 0,
}}
>
{this.state.address}
</span>
</div>
</InfoWindow>
{/* Marker */}
<Marker
google={this.props.google}
name="Dolores park"
draggable={this.props.draggable}
onDragEnd={this.onMarkerDragEnd}
position={{
lat: this.state.markerPosition.lat,
lng: this.state.markerPosition.lng,
}}
/>
<Marker />
{/* For Auto complete Search Box */}
</GoogleMap>
)),
);
let map;
if (this.props.center.lat == undefined) {
map = (
<div
style={{
height: this.props.height,
}}
/>
);
} else {
map = (
<div>
{/* <div>
<div className="form-group">
<label htmlFor="">Address</label>
<input type="text" name="address" className="form-control" onChange={ this.onChange } readOnly="readOnly" value={ this.state.address }/>
</div>
<div className="form-group">
<label htmlFor="">All Data</label>
<input type="text" name="address" className="form-control" onChange={ this.onChange } readOnly="readOnly" value={ this.state.markerPosition.lat + ";" + this.state.markerPosition.lng }/>
</div>
</div> */}
<AsyncMap
googleMapURL={`https://maps.googleapis.com/maps/api/js?key=${GoogleMapsAPI}&libraries=places`}
loadingElement={
<div
style={{
height: "100%",
}}
/>
}
containerElement={
<div
style={{
height: this.props.height,
}}
/>
}
mapElement={
<div
style={{
height: "100%",
}}
/>
}
/>
</div>
);
}
return map;
}
}
export default Map;