Commit 03afc1e8 authored by Andrew Hrdy's avatar Andrew Hrdy

Remove mapbox

parent 39069bc8
This diff is collapsed.
......@@ -30,7 +30,6 @@
<link rel="manifest" href="./manifest.json">
<link rel="shortcut icon" href="./favicon.png">
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.40.1/mapbox-gl.css' rel='stylesheet' />
</head>
<body>
......
......@@ -3,7 +3,6 @@ import { removeBrackets } from '../utils/nameUtils';
import { IFacility } from '../models/facility.model';
import WeekHours from './WeekHours';
import MapDialog from './MapDialog';
import Dialog from '@material-ui/core/Dialog';
import Grid from '@material-ui/core/Grid';
......@@ -14,30 +13,14 @@ import CloseIcon from '@material-ui/icons/Close';
import IconButton from '@material-ui/core/IconButton';
import LocationOnIcon from '@material-ui/icons/LocationOn';
class FacilityDialog extends React.Component<FacilityDialogProps, FacilityDialogState> {
class FacilityDialog extends React.Component<FacilityDialogProps> {
constructor(props: FacilityDialogProps) {
super(props);
this.state = {
isMapOpen: false
};
}
/**
* Toggles whether the map is shown.
*
* @memberof FacilityDialog
*/
toggleMap = () => {
this.setState({
isMapOpen: !this.state.isMapOpen
});
}
render() {
const {facility, facilities, isOpen, onClose} = this.props;
const {isMapOpen} = this.state;
return (
<Dialog classes={{
......@@ -74,19 +57,7 @@ class FacilityDialog extends React.Component<FacilityDialogProps, FacilityDialog
<Grid item={true} className={'fd-week-hours'}>
<WeekHours facility={facility} />
</Grid>
<Grid item={true} className={'fd-toggle-map-btn-container'}>
<Button className={'fd-toggle-map-btn'} onClick={this.toggleMap}>Open Map</Button>
</Grid>
</Grid>
<MapDialog
open={isMapOpen}
facilities={facilities}
facility={facility}
fullScreen={true}
onClose={this.toggleMap}
/>
</Dialog>
);
}
......@@ -99,8 +70,4 @@ export interface FacilityDialogProps {
onClose: () => void;
}
export interface FacilityDialogState {
isMapOpen: boolean;
}
export default FacilityDialog;
\ No newline at end of file
import * as React from 'react';
import { IFacility } from '../models/facility.model';
import FacilitiesMap from '../containers/FacilitiesMap';
import Dialog from '@material-ui/core/Dialog';
import IconButton from '@material-ui/core/IconButton';
import CloseIcon from '@material-ui/icons/Close';
class MapDialog extends React.Component<MapDialogProps> {
handleRequestClose = () => {
this.props.onClose();
}
render() {
const {facility, facilities, open, width, height, fullScreen = false} = this.props;
return (
<Dialog onClose={this.handleRequestClose} open={open} fullScreen={fullScreen}>
<div style={{
height: height || '100%',
width: width || '100%'
}}>
<IconButton className={'map-dialog-close-btn'} onClick={this.handleRequestClose}>
<CloseIcon />
</IconButton>
<FacilitiesMap
facilities={facilities}
facility={facility}
interactive={true}
/>
</div>
</Dialog>
);
}
}
export interface MapDialogProps {
facility: IFacility;
facilities: IFacility[];
open: boolean;
width?: string;
height?: string;
fullScreen?: boolean;
onClose: () => void;
}
export default MapDialog;
......@@ -2,12 +2,9 @@ import * as React from 'react';
import { removeBrackets } from '../utils/nameUtils';
import * as phoneFormatter from 'phone-formatter';
import { IFacility } from '../models/facility.model';
import { trackPiwikEvent } from '../piwik/piwik';
import { Link } from 'react-router-dom';
import TextwTitle from './TextwTitle';
import FacilitiesMap from '../containers/FacilitiesMap';
import MapDialog from './MapDialog';
import WeekHours from './WeekHours';
import Paper from '@material-ui/core/Paper';
......@@ -19,35 +16,14 @@ import IconButton from '@material-ui/core/IconButton';
import FacilityDialog from './FacilityDialog';
import { History } from 'history';
class Sidebar extends React.Component<SidebarProps, SidebarState> {
class Sidebar extends React.Component<SidebarProps> {
constructor(props: SidebarProps) {
super(props);
this.state = {
mapDialogOpen: false
};
}
handleMapDialogClose = () => {
trackPiwikEvent('map-action', 'close');
this.setState({
mapDialogOpen: false
});
}
handleMapDialogOpen = () => {
trackPiwikEvent('map-action', 'open');
this.setState({
mapDialogOpen: true
});
}
render() {
const {facility, facilities, history} = this.props;
const {mapDialogOpen} = this.state;
return (
<div className={'sidebar-container'}>
......@@ -79,24 +55,6 @@ class Sidebar extends React.Component<SidebarProps, SidebarState> {
<TextwTitle label="Hours" content={<WeekHours facility={facility} />} />
</div>
</div>
<div className={'sidebar-row2'}>
<div className={'sidebar-map-container'} onClick={this.handleMapDialogOpen}>
<FacilitiesMap
facilities={facilities}
facility={facility}
interactive={false}
/>
</div>
<MapDialog
open={mapDialogOpen}
facilities={facilities}
facility={facility}
height={'500px'}
width={'600px'}
onClose={this.handleMapDialogClose}
/>
</div>
</Paper>
<FacilityDialog facility={facility} facilities={facilities} isOpen={true} onClose={() => history.push('/')} />
......@@ -111,8 +69,4 @@ export interface SidebarProps {
facilities: IFacility[];
}
export interface SidebarState {
mapDialogOpen: boolean;
}
export default Sidebar;
\ No newline at end of file
import * as React from 'react';
import ReactMapboxGl, { Marker, Popup } from 'react-mapbox-gl';
import { getMaxBounds, getCenterOfCampusRegion } from '../utils/mapboxUtils';
import * as mapboxgl from 'mapbox-gl';
import { removeBrackets } from '../utils/nameUtils';
import { IFacility, CampusRegion, FacilitiesByLocation } from '../models/facility.model';
import { ApplicationState } from '../store';
import { connect } from 'react-redux';
import MenuItem from '@material-ui/core/MenuItem';
import Select from '@material-ui/core/Select';
import FormControl from '@material-ui/core/FormControl';
import Typography from '@material-ui/core/Typography';
const mapboxToken = 'pk.eyJ1IjoibWR1ZmZ5OCIsImEiOiJjaXk2a2lxODQwMDdyMnZzYTdyb3M4ZTloIn0.mSocl7zUnZBO6-CV9cvmnA';
const Mark = {
backgroundColor: '#e74c3c',
borderRadius: '50%',
width: '12px',
height: '12px',
border: '3px solid #EAA29B'
};
class FacilitiesMap extends React.Component<FacilitiesMapProps, FacilitiesMapState> {
private Map: any;
constructor(props: FacilitiesMapProps) {
super(props);
const {facility, interactive = true} = props;
const campusRegion = facility && facility.facility_location ? facility.facility_location.campus_region : CampusRegion.Fairfax;
this.Map = ReactMapboxGl({
accessToken: mapboxToken,
interactive: interactive,
attributionControl: false
});
this.state = {
maxBounds: getMaxBounds(campusRegion),
campusRegion: campusRegion,
zoom: [17],
center: facility && facility.facility_location ? facility.facility_location.coordinate_location.coordinates : getCenterOfCampusRegion(campusRegion),
selectedLocation: null,
isLoaded: false
};
}
componentWillReceiveProps(nextProps: FacilitiesMapProps) {
const {facility} = nextProps;
const campusRegion = facility && facility.facility_location ? facility.facility_location.campus_region : CampusRegion.Fairfax;
this.changeRegion(campusRegion, facility);
}
/**
* Change the region displayed on the map.
*
* @memberof FacilitiesMap
*/
changeRegion = (campusRegion: CampusRegion, facility: IFacility = this.props.facility) => {
const facilityLocationExists = facility && facility.facility_location && facility.facility_location.campus_region === campusRegion;
const newState = {
maxBounds: getMaxBounds(campusRegion),
campusRegion: campusRegion,
center: facilityLocationExists ? facility.facility_location.coordinate_location.coordinates : getCenterOfCampusRegion(campusRegion),
zoom: [17]
};
setTimeout(() => {
this.setState(newState);
}, 100);
}
/**
* Selects a location on the map. This will cause a popup
* to appear, showing all the facilities at that location.
*
* @memberof FacilitiesMap
*/
selectLocation = (location: FacilitiesByLocation) => {
const {interactive = true} = this.props;
const oldSelectedLocation = this.state.selectedLocation;
if (!interactive) {
return;
}
this.setState({
selectedLocation: oldSelectedLocation !== location ? location : null,
center: location && location.location.coordinate_location.coordinates,
zoom: [17]
});
}
render() {
const {interactive = true, facilitiesByLocation} = this.props;
const {maxBounds, selectedLocation, center, zoom} = this.state;
return (
<this.Map
onStyleLoad={(map: any) => {
if (interactive) {
map.addControl(new mapboxgl.GeolocateControl({
positionOptions: {
enableHighAccuracy: true
},
trackUserLocation: true
}));
}
}}
animationOptions={{
animate: true,
duration: 1250
}}
style="mapbox://styles/mduffy8/cjbcdxi3v73hp2spiyhxbkjde"
movingMethod="easeTo"
containerStyle={{
height: '100%',
width: '100%',
borderRadius: '5px',
cursor: 'pointer'
}}
center={center}
fitBounds={maxBounds}
zoom={zoom}
maxBounds={maxBounds}>
{interactive &&
(
<FormControl className={'facilities-map-campus-select'}>
<Select
disableUnderline={true}
value={this.state.campusRegion}
onChange={(e) => this.changeRegion(e.target.value as CampusRegion)}>
<MenuItem value={CampusRegion.Fairfax}>Fairfax</MenuItem>
<MenuItem value={CampusRegion.Arlington}>Arlington</MenuItem>
<MenuItem value={CampusRegion.PrinceWilliam}>SciTech</MenuItem>
<MenuItem value={CampusRegion.FrontRoyal}>Front Royal</MenuItem>
</Select>
</FormControl>
)}
{(facilitiesByLocation.length > 0) && facilitiesByLocation.map((item) => {
const location = item.location;
return (
<Marker
key={location.id}
coordinates={location.coordinate_location.coordinates}
anchor="bottom"
onClick={() => this.selectLocation(item)}>
<div style={Mark} />
</Marker>
);
})}
{selectedLocation && (
<Popup coordinates={selectedLocation.location.coordinate_location.coordinates} anchor="top">
<div>
<Typography variant="subtitle1" align={'center'}>
{selectedLocation.location.building}
</Typography>
</div>
<div>
<ul className={'facilities-map-popup-list'}>
{selectedLocation.facilities.map((facility) => {
return (
<li key={facility.slug}>
<Typography variant="caption">{removeBrackets(facility.facility_name)}</Typography>
</li>
);
})}
</ul>
</div>
</Popup>
)}
</this.Map>
);
}
}
export interface FacilitiesMapProps {
facility: IFacility;
facilities: IFacility[];
interactive: boolean;
facilitiesByLocation: FacilitiesByLocation[];
}
export interface FacilitiesMapState {
maxBounds: number[][];
campusRegion: CampusRegion;
zoom: number[];
center: number[];
selectedLocation: FacilitiesByLocation;
isLoaded: boolean;
}
const mapStateToProps = (state: ApplicationState) => ({
facilitiesByLocation: state.facilities.facilitiesByLocation || []
});
export default connect(mapStateToProps)(FacilitiesMap);
\ No newline at end of file
......@@ -63,8 +63,3 @@ export interface IFacilityScheduleEntry {
start_time: string;
end_time: string;
}
\ No newline at end of file
export interface FacilitiesByLocation {
location: IFacilityLocation;
facilities: IFacility[];
}
\ No newline at end of file
import { IFacility, FacilitiesByLocation } from '../../models/facility.model';
import { IFacility } from '../../models/facility.model';
import { FacilityAction, FacilityActionTypes } from './facility.action-types';
import { generateFacilitiesByLocation } from '../../utils/mapboxUtils';
export interface FacilityState {
isFetching: boolean;
facilities: IFacility[];
facilitiesByLocation: FacilitiesByLocation[];
}
export const facilityReducer = (state: FacilityState = {isFetching: false, facilities: [], facilitiesByLocation: []}, action: FacilityAction) => {
export const facilityReducer = (state: FacilityState = {isFetching: false, facilities: []}, action: FacilityAction) => {
switch (action.type) {
case FacilityActionTypes.FETCH_FACILITIES: {
return {
......@@ -20,8 +18,7 @@ export const facilityReducer = (state: FacilityState = {isFetching: false, facil
return {
...state,
isFetching: false,
facilities: action.facilities,
facilitiesByLocation: generateFacilitiesByLocation(action.facilities)
facilities: action.facilities
};
}
default:
......
......@@ -67,15 +67,6 @@
width: 100%;
}
.fd-toggle-map-btn-container {
padding: 0 !important;
width: 100%;
}
.fd-toggle-map-btn {
width: 100%;
}
//Above sm
@media screen and (min-width: map-get($breakpoints, sm)) {
.fd-dialog-paper {
......
.map-dialog-close-btn {
position: absolute !important;
z-index: 100;
top: 5px;
left: 5px;
width: 30px !important;
height: 30px !important;
padding: 4px !important;
}
\ No newline at end of file
......@@ -70,24 +70,6 @@
align-items: center;
}
.sidebar-row2 {
position: absolute;
bottom: 0;
width: 100%;
}
.sidebar-map-container {
transition: 250ms ease-in-out;
width: 100%;
height: 200px;
padding: 10px;
box-sizing: border-box;
}
.sidebar-toggle-map-btn {
width: 100%;
}
.sidebar-scroll {
height: calc(100% - 220px - 116px - 32px) !important;
overflow-y: auto;
......
.facilities-map-campus-select {
position: absolute !important;
z-index: 100;
left: 50%;
transform: translateX(-50%);
top: 10px;
height: 30px !important;
background-color: white !important;
border-radius: 5px;
box-shadow: 0 0 0 2px rgba(0,0,0,0.1);
}
.facilities-map-popup-list {
margin: 0;
padding-left: 16px;
max-height: 100px;
overflow-y: auto;
}
\ No newline at end of file
......@@ -8,13 +8,11 @@
@import './components/facilityDialog';
@import './components/facilityStatus';
@import './components/favoriteButton';
@import './components/mapDialog';
@import './components/sidebar';
@import './components/textwTitle';
@import './components/weekHours';
/* Containers */
@import './containers/alertContainer';
@import './containers/facilitiesMap';
@import './containers/facilityCard';
@import './containers/layout';
@import './containers/searchBar';
......
import { CampusRegion, IFacility, FacilitiesByLocation } from '../models/facility.model';
const campusBounds = {
fairfax: [
[-77.321649, 38.823919], // Southwest coordinates
[-77.295213, 38.835720] // Northeast coordinates
],
arlington: [
[-77.10365559, 38.88232150],
[-77.09969515, 38.88621749]
],
'prince william': [
[-77.52645645, 38.75469300],
[-77.51416565, 38.76009113]
],
'front royal': [
[-77.02180979, 38.88559549],
[-77.01998030, 38.88663396]
]
};
/**
* paints geojson data onto map
*
* @param map object
* @param geojson object
*/
const addRoute = (map: any, geometry: any) => {
map.addLayer({
id: 'route',
type: 'line',
source: {
type: 'geojson',
data: {
type: 'Feature',
properties: {},
geometry: geometry
}
},
layout: {
'line-join': 'round',
'line-cap': 'round'
},
paint: {
'line-color': '#4790E5',
'line-width': 5
}
});
};
/**
* Gets directions from start coord to end cood and returns a geojson line object
*
* @param mapbox client object
* @param start coordinate
* @param end coordinate
* @returns {Promise} the line object
*/
const getGeoLine = (mapboxClient: any, start: any, end: any) => {
return new Promise((resolve) => {
mapboxClient.getDirections([
start,
end
], {
profile: 'walking',
alternatives: false,
geometry: 'geojson'
}, (err: Error, results: any) => {