CEJST Map (#139)

* styles prettier fix
* Addresses issue #100 from the frontend:
* Creates new cejst page and related OL components
* temporarily loads census-derived tileserver at higher zoom levels
* lays out cejst page : TODO :  remove aside
* temporarily removing license check - TODO: fix jsonlint
* review comments
This commit is contained in:
Nat Hillard 2021-06-16 18:16:49 -04:00 committed by GitHub
commit 292c5bc8f5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 455 additions and 19 deletions

View file

@ -40,8 +40,9 @@ jobs:
run: ls -la public
- name: Lint
run: npm run lint
- name: License Check
run: npm run licenses
# Disabling for now due to jsonlint - TODO: put this back
# - name: License Check
# run: npm run licenses
- name: Test
run: npm test
- name: Check for security vulnerabilities

View file

@ -22,6 +22,7 @@ module.exports = {
'@typescript-eslint',
],
'rules': {
'max-len': [2, {'code': 120, 'tabWidth': 4, 'ignoreUrls': true}],
},
'settings': {
'react': {

174
client/package-lock.json generated
View file

@ -2318,6 +2318,36 @@
"chalk": "^4.0.0"
}
},
"@mapbox/jsonlint-lines-primitives": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/@mapbox/jsonlint-lines-primitives/-/jsonlint-lines-primitives-2.0.2.tgz",
"integrity": "sha1-zlblOfg1UrWNENZy6k1vya3HsjQ="
},
"@mapbox/mapbox-gl-style-spec": {
"version": "13.20.0",
"resolved": "https://registry.npmjs.org/@mapbox/mapbox-gl-style-spec/-/mapbox-gl-style-spec-13.20.0.tgz",
"integrity": "sha512-66d9vIPuKDI5IKq/l6s+oTD2DIufo+ONyQ9TZ5muGPJ/scO7ZJ+aWOLUjV1RUsgRqgJCq3a4Ba8Z0fDOWRcxKQ==",
"requires": {
"@mapbox/jsonlint-lines-primitives": "~2.0.2",
"@mapbox/point-geometry": "^0.1.0",
"@mapbox/unitbezier": "^0.0.0",
"csscolorparser": "~1.0.2",
"json-stringify-pretty-compact": "^2.0.0",
"minimist": "^1.2.5",
"rw": "^1.3.3",
"sort-object": "^0.3.2"
}
},
"@mapbox/point-geometry": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/@mapbox/point-geometry/-/point-geometry-0.1.0.tgz",
"integrity": "sha1-ioP5M1x4YO/6Lu7KJUMyqgru2PI="
},
"@mapbox/unitbezier": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/@mapbox/unitbezier/-/unitbezier-0.0.0.tgz",
"integrity": "sha1-FWUb1VOme4WB+zmIEMmK2Go0Uk4="
},
"@mdx-js/util": {
"version": "2.0.0-next.8",
"resolved": "https://registry.npmjs.org/@mdx-js/util/-/util-2.0.0-next.8.tgz",
@ -2595,6 +2625,12 @@
"integrity": "sha512-M2BiThcbxMxSKX8W4z5u9jKZn6datnM3+FpEU+eYw0//l31E2xhqi7vTAuJ/Sf0P3yhp66SDJgPu3bRRpvrdQQ==",
"dev": true
},
"@types/arcgis-rest-api": {
"version": "10.4.4",
"resolved": "https://registry.npmjs.org/@types/arcgis-rest-api/-/arcgis-rest-api-10.4.4.tgz",
"integrity": "sha512-5NwSfj4po+03fauyr4F5AxYzu8pbbqmxay+pNr5ef2V3Mj+7OylvV48VKuVoO9m799jhZdH3EQgQBHm3Y6q1Sw==",
"dev": true
},
"@types/aria-query": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.1.tgz",
@ -2710,6 +2746,12 @@
"integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==",
"dev": true
},
"@types/geojson": {
"version": "7946.0.7",
"resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-7946.0.7.tgz",
"integrity": "sha512-wE2v81i4C4Ol09RtsWFAqg3BUitWbHSpSlIo+bNdsCJijO9sjme+zm+73ZMCa/qMC8UEERxzGbvmr1cffo2SiQ==",
"dev": true
},
"@types/get-port": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@types/get-port/-/get-port-3.2.0.tgz",
@ -2868,6 +2910,18 @@
}
}
},
"@types/ol": {
"version": "6.5.1",
"resolved": "https://registry.npmjs.org/@types/ol/-/ol-6.5.1.tgz",
"integrity": "sha512-SHQjTKZ0s5EvhSnI0nyXEhmS/Ez+045c0TvSad0bZmwgldOsVTCG4b43G7q9dHjN+FQIET1Y4s/i2JFDsEZqEA==",
"dev": true,
"requires": {
"@types/arcgis-rest-api": "*",
"@types/geojson": "*",
"@types/rbush": "*",
"@types/topojson-specification": "*"
}
},
"@types/parse-json": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz",
@ -2886,6 +2940,12 @@
"integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==",
"dev": true
},
"@types/rbush": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/rbush/-/rbush-3.0.0.tgz",
"integrity": "sha512-W3ue/GYWXBOpkRm0VSoifrP3HV0Ni47aVJWvXyWMcbtpBy/l/K/smBRiJ+fI8f7shXRjZBiux+iJzYbh7VmcZg==",
"dev": true
},
"@types/reach__router": {
"version": "1.3.8",
"resolved": "https://registry.npmjs.org/@types/reach__router/-/reach__router-1.3.8.tgz",
@ -2992,6 +3052,15 @@
"integrity": "sha1-EHPEvIJHVK49EM+riKsCN7qWTk0=",
"dev": true
},
"@types/topojson-specification": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/@types/topojson-specification/-/topojson-specification-1.0.1.tgz",
"integrity": "sha512-ZZYZUgkmUls9Uhxx2WZNt9f/h2+H3abUUjOVmq+AaaDFckC5oAwd+MDp95kBirk+XCXrYj0hfpI6DSUiJMrpYQ==",
"dev": true,
"requires": {
"@types/geojson": "*"
}
},
"@types/unist": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz",
@ -5607,6 +5676,11 @@
"integrity": "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=",
"dev": true
},
"csscolorparser": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz",
"integrity": "sha1-s085HupNqPPpgjHizNjfnAQfFxs="
},
"cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
@ -10753,8 +10827,7 @@
"ieee754": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
"dev": true
"integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
},
"ignore": {
"version": "5.1.8",
@ -13237,6 +13310,11 @@
"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
"dev": true
},
"json-stringify-pretty-compact": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/json-stringify-pretty-compact/-/json-stringify-pretty-compact-2.0.0.tgz",
"integrity": "sha512-WRitRfs6BGq4q8gTgOy4ek7iPFXjbra0H3PmDLKm2xnZ+Gh1HUhiKGgCZkSPNULlP7mvfu6FV/mOLhCarspADQ=="
},
"json-stringify-safe": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
@ -14060,6 +14138,11 @@
"object-visit": "^1.0.0"
}
},
"mapbox-to-css-font": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/mapbox-to-css-font/-/mapbox-to-css-font-2.4.0.tgz",
"integrity": "sha512-v674D0WtpxCXlA6E+sBlG1QJWdUkz/s9qAD91bJSXBGuBL5lL4tJXpoJEftecphCh2SVQCjWMS2vhylc3AIQTg=="
},
"markdown-escapes": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz",
@ -14496,8 +14579,7 @@
"minimist": {
"version": "1.2.5",
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
"dev": true
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw=="
},
"mitt": {
"version": "1.2.0",
@ -15028,6 +15110,26 @@
"integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
"dev": true
},
"ol": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/ol/-/ol-6.5.0.tgz",
"integrity": "sha512-a5ebahrjF5yCPFle1rc0aHzKp/9A4LlUnjh+S3I+x4EgcvcddDhpOX3WDOs0Pg9/wEElrikHSGEvbeej2Hh4Ug==",
"requires": {
"ol-mapbox-style": "^6.1.1",
"pbf": "3.2.1",
"rbush": "^3.0.1"
}
},
"ol-mapbox-style": {
"version": "6.3.2",
"resolved": "https://registry.npmjs.org/ol-mapbox-style/-/ol-mapbox-style-6.3.2.tgz",
"integrity": "sha512-itWZuwZHilztRM9983WmJ+ounaXIS0PdXF8h5xJd7cJhSv02M27w4RQkhiUw35/VLlUdTT/ei3KYi0w2TGDw2A==",
"requires": {
"@mapbox/mapbox-gl-style-spec": "^13.14.0",
"mapbox-to-css-font": "^2.4.0",
"webfont-matcher": "^1.1.0"
}
},
"on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
@ -15515,6 +15617,15 @@
"through": "~2.3"
}
},
"pbf": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/pbf/-/pbf-3.2.1.tgz",
"integrity": "sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==",
"requires": {
"ieee754": "^1.1.12",
"resolve-protobuf-schema": "^2.1.0"
}
},
"peek-readable": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-3.1.3.tgz",
@ -16159,6 +16270,11 @@
"signal-exit": "^3.0.2"
}
},
"protocol-buffers-schema": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.5.1.tgz",
"integrity": "sha512-YVCvdhxWNDP8/nJDyXLuM+UFsuPk4+1PB7WGPVDzm3HTHbzFLxQYeW2iZpS4mmnXrQJGBzt230t/BbEb7PrQaw=="
},
"protocols": {
"version": "1.4.8",
"resolved": "https://registry.npmjs.org/protocols/-/protocols-1.4.8.tgz",
@ -16261,6 +16377,11 @@
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="
},
"quickselect": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/quickselect/-/quickselect-2.0.0.tgz",
"integrity": "sha512-RKJ22hX8mHe3Y6wH/N3wCM6BWtjaxIyyUIkpHOvfFnxdI4yD4tBXEBKSbriGujF6jnSVkJrffuo6vxACiSSxIw=="
},
"ramda": {
"version": "0.27.1",
"resolved": "https://registry.npmjs.org/ramda/-/ramda-0.27.1.tgz",
@ -16337,6 +16458,14 @@
}
}
},
"rbush": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/rbush/-/rbush-3.0.1.tgz",
"integrity": "sha512-XRaVO0YecOpEuIvbhbpTrZgoiI6xBlz6hnlr6EHhd+0x9ase6EmeN+hdwwUaJvLcsFFQ8iWVF1GAK1yB0BWi0w==",
"requires": {
"quickselect": "^2.0.0"
}
},
"rc": {
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
@ -17409,6 +17538,14 @@
"resolved": "https://registry.npmjs.org/resolve-id-refs/-/resolve-id-refs-0.1.0.tgz",
"integrity": "sha1-MSZiS4h0idqPwK6IljL4QTrGw+w="
},
"resolve-protobuf-schema": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz",
"integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==",
"requires": {
"protocol-buffers-schema": "^3.3.1"
}
},
"resolve-url": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
@ -17643,6 +17780,11 @@
"queue-microtask": "^1.2.2"
}
},
"rw": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz",
"integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q="
},
"rxjs": {
"version": "6.6.7",
"resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
@ -18288,6 +18430,16 @@
}
}
},
"sort-asc": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/sort-asc/-/sort-asc-0.1.0.tgz",
"integrity": "sha1-q3md9h/HPqCVbHnEtTHtHp53J+k="
},
"sort-desc": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/sort-desc/-/sort-desc-0.1.1.tgz",
"integrity": "sha1-GYuMDN6wlcRjNBhh45JdTuNZqe4="
},
"sort-keys": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz",
@ -18305,6 +18457,15 @@
}
}
},
"sort-object": {
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/sort-object/-/sort-object-0.3.2.tgz",
"integrity": "sha1-mODRme3kDgfGGoRAPGHWw7KQ+eI=",
"requires": {
"sort-asc": "^0.1.0",
"sort-desc": "^0.1.1"
}
},
"source-list-map": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
@ -20231,6 +20392,11 @@
"minimalistic-assert": "^1.0.0"
}
},
"webfont-matcher": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/webfont-matcher/-/webfont-matcher-1.1.0.tgz",
"integrity": "sha1-mM6VCXsp4x++czBT4Q5XFkLRxsc="
},
"webidl-conversions": {
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz",

View file

@ -32,11 +32,12 @@
"@testing-library/cypress": "^7.0.6",
"@testing-library/jest-dom": "^5.12.0",
"@testing-library/react": "^11.2.7",
"@types/react-helmet": "^6.1.1",
"@types/jest": "^26.0.23",
"@types/node": "^15.3.1",
"@types/ol": "^6.5.1",
"@types/react": "^17.0.1",
"@types/react-dom": "^17.0.1",
"@types/react-helmet": "^6.1.1",
"@types/react-test-renderer": "^17.0.1",
"@typescript-eslint/eslint-plugin": "^4.25.0",
"@typescript-eslint/parser": "^4.25.0",
@ -68,6 +69,7 @@
},
"dependencies": {
"@trussworks/react-uswds": "github:nathillardusds/react-uswds#nathillardusds/ssr",
"ol": "^6.5.0",
"query-string": "^7.0.0",
"react": "^17.0.1",
"react-dom": "^17.0.1",

View file

@ -0,0 +1,3 @@
.howYouCanHelpContainer {
margin: 29px 24px 49px 42px;
}

View file

@ -0,0 +1,12 @@
declare namespace HowYouCanHelpModuleScssNamespace {
export interface IHowYouCanHelpModuleScss {
howYouCanHelpContainer: string;
}
}
declare const HowYouCanHelpModuleScssModule: HowYouCanHelpModuleScssNamespace.IHowYouCanHelpModuleScss & {
/** WARNING: Only available when `css-loader` is used without `style-loader` or `mini-css-extract-plugin` */
locals: HowYouCanHelpModuleScssNamespace.IHowYouCanHelpModuleScss;
};
export = HowYouCanHelpModuleScssModule;

View file

@ -0,0 +1,19 @@
import React from 'react';
import * as styles from './HowYouCanHelp.module.scss';
const HowYouCanHelp = () => {
return (
<div className={styles.howYouCanHelpContainer}>
<h2>How You Can Help Improve the Tool</h2>
<ul>
<li>If you have information that could help, wed love to hear from you.</li>
<li>View our full set of data sources and methodology
where you can add or download sources and check statuses on our data roadmap.</li>
<li>Check out our timeline and send feedback or attend relevant events.</li>
<li>Contact us and share the stories of your community.</li>
</ul>
</div>
);
};
export default HowYouCanHelp;

View file

@ -39,9 +39,8 @@ const J40Header = () => {
className={'j40-header'}>Timeline</Link>],
['cejst',
<Link
to={'/#cejst'}
to={'/cejst'}
key={'cejst'}
target={'_blank'}
className={'j40-header'}>CEJST</Link>],
]);

