Skip to content

Commit

Permalink
Merge pull request #339 from hackforla/client/router
Browse files Browse the repository at this point in the history
Client/router
  • Loading branch information
jmensch1 committed Dec 22, 2020
2 parents 1f13592 + cb8c333 commit 7cebca9
Show file tree
Hide file tree
Showing 27 changed files with 1,148 additions and 1,885 deletions.
2,358 changes: 832 additions & 1,526 deletions client/web/package-lock.json

Large diffs are not rendered by default.

8 changes: 2 additions & 6 deletions client/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"bulma-start": "0.0.4",
"bulma-switch": "^2.0.0",
"classnames": "^2.2.6",
"deck.gl": "^8.2.10",
"connected-react-router": "^6.8.0",
"js-cookie": "^2.2.1",
"mapbox-gl": "^1.3.1",
"mixpanel-browser": "^2.40.0",
Expand All @@ -35,18 +35,14 @@
"react-div-100vh": "^0.5.6",
"react-dom": "^16.13.1",
"react-hotjar": "^2.2.1",
"react-map-gl": "^5.2.8",
"react-moment": "^1.0.0",
"react-redux": "^7.2.1",
"react-responsive": "^8.1.0",
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.0",
"redux": "^4.0.5",
"redux-devtools-extension": "^2.13.8",
"redux-thunk": "^2.3.0",
"reselect": "^4.0.0",
"resizable-panels-react": "^2.0.8",
"rsuite": "^4.8.3"
"reselect": "^4.0.0"
},
"scripts": {
"start": "react-scripts start",
Expand Down
6 changes: 3 additions & 3 deletions client/web/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react'
import { Router } from 'react-router-dom'
import { ConnectedRouter } from 'connected-react-router'
import Header from './components/main/Header'
import Footer from './components/main/Footer'
import CookieConsentBanner from './components/main/CookieConsentBanner'
Expand All @@ -22,7 +22,7 @@ const useStyles = makeStyles({
const App = () => {
const classes = useStyles()
return (
<Router history={history}>
<ConnectedRouter history={history}>
<Div100vh className={classes.root}>
<Header />
<div className={classes.content}>
Expand All @@ -32,7 +32,7 @@ const App = () => {
<CookieConsentBanner />
</Div100vh>
<Modals />
</Router>
</ConnectedRouter>
)
}

Expand Down
2 changes: 1 addition & 1 deletion client/web/src/components/MapPage/Mobile/index.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useState, useEffect, useCallback } from 'react'
import { connect } from 'react-redux'
import * as select from 'store/selectors'
import { selectLocation } from 'store/actions'
import { selectLocation } from 'store/actions/router'
import LocationCard from '../shared/LocationCard'
import LocationDetail from '../shared/LocationDetail'
import CheckSteps from '../shared/LocationDetail/CheckSteps'
Expand Down
44 changes: 12 additions & 32 deletions client/web/src/components/MapPage/index.js
Original file line number Diff line number Diff line change
@@ -1,63 +1,43 @@
import React, { useEffect } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { useLocation } from 'react-router-dom'
import * as select from 'store/selectors'
import { saveQuery, getJurisdiction, clearJurisdiction } from 'store/actions'
import { getJurisdiction } from 'store/actions/data'
import useBreakpoints from 'hooks/useBreakpoints'
import Desktop from './Desktop'
import Mobile from './Mobile'

const MapPage = ({
jurisdictionId,
saveQuery,
getJurisdiction,
clearJurisdiction,
}) => {
const location = useLocation()
const MapPage = ({ selectedJurisdictionId, getJurisdiction }) => {
const { isMobile } = useBreakpoints()

// clear query/data when leaving map page
// clear jurisdiction when leaving map
useEffect(() => {
return () => {
saveQuery(null)
clearJurisdiction()
}
}, [saveQuery, clearJurisdiction])
return () => getJurisdiction(null)
}, [getJurisdiction])

// save query params whenever url changes
// get jurisdiction whenever selection changes
useEffect(() => {
saveQuery()
}, [saveQuery, location.search])

// load the jurisdiction whenever the id changes
useEffect(() => {
if (jurisdictionId) getJurisdiction(jurisdictionId)
else clearJurisdiction()
}, [getJurisdiction, clearJurisdiction, jurisdictionId])
getJurisdiction(selectedJurisdictionId)
}, [selectedJurisdictionId, getJurisdiction])

return isMobile ? <Mobile /> : <Desktop />
}

const mapStateToProps = (state) => ({
jurisdictionId: select.query(state).jurisdictionId,
selectedJurisdictionId: select.selectedJurisdictionId(state),
})

