diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 00000000..de2caab8
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,24 @@
+module.exports = {
+ extends: ["airbnb", "plugin:@typescript-eslint/recommended"],
+ parser: "@typescript-eslint/parser",
+ plugins: ["@typescript-eslint", "prettier"],
+ settings: {
+ "import/parsers": {
+ "@typescript-eslint/parser": [".ts", ".tsx"],
+ },
+ "import/resolver": {
+ typescript: {},
+ },
+ },
+ ignorePatterns: ["**/build/*", "*.js", "*.jsx"],
+ rules: {
+ quotes: [2, "single"],
+ "react/jsx-filename-extension": [2, { extensions: [".ts", ".tsx"] }],
+ "import/no-extraneous-dependencies": [
+ 2,
+ { devDependencies: ["**/test.tsx", "**/test.ts"] },
+ ],
+ "@typescript-eslint/indent": [2, 2],
+ "react/react-in-jsx-scope": "off",
+ },
+};
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 00000000..98ab969d
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,33 @@
+"[javascript]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode",
+ "editor.formatOnSave": false
+},
+"[javascriptreact]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode",
+ "editor.formatOnSave": false
+},
+"[typescript]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode",
+ "editor.formatOnSave": false
+},
+"[typescriptreact]": {
+ "editor.defaultFormatter": "esbenp.prettier-vscode",
+ "editor.formatOnSave": false
+},
+"eslint.autoFixOnSave": true,
+"eslint.validate": [
+ "javascript",
+ "javascriptreact",
+ {
+ "autoFix": true,
+ "language": "typescript"
+ },
+ {
+ "autoFix": true,
+ "language": "typescriptreact"
+ }
+],
+"prettier.eslintIntegration": true,
+"editor.codeActionsOnSave": {
+ "source.fixAll.eslint": true
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index 474e7ea3..735f7945 100644
--- a/package.json
+++ b/package.json
@@ -14,6 +14,7 @@
"@testing-library/jest-dom": "^5.12.0",
"@testing-library/react": "^11.2.7",
"@testing-library/user-event": "^13.1.9",
+ "@types/reactour": "^1.18.1",
"axios": "^0.21.1",
"clsx": "^1.1.1",
"moment": "^2.29.1",
@@ -28,6 +29,7 @@
"reactour": "^1.18.4",
"serve": "^11.3.2",
"styled-components": "^5.3.0",
+ "typescript": "^4.3.2",
"web-vitals": "^1.1.2",
"zustand": "^3.5.1"
},
@@ -37,7 +39,8 @@
"test": "react-scripts test",
"eject": "react-scripts eject",
"predeploy": "yarn build",
- "deploy": "gh-pages -d build"
+ "deploy": "gh-pages -d build",
+ "lint": "eslint . --ext .js,.jsx,.ts,.tsx"
},
"eslintConfig": {
"extends": [
@@ -58,18 +61,26 @@
]
},
"devDependencies": {
+ "@types/react-router-dom": "^5.1.7",
"@typescript-eslint/eslint-plugin": "^4.25.0",
"@typescript-eslint/parser": "^4.25.0",
"babel-eslint": "^10.1.0",
"eslint": "^7.27.0",
+ "eslint-config-airbnb": "^18.2.1",
+ "eslint-config-airbnb-typescript": "^12.3.1",
+ "eslint-config-prettier": "^8.3.0",
"eslint-config-react-app": "^6.0.0",
+ "eslint-import-resolver-typescript": "^2.4.0",
"eslint-plugin-flowtype": "^5.7.2",
"eslint-plugin-import": "^2.23.4",
+ "eslint-plugin-jest": "^24.3.6",
+ "eslint-plugin-json": "^3.0.0",
"eslint-plugin-jsx-a11y": "^6.4.1",
+ "eslint-plugin-prettier": "^3.4.0",
"eslint-plugin-react": "^7.24.0",
- "eslint-plugin-react-hooks": "^4.2.0",
+ "eslint-plugin-react-hooks": "^4.0.8",
"gh-pages": "^3.2.0",
- "react-is": "^17.0.2",
- "webpack": "^5.38.1"
+ "prettier": "^2.3.0",
+ "react-is": "^17.0.2"
}
}
diff --git a/src/App.jsx b/src/App.jsx
index b36d6a7e..7ddf7b38 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -1,43 +1,41 @@
-import { useEffect } from "react";
-import useStore from "./utils/apiStore";
-import useStyles from "./App.styles";
-import "./App.css";
-import "./assets/materialdesignicons.css";
+import { useEffect } from 'react';
+import { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';
+import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
+import clsx from 'clsx';
+import CssBaseline from '@material-ui/core/CssBaseline';
-import clsx from "clsx";
-import CssBaseline from "@material-ui/core/CssBaseline";
+import useStore from './utils/apiStore';
+import useStyles from './App.styles';
+import './App.css';
+import './assets/materialdesignicons.css';
-import LeftBar from "./components/Bars/BarLeft";
-import TopBar from "./components/Bars/BarTop";
-import BottomBar from "./components/Bars/BarBottom";
-import MessageBar from "./components/Bars/BarMessage";
+import LeftBar from './components/Bars/BarLeft';
+import TopBar from './components/Bars/BarTop';
+import BottomBar from './components/Bars/BarBottom';
+import MessageBar from './components/Bars/BarMessage';
-import { MuiThemeProvider } from "@material-ui/core/styles";
-import { createMuiTheme } from "@material-ui/core/styles";
-
-import DialogNoHost from "./components/DialogNoHost";
-import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
-import Home from "./pages/Home";
-import Devices from "./pages/Devices";
-import Device from "./pages/Device/Device";
-import Scenes from "./pages/Scenes";
-import Settings from "./pages/Settings";
-import Integrations from "./pages/Integrations";
+import DialogNoHost from './components/DialogNoHost';
+import Home from './pages/Home';
+import Devices from './pages/Devices';
+import Device from './pages/Device/Device';
+import Scenes from './pages/Scenes';
+import Settings from './pages/Settings';
+import Integrations from './pages/Integrations';
const curacaoDarkTheme = createMuiTheme({
palette: {
- type: "dark",
+ type: 'dark',
primary: {
- main: "#0dbedc",
+ main: '#0dbedc',
},
secondary: {
- main: "#999",
+ main: '#999',
},
- background: { default: "#030303", paper: "#151515" },
+ background: { default: '#030303', paper: '#151515' },
},
props: {
MuiCard: {
- variant: "outlined",
+ variant: 'outlined',
},
},
});
diff --git a/src/App.styles.jsx b/src/App.styles.jsx
index a742bdf6..fa0791f7 100644
--- a/src/App.styles.jsx
+++ b/src/App.styles.jsx
@@ -1,52 +1,52 @@
-import { makeStyles } from "@material-ui/core/styles";
-import { drawerWidth } from "./utils/helpers";
+import { makeStyles } from '@material-ui/core/styles';
+import { drawerWidth } from './utils/helpers';
const useStyles = makeStyles((theme) => ({
- "@global": {
- "*::-webkit-scrollbar": {
- backgroundColor: "#ffffff30",
- width: "8px",
- borderRadius: "8px",
+ '@global': {
+ '*::-webkit-scrollbar': {
+ backgroundColor: '#ffffff30',
+ width: '8px',
+ borderRadius: '8px',
},
- "*::-webkit-scrollbar-track": {
- backgroundColor: "#00000060",
- borderRadius: "8px",
+ '*::-webkit-scrollbar-track': {
+ backgroundColor: '#00000060',
+ borderRadius: '8px',
},
- "*::-webkit-scrollbar-thumb": {
- backgroundColor: "#555555",
- borderRadius: "8px",
+ '*::-webkit-scrollbar-thumb': {
+ backgroundColor: '#555555',
+ borderRadius: '8px',
},
- "*::-webkit-scrollbar-button": {
- display: "none",
+ '*::-webkit-scrollbar-button': {
+ display: 'none',
},
},
root: {
- display: "flex",
+ display: 'flex',
},
drawerHeader: {
- display: "flex",
- justifyContent: "space-between",
- alignItems: "center",
+ display: 'flex',
+ justifyContent: 'space-between',
+ alignItems: 'center',
padding: theme.spacing(0, 1),
...theme.mixins.toolbar,
},
content: {
flexGrow: 1,
- background: "transparent",
+ background: 'transparent',
padding: theme.spacing(3),
- transition: theme.transitions.create("margin", {
+ transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
marginLeft: -drawerWidth,
- "@media (max-width: 580px)": {
- marginLeft: "-100vw",
- padding: "0 10px",
+ '@media (max-width: 580px)': {
+ marginLeft: '-100vw',
+ padding: '0 10px',
},
},
contentShift: {
- transition: theme.transitions.create("margin", {
+ transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
diff --git a/src/assets/Wled.jsx b/src/assets/Wled.jsx
index 6b9cea78..9410d977 100644
--- a/src/assets/Wled.jsx
+++ b/src/assets/Wled.jsx
@@ -1,18 +1,18 @@
-import React from 'react';
-
-const Wled = ({ stroke, strokeWidth, strokeLinejoin, strokeLinecap }) => {
- return (
-
- );
-};
-
-export default Wled;
+import React from 'react';
+
+const Wled = ({
+ stroke, strokeWidth, strokeLinejoin, strokeLinecap,
+}) => (
+
+);
+
+export default Wled;
diff --git a/src/components/Bars/BarBottom.jsx b/src/components/Bars/BarBottom.jsx
index ae847309..8118935a 100644
--- a/src/components/Bars/BarBottom.jsx
+++ b/src/components/Bars/BarBottom.jsx
@@ -1,20 +1,20 @@
-import { makeStyles } from "@material-ui/core/styles";
-import { useState, useEffect } from "react";
-import BottomNavigation from "@material-ui/core/BottomNavigation";
-import BottomNavigationAction from "@material-ui/core/BottomNavigationAction";
-import Settings from "@material-ui/icons/Settings";
-import HomeIcon from "@material-ui/icons/Home";
-import Wallpaper from "@material-ui/icons/Wallpaper";
-import { useLocation } from 'react-router-dom'
+import { makeStyles } from '@material-ui/core/styles';
+import { useState, useEffect } from 'react';
+import BottomNavigation from '@material-ui/core/BottomNavigation';
+import BottomNavigationAction from '@material-ui/core/BottomNavigationAction';
+import Settings from '@material-ui/icons/Settings';
+import HomeIcon from '@material-ui/icons/Home';
+import Wallpaper from '@material-ui/icons/Wallpaper';
+import { useLocation, Link } from 'react-router-dom';
// import SettingsInputSvideoIcon from "@material-ui/icons/SettingsInputSvideo";
-import SettingsInputComponent from "@material-ui/icons/SettingsInputComponent";
-import { Link } from "react-router-dom";
+import SettingsInputComponent from '@material-ui/icons/SettingsInputComponent';
+
const useStyles = makeStyles({
root: {
- width: "100%",
- position: "fixed",
+ width: '100%',
+ position: 'fixed',
bottom: 0,
- background: "#121212",
+ background: '#121212',
},
});
@@ -24,8 +24,8 @@ export default function LabelBottomNavigation() {
const [value, setValue] = useState(pathname);
useEffect(() => {
- setValue(pathname)
- }, [pathname])
+ setValue(pathname);
+ }, [pathname]);
return (