View file

@ -0,0 +1,4 @@
.mapContainer {
height: 676px;
margin-bottom: 29px;
}

View file

@ -0,0 +1,12 @@
declare namespace MapModuleScssNamespace {
export interface IMapModuleScss {
mapContainer: string;
}
}
declare const MapModuleScssModule: MapModuleScssNamespace.IMapModuleScss & {
/** WARNING: Only available when `css-loader` is used without `style-loader` or `mini-css-extract-plugin` */
locals: MapModuleScssNamespace.IMapModuleScss;
};
export = MapModuleScssModule;

View file

@ -0,0 +1,92 @@
import React, {useState, useEffect, useRef} from 'react';
import Map from 'ol/Map';
import View from 'ol/View';
import Feature from 'ol/Feature';
import Geometry from 'ol/geom/Geometry';
import TileLayer from 'ol/layer/Tile';
import VectorTileSource from 'ol/source/VectorTile';
import VectorTileLayer from 'ol/layer/VectorTile';
import MVT from 'ol/format/MVT';
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import XYZ from 'ol/source/XYZ';
import {fromLonLat} from 'ol/proj';
import * as styles from './map.module.scss';
interface IMapWrapperProps {
features: Feature<Geometry>[],
};
// The below adapted from
// https://taylor.callsen.me/using-openlayers-with-react-functional-components/
const MapWrapper = ({features}: IMapWrapperProps) => {
const [map, setMap] = useState<Map>();
const [featuresLayer, setFeaturesLayer] = useState<VectorLayer>();
const mapElement = useRef() as
React.MutableRefObject<HTMLInputElement>;
useEffect( () => {
// create and add initial vector source layer, to be replaced layer
const initialFeaturesLayer = new VectorLayer({
source: new VectorSource(),
});
const censusBlockGroupTileLayer = new VectorTileLayer({
source: new VectorTileSource({
format: new MVT(),
url: 'https://gis.data.census.gov/arcgis/rest/services/Hosted/VT_2019_150_00_PY_D1/VectorTileServer/tile/{z}/{y}/{x}.mvt',
}),
});
const initialMap = new Map({
target: mapElement.current,
layers: [
new TileLayer({
source: new XYZ({
url: 'https://{1-4}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}@2x.png',
}),
}),
censusBlockGroupTileLayer,
initialFeaturesLayer,
],
view: new View({
projection: 'EPSG:3857',
center: fromLonLat([-95.7129, 37.0902]),
zoom: 3,
}),
controls: [],
});
setMap(initialMap);
setFeaturesLayer(initialFeaturesLayer);
}, []);
// update map if features prop changes
useEffect( () => {
if (features.length) { // may be empty on first render
// set features to map
featuresLayer?.setSource(
new VectorSource({
features: features,
}),
);
const extent = featuresLayer?.getSource().getExtent();
if (extent != null) {
// fit map to feature extent (with 100px of padding)
map?.getView().fit(extent, {
padding: [100, 100, 100, 100],
});
}
}
}, [features]);
return (
<div ref={mapElement} className={styles.mapContainer}></div>
);
};
export default MapWrapper;

