diff --git a/client/App.jsx b/client/App.jsx
index 21a96c6d0..38508f821 100644
--- a/client/App.jsx
+++ b/client/App.jsx
@@ -7,20 +7,49 @@ import { getMetadataRequest } from '@reducers/metadata';
import Header from '@components/Header';
import Footer from '@components/Footer';
import MapContainer from '@components/Map';
+import PersistentDrawerLeft from '@components/LeftDrawer';
+import GearButton from '@components/GearButton';
+import { toggleMenu as reduxToggleMenu } from '@reducers/ui';
+import { useSwipeable } from 'react-swipeable';
import theme from './theme/theme';
+const menuStyles = {
+ swipeAreaOpen: {
+ float: 'left',
+ position: 'fixed',
+ width: '30%',
+ height: '100%',
+ },
+ gear: {
+ marginLeft: '85vw',
+ marginTop: '70vh',
+ },
+};
+
const App = ({
getMetadata,
+ toggleMenu,
}) => {
useEffect(() => {
getMetadata();
});
+ const handleSwipeMenu = useSwipeable({
+ trackMouse: true,
+ onSwipedRight: () => toggleMenu(),
+ onSwipedLeft: () => toggleMenu(),
+ });
+
return (
+
+ {/* area where you can swipe the menu sidebar */}
+ {/* eslint-disable-next-line react/jsx-props-no-spreading */}
+
+
);
@@ -28,10 +57,12 @@ const App = ({
const mapDispatchToProps = dispatch => ({
getMetadata: () => dispatch(getMetadataRequest()),
+ toggleMenu: () => dispatch(reduxToggleMenu()),
});
export default connect(null, mapDispatchToProps)(App);
App.propTypes = {
getMetadata: PropTypes.func.isRequired,
+ toggleMenu: PropTypes.func.isRequired,
};
diff --git a/client/components/GearButton/index.jsx b/client/components/GearButton/index.jsx
index 4d1df34ba..405769148 100644
--- a/client/components/GearButton/index.jsx
+++ b/client/components/GearButton/index.jsx
@@ -18,10 +18,10 @@ const useStyles = makeStyles({
},
});
-const GearButton = ({ onClick }) => {
+const GearButton = props => {
const { gearIcon, button } = useStyles();
const [pressed, setPressed] = useState(false);
-
+ const { onClick, style } = props;
const onKeyDown = e => {
e.preventDefault();
if (e.key === ' '
@@ -44,6 +44,7 @@ const GearButton = ({ onClick }) => {
role="button"
aria-pressed={pressed}
aria-label="Toggle Sidebar"
+ style={style}
>
@@ -52,9 +53,11 @@ const GearButton = ({ onClick }) => {
GearButton.propTypes = {
onClick: PropTypes.func,
+ style: PropTypes.obj,
};
GearButton.defaultProps = {
onClick: undefined,
+ style: undefined,
};
export default GearButton;
diff --git a/client/components/LeftDrawer/index.jsx b/client/components/LeftDrawer/index.jsx
new file mode 100644
index 000000000..754e3c8a8
--- /dev/null
+++ b/client/components/LeftDrawer/index.jsx
@@ -0,0 +1,252 @@
+import React from 'react';
+import PropTypes from 'proptypes';
+import { makeStyles, useTheme } from '@material-ui/core/styles';
+import Drawer from '@material-ui/core/Drawer';
+import CssBaseline from '@material-ui/core/CssBaseline';
+import List from '@material-ui/core/List';
+import Divider from '@material-ui/core/Divider';
+import IconButton from '@material-ui/core/IconButton';
+import ChevronLeftIcon from '@material-ui/icons/ChevronLeft';
+import ChevronRightIcon from '@material-ui/icons/ChevronRight';
+import ListItem from '@material-ui/core/ListItem';
+import ListItemIcon from '@material-ui/core/ListItemIcon';
+import ListItemText from '@material-ui/core/ListItemText';
+import LinkIcon from '@material-ui/icons/Link';
+import { connect } from 'react-redux';
+import { toggleMenu as reduxToggleMenu } from '@reducers/ui';
+import Radio from '@material-ui/core/Radio';
+
+const drawerWidth = 275;
+
+const useStyles = makeStyles(theme => ({
+ root: {
+ display: 'flex',
+ },
+ menuButton: {
+ marginRight: theme.spacing(2),
+ },
+ hide: {
+ display: 'none',
+ },
+ drawer: {
+ width: drawerWidth,
+ flexShrink: 0,
+ },
+ drawerPaper: {
+ width: drawerWidth,
+ backgroundColor: '#2A404E',
+ },
+ content: {
+ flexGrow: 1,
+ padding: theme.spacing(3),
+ transition: theme.transitions.create('margin', {
+ easing: theme.transitions.easing.sharp,
+ duration: theme.transitions.duration.leavingScreen,
+ }),
+ marginLeft: -drawerWidth,
+ },
+ share: {
+ marginBottom: '100px',
+ paddingLeft: '25px',
+ },
+ listItem: {
+ paddingTop: '15px',
+ paddingBottom: '15px',
+ height: '24px',
+ },
+ listItemTitle: {
+ paddingLeft: '28px',
+ },
+}));
+
+const PersistentDrawerLeft = ({ menuIsOpen, toggleMenu }) => {
+ // TODO ADD FUNCTIONALITY
+ const [selectedMapStyleValue, setMapStyleValue] = React.useState('Point Map');
+ const [selectedMapModeValue, setMapModeValue] = React.useState('Dark');
+ const [selectedDataColorScheme, setDataColorScheme] = React.useState('Original');
+ const [selectedBoundariesValue, setBoundariesValue] = React.useState('None');
+
+ const handleChangeMapStyle = event => {
+ setMapStyleValue(event.target.value);
+ };
+
+ const handleChangeMapMode = event => {
+ setMapModeValue(event.target.value);
+ };
+
+ const handleChangeDataColorScheme = event => {
+ setDataColorScheme(event.target.value);
+ };
+
+ const handleChangeBoundaries = event => {
+ setBoundariesValue(event.target.value);
+ };
+
+ const classes = useStyles();
+ const theme = useTheme();
+
+ const onClickShare = () => {
+ // TODO ADD FUNCTIONALITY
+ };
+
+ const escFunction = e => {
+ e.preventDefault();
+ if (e.key === 'Escape'
+ ) {
+ toggleMenu();
+ }
+ };
+
+ React.useEffect(() => {
+ document.addEventListener('keypress', escFunction, false);
+ return () => {
+ document.removeEventListener('keypress', escFunction, false);
+ };
+ }, [escFunction]);
+
+ return (
+
+
+
+
+
+ {theme.direction === 'ltr' ? : }
+
+
+
+
+
+
+
+ {['Point Map', 'Heat Map'].map(text => (
+
+
+
+
+
+
+ ))}
+
+
+ {
+ /**
+ * TODO ADD DYNAMIC LIST OF ITEMS
+ * ADD COLOR TO RADIO BUTTONS
+ */
+ }
+
+
+
+
+ {['Dark', 'Light', 'Street'].map(text => (
+
+
+
+
+
+
+ ))}
+
+
+
+
+
+
+ {['Original', 'Prism', 'Bold'].map(text => (
+
+
+
+
+
+
+ ))}
+
+
+
+
+
+
+ {['None', 'Neighborhood Councils', 'City Councils'].map(text => (
+
+
+
+
+
+
+ ))}
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+};
+
+PersistentDrawerLeft.propTypes = {
+ menuIsOpen: PropTypes.bool.isRequired,
+ toggleMenu: PropTypes.func.isRequired,
+};
+
+const mapStateToProps = state => ({
+ menuIsOpen: state.ui.menu.isOpen,
+});
+
+const mapDispatchToProps = dispatch => ({
+ toggleMenu: () => dispatch(reduxToggleMenu()),
+});
+
+export default connect(mapStateToProps, mapDispatchToProps)(PersistentDrawerLeft);
diff --git a/client/package-lock.json b/client/package-lock.json
index 59126dd0b..a61370db9 100644
--- a/client/package-lock.json
+++ b/client/package-lock.json
@@ -12309,6 +12309,11 @@
}
}
},
+ "react-swipeable": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/react-swipeable/-/react-swipeable-6.0.1.tgz",
+ "integrity": "sha512-69nonicgjT4ofeHxZSpjuz37BoIiWMEbUYkX0mdTCY2mX1U53XDzDUIOVKRg6vVBNGL+pxYjbRzmylXWORh1xQ=="
+ },
"react-test-renderer": {
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-16.13.1.tgz",
diff --git a/client/package.json b/client/package.json
index b06ddcf23..795986fe2 100644
--- a/client/package.json
+++ b/client/package.json
@@ -35,6 +35,7 @@
"react-redux": "^7.1.3",
"react-router": "^5.1.2",
"react-router-dom": "^5.1.2",
+ "react-swipeable": "^6.0.1",
"react-test-renderer": "^16.12.0",
"react-vis": "^1.11.7",
"redux": "^4.0.4",
diff --git a/client/redux/reducers/ui.js b/client/redux/reducers/ui.js
index 52392400d..30408666b 100644
--- a/client/redux/reducers/ui.js
+++ b/client/redux/reducers/ui.js
@@ -57,7 +57,7 @@ export const setMapMode = mode => ({
const initialState = {
menu: {
- isOpen: true,
+ isOpen: false,
// activeTab: MENU_TABS.MAP,
},
map: {