diff --git a/client/App.jsx b/client/App.jsx
index 38508f821..ae4dd400d 100644
--- a/client/App.jsx
+++ b/client/App.jsx
@@ -1,29 +1,22 @@
import React, { useEffect } from 'react';
import PropTypes from 'proptypes';
+import { BrowserRouter } from 'react-router-dom';
import { connect } from 'react-redux';
-import { ThemeProvider } from '@material-ui/core/styles';
-import { CssBaseline } from '@material-ui/core';
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';
+
+import Header from '@components/Header';
+import Footer from '@components/Footer';
+import Routes from './Routes';
const menuStyles = {
swipeAreaOpen: {
float: 'left',
position: 'fixed',
- width: '30%',
+ width: 150,
height: '100%',
},
- gear: {
- marginLeft: '85vw',
- marginTop: '70vh',
- },
};
const App = ({
@@ -41,17 +34,14 @@ const App = ({
});
return (
-
-
+
-
-
+
{/* area where you can swipe the menu sidebar */}
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
-
-
+
);
};
diff --git a/client/Routes.jsx b/client/Routes.jsx
index 421d053f8..183d8d273 100644
--- a/client/Routes.jsx
+++ b/client/Routes.jsx
@@ -1,27 +1,18 @@
-/* eslint-disable */
-// temporarily disabling eslint here until v2 refactor
import React from 'react';
import {
Switch,
Route,
+ Redirect,
} from 'react-router-dom';
-
-import PrivacyPolicy from '@components/privacyPolicy/PrivacyPolicy';
-import Contact from './components/contact/Contact';
-import About from './components/about/About';
-import Body from './components/main/body/Body';
-import Faq from './components/faq/Faq';
+import Desktop from '@components/main/Desktop';
export default function Routes() {
return (
-
-
-
-
-
-
-
+
+
+
+
);
}
diff --git a/client/components/FilterMenu/index.js b/client/components/FilterMenu/index.js
new file mode 100644
index 000000000..14834e17c
--- /dev/null
+++ b/client/components/FilterMenu/index.js
@@ -0,0 +1,111 @@
+import React, { useState } from 'react';
+import PropTypes from 'proptypes';
+import { connect } from 'react-redux';
+import { toggleMenu as reduxToggleMenu } from '@reducers/ui';
+import { makeStyles } from '@material-ui/core/styles';
+
+import Card from '@material-ui/core/Card';
+import CardHeader from '@material-ui/core/CardHeader';
+import CardContent from '@material-ui/core/CardContent';
+import IconButton from '@material-ui/core/IconButton';
+import ArrowDropDownIcon from '@material-ui/icons/ArrowDropDown';
+import ArrowDropUpIcon from '@material-ui/icons/ArrowDropUp';
+import Collapse from '@material-ui/core/Collapse';
+import Typography from '@material-ui/core/Typography';
+import GearButton from '../GearButton';
+
+const useStyles = makeStyles(theme => ({
+ card: {
+ width: 300,
+ backgroundColor: theme.palette.primary.main,
+ position: 'absolute',
+ left: 35,
+ top: 75,
+ borderRadius: 10,
+ zIndex: 2000,
+ },
+ header: {
+ color: theme.palette.text.cyan,
+ padding: 5,
+ paddingRight: 0,
+ },
+ headerAction: {
+ margin: 'auto',
+ },
+ headerTitle: {
+ marginLeft: 10,
+ fontSize: 20,
+ fontWeight: 600,
+ letterSpacing: '2px',
+ },
+ button: {
+ padding: 5,
+ paddingRight: 0,
+ color: theme.palette.text.dark,
+ '&:hover': {
+ backgroundColor: theme.palette.primary.main,
+ },
+ '& svg': {
+ fontSize: 30,
+ },
+ },
+}));
+
+const FilterMenu = ({
+ toggleMenu,
+}) => {
+ const [expanded, setExpanded] = useState(false);
+ const classes = useStyles();
+
+ // TODO: add basic/advanced toggle switch
+ return (
+
+
+
+
+ FILTERS
+
+ >
+ )}
+ action={(
+ setExpanded(prevExpanded => !prevExpanded)}
+ disableFocusRipple
+ disableRipple
+ >
+ {expanded ? : }
+
+ )}
+ />
+
+
+ TODO: Selectors
+
+
+
+ );
+};
+
+const mapDispatchToProps = dispatch => ({
+ toggleMenu: () => dispatch(reduxToggleMenu()),
+});
+
+export default connect(null, mapDispatchToProps)(FilterMenu);
+
+FilterMenu.propTypes = {
+ toggleMenu: PropTypes.func.isRequired,
+};
diff --git a/client/components/Footer.jsx b/client/components/Footer.jsx
index 8b422740a..11418da53 100644
--- a/client/components/Footer.jsx
+++ b/client/components/Footer.jsx
@@ -8,19 +8,19 @@ import {
import { makeStyles } from '@material-ui/core/styles';
import moment from 'moment';
-// TODO: pull style constants into mui theme
const useStyles = makeStyles(theme => ({
footer: {
position: 'absolute',
bottom: 0,
- height: '40px',
+ height: theme.footer.height,
width: '100%',
backgroundColor: theme.palette.primary.dark,
},
lastUpdated: {
- color: theme.palette.typography.dark,
- lineHeight: '40px',
+ color: theme.palette.text.dark,
+ lineHeight: theme.footer.height,
fontSize: '14px',
+ fontFamily: 'Roboto',
},
}));
diff --git a/client/components/GearButton/index.jsx b/client/components/GearButton/index.jsx
index 405769148..875f1b4f4 100644
--- a/client/components/GearButton/index.jsx
+++ b/client/components/GearButton/index.jsx
@@ -4,9 +4,9 @@ import { IconButton } from '@material-ui/core';
import { makeStyles } from '@material-ui/core/styles';
import SettingsSharpIcon from '@material-ui/icons/SettingsSharp';
-const useStyles = makeStyles({
+const useStyles = makeStyles(theme => ({
gearIcon: {
- color: 'white',
+ color: theme.palette.text.dark,
background: '#29404F',
borderRadius: '12px',
height: '33px',
@@ -16,12 +16,14 @@ const useStyles = makeStyles({
button: {
padding: '0',
},
-});
+}));
-const GearButton = props => {
+const GearButton = ({
+ onClick,
+}) => {
const { gearIcon, button } = useStyles();
const [pressed, setPressed] = useState(false);
- const { onClick, style } = props;
+
const onKeyDown = e => {
e.preventDefault();
if (e.key === ' '
@@ -32,10 +34,12 @@ const GearButton = props => {
onClick();
}
};
+
const toggleClick = () => {
setPressed(!pressed);
onClick();
};
+
return (
{
role="button"
aria-pressed={pressed}
aria-label="Toggle Sidebar"
- style={style}
+ disableFocusRipple
+ disableRipple
>
@@ -53,11 +58,9 @@ const GearButton = props => {
GearButton.propTypes = {
onClick: PropTypes.func,
- style: PropTypes.obj,
};
GearButton.defaultProps = {
onClick: undefined,
- style: undefined,
};
export default GearButton;
diff --git a/client/components/Header.jsx b/client/components/Header.jsx
index ed51ecfdf..0e749987b 100644
--- a/client/components/Header.jsx
+++ b/client/components/Header.jsx
@@ -10,15 +10,17 @@ import {
const useStyles = makeStyles(theme => ({
appBar: {
- height: theme.palette.header.height,
+ height: theme.header.height,
backgroundColor: theme.palette.primary.main,
},
button: {
textTransform: 'none',
+ fontFamily: 'Roboto',
+ marginLeft: theme.spacing(2),
},
title: {
flexGrow: 1,
- fontFamily: theme.palette.typography.fontFamily,
+ fontFamily: theme.typography.fontFamily,
fontSize: '30px',
fontWeight: 'bold',
letterSpacing: '4px',
diff --git a/client/components/LeftDrawer/index.jsx b/client/components/LeftDrawer/index.jsx
index 754e3c8a8..62f8e62d9 100644
--- a/client/components/LeftDrawer/index.jsx
+++ b/client/components/LeftDrawer/index.jsx
@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { useEffect } from 'react';
import PropTypes from 'proptypes';
import { makeStyles, useTheme } from '@material-ui/core/styles';
import Drawer from '@material-ui/core/Drawer';
@@ -31,6 +31,7 @@ const useStyles = makeStyles(theme => ({
drawer: {
width: drawerWidth,
flexShrink: 0,
+ zIndex: 2100,
},
drawerPaper: {
width: drawerWidth,
@@ -89,20 +90,18 @@ const PersistentDrawerLeft = ({ menuIsOpen, toggleMenu }) => {
// TODO ADD FUNCTIONALITY
};
- const escFunction = e => {
- e.preventDefault();
- if (e.key === 'Escape'
- ) {
- toggleMenu();
- }
- };
+ useEffect(() => {
+ 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 () => document.removeEventListener('keypress', escFunction, false);
+ }, [toggleMenu]);
return (
diff --git a/client/components/Map/index.jsx b/client/components/Map/index.js
similarity index 96%
rename from client/components/Map/index.jsx
rename to client/components/Map/index.js
index e979de2b8..114469c59 100644
--- a/client/components/Map/index.jsx
+++ b/client/components/Map/index.js
@@ -12,11 +12,7 @@ import Map from './Map';
const styles = theme => ({
root: {
- position: 'absolute',
- top: theme.palette.header.height,
- bottom: theme.palette.footer.height,
- left: 0,
- right: 0,
+ height: '100%',
},
})
diff --git a/client/components/main/Desktop/index.js b/client/components/main/Desktop/index.js
new file mode 100644
index 000000000..41434a856
--- /dev/null
+++ b/client/components/main/Desktop/index.js
@@ -0,0 +1,30 @@
+import React from 'react';
+import { makeStyles } from '@material-ui/core/styles';
+
+import MapContainer from '@components/Map';
+import FilterMenu from '@components/FilterMenu';
+import PersistentDrawerLeft from '@components/LeftDrawer';
+
+const useStyles = makeStyles(theme => ({
+ root: {
+ position: 'absolute',
+ top: theme.header.height,
+ bottom: theme.footer.height,
+ left: 0,
+ right: 0,
+ },
+}));
+
+const Desktop = () => {
+ const classes = useStyles();
+
+ return (
+
+ );
+};
+
+export default Desktop;
diff --git a/client/components/main/Mobile/.gitkeep b/client/components/main/Mobile/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/client/index.js b/client/index.js
index 069ee496c..d09a0bcaa 100644
--- a/client/index.js
+++ b/client/index.js
@@ -5,12 +5,18 @@ import 'regenerator-runtime/runtime';
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
+import { ThemeProvider } from '@material-ui/core/styles';
+import { CssBaseline } from '@material-ui/core';
import store from './redux/store';
import App from './App';
+import theme from './theme/theme';
ReactDOM.render(
-
+
+
+
+
,
document.getElementById('root'),
);
diff --git a/client/redux/reducers/data.js b/client/redux/reducers/data.js
index d9f3fff92..5f30e1cf6 100644
--- a/client/redux/reducers/data.js
+++ b/client/redux/reducers/data.js
@@ -5,8 +5,6 @@ export const types = {
GET_PIN_INFO_REQUEST: 'GET_PIN_INFO_REQUEST',
GET_PIN_INFO_SUCCESS: 'GET_PIN_INFO_SUCCESS',
GET_PIN_INFO_FAILURE: 'GET_PIN_INFO_FAILURE',
- GET_PIN_CLUSTERS_SUCCESS: 'GET_PIN_CLUSTERS_SUCCESS',
- GET_PIN_CLUSTERS_FAILURE: 'GET_PIN_CLUSTERS_FAILURE',
GET_HEATMAP_SUCCESS: 'GET_HEATMAP_SUCCESS',
GET_HEATMAP_FAILURE: 'GET_HEATMAP_FAILURE',
GET_VIS_DATA_SUCCESS: 'GET_VIS_DATA_SUCCESS',
@@ -45,16 +43,6 @@ export const getPinInfoFailure = error => ({
payload: error,
});
-export const getPinClustersSuccess = response => ({
- type: types.GET_PIN_CLUSTERS_SUCCESS,
- payload: response,
-});
-
-export const getPinClustersFailure = error => ({
- type: types.GET_PIN_CLUSTERS_FAILURE,
- payload: error,
-});
-
export const getHeatmapSuccess = response => ({
type: types.GET_HEATMAP_SUCCESS,
payload: response,
@@ -95,7 +83,6 @@ const initialState = {
isVisLoading: false,
error: null,
pins: [],
- pinClusters: [],
heatmap: [],
pinsInfo: {},
counts: {},
@@ -159,28 +146,6 @@ export default (state = initialState, action) => {
},
};
}
- case types.GET_PIN_CLUSTERS_SUCCESS:
- return {
- ...state,
- error: null,
- pinClusters: action.payload,
- isMapLoading: false,
- };
- case types.GET_PIN_CLUSTERS_FAILURE: {
- const {
- response: { status },
- message,
- } = action.payload;
- return {
- ...state,
- error: {
- code: status,
- message,
- error: action.payload,
- },
- isMapLoading: false,
- };
- }
case types.GET_HEATMAP_SUCCESS:
return {
...state,
diff --git a/client/redux/reducers/metadata.js b/client/redux/reducers/metadata.js
index 292df2a69..9ebf10dab 100644
--- a/client/redux/reducers/metadata.js
+++ b/client/redux/reducers/metadata.js
@@ -2,6 +2,9 @@ export const types = {
GET_METADATA_REQUEST: 'GET_METADATA_REQUEST',
GET_METADATA_SUCCESS: 'GET_METADATA_SUCCESS',
GET_METADATA_FAILURE: 'GET_METADATA_FAILURE',
+ GET_REQUEST_TYPES_SUCCESS: 'GET_REQUEST_TYPES_SUCCESS',
+ GET_COUNCILS_SUCCESS: 'GET_COUNCILS_SUCCESS',
+ GET_REGIONS_SUCCESS: 'GET_REGIONS_SUCCESS',
};
export const getMetadataRequest = () => ({
@@ -18,14 +21,53 @@ export const getMetadataFailure = error => ({
payload: error,
});
-const initialState = {};
+export const getRequestTypesSuccess = response => ({
+ type: types.GET_REQUEST_TYPES_SUCCESS,
+ payload: response,
+});
+
+export const getCouncilsSuccess = response => ({
+ type: types.GET_COUNCILS_SUCCESS,
+ payload: response,
+});
+
+export const getRegionsSuccess = response => ({
+ type: types.GET_REGIONS_SUCCESS,
+ payload: response,
+});
+
+const initialState = {
+ currentTime: null,
+ gitSha: null,
+ version: null,
+ lastPulled: null,
+ requestTypes: null,
+ councils: null,
+ regions: null,
+};
export default (state = initialState, action) => {
switch (action.type) {
case types.GET_METADATA_SUCCESS:
return {
+ ...state,
...action.payload,
};
+ case types.GET_REQUEST_TYPES_SUCCESS:
+ return {
+ ...state,
+ requestTypes: action.payload,
+ };
+ case types.GET_COUNCILS_SUCCESS:
+ return {
+ ...state,
+ councils: action.payload,
+ };
+ case types.GET_REGIONS_SUCCESS:
+ return {
+ ...state,
+ regions: action.payload,
+ };
case types.GET_METADATA_FAILURE: {
const {
response: { status },
diff --git a/client/redux/sagas/data.js b/client/redux/sagas/data.js
index bdce07faa..b0dac50ca 100644
--- a/client/redux/sagas/data.js
+++ b/client/redux/sagas/data.js
@@ -15,8 +15,6 @@ import {
getDataRequest,
getPinsSuccess,
getPinsFailure,
- // getPinClustersSuccess,
- // getPinClustersFailure,
getHeatmapSuccess,
getHeatmapFailure,
getPinInfoSuccess,
@@ -52,28 +50,6 @@ function* fetchPins(filters) {
return data;
}
-// function* fetchPinClusters(filters, { zoom, bounds }) {
-// const clustersUrl = `${BASE_URL}/map/clusters`;
-
-// const {
-// _northEast: { lat: north, lng: east },
-// _southWest: { lat: south, lng: west },
-// } = bounds;
-
-// const { data } = yield call(axios.post, clustersUrl, {
-// ...filters,
-// zoom,
-// bounds: {
-// north,
-// east,
-// south,
-// west,
-// },
-// });
-
-// return data;
-// }
-
function* fetchHeatmap(filters) {
const heatmapUrl = `${BASE_URL}/map/heat`;
@@ -199,26 +175,6 @@ function* getVisData() {
}
}
-// function* updatePinClusters() {
-// const filters = yield getFilters();
-
-// if (
-// !filters.startDate
-// || !filters.endDate
-// || !filters.ncList.length
-// || !filters.requestTypes.length
-// ) return;
-
-// const mapPosition = yield getMapPosition();
-// try {
-// const data = yield call(fetchPinClusters, filters, mapPosition);
-// yield put(getPinClustersSuccess(data));
-// } catch (e) {
-// yield put(getPinClustersFailure(e));
-// yield put(setErrorModal(true));
-// }
-// }
-
function* getPinData(action) {
try {
const srnumber = action.payload;
@@ -248,5 +204,4 @@ export default function* rootSaga() {
yield takeLatest(types.GET_DATA_REQUEST, getVisData);
yield takeEvery(types.GET_PIN_INFO_REQUEST, getPinData);
yield takeLatest(types.SEND_GIT_REQUEST, sendContactData);
- // yield takeLatest(uiTypes.UPDATE_MAP_POSITION, updatePinClusters);
}
diff --git a/client/redux/sagas/metadata.js b/client/redux/sagas/metadata.js
index 38758f9d9..1ac00c49e 100644
--- a/client/redux/sagas/metadata.js
+++ b/client/redux/sagas/metadata.js
@@ -3,19 +3,38 @@ import {
takeLatest,
call,
put,
+ all,
} from 'redux-saga/effects';
import {
types,
getMetadataSuccess,
+ getRequestTypesSuccess,
+ getCouncilsSuccess,
+ getRegionsSuccess,
getMetadataFailure,
} from '../reducers/metadata';
function* getMetadata() {
- const url = `${process.env.API_URL}/status/api`;
+ const baseUrl = process.env.API_URL;
try {
- const { data } = yield call(axios.get, url);
- yield put(getMetadataSuccess(data));
+ const [metadata, requestTypes, councils, regions] = yield all([
+ call(axios.get, `${baseUrl}/status/api`),
+ call(axios.get, `${baseUrl}/types/`),
+ call(axios.get, `${baseUrl}/councils/`),
+ call(axios.get, `${baseUrl}/regions/`),
+ ]);
+ const { data: statusMetadata } = metadata;
+ const { data: typesMetadata } = requestTypes;
+ const { data: councilsMetadata } = councils;
+ const { data: regionsMetadata } = regions;
+
+ yield all([
+ put(getMetadataSuccess(statusMetadata)),
+ put(getRequestTypesSuccess(typesMetadata)),
+ put(getCouncilsSuccess(councilsMetadata)),
+ put(getRegionsSuccess(regionsMetadata)),
+ ]);
} catch (e) {
yield put(getMetadataFailure(e));
}
diff --git a/client/theme/theme.js b/client/theme/theme.js
index 6fe3e31b6..a792ba53a 100644
--- a/client/theme/theme.js
+++ b/client/theme/theme.js
@@ -4,7 +4,7 @@ const theme = createMuiTheme({
palette: {
type: 'dark',
primary: {
- main: '#2A404E',
+ main: '#29404F',
dark: '#192730',
},
secondary: {
@@ -13,16 +13,19 @@ const theme = createMuiTheme({
background: {
default: '#1A1A1A',
},
- typography: {
- fontFamily: ['Oswald', 'sans-serif'],
+ text: {
dark: '#C4C4C4',
+ cyan: '#87C8BC',
},
- header: {
- height: '62px',
- },
- footer: {
- height: '40px',
- },
+ },
+ header: {
+ height: '62px',
+ },
+ footer: {
+ height: '40px',
+ },
+ typography: {
+ fontFamily: ['Oswald', 'sans-serif'],
},
});