Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

132 Add pop up message to CPE about outdated data #131

Merged
merged 2 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 49 additions & 7 deletions app/capitalprojects/LandingPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,36 +4,74 @@ import { connect } from 'react-redux';
import { Link } from 'react-router';

import Footer from '../common/Footer';
import AdvisoryModal from '../common/AdvisoryModal';

import * as capitalProjectsActions from '../actions/capitalProjects';

import './LandingPage.scss';

class LandingPage extends React.Component {
constructor(props) {
super(props);
this.state = {
showModal: true,
};
}

componentWillMount() {
this.props.resetFilter();
document.addEventListener('keydown', this.handleEscKey);
}

componentWillUnmount() {
document.removeEventListener('keydown', this.handleEscKey);
}

handleClose = () => {
this.setState({ showModal: false });
};

handleEscKey = (event) => {
if (event.key === 'Escape') {
this.handleClose();
TangoYankee marked this conversation as resolved.
Show resolved Hide resolved
}
};

render() {
const { showModal } = this.state;

return (
<div className="capitalprojects-landing">
{showModal && <AdvisoryModal handleClose={this.handleClose} />}
<section className="header-area" id="about">
<div className="container">
<div className="row">
<div className="col-lg-10 col-lg-offset-1 text-center" style={{ background: '#777', padding: '40px' }}>
<div
className="col-lg-10 col-lg-offset-1 text-center"
style={{ background: '#777', padding: '40px' }}
>
<h1 className="section-heading">NYC Capital Projects</h1>
<p className="subtitle">A new way to explore NYC&apos;s Capital Commitment Plan and Capital Spending</p>
<p className="learn-more"><Link to="/about/capitalprojects">Learn More</Link></p>
<p className="subtitle">
A new way to explore NYC&apos;s Capital Commitment Plan and
Capital Spending
</p>
<p className="learn-more">
<Link to="/about/capitalprojects">Learn More</Link>
</p>
<div className="splash-button-section">
<div className="box all-link">
<Link
to="/capitalprojects/table"
className="btn btn-default"
>
<div className="vertical-align">Search the <br /> Capital Commitment Plan</div>
<div className="vertical-align">
Search the <br /> Capital Commitment Plan
</div>
</Link>
<div className="blurb">
Raw data for all capital projects within the most recent Capital Commitment Plan published by the Mayor’s Office of Management and Budget.
Raw data for all capital projects within the most recent
Capital Commitment Plan published by the Mayor&apos;s
Office of Management and Budget.
</div>
</div>

Expand All @@ -46,10 +84,14 @@ class LandingPage extends React.Component {
to="/capitalprojects/explorer"
className="btn btn-default"
>
<div className="vertical-align">Explore <br /> Capital Projects on a Map</div>
<div className="vertical-align">
Explore <br /> Capital Projects on a Map
</div>
</Link>
<div className="blurb">
Capital projects within the Capital Commitment Plan that NYC Planning has worked with agencies to map - a subset of total planned spending.
Capital projects within the Capital Commitment Plan that
NYC Planning has worked with agencies to map - a subset of
total planned spending.
</div>
</div>
</div>
Expand Down
47 changes: 47 additions & 0 deletions app/common/AdvisoryModal.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Modal } from 'react-bootstrap';

const AdvisoryModal = ({ handleClose }) => (
<Modal
show
onHide={handleClose}
style={{ top: '5em' }}
>
<Modal.Header
className="advisory-modal-header"
style={{ paddingTop: '45px' }}
/>

<Modal.Body>
<div style={{ margin: '0 3em', fontSize: '18px' }}>
The Capital Projects section of the Capital Planning Explorer is no
longer being updated with the latest data (the most recent data
available in this application are from April 2023). To download the
latest Capital Projects data, please refer to&nbsp;
<a href="https://data.cityofnewyork.us/City-Government/Capital-Projects-Database-CPDB-Projects/fi59-268w/about_data">
NYC Open Data
</a>
&nbsp;or&nbsp;
<a href="https://www.nyc.gov/site/planning/data-maps/open-data.page">
Bytes of the Big Apple
</a>
. Other sections of the Capital Planning Explorer are still being
actively updated, and we encourage you to stay tuned for future
enhancements to this platform.
</div>
</Modal.Body>

<Modal.Footer className="advisory-modal-footer">
<div className="btn dcp-orange" onClick={handleClose}>
Close
</div>
</Modal.Footer>
</Modal>
);

AdvisoryModal.propTypes = {
handleClose: PropTypes.func.isRequired,
};

export default AdvisoryModal;
2 changes: 1 addition & 1 deletion app/common/GlobalModal.scss
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
color: #d96b27;
}

.modal-body h5, {
.modal-body h5 {
font-family: 'Oswald';
font-size: 17px;
}
Expand Down
107 changes: 81 additions & 26 deletions app/explorer/Explorer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ import {

import appConfig from '../config/appConfig';

import AdvisoryModal from "../common/AdvisoryModal";

const { mapbox_accessToken, searchConfig } = appConfig;

const mapboxGLOptions = {
Expand All @@ -52,30 +54,46 @@ class Explorer extends React.Component {
inKilometers: 0,
centerPointCoordinates: [],
},
showModal: true,
};
this.selectedFeaturesCache = [];
this.mapClicked = false;
}

componentWillMount() {
document.addEventListener('keydown', this.handleEscKey);
}

componentWillReceiveProps(nextProps) {
if (!this.mapClicked && (this.props.map.centerOnGeometry !== nextProps.map.centerOnGeometry)) {
if (
!this.mapClicked &&
this.props.map.centerOnGeometry !== nextProps.map.centerOnGeometry
) {
this.centerFromGeometry(nextProps.map.centerOnGeometry);
this.setState({
selectedPointType: 'point',
selectedPointCoordinates: this.centroidFromGeometry(nextProps.map.centerOnGeometry),
highlightPointCoordinates: this.centroidFromGeometry(nextProps.map.centerOnGeometry),
selectedPointCoordinates: this.centroidFromGeometry(
nextProps.map.centerOnGeometry,
),
highlightPointCoordinates: this.centroidFromGeometry(
nextProps.map.centerOnGeometry,
),
});
}
}

componentWillUnmount() {
document.removeEventListener('keydown', this.handleEscKey);
}

onLayerToggle = (layerId, wasEnabled) => {
ReactGA4.gtag('event', 'toggle-layer', {
'action': `toggle-layer-${layerId}`,
'layer_view_value': !wasEnabled,
});
FS.event('capitalPlanningExplorerLayerToggle', {
layer_id: layerId,
layer_enabled: !wasEnabled
layer_enabled: !wasEnabled,
});

const janeLayerIdsMap = {
Expand All @@ -96,7 +114,7 @@ class Explorer extends React.Component {
}
});
}
}
};

// Nasty debounces cause I suck at async
setSelectedFeatures = _.debounce(() => {
Expand All @@ -114,7 +132,10 @@ class Explorer extends React.Component {
});
}

if (payload.action === 'clear' && this.state.selectedPointType === 'address') {
if (
payload.action === 'clear' &&
this.state.selectedPointType === 'address'
) {
this.setState({
selectedPointType: '',
selectedPointCoordinates: [],
Expand Down Expand Up @@ -152,7 +173,10 @@ class Explorer extends React.Component {
});
}

if (features[0].geometry.type === 'Polygon' || features[0].geometry.type === 'MultiPolygon') {
if (
features[0].geometry.type === 'Polygon' ||
features[0].geometry.type === 'MultiPolygon'
) {
this.setState({
selectedPointType: 'point',
selectedPointCoordinates: [event.lngLat.lng, event.lngLat.lat],
Expand All @@ -175,7 +199,7 @@ class Explorer extends React.Component {
centerPointCoordinates: this.state.selectedPointCoordinates,
},
});
}
};

clearSelectedFeatures = () => {
this.props.resetSelectedFeatures();
Expand All @@ -192,9 +216,10 @@ class Explorer extends React.Component {

this.props.resetSelectedFeatures();
this.props.router.push('/map');
}
};

layerIdsInSelectedFeatures = () => _.uniq(this.props.selectedFeatures.map(f => f.layer.id));
layerIdsInSelectedFeatures = () =>
_.uniq(this.props.selectedFeatures.map(f => f.layer.id));

featureRoute = (feature) => {
switch (feature.layer.source) {
Expand All @@ -213,7 +238,7 @@ class Explorer extends React.Component {
default:
return null;
}
}
};

centerMap = _.debounce((lnglat) => {
this.Jane.GLMap.map.easeTo({
Expand All @@ -223,16 +248,32 @@ class Explorer extends React.Component {
});
}, 50);

handleClose = () => {
this.setState({ showModal: false });
};

handleEscKey = (event) => {
if (event.key === "Escape") {
this.handleClose();
}
};

render() {
const setStartingLayer = () => {
if (this.props.children) {
switch (this.props.children.props.route.type) {
case 'capitalproject': return 'capitalprojects';
case 'facility': return 'facilities';
case 'pops': return 'pops';
case 'development': return 'housing';
case 'sca': return 'sca';
case 'budgetrequest': return 'budgetrequests';
case 'capitalproject':
return 'capitalprojects';
case 'facility':
return 'facilities';
case 'pops':
return 'pops';
case 'development':
return 'housing';
case 'sca':
return 'sca';
case 'budgetrequest':
return 'budgetrequests';
default:
return this.props.params.layer || 'capitalprojects';
}
Expand All @@ -244,16 +285,22 @@ class Explorer extends React.Component {
const startingLayer = setStartingLayer();

const popsLocationState = {
filterDimensions: getDefaultFilterDimensions({ selected: {
'Parks, Gardens, and Historical Sites': {
'Parks and Plazas': {
'Privately Owned Public Space': null },
filterDimensions: getDefaultFilterDimensions({
selected: {
'Parks, Gardens, and Historical Sites': {
'Parks and Plazas': {
'Privately Owned Public Space': null,
},
},
},
} }),
}),
};

const { showModal } = this.state;

return (
<div className="full-screen cp-explorer">
<div className='full-screen cp-explorer'>
{showModal && <AdvisoryModal handleClose={this.handleClose} />}
<Jane
mapboxGLOptions={mapboxGLOptions}
search
Expand All @@ -265,7 +312,9 @@ class Explorer extends React.Component {
selectedFeatures={selectedFeatures}
setBottomOffset={this.setBottomOffset}
onLayerToggle={this.onLayerToggle}
ref={(jane) => { this.Jane = jane; }}
ref={(jane) => {
this.Jane = jane;
}}
>
<HighlightJaneLayer
coordinates={this.state.highlightPointCoordinates}
Expand All @@ -288,8 +337,14 @@ class Explorer extends React.Component {
handleRadiusFilter={this.handleRadiusFilter}
sql={this.props.facilitiesSql}
enabled={startingLayer === 'facilities' || startingLayer === 'pops'}
selected={startingLayer === 'facilities' || startingLayer === 'pops'}
locationState={startingLayer === 'pops' ? popsLocationState : this.props.location.state}
selected={
startingLayer === 'facilities' || startingLayer === 'pops'
}
locationState={
startingLayer === 'pops'
? popsLocationState
: this.props.location.state
}
/>

<HousingDevelopmentJaneLayer
Expand Down
Loading