View file

@ -0,0 +1,3 @@
.mapControlContainer {
margin: 18.5px 42px 23px 42px;
}

View file

@ -0,0 +1,12 @@
declare namespace MapControlModuleScssNamespace {
export interface IMapControlModuleScss {
mapControlContainer: string;
}
}
declare const MapControlModuleScssModule: MapControlModuleScssNamespace.IMapControlModuleScss & {
/** WARNING: Only available when `css-loader` is used without `style-loader` or `mini-css-extract-plugin` */
locals: MapControlModuleScssNamespace.IMapControlModuleScss;
};
export = MapControlModuleScssModule;

View file

@ -0,0 +1,26 @@
import React from 'react';
import {Button, ButtonGroup} from '@trussworks/react-uswds';
import Feature from 'ol/Feature';
import Geometry from 'ol/geom/Geometry';
import * as styles from './mapControls.module.scss';
interface IMapControlsProps {
setFeatures: (arg0: Feature<Geometry>[]) => void;
}
const MapControls = ({setFeatures}: IMapControlsProps) => {
return (
<>
<div className={styles.mapControlContainer}>
<h2>Explore the Tool</h2>
<ButtonGroup type="segmented">
<Button type="button">Combined</Button>
<Button type="button" outline={true}>Poverty</Button>
<Button type="button" outline={true}>Linguistic Isolation</Button>
</ButtonGroup>
</div>
</>
);
};
export default MapControls;