const mapDispatchToProps = (dispatch) => ({
saveQuery: (urlQueryString) => dispatch(saveQuery(urlQueryString)),
getJurisdiction: (jurisdictionId) =>
dispatch(getJurisdiction(jurisdictionId)),
clearJurisdiction: () => dispatch(clearJurisdiction()),
getJurisdiction: (jid) => dispatch(getJurisdiction(jid)),
})

export default connect(mapStateToProps, mapDispatchToProps)(MapPage)

MapPage.propTypes = {
jurisdictionId: PropTypes.number,
saveQuery: PropTypes.func.isRequired,
selectedJurisdictionId: PropTypes.number,
getJurisdiction: PropTypes.func.isRequired,
}

MapPage.defaultProps = {
jurisdictionId: null,
selectedJurisdictionId: null,
}
2 changes: 1 addition & 1 deletion client/web/src/components/MapPage/shared/BackButton.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { selectLocation } from 'store/actions'
import { selectLocation } from 'store/actions/router'
import KeyboardBackspaceIcon from '@material-ui/icons/KeyboardBackspace'
import Typography from '@material-ui/core/Typography'

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { connect } from 'react-redux'
import { useHistory } from 'react-router-dom'
import queryString from 'query-string'
import * as select from 'store/selectors'
import { getStatesWithJurisdictions } from 'store/actions'
import { getStatesWithJurisdictions } from 'store/actions/data'
import { makeStyles } from '@material-ui/core/styles'
import useBreakpoints from 'hooks/useBreakpoints'
import IconButton from '@material-ui/core/IconButton'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ const useStyles = makeStyles((theme) => ({

function addressString(location) {
return [
`${location.address1}, ${location.address2} ${location.city},`,
`${location.address1.trim()}, ${location.address2} ${location.city},`,
`${location.state} ${location.zip}`,
].join(' ')
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react'
import { connect } from 'react-redux'
import { withStyles } from '@material-ui/core/styles'
import IconButton from '@material-ui/core/IconButton'
import { openModal } from 'store/actions'
import { openModal } from 'store/actions/modals'
import Accordion from './Accordion'
import { ReactComponent as CheckCircleIcon } from 'assets/icons/check-circle.svg'
import { ReactComponent as ArrowForwardIcon } from 'assets/icons/arrow-forward.svg'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,21 @@ function addressString(location) {
].join(' ')
}

const DirectionsButton = ({ location, userLngLat, userAddress }) => {
const DirectionsButton = ({ location, userLocation, userAddress }) => {
const classes = useStyles()

const showDirections = useCallback(() => {
const query = queryString.stringify({
api: 1,
origin: (() => {
if (userAddress) return userAddress
if (userLngLat) return `${userLngLat.lat},${userLngLat.lng}`
if (userLocation) return `${userLocation.lat},${userLocation.lng}`
return undefined
})(),
destination: addressString(location),
})
window.open(`https://www.google.com/maps/dir/?${query}`)
}, [location, userLngLat, userAddress])
}, [location, userLocation, userAddress])

return (
<div className={classes.root} onClick={showDirections}>
Expand All @@ -61,12 +61,12 @@ export default DirectionsButton

DirectionsButton.propTypes = {
location: PropTypes.shape({}),
userLngLat: PropTypes.shape({}),
userLocation: PropTypes.shape({}),
userAddress: PropTypes.string,
}

DirectionsButton.defaultProps = {
location: null,
userLngLat: undefined,
userLocation: undefined,
userAddress: undefined,
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'
import { makeStyles } from '@material-ui/core/styles'
import { ReactComponent as ShareIcon } from 'assets/icons/share.svg'
import { openModal } from 'store/actions'
import { openModal } from 'store/actions/modals'
import { connect } from 'react-redux'

const useStyles = makeStyles((theme) => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ const VerifyBox = ({ location, jurisdiction }) => {
</div>
)}
{nonEmailUrls.map(({ url, name }) => (
<div className={classes.infoItem}>
<div key={url} className={classes.infoItem}>
<NewWindowIcon />
<a target="_blank" rel="noreferrer" href={url}>
{name}
Expand Down
12 changes: 6 additions & 6 deletions client/web/src/components/MapPage/shared/LocationDetail/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import DisplayNote from './DisplayNote'
const LocationDetail = ({
location,
jurisdiction,
userLngLat,
userLocation,
userAddress,
}) => {
if (!location) return null
Expand All @@ -31,7 +31,7 @@ const LocationDetail = ({
>
<ShareButton location={location} />
<DirectionsButton
userLngLat={userLngLat}
userLocation={userLocation}
userAddress={userAddress}
location={location}
/>
Expand All @@ -45,20 +45,20 @@ const LocationDetail = ({

const mapStateToProps = (state) => ({
jurisdiction: select.jurisdiction(state),
userLngLat: select.query(state).lngLat,
userAddress: select.query(state).address,
userLocation: select.userLocation(state),
userAddress: select.userAddress(state),
})

export default connect(mapStateToProps)(LocationDetail)

LocationDetail.propTypes = {
location: PropTypes.shape({}),
userLngLat: PropTypes.shape({}),
userLocation: PropTypes.shape({}),
userAddress: PropTypes.string,
}

LocationDetail.defaultProps = {
location: null,
userLngLat: undefined,
userLocation: undefined,
userAddress: undefined,
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { Fragment } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import * as select from 'store/selectors'
import { selectLocation } from 'store/actions'
import { selectLocation } from 'store/actions/router'
import LocationCard from '../LocationCard'
import Divider from '@material-ui/core/Divider'
import { makeStyles } from '@material-ui/core/styles'
Expand Down
40 changes: 20 additions & 20 deletions client/web/src/components/MapPage/shared/Map/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useState, useEffect, useCallback } from 'react'
import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import * as select from 'store/selectors'
import { selectLocation } from 'store/actions'
import { selectLocation } from 'store/actions/router'
import { lineString } from '@turf/helpers'
import bbox from '@turf/bbox'
import Map from './Map'
Expand Down Expand Up @@ -36,11 +36,6 @@ const CONTINENTAL_US = [
[-66.885444, 49.384358],
]

const GEORGIA = [
[-85.61, 30.36],
[-80.84, 35.0],
]

const DEFAULT_ZOOM = 13

const MapContainer = ({
Expand All @@ -49,14 +44,15 @@ const MapContainer = ({
userLocation,
selectedLocation,
selectLocation,
isLoading,
selectedJurisdictionId,
}) => {
const [position, setPosition] = useState(null)
const [map, setMap] = useState(null)
const delta = useDeltaObject({
jurisdiction,
userLocation,
selectedLocation,
selectedJurisdictionId,
})

const setMapPosition = useCallback(() => {
Expand All @@ -78,11 +74,6 @@ const MapContainer = ({

// jurisdiction select
if (!userLocation && !selectedLocation) {
if (!jurisdiction || !jurisdiction.geojson)
return setPosition({
bounds: GEORGIA,
})

if (jurisdiction.geojson)
return setPosition({
bounds: bbox(jurisdiction.geojson),
Expand Down Expand Up @@ -125,11 +116,20 @@ const MapContainer = ({
}, [jurisdiction, locations, userLocation, selectedLocation])

useEffect(() => {
// move map whenever jurisdiction exists and is changed
if (jurisdiction && delta.jurisdiction) return setMapPosition()

// also move the map when the userLocation exists and is changed, if:
// (1) there's no selectedJurisdictionId. This happens when the user moves
// to or between locations where we don't have jurisdictional coverage.
// (2) the selectedJurisdictionId hasn't changed. This happens when
// the user moves between locations in the same jurisdiction.
if (
delta.jurisdiction ||
(delta.userLocation && delta.userLocation.curr && !isLoading)
userLocation &&
delta.userLocation &&
(!selectedJurisdictionId || !delta.selectedJurisdictionId)
)
setMapPosition()
return setMapPosition()
})

useEffect(() => {
Expand Down Expand Up @@ -164,7 +164,7 @@ const mapStateToProps = (state) => ({
locations: select.sortedLocations(state),
userLocation: select.userLocation(state),
selectedLocation: select.selectedLocation(state),
isLoading: select.isLoading(state),
selectedJurisdictionId: select.selectedJurisdictionId(state),
})

const mapDispatchToProps = (dispatch) => ({
Expand All @@ -181,14 +181,14 @@ MapContainer.propTypes = {
lat: PropTypes.number,
}),
selectLocation: PropTypes.func.isRequired,
selectedLocationId: PropTypes.number,
isLoading: PropTypes.bool,
selectedLocation: PropTypes.shape({}),
selectedJurisdictionId: PropTypes.number,
}

MapContainer.defaultProps = {
jurisdiction: null,
locations: [],
userLocation: null,
selectedLocationId: null,
isLoading: false,
selectedLocation: null,
selectedJurisdictionId: null,
}
2 changes: 1 addition & 1 deletion client/web/src/components/main/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import logo from 'assets/logos/ballotnav.svg'
import Footer from 'components/main/Footer'
import IconButton from '@material-ui/core/IconButton'
import SearchIcon from '@material-ui/icons/Search'
import { openModal } from 'store/actions'
import { openModal } from 'store/actions/modals'
import * as select from 'store/selectors'
import { makeStyles } from '@material-ui/core/styles'
import Div100vh from 'react-div-100vh'
Expand Down
Loading

0 comments on commit 7cebca9

Please sign in to comment.