diff --git a/.eslintrc.js b/.eslintrc.js
index 053f0736b..67ca8fd7a 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -4,54 +4,58 @@ module.exports = {
es6: true,
node: true,
},
- extends: ["airbnb", "eslint:recommended", "plugin:react/recommended"],
+ extends: ['airbnb', 'eslint:recommended', 'plugin:react/recommended'],
globals: {
- Atomics: "readonly",
- SharedArrayBuffer: "readonly",
+ Atomics: 'readonly',
+ SharedArrayBuffer: 'readonly',
},
- parser: "babel-eslint",
+ parser: '@babel/eslint-parser',
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 2018,
- sourceType: "module",
+ sourceType: 'module',
},
settings: {
- "import/extensions": [".js", ".jsx"],
- "import/resolver": {
+ 'import/extensions': ['.js', '.jsx'],
+ 'import/resolver': {
node: {},
- webpack: "webpack.config.js",
+ webpack: 'webpack.config.js',
},
},
- plugins: ["react", "react-hooks"],
+ plugins: ['react', 'react-hooks'],
rules: {
- "linebreak-style": "off",
- "react-hooks/rules-of-hooks": "error",
- "react-hooks/exhaustive-deps": "warn",
- "arrow-parens": ["error", "as-needed"],
+ 'linebreak-style': 'off',
+ 'react-hooks/rules-of-hooks': 'error',
+ 'react-hooks/exhaustive-deps': 'warn',
+ 'arrow-parens': ['error', 'as-needed'],
indent: [
- "error",
+ 'error',
2,
{
SwitchCase: 1,
- MemberExpression: "off",
- ignoredNodes: ["TemplateLiteral"],
+ MemberExpression: 'off',
+ ignoredNodes: ['TemplateLiteral'],
},
],
- "template-curly-spacing": "off",
- "jsx-a11y/no-noninteractive-tabindex": [
- "error",
+ 'template-curly-spacing': 'off',
+ 'jsx-a11y/no-noninteractive-tabindex': [
+ 'error',
{
tags: [],
- roles: ["tabpanel"],
+ roles: ['tabpanel'],
},
],
- "jsx-a11y/label-has-associated-control": [ 2, {
- "labelComponents": ["label"],
- "labelAttributes": ["htmlFor"],
- "controlComponents": ["input"]
+ 'jsx-a11y/label-has-associated-control': [2, {
+ labelComponents: ['label'],
+ labelAttributes: ['htmlFor'],
+ controlComponents: ['input'],
}],
- "react/jsx-filename-extension": [1, { extensions: [".js", ".jsx"] }],
+ 'react/jsx-filename-extension': [1, { extensions: ['.js', '.jsx'] }],
+
+ 'default-param-last': 'warn',
+ 'no-restricted-exports': 'warn',
+ 'react/jsx-no-constructed-context-values': 'warn',
},
};
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index a468a9cf7..12143c739 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -24,10 +24,10 @@ jobs:
# with:
# python-version: '2.x'
- - name: Use Node.js 12.x
+ - name: Use Node.js 18.x
uses: actions/setup-node@v3
with:
- node-version: '12.x'
+ node-version: '18.x'
- name: Install Packages
run: npm ci
diff --git a/.gitignore b/.gitignore
index 9c39b8a6f..8e476ff22 100644
--- a/.gitignore
+++ b/.gitignore
@@ -39,3 +39,5 @@ venv/
# archive
/archive/aws/API\ Responses/*
+
+.DS_Store
\ No newline at end of file
diff --git a/App.jsx b/App.jsx
index 735023098..f0c77a5ab 100644
--- a/App.jsx
+++ b/App.jsx
@@ -6,10 +6,9 @@ import { getMetadataRequest } from '@reducers/metadata';
import Header from '@components/Header';
import Footer from '@components/Footer';
-import Routes from './Routes';
-import RouteChange from './components/main/util/RouteChange';
+import AppRoutes from './Routes';
-const App = ({ getMetadata }) => {
+function App({ getMetadata }) {
useEffect(() => {
getMetadata();
});
@@ -17,12 +16,11 @@ const App = ({ getMetadata }) => {
return (
-
+
-
);
-};
+}
const mapDispatchToProps = dispatch => ({
getMetadata: () => dispatch(getMetadataRequest()),
diff --git a/README.md b/README.md
index 1bcb3ba4d..3408870b1 100644
--- a/README.md
+++ b/README.md
@@ -27,7 +27,7 @@ Our mission is to create a user-friendly platform for anyone interested in explo
* React.js
* Duckdb-wasm
* Redux
-* Material-UI 4.x
+* Material-UI 5.x
### Data Analysis
@@ -45,9 +45,9 @@ Our mission is to create a user-friendly platform for anyone interested in explo
## Quick Start
* Ensure that node version manager (nvm) is installed (e.g. follow a [tutorial](https://heynode.com/tutorial/install-nodejs-locally-nvm/))
-* Run `nvm install lts/erbium` (on windows `nvm install erbium`)
-* Run `nvm use lts/erbium` (on windows `nvm use erbium`)
-* confirm you are using Node 12 by running `node -v` (e.g. `Now using node v12.22.12 (npm v6.14.16)`)
+* Run `nvm install lts/hydrogen` (on windows `nvm install hydrogen`)
+* Run `nvm use lts/hydrogen` (on windows `nvm use hydrogen`)
+* confirm you are using Node 18 by running `node -v` (e.g. `Now using node v18.7.0 (npm v8.9.2)`)
* clone the repo
* cd 311-data/
* cp .example.env .env
diff --git a/Routes.jsx b/Routes.jsx
index d9853f764..732e01316 100644
--- a/Routes.jsx
+++ b/Routes.jsx
@@ -1,10 +1,10 @@
import React from 'react';
import {
- Switch, Route, Redirect, useLocation,
+ Routes, Route, Navigate, useLocation,
} from 'react-router-dom';
-import { ThemeProvider } from '@material-ui/core/styles';
-import Paper from '@material-ui/core/Paper';
-import Box from '@material-ui/core/Box';
+import { ThemeProvider, StyledEngineProvider } from '@mui/material/styles';
+import Paper from '@mui/material/Paper';
+import Box from '@mui/material/Box';
import queryString from 'query-string';
import theme, { darkTheme } from '@theme/theme';
import Desktop from '@components/main/Desktop';
@@ -17,42 +17,44 @@ import Research from '@components/main/Research';
import Contact from '@components/contact/Contact';
import ContentBottom from '@components/common/ContentBottom';
-export default function Routes() {
+export default function AppRoutes() {
const { pathname, search } = useLocation();
const values = queryString.parse(search);
return (
<>
{/* Dark Theme - Map. */}
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
{/* Default theme - Everything else. */}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+ } />
+ }
+ />
+ } />
+ } />
+ } />
+ } />
+ } />
+ } />
+
+
+
+
+
>
);
}
diff --git a/components/Dashboards/DashboardComparison.jsx b/components/Dashboards/DashboardComparison.jsx
index aec31597f..7937c8c96 100644
--- a/components/Dashboards/DashboardComparison.jsx
+++ b/components/Dashboards/DashboardComparison.jsx
@@ -4,7 +4,7 @@ import ContentBody from '@components/common/ContentBody';
// import ddbh from '@utils/duckDbHelpers.js';
// import DbContext from '@db/DbContext';
-const DashboardComparison = () => {
+function DashboardComparison() {
const isMapLoading = useSelector(state => state.data.isMapLoading);
if (isMapLoading) return null;
@@ -15,6 +15,6 @@ const DashboardComparison = () => {
Welcome to the future of Dashboard Comparison
);
-};
+}
export default DashboardComparison;
diff --git a/components/Dashboards/layouts/QuadLayout.jsx b/components/Dashboards/layouts/QuadLayout.jsx
index 82772b764..a398cd6ef 100644
--- a/components/Dashboards/layouts/QuadLayout.jsx
+++ b/components/Dashboards/layouts/QuadLayout.jsx
@@ -1,25 +1,27 @@
import React from 'react';
import PropTypes from 'prop-types';
-import { Grid } from '@material-ui/core';
+import { Grid } from '@mui/material';
-const QuadLayout = ({
+function QuadLayout({
quadrant1, quadrant2, quadrant3, quadrant4,
-}) => (
-
-
- {quadrant1}
+}) {
+ return (
+
+
+ {quadrant1}
+
+
+ {quadrant2}
+
+
+ {quadrant3}
+
+
+ {quadrant4}
+
-
- {quadrant2}
-
-
- {quadrant3}
-
-
- {quadrant4}
-
-
-);
+ );
+}
QuadLayout.propTypes = {
quadrant1: PropTypes.element.isRequired,
diff --git a/components/Dashboards/widgets/TotalByDayOfWeek.jsx b/components/Dashboards/widgets/TotalByDayOfWeek.jsx
index b629b83ba..0e8174216 100644
--- a/components/Dashboards/widgets/TotalByDayOfWeek.jsx
+++ b/components/Dashboards/widgets/TotalByDayOfWeek.jsx
@@ -1,20 +1,22 @@
import React from 'react';
import PropTypes from 'proptypes';
-const TotalByDayOfWeek = ({ data }) => (
- <>
- Total Requests by Day of The Week
- {
+function TotalByDayOfWeek({ data }) {
+ return (
+ <>
+ Total Requests by Day of The Week
+ {
// Observable code goes here
// https://observablehq.com/d/8236de092b1f9523#cell-237
- }
-
- {data?.map(request => (
- - {request.SRNumber}
- ))}
-
- >
-);
+ }
+
+ {data?.map(request => (
+ - {request.SRNumber}
+ ))}
+
+ >
+ );
+}
TotalByDayOfWeek.propTypes = {
data: PropTypes.arrayOf(PropTypes.shape({})).isRequired,
diff --git a/components/DateSelector/DateRanges.jsx b/components/DateSelector/DateRanges.jsx
index 0595a5903..ab8ead759 100644
--- a/components/DateSelector/DateRanges.jsx
+++ b/components/DateSelector/DateRanges.jsx
@@ -1,9 +1,9 @@
import React from 'react';
import PropTypes from 'prop-types';
-const DateRanges = ({
+function DateRanges({
options, onSelect, dates, classes,
-}) => {
+}) {
function highlightIfSelected(optionDays, selectedDays) {
if (dates.length > 0) {
const [from, to, start, end] = [
@@ -38,7 +38,7 @@ const DateRanges = ({
: null}
);
-};
+}
const {
func, arrayOf, shape, string,
diff --git a/components/DateSelector/useStyles.js b/components/DateSelector/useStyles.js
index 101c2eb8f..9ad45069d 100644
--- a/components/DateSelector/useStyles.js
+++ b/components/DateSelector/useStyles.js
@@ -1,4 +1,4 @@
-import { makeStyles } from '@material-ui/core/styles';
+import makeStyles from '@mui/styles/makeStyles';
const useStyles = makeStyles(theme => ({
label: {
diff --git a/components/FactModal/index.jsx b/components/FactModal/index.jsx
index e0a9a920c..45da5aa93 100644
--- a/components/FactModal/index.jsx
+++ b/components/FactModal/index.jsx
@@ -1,6 +1,6 @@
import React, { useState, useEffect } from 'react';
-import { makeStyles } from '@material-ui/core/styles';
-import { Modal, Typography } from '@material-ui/core';
+import makeStyles from '@mui/styles/makeStyles';
+import { Modal, Typography } from '@mui/material';
import { seconds } from '@utils';
import facts from '@data/facts';
diff --git a/components/Footer/LastUpdated.jsx b/components/Footer/LastUpdated.jsx
index 7b1fbce21..1705fe28c 100644
--- a/components/Footer/LastUpdated.jsx
+++ b/components/Footer/LastUpdated.jsx
@@ -1,7 +1,7 @@
import React, { useContext, useEffect, useState } from 'react';
import moment from 'moment';
-import Typography from '@material-ui/core/Typography';
-import { makeStyles } from '@material-ui/core/styles';
+import Typography from '@mui/material/Typography';
+import makeStyles from '@mui/styles/makeStyles';
import DbContext from '@db/DbContext';
import ddbh from '@utils/duckDbHelpers.js';
import { isEmpty } from '@utils';
@@ -14,7 +14,7 @@ const useStyles = makeStyles(theme => ({
},
}));
-const LastUpdated = () => {
+function LastUpdated() {
const classes = useStyles();
const [lastUpdated, setLastUpdated] = useState('');
const { conn } = useContext(DbContext);
@@ -45,6 +45,6 @@ const LastUpdated = () => {
)
);
-};
+}
export default LastUpdated;
diff --git a/components/Footer/SocialMediaLinks.jsx b/components/Footer/SocialMediaLinks.jsx
index fa75763a4..26dab7525 100644
--- a/components/Footer/SocialMediaLinks.jsx
+++ b/components/Footer/SocialMediaLinks.jsx
@@ -1,5 +1,5 @@
import React from 'react';
-import { makeStyles } from '@material-ui/core/styles';
+import makeStyles from '@mui/styles/makeStyles';
import TwitterSVG from '@assets/twitter-round.svg';
import FacebookSVG from '@assets/facebook-round.svg';
@@ -23,7 +23,7 @@ const useStyles = makeStyles(theme => ({
},
}));
-const SocialMediaLinks = () => {
+function SocialMediaLinks() {
const classes = useStyles();
return (
@@ -45,6 +45,6 @@ const SocialMediaLinks = () => {
);
-};
+}
export default SocialMediaLinks;
diff --git a/components/Footer/index.jsx b/components/Footer/index.jsx
index 56c35d2ed..1635e9605 100644
--- a/components/Footer/index.jsx
+++ b/components/Footer/index.jsx
@@ -1,7 +1,7 @@
import React from 'react';
import { connect } from 'react-redux';
-import Typography from '@material-ui/core/Typography';
-import { makeStyles } from '@material-ui/core/styles';
+import Typography from '@mui/material/Typography';
+import makeStyles from '@mui/styles/makeStyles';
import { Link } from 'react-router-dom';
import LastUpdated from '@components/Footer/LastUpdated';
import SocialMediaLinks from '@components/Footer/SocialMediaLinks';
@@ -42,7 +42,7 @@ const useStyles = makeStyles(theme => ({
}));
// TODO: check with UI/UX re placement of social media, privacy policy links
-const Footer = () => {
+function Footer() {
const classes = useStyles();
const currentDate = new Date();
@@ -69,7 +69,7 @@ const Footer = () => {
);
-};
+}
const mapStateToProps = state => ({
lastUpdated: state.metadata.lastPulledLocal,
diff --git a/components/Header.jsx b/components/Header.jsx
index 3bb77f8ec..b71f129a3 100644
--- a/components/Header.jsx
+++ b/components/Header.jsx
@@ -1,12 +1,12 @@
import React from 'react';
import { NavLink, Link } from 'react-router-dom';
-import { makeStyles } from '@material-ui/core/styles';
-import AppBar from '@material-ui/core/AppBar';
-import Button from '@material-ui/core/Button';
-import Toolbar from '@material-ui/core/Toolbar';
-import Typography from '@material-ui/core/Typography';
-import Menu from '@material-ui/core/Menu';
-import MenuItem from '@material-ui/core/MenuItem';
+import makeStyles from '@mui/styles/makeStyles';
+import AppBar from '@mui/material/AppBar';
+import Button from '@mui/material/Button';
+import Toolbar from '@mui/material/Toolbar';
+import Typography from '@mui/material/Typography';
+import Menu from '@mui/material/Menu';
+import MenuItem from '@mui/material/MenuItem';
import fonts from '@theme/fonts';
import colors from '@theme/colors';
@@ -57,7 +57,7 @@ const activeStyle = {
};
// TODO: links/routing, mobile
-const Header = () => {
+function Header() {
const classes = useStyles();
const [anchorEl, setAnchorEl] = React.useState(null);
@@ -77,7 +77,7 @@ const Header = () => {
311DATA
-
+ (isActive ? activeStyle : null)}>