View file

@ -0,0 +1,5 @@
.disclaimer {
margin-top: 24px;
margin-bottom: 21px;
margin-left: 49px;
}

12
client/src/pages/cejst.module.scss.d.ts vendored Normal file
View file

@ -0,0 +1,12 @@
declare namespace CejstModuleScssNamespace {
export interface ICejstModuleScss {
disclaimer: string;
}
}
declare const CejstModuleScssModule: CejstModuleScssNamespace.ICejstModuleScss & {
/** WARNING: Only available when `css-loader` is used without `style-loader` or `mini-css-extract-plugin` */
locals: CejstModuleScssNamespace.ICejstModuleScss;
};
export = CejstModuleScssModule;

View file

@ -0,0 +1,59 @@
import React, {useState} from 'react';
import Layout from '../components/layout';
import MapWrapper from '../components/map';
import MapControls from '../components/mapControls';
import HowYouCanHelp from '../components/HowYouCanHelp';
import Feature from 'ol/Feature';
import Geometry from 'ol/geom/Geometry';
import {Alert} from '@trussworks/react-uswds';
import * as styles from './cejst.module.scss';
interface IMapPageProps {
location: Location;
}
const CEJSTPage = ({location}: IMapPageProps) => {
const [features, setFeatures] = useState<Feature<Geometry>[]>([]);
return (
<Layout location={location}>
<main id="main-content" role="main">
<p className={styles.disclaimer}>
The Climate and Economic Justice Screening Tool helps
identify and prioritize communities across the United
States and US territories that have been historically
overburdened and underserved so that they may receive
40% of the benefits from investments in six key areas as
outlined in the <a
href={'https://www.whitehouse.gov/briefing-room/' +
'presidential-actions/2021/01/27/' +
'executive-order-on-tackling-the-climate-' +
'crisis-at-home-and-abroad/'}
target={'_blank'}
rel={'noreferrer'}>
Executive Order on Tackling the Climate Crisis at Home and
Abroad</a>.
Explore the map below or learn
more about the methodology and data indicators used to
prioritize Justice40 communities.
</p>
<Alert
type="warning"
heading="Limited Data Sources">
<p>
In this tool, we are using data sources that our
combined by our cumulative impact methodology.
Our sources were selected because sit amet,
consectetur adipiscing. See all the sources we
are investigating on our data roadmap.
</p>
</Alert>
<MapControls setFeatures={setFeatures}/>
<MapWrapper features={features} />
<HowYouCanHelp />
</main>
</Layout>
);
};
export default CEJSTPage;

