Skip to content

Commit

Permalink
resolve merged conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
joshuayhwu committed Aug 4, 2022
2 parents ff4eafb + 3df408a commit 965cad2
Show file tree
Hide file tree
Showing 21 changed files with 773 additions and 210 deletions.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# The 311 Data project
# [311 Data](https://www.311-data.org/)

Empowering Los Angeles neighborhood councils to analyze initiatives using data collected from the city 311 system.
Each day, Los Angelenos report thousands of 311 requests all across LA to resolve issues such as illegal dumping and graffiti in their neighborhoods. These requests are then received by relevant agencies, such as the Police, Building and Safety, or Department of Transportation. The agency responds to the request, addresses it, and then closes it once it is fixed. Thanks to Mayor Eric Garcetti's [Open Data Initiative](https://data.lacity.org/), the expansive amount of data associated with these 311 requests is available online.

To empower local residents and [Neighborhood Councils](https://empowerla.org/councils/) to make informed decisions about how to improve their communities using an easy-to-use application, [Hack For LA](https://www.hackforla.org/) partnered with [EmpowerLA](https://empowerla.org/) to create the [311 Data project](https://www.hackforla.org/projects/311-data). 311 Data makes navigating the wealth of 311 data easier using an open source application built and maintained by volunteers throughout our community. To that end, 311 Data primarily provides two types of visualization:
* An interactive map showing where different types of 311 requests are being submitted
* Dashboards that show what types of requests are being made, how quickly they're being resolved, how different councils compare, and more

![311 Screenshot](docs/images/screenshot.png)

Expand Down
2 changes: 2 additions & 0 deletions client/Routes.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Desktop from '@components/main/Desktop';
import Reports from '@components/main/Reports';
import Privacy from '@components/main/Privacy';
import Faqs from '@components/main/Faqs';
import About from '@components/main/About';
import Blog from '@components/main/Blog';
import ContactForm from '@components/main/ContactForm';

Expand All @@ -25,6 +26,7 @@ export default function Routes() {
<Route path="/reports" component={Reports} />
<Route path="/privacy" component={Privacy} />
<Route path="/faqs" component={Faqs} />
<Route path="/about" component={About} />
<Route path="/blog" component={Blog} />
<Route path="/contact" component={ContactForm} />
<Route path="/">
Expand Down
16 changes: 0 additions & 16 deletions client/components/DateSelector/DateSelector.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,21 @@ import DateRanges from './DateRanges';
const dateFormat = 'YYYY-MM-DD';

function DateSelector({
onRangeSelect,
range,
initialDates,
updateStartDate,
updateEndDate,
}) {
const [dates, setDates] = useState(initialDates);
const [expanded, setExpanded] = useState(false);
const classes = useStyles();

const handleOptionSelect = optionDates => {
const formattedStart = moment(optionDates[0]).format(dateFormat);
const formattedEnd = moment(optionDates[1]).format(dateFormat);
setDates(() => optionDates);
updateStartDate(formattedStart);
updateEndDate(formattedEnd);
setExpanded(false);
};

const handleDateSelect = selectedDays => {
setDates(() => selectedDays);
if (typeof onRangeSelect === 'function') onRangeSelect(selectedDays);
};

const closeOptionsOnDateToggle = useCallback(() => {
setExpanded(false);
}, []);
Expand All @@ -53,9 +44,7 @@ function DateSelector({
<div className={classes.selector}>
<DatePicker
range={range}
dates={dates}
onToggle={closeOptionsOnDateToggle}
onSelect={handleDateSelect}
/>
<div className={classes.separator} />
</div>
Expand All @@ -65,7 +54,6 @@ function DateSelector({
classes={{ option, selected }}
options={options}
onSelect={handleOptionSelect}
dates={dates}
/>
</SelectorBox.Collapse>
</SelectorBox>
Expand All @@ -82,14 +70,10 @@ export default connect(null, mapDispatchToProps)(DateSelector);

DateSelector.propTypes = {
range: PropTypes.bool,
onRangeSelect: PropTypes.func,
initialDates: PropTypes.arrayOf(Date),
updateStartDate: PropTypes.func.isRequired,
updateEndDate: PropTypes.func.isRequired,
};

DateSelector.defaultProps = {
range: false,
onRangeSelect: null,
initialDates: [],
};
3 changes: 3 additions & 0 deletions client/components/Header.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ const Header = () => {
<NavLink to="/faqs" className={classes.link} activeStyle={activeStyle}>
<Button className={classes.button}>FAQ</Button>
</NavLink>
<NavLink to="/about" className={classes.link} activeStyle={activeStyle}>
<Button className={classes.button}>About</Button>
</NavLink>
<NavLink to="/blog" className={classes.link} activeStyle={activeStyle}>
<Button className={classes.button}>Blog</Button>
</NavLink>
Expand Down
41 changes: 21 additions & 20 deletions client/components/Map/Map.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ class Map extends React.Component {
if (
this.state.filterGeo !== prevState.filterGeo ||
this.state.selectedTypes !== prevState.selectedTypes
) this.map.once('idle', this.setFilteredRequestCounts);
) this.map.once('idle', this.setFilteredRequestCounts);

if (this.props.ncBoundaries != prevProps.ncBoundaries) {
this.ncLayer.init({
Expand Down Expand Up @@ -235,14 +235,14 @@ class Map extends React.Component {
filterGeo: geo,
...(
center
? {
locationInfo: {
location: `${center.lat.toFixed(6)} N ${center.lng.toFixed(6)} E`,
radius: 1,
nc: ncInfoFromLngLat(center),
? {
locationInfo: {
location: `${center.lat.toFixed(6)} N ${center.lng.toFixed(6)} E`,
radius: 1,
nc: ncInfoFromLngLat(center),
}
}
}
: {}
: {}
)
}),
});
Expand Down Expand Up @@ -335,7 +335,7 @@ class Map extends React.Component {
const feature = features[i];

if (hoverables.includes(feature.layer.id) && !feature.state.selected) {
switch(feature.layer.id) {
switch (feature.layer.id) {
case 'nc-fills':
this.setState({ address: null });
updateNcId(feature.properties.council_id);
Expand Down Expand Up @@ -367,12 +367,12 @@ class Map extends React.Component {
updateNcId(result.id);
} else {
const address = result.place_name
.split(',')
.slice(0, -2)
.join(', ');
.split(',')
.slice(0, -2)
.join(', ');

getNc({ longitude: result.center[0], latitude: result.center[1] });

this.setState({
address: address,
});
Expand Down Expand Up @@ -409,7 +409,7 @@ class Map extends React.Component {
getDistrictCounts = (geoFilterType, filterGeo, selectedTypes) => {
const { ncCounts, ccCounts } = this.props;
const { counts, regionId } = (() => {
switch(geoFilterType) {
switch (geoFilterType) {
case GEO_FILTER_TYPES.nc: return {
counts: ncCounts,
regionId: filterGeo.properties.nc_id,
Expand Down Expand Up @@ -486,7 +486,6 @@ class Map extends React.Component {
} = this.props;

const {
requests,
geoFilterType,
locationInfo,
// filteredRequestCounts,
Expand All @@ -508,7 +507,6 @@ class Map extends React.Component {
<div className={classes.root} ref={el => this.mapContainer = el} >
<RequestsLayer
ref={el => this.requestsLayer = el}
requests={requests}
activeLayer={activeRequestsLayer}
selectedTypes={selectedTypes}
colorScheme={colorScheme}
Expand All @@ -534,7 +532,7 @@ class Map extends React.Component {
<div ref={el => this.requestDetail = el}>
<RequestDetail requestId={selectedRequestId} />
</div>
{ this.state.mapReady && requestTypes && (
{this.state.mapReady && requestTypes && (
<>
{/* <MapOverview
date={lastUpdated}
Expand All @@ -556,7 +554,7 @@ class Map extends React.Component {
{
(selectedNc || address) && <LocationDetail address={address} nc={selectedNc} />
}

</div>
{/* <MapLayers
selectedTypes={selectedTypes}
Expand Down Expand Up @@ -600,4 +598,7 @@ const mapDispatchToProps = dispatch => ({
updateNcId: id => dispatch(updateNcId(id)),
});

export default connect(mapStateToProps, mapDispatchToProps)(withStyles(styles)(Map));
// We need to specify forwardRef to allow refs on connected components.
// See https://github.com/reduxjs/react-redux/issues/1291#issuecomment-494185126
// for more info.
export default connect(mapStateToProps, mapDispatchToProps, null, { forwardRef: true })(withStyles(styles)(Map));
Loading

0 comments on commit 965cad2

Please sign in to comment.