diff --git a/package.json b/package.json
index bc8226e15..1e6326f8f 100644
--- a/package.json
+++ b/package.json
@@ -41,10 +41,10 @@
"deploy": "gh-pages -d dist"
},
"devDependencies": {
- "@babel/core": "^7.7.2",
+ "@babel/core": "^7.8.4",
"@babel/plugin-proposal-class-properties": "^7.7.0",
- "@babel/preset-env": "^7.7.1",
- "@babel/preset-react": "^7.7.0",
+ "@babel/preset-env": "^7.8.4",
+ "@babel/preset-react": "^7.8.3",
"babel-eslint": "^10.0.3",
"babel-loader": "^8.0.6",
"css-loader": "^3.2.0",
diff --git a/src/components/common/Button.jsx b/src/components/common/Button.jsx
index 995c6a4ee..70adfe440 100644
--- a/src/components/common/Button.jsx
+++ b/src/components/common/Button.jsx
@@ -24,6 +24,8 @@ const Button = ({
isStatic,
disabled,
style,
+ icon,
+ iconStyle,
}) => {
// Dynamically generates button className from props to comply with Bulma styling modifiers.
const buttonClassName = classNames('button', {
@@ -53,7 +55,14 @@ const Button = ({
className={buttonClassName}
style={style}
>
- {label}
+ {icon && (
+
+
+
+ )}
+
+ {label}
+
);
};
@@ -78,6 +87,8 @@ Button.propTypes = {
isStatic: PropTypes.bool,
disabled: PropTypes.bool,
style: PropTypes.shape({}),
+ iconStyle: PropTypes.shape({}),
+ icon: PropTypes.string,
};
Button.defaultProps = {
@@ -97,4 +108,6 @@ Button.defaultProps = {
isStatic: false,
disabled: false,
style: undefined,
+ iconStyle: undefined,
+ icon: undefined,
};
diff --git a/src/components/common/Checkbox.jsx b/src/components/common/Checkbox.jsx
index 93df7b6e7..92785a8f0 100644
--- a/src/components/common/Checkbox.jsx
+++ b/src/components/common/Checkbox.jsx
@@ -73,6 +73,7 @@ Checkbox.propTypes = {
hasNoBorder: PropTypes.bool,
hasBackgroundColor: PropTypes.bool,
disabled: PropTypes.bool,
+ checked: PropTypes.bool,
};
Checkbox.defaultProps = {
@@ -90,4 +91,5 @@ Checkbox.defaultProps = {
hasNoBorder: false,
hasBackgroundColor: false,
disabled: false,
+ checked: false,
};
diff --git a/src/components/main/menu/Menu.jsx b/src/components/main/menu/Menu.jsx
index 923c5b0fc..196a5c8c0 100644
--- a/src/components/main/menu/Menu.jsx
+++ b/src/components/main/menu/Menu.jsx
@@ -1,6 +1,11 @@
+/* eslint-disable jsx-a11y/anchor-is-valid */
+/* eslint-disable jsx-a11y/no-static-element-interactions */
+/* eslint-disable jsx-a11y/click-events-have-key-events */
import React, { useState } from 'react';
import { slide as Sidebar } from 'react-burger-menu';
+
import Button from '../../common/Button';
+import NCSelector from './NCSelector';
// const buildDataUrl = () => {
// return `https://data.lacity.org/resource/${dataResources[year]}.json?$select=location,zipcode,address,requesttype,status,ncname,streetname,housenumber&$where=date_extract_m(CreatedDate)+between+${startMonth}+and+${endMonth}+and+requesttype='${request}'`;
@@ -24,11 +29,10 @@ const Menu = () => {
return (
{
styles={{
bmMenu: {
background: 'white',
- boxShadow: '0 4px 5px grey',
+ boxShadow: '0px 4px 5px rgba(108, 108, 108, 0.3)',
},
}}
>
-
diff --git a/src/components/main/menu/NCSelector.jsx b/src/components/main/menu/NCSelector.jsx
new file mode 100644
index 000000000..37639235d
--- /dev/null
+++ b/src/components/main/menu/NCSelector.jsx
@@ -0,0 +1,170 @@
+import React, { useState } from 'react';
+import { connect } from 'react-redux';
+import propTypes from 'proptypes';
+
+import { updateNC } from '../../../redux/reducers/data';
+
+import { COUNCILS } from '../../common/CONSTANTS';
+import Checkbox from '../../common/Checkbox';
+
+const NCSelector = ({
+ updateNCList,
+}) => {
+ const [searchValue, setSearchValue] = useState('');
+ const [filteredCouncilList, setFilteredCouncilList] = useState(COUNCILS);
+ const [selectedCouncilList, setSelectedCouncilList] = useState(
+ COUNCILS.reduce((acc, council) => {
+ acc[council] = false;
+ return acc;
+ }, { all: false }),
+ );
+
+ const selectRowStyle = {
+ margin: '0 0 7px 0',
+ };
+
+ const selectRowTextStyle = {
+ width: '280px',
+ };
+
+ const handleSearch = (e) => {
+ const term = e.target.value;
+ const searchFilter = new RegExp(term, 'i');
+ const searchList = COUNCILS.filter((council) => searchFilter.test(council));
+ setFilteredCouncilList(searchList);
+ setSearchValue(e.target.value);
+ };
+
+ const handleSelectCouncil = (council) => {
+ const newSelectedCouncilList = { ...selectedCouncilList };
+
+ switch (council) {
+ case 'all': {
+ let value = true;
+
+ if (newSelectedCouncilList.all) {
+ newSelectedCouncilList.all = false;
+ value = false;
+ }
+
+ Object.keys(newSelectedCouncilList).forEach((c) => {
+ newSelectedCouncilList[c] = value;
+ });
+ break;
+ }
+ default:
+ newSelectedCouncilList.all = false;
+ newSelectedCouncilList[council] = !newSelectedCouncilList[council];
+ break;
+ }
+
+ const newNCList = Object.keys(newSelectedCouncilList).filter((c) => newSelectedCouncilList[c] && c !== 'all');
+
+ setSelectedCouncilList(newSelectedCouncilList);
+ updateNCList(newNCList);
+ };
+
+ return (
+
+
+
+
+ Neighborhood Council (NC) Selection
+
+
+
+
+
+
+
+
+
+
+
+
+ handleSelectCouncil('all')}
+ checked={selectedCouncilList?.all ?? false}
+ />
+
+
+
+
+ {filteredCouncilList.map((council) => (
+
+
+
+
+ handleSelectCouncil(council)}
+ checked={selectedCouncilList?.[council] ?? false}
+ />
+
+
+
+ ))}
+
+
+
+ );
+};
+
+const mapDispatchToProps = (dispatch) => ({
+ updateNCList: (council) => dispatch(updateNC(council)),
+});
+
+NCSelector.propTypes = {
+ updateNCList: propTypes.func,
+};
+
+NCSelector.defaultProps = {
+ updateNCList: () => null,
+};
+
+export default connect(null, mapDispatchToProps)(NCSelector);
diff --git a/src/redux/reducers/data.js b/src/redux/reducers/data.js
index 6d9ec179f..693d2975e 100644
--- a/src/redux/reducers/data.js
+++ b/src/redux/reducers/data.js
@@ -22,7 +22,7 @@ export const updateRequestType = (requestType) => ({
payload: requestType,
});
-export const updateNeighborhoodCouncil = (council) => ({
+export const updateNC = (council) => ({
type: types.UPDATE_NEIGHBORHOOD_COUNCIL,
payload: council,
});
@@ -31,7 +31,7 @@ const initialState = {
startDate: null,
endDate: null,
requestType: 'Bulky Items',
- council: null,
+ councils: [],
};
export default (state = initialState, action) => {
@@ -56,7 +56,7 @@ export default (state = initialState, action) => {
case types.UPDATE_NEIGHBORHOOD_COUNCIL:
return {
...state,
- council: action.payload,
+ councils: action.payload,
};
default:
return state;