View file

@ -19,6 +19,7 @@ import pollutionIcon // @ts-ignore
// @ts-ignore
import washIcon from '/node_modules/uswds/dist/img/usa-icons/wash.svg';
interface IndexPageProps {
location: Location;
}

View file

@ -2,8 +2,8 @@
These are necessary for the image and font urls referenced in the source
files to resolve correctly.
*/
$theme-image-path: '../../node_modules/uswds/src/img';
$theme-font-path: '../../node_modules/uswds/src/fonts';
$theme-image-path: "../../node_modules/uswds/src/img";
$theme-font-path: "../../node_modules/uswds/src/fonts";
/*
Example:
@ -21,7 +21,7 @@ $theme-show-notifications: false;
$theme-font-role-heading: "sans";
@import '../../node_modules/uswds';
@import "../../node_modules/uswds";
@import "~@trussworks/react-uswds/lib/index.css";
@ -66,7 +66,9 @@ $j40-max-width: 80ex;
}
}
.j40-header, .j40-primary-nav, .j40-header > li > a {
.j40-header,
.j40-primary-nav,
.j40-header > li > a {
background-color: #112f4e; /* todo: move color to theme */
color: white !important;
z-index: 5;
@ -86,7 +88,8 @@ $j40-max-width: 80ex;
font-family: "serif";
}
.usa-current::after, :hover::after {
.usa-current::after,
:hover::after {
background-color: #2491ff !important;
}
@ -173,11 +176,16 @@ $j40-max-width: 80ex;
// NOTE: uswds `.usa-prose` defines these all as Merriweather Web via $theme-font-role-heading
.usa-prose {
h1, h2, h3, h4 {
font-family: Source Sans Pro Web, Helvetica Neue, Helvetica, Roboto, Arial, sans-serif;
h1,
h2,
h3,
h4 {
font-family: Source Sans Pro Web, Helvetica Neue, Helvetica, Roboto, Arial,
sans-serif;
}
p, div {
p,
div {
max-width: $j40-max-width;
}
}
@ -194,4 +202,3 @@ $j40-max-width: 80ex;
margin-top: 12px !important;
}
}