Spice up the maps with some InfoWindows
This commit is contained in:
21
src/components/Map/Map.css
Normal file
21
src/components/Map/Map.css
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
.root {
|
||||||
|
height: 360px;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 480px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-shadow: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.map {
|
||||||
|
height: 360px;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 480px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.info {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
|
.infoTitle {
|
||||||
|
margin: 2px 0 10px;
|
||||||
|
}
|
||||||
@@ -1,57 +1,103 @@
|
|||||||
import React, { PropTypes } from 'react';
|
import React, { PropTypes } from 'react';
|
||||||
import { withGoogleMap, GoogleMap, Marker } from 'react-google-maps';
|
import withStyles from 'isomorphic-style-loader/lib/withStyles';
|
||||||
|
import { withGoogleMap, GoogleMap, Marker, InfoWindow } from 'react-google-maps';
|
||||||
|
import s from './Map.css';
|
||||||
|
|
||||||
class Map extends React.Component {
|
class Map extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
defaultZoom: PropTypes.number.isRequired,
|
defaultZoom: PropTypes.number.isRequired,
|
||||||
lat: PropTypes.number.isRequired,
|
defaultCenter: PropTypes.shape({
|
||||||
lng: PropTypes.number.isRequired,
|
|
||||||
markers: PropTypes.arrayOf(PropTypes.shape({
|
|
||||||
title: PropTypes.string.isRequired,
|
|
||||||
lat: PropTypes.number.isRequired,
|
lat: PropTypes.number.isRequired,
|
||||||
lng: PropTypes.number.isRequired,
|
lng: PropTypes.number.isRequired,
|
||||||
|
}).isRequired,
|
||||||
|
markers: PropTypes.arrayOf(PropTypes.shape({
|
||||||
|
title: PropTypes.string.isRequired,
|
||||||
|
position: PropTypes.shape({
|
||||||
|
lat: PropTypes.number.isRequired,
|
||||||
|
lng: PropTypes.number.isRequired,
|
||||||
|
}).isRequired,
|
||||||
|
showInfo: PropTypes.boolean,
|
||||||
|
infoContent: PropTypes.string,
|
||||||
})).isRequired,
|
})).isRequired,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.state = {
|
||||||
|
markers: this.props.markers,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
handleMarkerClick = (targetMarker) => {
|
||||||
|
this.setState({
|
||||||
|
markers: this.state.markers.map(marker => {
|
||||||
|
if (marker === targetMarker) {
|
||||||
|
return {
|
||||||
|
...marker,
|
||||||
|
showInfo: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return marker;
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
handleMarkerClose = (targetMarker) => {
|
||||||
|
this.setState({
|
||||||
|
markers: this.state.markers.map(marker => {
|
||||||
|
if (marker === targetMarker) {
|
||||||
|
return {
|
||||||
|
...marker,
|
||||||
|
showInfo: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return marker;
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const GMap = withGoogleMap(() => (
|
const GMap = withGoogleMap(() => (
|
||||||
<GoogleMap
|
<GoogleMap
|
||||||
defaultZoom={this.props.defaultZoom}
|
defaultZoom={this.props.defaultZoom}
|
||||||
defaultCenter={{ lat: this.props.lat, lng: this.props.lng }}
|
defaultCenter={this.props.defaultCenter}
|
||||||
>
|
>
|
||||||
{this.props.markers.map((props, index) => (
|
{this.state.markers.map((marker, index) => (
|
||||||
<Marker
|
<Marker
|
||||||
title={props.title}
|
|
||||||
position={{ lat: props.lat, lng: props.lng }}
|
|
||||||
key={index}
|
key={index}
|
||||||
/>
|
defaultAnimation="2"
|
||||||
|
{...marker}
|
||||||
|
onClick={() => this.handleMarkerClick(marker)}
|
||||||
|
>
|
||||||
|
{marker.showInfo && (
|
||||||
|
<InfoWindow
|
||||||
|
onCloseClick={() => this.handleMarkerClose(marker)}
|
||||||
|
>
|
||||||
|
<div className={s.info}>
|
||||||
|
<h6 className={s.infoTitle}>
|
||||||
|
{marker.url ? (
|
||||||
|
<a href={marker.url}>{marker.title}</a>
|
||||||
|
) : marker.title }
|
||||||
|
</h6>
|
||||||
|
{marker.infoContent}
|
||||||
|
</div>
|
||||||
|
</InfoWindow>
|
||||||
|
)}
|
||||||
|
</Marker>
|
||||||
))}
|
))}
|
||||||
</GoogleMap>
|
</GoogleMap>
|
||||||
));
|
));
|
||||||
return (
|
return (
|
||||||
<GMap
|
<GMap
|
||||||
containerElement={
|
containerElement={
|
||||||
<div
|
<div className={s.root} />
|
||||||
style={{
|
|
||||||
height: '360px',
|
|
||||||
width: '100%',
|
|
||||||
maxWidth: '480px',
|
|
||||||
overflow: 'hidden',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
mapElement={
|
mapElement={
|
||||||
<div
|
<div className={s.map} />
|
||||||
style={{
|
|
||||||
height: '360px',
|
|
||||||
width: '100%',
|
|
||||||
maxWidth: '480px',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Map;
|
export default withStyles(s)(Map);
|
||||||
|
|||||||
@@ -3,43 +3,57 @@ import withStyles from 'isomorphic-style-loader/lib/withStyles';
|
|||||||
import s from './Accomodation.css';
|
import s from './Accomodation.css';
|
||||||
import Map from '../../components/Map';
|
import Map from '../../components/Map';
|
||||||
|
|
||||||
const offley = [
|
const offley = {
|
||||||
{
|
title: 'Offley Place',
|
||||||
title: 'Offley Place',
|
url: 'http://www.offleyplace.com/',
|
||||||
url: 'http://www.offleyplace.com/',
|
position: {
|
||||||
lat: 51.9282,
|
lat: 51.9282,
|
||||||
lng: -0.3332,
|
lng: -0.3332,
|
||||||
},
|
},
|
||||||
];
|
showInfo: true,
|
||||||
|
};
|
||||||
|
|
||||||
const hotels = [
|
const hotels = [
|
||||||
{
|
{
|
||||||
title: 'Hilton Garden Inn',
|
title: 'Hilton Garden Inn',
|
||||||
url: 'http://hiltongardeninn3.hilton.com/en/hotels/united-kingdom/hilton-garden-inn-luton-north-LTNNOGI/index.html',
|
url: 'http://hiltongardeninn3.hilton.com/en/hotels/united-kingdom/hilton-garden-inn-luton-north-LTNNOGI/index.html',
|
||||||
lat: 51.9116,
|
position: {
|
||||||
lng: -0.3883,
|
lat: 51.9116,
|
||||||
|
lng: -0.3883,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Premier Inn',
|
title: 'Premier Inn',
|
||||||
url: 'http://www.premierinn.com/gb/en/hotels/england/hertfordshire/hitchin/hitchin-town-centre.html',
|
url: 'http://www.premierinn.com/gb/en/hotels/england/hertfordshire/hitchin/hitchin-town-centre.html',
|
||||||
lat: 51.9493,
|
position: {
|
||||||
lng: -0.2762,
|
lat: 51.9493,
|
||||||
|
lng: -0.2762,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Lodge Farm House',
|
title: 'Lodge Farm House',
|
||||||
url: 'http://lodgefarmbandb.co.uk',
|
url: 'http://lodgefarmbandb.co.uk',
|
||||||
lat: 51.9054,
|
position: {
|
||||||
lng: -0.3354,
|
lat: 51.9054,
|
||||||
|
lng: -0.3354,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Red Lion Inn',
|
title: 'Red Lion Inn',
|
||||||
url: 'http://www.theredliongreatoffley.co.uk',
|
url: 'http://www.theredliongreatoffley.co.uk',
|
||||||
lat: 51.9266,
|
position: {
|
||||||
lng: -0.3348,
|
lat: 51.9266,
|
||||||
|
lng: -0.3348,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
class Accomodation extends React.Component {
|
class Accomodation extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.markers = [offley].concat(hotels);
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className={s.root}>
|
<div className={s.root}>
|
||||||
@@ -57,9 +71,8 @@ class Accomodation extends React.Component {
|
|||||||
</ul>
|
</ul>
|
||||||
<Map
|
<Map
|
||||||
defaultZoom={12}
|
defaultZoom={12}
|
||||||
lat={offley[0].lat}
|
defaultCenter={offley.position}
|
||||||
lng={offley[0].lng}
|
markers={this.markers}
|
||||||
markers={hotels}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,13 +3,14 @@ import withStyles from 'isomorphic-style-loader/lib/withStyles';
|
|||||||
import s from './Ceremony.css';
|
import s from './Ceremony.css';
|
||||||
import Map from '../../components/Map';
|
import Map from '../../components/Map';
|
||||||
|
|
||||||
const markers = [
|
const church = {
|
||||||
{
|
title: 'All Saints\' Church',
|
||||||
title: 'All Saints\' Church',
|
position: {
|
||||||
lat: 51.7109,
|
lat: 51.7109,
|
||||||
lng: -0.4479,
|
lng: -0.4479,
|
||||||
},
|
},
|
||||||
];
|
showInfo: true,
|
||||||
|
};
|
||||||
|
|
||||||
class Ceremony extends React.Component {
|
class Ceremony extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
@@ -31,9 +32,8 @@ class Ceremony extends React.Component {
|
|||||||
Parking is available across the road at the Rose and Crown pub.</p>
|
Parking is available across the road at the Rose and Crown pub.</p>
|
||||||
<Map
|
<Map
|
||||||
defaultZoom={14}
|
defaultZoom={14}
|
||||||
lat={markers[0].lat}
|
defaultCenter={church.position}
|
||||||
lng={markers[0].lng}
|
markers={[church]}
|
||||||
markers={markers}
|
|
||||||
/>
|
/>
|
||||||
<h3>About the church</h3>
|
<h3>About the church</h3>
|
||||||
<p>All Saints Church is a medieval church with parts dating from the 13th century.
|
<p>All Saints Church is a medieval church with parts dating from the 13th century.
|
||||||
|
|||||||
@@ -3,14 +3,15 @@ import withStyles from 'isomorphic-style-loader/lib/withStyles';
|
|||||||
import s from './Reception.css';
|
import s from './Reception.css';
|
||||||
import Map from '../../components/Map';
|
import Map from '../../components/Map';
|
||||||
|
|
||||||
const offley = [
|
const offley = {
|
||||||
{
|
title: 'Offley Place',
|
||||||
title: 'Offley Place',
|
url: 'http://www.offleyplace.com/',
|
||||||
url: 'http://www.offleyplace.com/',
|
position: {
|
||||||
lat: 51.9282,
|
lat: 51.9282,
|
||||||
lng: -0.3332,
|
lng: -0.3332,
|
||||||
},
|
},
|
||||||
];
|
showInfo: true,
|
||||||
|
};
|
||||||
|
|
||||||
class Reception extends React.Component {
|
class Reception extends React.Component {
|
||||||
render() {
|
render() {
|
||||||
@@ -35,9 +36,8 @@ class Reception extends React.Component {
|
|||||||
<p>The venue is approximately a 30 minute drive from the Church.</p>
|
<p>The venue is approximately a 30 minute drive from the Church.</p>
|
||||||
<Map
|
<Map
|
||||||
defaultZoom={12}
|
defaultZoom={12}
|
||||||
lat={offley[0].lat}
|
defaultCenter={offley.position}
|
||||||
lng={offley[0].lng}
|
markers={[offley]}
|
||||||
markers={offley}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -3,34 +3,45 @@ import withStyles from 'isomorphic-style-loader/lib/withStyles';
|
|||||||
import s from './Transport.css';
|
import s from './Transport.css';
|
||||||
import Map from '../../components/Map';
|
import Map from '../../components/Map';
|
||||||
|
|
||||||
const offley = [
|
const offley = {
|
||||||
{
|
title: 'Offley Place',
|
||||||
title: 'Offley Place',
|
url: 'http://www.offleyplace.com/',
|
||||||
url: 'http://www.offleyplace.com/',
|
position: {
|
||||||
lat: 51.9282,
|
lat: 51.9282,
|
||||||
lng: -0.3332,
|
lng: -0.3332,
|
||||||
},
|
},
|
||||||
];
|
showInfo: true,
|
||||||
|
};
|
||||||
|
|
||||||
const stations = [
|
const stations = [
|
||||||
{
|
{
|
||||||
title: 'Hitchin',
|
title: 'Hitchin',
|
||||||
lat: 51.9532,
|
position: {
|
||||||
lng: -0.2655,
|
lat: 51.9532,
|
||||||
|
lng: -0.2655,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Luton',
|
title: 'Luton',
|
||||||
lat: 51.8820,
|
position: {
|
||||||
lng: -0.4171,
|
lat: 51.8820,
|
||||||
|
lng: -0.4171,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Luton Airport Parkway',
|
title: 'Luton Airport Parkway',
|
||||||
lat: 51.8724,
|
position: {
|
||||||
lng: -0.3984,
|
lat: 51.8724,
|
||||||
|
lng: -0.3984,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
class Transport extends React.Component {
|
class Transport extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.markers = [offley].concat(stations);
|
||||||
|
}
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className={s.root}>
|
<div className={s.root}>
|
||||||
@@ -45,9 +56,8 @@ class Transport extends React.Component {
|
|||||||
All trains terminate at London St Pancras or London Kings Cross</p>
|
All trains terminate at London St Pancras or London Kings Cross</p>
|
||||||
<Map
|
<Map
|
||||||
defaultZoom={11}
|
defaultZoom={11}
|
||||||
lat={offley[0].lat}
|
defaultCenter={offley.position}
|
||||||
lng={offley[0].lng}
|
markers={this.markers}
|
||||||
markers={stations}
|
|
||||||
/>
|
/>
|
||||||
<h3>Car</h3>
|
<h3>Car</h3>
|
||||||
<p>Offley Place has secure parking facilities.</p>
|
<p>Offley Place has secure parking facilities.</p>
|
||||||
|
|||||||
Reference in New Issue
Block a user