Skip to content

Commit

Permalink
Merge pull request #1703 from COVID19Tracking/feature/ltc-facilities-map
Browse files Browse the repository at this point in the history
feat: Add LTC facilities map
  • Loading branch information
kevee committed Feb 18, 2021
2 parents ad827ab + 7e8c47d commit 2cd15ed
Show file tree
Hide file tree
Showing 31 changed files with 2,778 additions and 1,533 deletions.
21 changes: 21 additions & 0 deletions src/components/common/map/infobox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React, { useContext } from 'react'
import MapContext from './map-context'
import infoboxStyle from './infobox.module.scss'

const Infobox = ({ children }) => {
const mapContext = useContext(MapContext)

return (
<div
className={infoboxStyle.infobox}
style={{
left: Math.max(10, mapContext.infoboxPosition.x - 175),
top: mapContext.infoboxPosition.y + 15,
}}
>
{children}
</div>
)
}

export default Infobox
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
@include padding(16);
@include type-size(100);
h3 {
@include type-size(100);
@include type-size(200);
font-weight: bold;
&:first-child {
margin-top: 0;
Expand Down
28 changes: 28 additions & 0 deletions src/components/common/map/layer-toggle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React, { useContext } from 'react'
import MapContext from './map-context'
import toggleStyle from './layer-toggle.module.scss'

const LayerToggle = ({ layers }) => {
const mapContext = useContext(MapContext)
return (
<div
className={toggleStyle.toggle}
role="group"
aria-label="Toggle map layers"
>
{layers.map(layer => (
<button
className={mapContext.mapLayer === layer.id && toggleStyle.active}
type="button"
onClick={() => {
mapContext.setMapLayer(layer.id)
}}
>
{layer.name}
</button>
))}
</div>
)
}

export default LayerToggle
30 changes: 30 additions & 0 deletions src/components/common/map/layer-toggle.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
.toggle {
cursor: pointer;
display: flex;
width: fit-content;
button {
@include remove-button-style();
color: $color-slate-600;
border: solid $color-slate-200 2px;
font-weight: initial;
&:before {
display: block;
content: attr(title);
font-weight: 700;
height: 0;
overflow: hidden;
visibility: hidden;
}
@include type-size(100);
margin: -1px; // ignore-style-rule
padding: 2px 15px; // ignore-style-rule
white-space: nowrap;

&.active {
color: black;
border: solid black 2px;
font-weight: 700;
z-index: 1;
}
}
}
5 changes: 5 additions & 0 deletions src/components/common/map/map-context.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { createContext } from 'react'

const MapContext = createContext()

export default MapContext
29 changes: 29 additions & 0 deletions src/components/common/map/overlay.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react'
/* eslint-disable jsx-a11y/no-noninteractive-element-interactions */
import overlayStyles from './overlay.module.scss'

const Overlay = ({ children, close }) => (
<>
<div
role="dialog"
className={overlayStyles.overlay}
onClick={() => close()}
onKeyDown={() => close()}
/>
<div className={overlayStyles.card} role="dialog">
<button
className={overlayStyles.close}
type="button"
onClick={event => {
event.preventDefault()
close()
}}
>
&times;
</button>
<div>{children}</div>
</div>
</>
)

export default Overlay
41 changes: 41 additions & 0 deletions src/components/common/map/overlay.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
.overlay {
width: 0;
position: absolute;
height: 100%;
top: 0;
bottom: 0;
right: 0;
z-index: 1000;
background: rgba(0, 0, 0, 0.4);
box-shadow: inset 3px 0px 6px -2px rgba(0, 0, 0, 0.8);
@media (min-width: $viewport-md) {
width: 10%;
}
}

.card {
position: absolute;
width: 100%;
height: 100%;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 1000;
overflow-y: scroll;
background: white;
border-left: 1px solid $color-slate-100;
@include padding(16);

@media (min-width: $viewport-md) {
width: 90%;
}
h2 {
margin-top: 0;
}
.close {
@include remove-button-style();
float: right;
@include type-size(600);
}
}
66 changes: 66 additions & 0 deletions src/components/common/map/sidebar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import React, { useState } from 'react'
import { Form, Input } from '~components/common/form'
import { Row, Col } from '~components/common/grid'
import sidebarStyle from './sidebar.module.scss'

const Sidebar = ({ children, map }) => {
const [query, setQuery] = useState(false)

return (
<div className={sidebarStyle.sidebar}>
<Form
onSubmit={event => {
event.preventDefault()
if (
typeof window === 'undefined' ||
typeof window.fetch === 'undefined'
) {
return
}
window
.fetch(
`https://api.mapbox.com/geocoding/v5/mapbox.places/${encodeURIComponent(
query,
)}.json?limit=1&access_token=${
process.env.GATSBY_MAPBOX_API_TOKEN
}`,
)
.then(response => response.json())
.then(response => {
if (response.features.length === 0) {
return
}
const feature = response.features.pop()
map.easeTo({
center: feature.center,
zoom: 7,
})
})
}}
noMargin
>
<Row>
<Col width={[4, 6, 8]}>
<Input
type="text"
label="Search facilities"
placeholder="Enter a city or zip code"
hideLabel
onChange={event => {
setQuery(event.target.value)
}}
/>
</Col>
<Col width={[4, 6, 4]} paddingLeft={[0, 0, 8]}>
<button type="submit" className={sidebarStyle.searchButton}>
Search
</button>
</Col>
</Row>
</Form>
{children}
</div>
)
}

export default Sidebar
40 changes: 40 additions & 0 deletions src/components/common/map/sidebar.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
.sidebar {
box-sizing: border-box;
flex: 0 0 auto;
width: 100%;
order: 1;
input[type='text'] {
margin-bottom: 0;
}
p {
@include margin(16, left);
}
table {
overflow-y: scroll;
&[aria-hidden] {
margin-bottom: 0;
}
th {
padding-top: 0;
}
button {
@include remove-button-style();
text-align: left;
text-decoration: underline;
cursor: pointer;
}
}
form {
background: $color-slate-100;
@include padding(16, top left right);
}
@media (min-width: $viewport-md) {
order: 0;
max-width: 25%;
flex-basis: 25%;
}
@media (min-width: $viewport-lg) {
max-width: 30%;
flex-basis: 30%;
}
}
17 changes: 17 additions & 0 deletions src/components/common/map/wrapper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react'
import classnames from 'classnames'
import wrapperStyle from './wrapper.module.scss'

const Wrapper = ({ children, fullWidth = false }) => (
<div
className={classnames(
wrapperStyle.wrapper,
fullWidth && wrapperStyle.fullWidth,
)}
role="img"
>
<div className={wrapperStyle.inset}>{children}</div>
</div>
)

export default Wrapper
33 changes: 33 additions & 0 deletions src/components/common/map/wrapper.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
.wrapper {
box-sizing: border-box;
flex: 0 0 auto;
width: 100%;
order: 0;
@media (min-width: $viewport-md) {
order: 1;
max-width: 75%;
flex-basis: 75%;
}
@media (min-width: $viewport-lg) {
max-width: 70%;
flex-basis: 70%;
}
&.full-width {
@media (min-width: $viewport-md) {
order: 1;
max-width: 100%;
flex-basis: 100%;
}
@media (min-width: $viewport-lg) {
max-width: 100%;
flex-basis: 100%;
}
}
}

.inset {
position: relative;
flex: 1 0 auto;
width: 100%;
height: 80vh;
}
Loading

0 comments on commit 2cd15ed

Please sign in to comment.