From a81546c02cae25c6386b2f8ba18a4813b0cf5531 Mon Sep 17 00:00:00 2001 From: Juan Carlos Miranda Carruana Date: Wed, 30 Mar 2022 18:20:44 +0200 Subject: [PATCH 1/6] SPF-18: create a template for the different pages in the application --- Frontend/package-lock.json | 868 +++++++++++++++++- Frontend/package.json | 5 + .../public/assets/images/allianz-logo.jpeg | Bin 0 -> 10346 bytes .../public/assets/images/swe-finance-logo.png | Bin 0 -> 12777 bytes Frontend/src/App.css | 42 +- Frontend/src/App.jsx | 18 + Frontend/src/{App.test.tsx => App.test.jsx} | 4 +- Frontend/src/App.tsx | 30 - Frontend/src/components/About.tsx | 5 - Frontend/src/components/Home.tsx | 5 - Frontend/src/components/ScreensTemplate.jsx | 81 ++ .../screens/Dashboard/DashboardScreen.jsx | 26 + Frontend/src/components/screens/Home.jsx | 27 + Frontend/src/index.css | 10 +- Frontend/src/{index.tsx => index.jsx} | 3 +- Frontend/src/logo.svg | 8 +- Frontend/src/reportWebVitals.ts | 20 +- Frontend/src/routes/{index.tsx => index.jsx} | 0 18 files changed, 1070 insertions(+), 82 deletions(-) create mode 100644 Frontend/public/assets/images/allianz-logo.jpeg create mode 100644 Frontend/public/assets/images/swe-finance-logo.png create mode 100644 Frontend/src/App.jsx rename Frontend/src/{App.test.tsx => App.test.jsx} (72%) delete mode 100644 Frontend/src/App.tsx delete mode 100644 Frontend/src/components/About.tsx delete mode 100644 Frontend/src/components/Home.tsx create mode 100644 Frontend/src/components/ScreensTemplate.jsx create mode 100644 Frontend/src/components/screens/Dashboard/DashboardScreen.jsx create mode 100644 Frontend/src/components/screens/Home.jsx rename Frontend/src/{index.tsx => index.jsx} (82%) rename Frontend/src/routes/{index.tsx => index.jsx} (100%) diff --git a/Frontend/package-lock.json b/Frontend/package-lock.json index 5a1a50ad..047dd7e4 100644 --- a/Frontend/package-lock.json +++ b/Frontend/package-lock.json @@ -1,13 +1,17 @@ { - "name": "finanzen", + "name": "finanzen-projekt", "version": "0.1.0", "lockfileVersion": 2, "requires": true, "packages": { "": { - "name": "finanzen", + "name": "finanzen-projekt", "version": "0.1.0", "dependencies": { + "@emotion/react": "^11.8.2", + "@emotion/styled": "^11.8.1", + "@mui/icons-material": "^5.5.1", + "@mui/material": "^5.5.2", "@testing-library/jest-dom": "^5.16.2", "@testing-library/react": "^12.1.4", "@testing-library/user-event": "^13.5.0", @@ -15,8 +19,11 @@ "@types/node": "^16.11.26", "@types/react": "^17.0.40", "@types/react-dom": "^17.0.13", + "bootstrap": "^5.1.3", + "prop-types": "^15.8.1", "react": "^17.0.2", "react-dom": "^17.0.2", + "react-router-dom": "^6.2.2", "react-scripts": "5.0.0", "typescript": "^4.6.2", "web-vitals": "^2.1.4" @@ -1975,6 +1982,177 @@ "postcss": "^8.3" } }, + "node_modules/@emotion/babel-plugin": { + "version": "11.7.2", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.7.2.tgz", + "integrity": "sha512-6mGSCWi9UzXut/ZAN6lGFu33wGR3SJisNl3c0tvlmb8XChH1b2SUvxvnOh7hvLpqyRdHHU9AiazV3Cwbk5SXKQ==", + "dependencies": { + "@babel/helper-module-imports": "^7.12.13", + "@babel/plugin-syntax-jsx": "^7.12.13", + "@babel/runtime": "^7.13.10", + "@emotion/hash": "^0.8.0", + "@emotion/memoize": "^0.7.5", + "@emotion/serialize": "^1.0.2", + "babel-plugin-macros": "^2.6.1", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.0.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/babel-plugin-macros": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz", + "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==", + "dependencies": { + "@babel/runtime": "^7.7.2", + "cosmiconfig": "^6.0.0", + "resolve": "^1.12.0" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@emotion/babel-plugin/node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@emotion/cache": { + "version": "11.7.1", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.7.1.tgz", + "integrity": "sha512-r65Zy4Iljb8oyjtLeCuBH8Qjiy107dOYC6SJq7g7GV5UCQWMObY4SJDPGFjiiVpPrOJ2hmJOoBiYTC7hwx9E2A==", + "dependencies": { + "@emotion/memoize": "^0.7.4", + "@emotion/sheet": "^1.1.0", + "@emotion/utils": "^1.0.0", + "@emotion/weak-memoize": "^0.2.5", + "stylis": "4.0.13" + } + }, + "node_modules/@emotion/hash": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", + "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" + }, + "node_modules/@emotion/is-prop-valid": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.1.2.tgz", + "integrity": "sha512-3QnhqeL+WW88YjYbQL5gUIkthuMw7a0NGbZ7wfFVk2kg/CK5w8w5FFa0RzWjyY1+sujN0NWbtSHH6OJmWHtJpQ==", + "dependencies": { + "@emotion/memoize": "^0.7.4" + } + }, + "node_modules/@emotion/memoize": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.5.tgz", + "integrity": "sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==" + }, + "node_modules/@emotion/react": { + "version": "11.8.2", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.8.2.tgz", + "integrity": "sha512-+1bcHBaNJv5nkIIgnGKVsie3otS0wF9f1T1hteF3WeVvMNQEtfZ4YyFpnphGoot3ilU/wWMgP2SgIDuHLE/wAA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@emotion/babel-plugin": "^11.7.1", + "@emotion/cache": "^11.7.1", + "@emotion/serialize": "^1.0.2", + "@emotion/utils": "^1.1.0", + "@emotion/weak-memoize": "^0.2.5", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/serialize": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.0.2.tgz", + "integrity": "sha512-95MgNJ9+/ajxU7QIAruiOAdYNjxZX7G2mhgrtDWswA21VviYIRP1R5QilZ/bDY42xiKsaktP4egJb3QdYQZi1A==", + "dependencies": { + "@emotion/hash": "^0.8.0", + "@emotion/memoize": "^0.7.4", + "@emotion/unitless": "^0.7.5", + "@emotion/utils": "^1.0.0", + "csstype": "^3.0.2" + } + }, + "node_modules/@emotion/sheet": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.1.0.tgz", + "integrity": "sha512-u0AX4aSo25sMAygCuQTzS+HsImZFuS8llY8O7b9MDRzbJM0kVJlAz6KNDqcG7pOuQZJmj/8X/rAW+66kMnMW+g==" + }, + "node_modules/@emotion/styled": { + "version": "11.8.1", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.8.1.tgz", + "integrity": "sha512-OghEVAYBZMpEquHZwuelXcRjRJQOVayvbmNR0zr174NHdmMgrNkLC6TljKC5h9lZLkN5WGrdUcrKlOJ4phhoTQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@emotion/babel-plugin": "^11.7.1", + "@emotion/is-prop-valid": "^1.1.2", + "@emotion/serialize": "^1.0.2", + "@emotion/utils": "^1.1.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "@emotion/react": "^11.0.0-rc.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + }, + "node_modules/@emotion/utils": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.1.0.tgz", + "integrity": "sha512-iRLa/Y4Rs5H/f2nimczYmS5kFJEbpiVvgN3XVfZ022IYhuNA1IRSHEizcof88LtCTXtl9S2Cxt32KgaXEu72JQ==" + }, + "node_modules/@emotion/weak-memoize": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz", + "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==" + }, "node_modules/@eslint/eslintrc": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", @@ -2727,6 +2905,236 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@mui/base": { + "version": "5.0.0-alpha.73", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.73.tgz", + "integrity": "sha512-TEUCIIEAWrngAqpIa+dY3nofGSNj70LC3KC9WcCzyXPK3M4AG2GNi7ndd/g/0DtC55kbxrudzlV8TG3vrB2Vjw==", + "dependencies": { + "@babel/runtime": "^7.17.2", + "@emotion/is-prop-valid": "^1.1.2", + "@mui/utils": "^5.4.4", + "@popperjs/core": "^2.11.4", + "clsx": "^1.1.1", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@types/react": "^16.8.6 || ^17.0.0", + "react": "^17.0.0", + "react-dom": "^17.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/icons-material": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.5.1.tgz", + "integrity": "sha512-40f68p5+Yhq3dCn3QYHqQt5RETPyR3AkDw+fma8PtcjqvZ+d+jF84kFmT6NqwA3he7TlwluEtkyAmPzUE4uPdA==", + "dependencies": { + "@babel/runtime": "^7.17.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@mui/material": "^5.0.0", + "@types/react": "^16.8.6 || ^17.0.0", + "react": "^17.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/material": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.5.2.tgz", + "integrity": "sha512-r4p1u9eDlSqW3TS/Iq9yolifWHpuW6e0BSeqEJW3EEIcKfPVVk4WNUNJ+s8DtN7dBoDcveXxcQVVjYXTIv1d9g==", + "dependencies": { + "@babel/runtime": "^7.17.2", + "@mui/base": "5.0.0-alpha.73", + "@mui/system": "^5.5.2", + "@mui/types": "^7.1.3", + "@mui/utils": "^5.4.4", + "@types/react-transition-group": "^4.4.4", + "clsx": "^1.1.1", + "csstype": "^3.0.11", + "hoist-non-react-statics": "^3.3.2", + "prop-types": "^15.7.2", + "react-is": "^17.0.2", + "react-transition-group": "^4.4.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^16.8.6 || ^17.0.0", + "react": "^17.0.0", + "react-dom": "^17.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/private-theming": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.4.4.tgz", + "integrity": "sha512-V/gxttr6736yJoU9q+4xxXsa0K/w9Hn9pg99zsOHt7i/O904w2CX5NHh5WqDXtoUzVcayLF0RB17yr6l79CE+A==", + "dependencies": { + "@babel/runtime": "^7.17.2", + "@mui/utils": "^5.4.4", + "prop-types": "^15.7.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@types/react": "^16.8.6 || ^17.0.0", + "react": "^17.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/styled-engine": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.5.2.tgz", + "integrity": "sha512-jkz5AHHbA43akBo5L3y1X1/X0f+RvXvCp3eXKt+iOf3qnKSAausbtlVz7gBbC4xIWDnP1Jb/6T+t/0/7gObRYA==", + "dependencies": { + "@babel/runtime": "^7.17.2", + "@emotion/cache": "^11.7.1", + "prop-types": "^15.7.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "react": "^17.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + } + } + }, + "node_modules/@mui/system": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.5.2.tgz", + "integrity": "sha512-OATYFI36nliud8xh0u+ZNqDo0jWjxpO0vZLlzqNB+ZtkR5Q/+1X3GgboA9ruiB8Rq+udnJlMBQNGW0qqjvAOHQ==", + "dependencies": { + "@babel/runtime": "^7.17.2", + "@mui/private-theming": "^5.4.4", + "@mui/styled-engine": "^5.5.2", + "@mui/types": "^7.1.3", + "@mui/utils": "^5.4.4", + "clsx": "^1.1.1", + "csstype": "^3.0.11", + "prop-types": "^15.7.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "@emotion/react": "^11.5.0", + "@emotion/styled": "^11.3.0", + "@types/react": "^16.8.6 || ^17.0.0", + "react": "^17.0.0" + }, + "peerDependenciesMeta": { + "@emotion/react": { + "optional": true + }, + "@emotion/styled": { + "optional": true + }, + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/types": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.1.3.tgz", + "integrity": "sha512-DDF0UhMBo4Uezlk+6QxrlDbchF79XG6Zs0zIewlR4c0Dt6GKVFfUtzPtHCH1tTbcSlq/L2bGEdiaoHBJ9Y1gSA==", + "peerDependencies": { + "@types/react": "*" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@mui/utils": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.4.4.tgz", + "integrity": "sha512-hfYIXEuhc2mXMGN5nUPis8beH6uE/zl3uMWJcyHX0/LN/+QxO9zhYuV6l8AsAaphHFyS/fBv0SW3Nid7jw5hKQ==", + "dependencies": { + "@babel/runtime": "^7.17.2", + "@types/prop-types": "^15.7.4", + "@types/react-is": "^16.7.1 || ^17.0.0", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui" + }, + "peerDependencies": { + "react": "^17.0.0" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -2816,6 +3224,15 @@ "node": ">= 8" } }, + "node_modules/@popperjs/core": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.4.tgz", + "integrity": "sha512-q/ytXxO5NKvyT37pmisQAItCFqA7FD/vNb8dgaJy3/630Fsc+Mz9/9f2SziBoIZ30TJooXyTwZmhi1zjXmObYg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, "node_modules/@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -3596,6 +4013,22 @@ "@types/react": "*" } }, + "node_modules/@types/react-is": { + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz", + "integrity": "sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==", + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-transition-group": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.4.tgz", + "integrity": "sha512-7gAPz7anVK5xzbeQW9wFBDg7G++aPLAFY0QaSMOou9rJZpbuI58WAuJrgu+qR92l61grlnCUe7AFX8KGahAgug==", + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -4886,6 +5319,18 @@ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" }, + "node_modules/bootstrap": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.1.3.tgz", + "integrity": "sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/bootstrap" + }, + "peerDependencies": { + "@popperjs/core": "^2.10.2" + } + }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -5178,6 +5623,14 @@ "wrap-ansi": "^7.0.0" } }, + "node_modules/clsx": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz", + "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==", + "engines": { + "node": ">=6" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -6162,6 +6615,15 @@ "utila": "~0.4" } }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "node_modules/dom-serializer": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", @@ -7443,6 +7905,11 @@ "url": "https://github.com/avajs/find-cache-dir?sponsor=1" } }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -7991,6 +8458,27 @@ "he": "bin/he" } }, + "node_modules/history": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz", + "integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==", + "dependencies": { + "@babel/runtime": "^7.7.6" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -13191,6 +13679,30 @@ "node": ">=0.10.0" } }, + "node_modules/react-router": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.2.tgz", + "integrity": "sha512-/MbxyLzd7Q7amp4gDOGaYvXwhEojkJD5BtExkuKmj39VEE0m3l/zipf6h2WIB2jyAO0lI6NGETh4RDcktRm4AQ==", + "dependencies": { + "history": "^5.2.0" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.2.2.tgz", + "integrity": "sha512-AtYEsAST7bDD4dLSQHDnk/qxWLJdad5t1HFa1qJyUrCeGgEuCSw0VB/27ARbF9Fi/W5598ujvJOm3ujUCVzuYQ==", + "dependencies": { + "history": "^5.2.0", + "react-router": "6.2.2" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, "node_modules/react-scripts": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.0.tgz", @@ -13263,6 +13775,21 @@ } } }, + "node_modules/react-transition-group": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz", + "integrity": "sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, "node_modules/readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -14340,6 +14867,11 @@ "postcss": "^8.2.15" } }, + "node_modules/stylis": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz", + "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==" + }, "node_modules/supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", @@ -17351,6 +17883,142 @@ "postcss-value-parser": "^4.2.0" } }, + "@emotion/babel-plugin": { + "version": "11.7.2", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.7.2.tgz", + "integrity": "sha512-6mGSCWi9UzXut/ZAN6lGFu33wGR3SJisNl3c0tvlmb8XChH1b2SUvxvnOh7hvLpqyRdHHU9AiazV3Cwbk5SXKQ==", + "requires": { + "@babel/helper-module-imports": "^7.12.13", + "@babel/plugin-syntax-jsx": "^7.12.13", + "@babel/runtime": "^7.13.10", + "@emotion/hash": "^0.8.0", + "@emotion/memoize": "^0.7.5", + "@emotion/serialize": "^1.0.2", + "babel-plugin-macros": "^2.6.1", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.0.13" + }, + "dependencies": { + "babel-plugin-macros": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz", + "integrity": "sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg==", + "requires": { + "@babel/runtime": "^7.7.2", + "cosmiconfig": "^6.0.0", + "resolve": "^1.12.0" + } + }, + "cosmiconfig": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-6.0.0.tgz", + "integrity": "sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg==", + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.7.2" + } + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" + } + } + }, + "@emotion/cache": { + "version": "11.7.1", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.7.1.tgz", + "integrity": "sha512-r65Zy4Iljb8oyjtLeCuBH8Qjiy107dOYC6SJq7g7GV5UCQWMObY4SJDPGFjiiVpPrOJ2hmJOoBiYTC7hwx9E2A==", + "requires": { + "@emotion/memoize": "^0.7.4", + "@emotion/sheet": "^1.1.0", + "@emotion/utils": "^1.0.0", + "@emotion/weak-memoize": "^0.2.5", + "stylis": "4.0.13" + } + }, + "@emotion/hash": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", + "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" + }, + "@emotion/is-prop-valid": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.1.2.tgz", + "integrity": "sha512-3QnhqeL+WW88YjYbQL5gUIkthuMw7a0NGbZ7wfFVk2kg/CK5w8w5FFa0RzWjyY1+sujN0NWbtSHH6OJmWHtJpQ==", + "requires": { + "@emotion/memoize": "^0.7.4" + } + }, + "@emotion/memoize": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.5.tgz", + "integrity": "sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==" + }, + "@emotion/react": { + "version": "11.8.2", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.8.2.tgz", + "integrity": "sha512-+1bcHBaNJv5nkIIgnGKVsie3otS0wF9f1T1hteF3WeVvMNQEtfZ4YyFpnphGoot3ilU/wWMgP2SgIDuHLE/wAA==", + "requires": { + "@babel/runtime": "^7.13.10", + "@emotion/babel-plugin": "^11.7.1", + "@emotion/cache": "^11.7.1", + "@emotion/serialize": "^1.0.2", + "@emotion/utils": "^1.1.0", + "@emotion/weak-memoize": "^0.2.5", + "hoist-non-react-statics": "^3.3.1" + } + }, + "@emotion/serialize": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.0.2.tgz", + "integrity": "sha512-95MgNJ9+/ajxU7QIAruiOAdYNjxZX7G2mhgrtDWswA21VviYIRP1R5QilZ/bDY42xiKsaktP4egJb3QdYQZi1A==", + "requires": { + "@emotion/hash": "^0.8.0", + "@emotion/memoize": "^0.7.4", + "@emotion/unitless": "^0.7.5", + "@emotion/utils": "^1.0.0", + "csstype": "^3.0.2" + } + }, + "@emotion/sheet": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.1.0.tgz", + "integrity": "sha512-u0AX4aSo25sMAygCuQTzS+HsImZFuS8llY8O7b9MDRzbJM0kVJlAz6KNDqcG7pOuQZJmj/8X/rAW+66kMnMW+g==" + }, + "@emotion/styled": { + "version": "11.8.1", + "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.8.1.tgz", + "integrity": "sha512-OghEVAYBZMpEquHZwuelXcRjRJQOVayvbmNR0zr174NHdmMgrNkLC6TljKC5h9lZLkN5WGrdUcrKlOJ4phhoTQ==", + "requires": { + "@babel/runtime": "^7.13.10", + "@emotion/babel-plugin": "^11.7.1", + "@emotion/is-prop-valid": "^1.1.2", + "@emotion/serialize": "^1.0.2", + "@emotion/utils": "^1.1.0" + } + }, + "@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + }, + "@emotion/utils": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.1.0.tgz", + "integrity": "sha512-iRLa/Y4Rs5H/f2nimczYmS5kFJEbpiVvgN3XVfZ022IYhuNA1IRSHEizcof88LtCTXtl9S2Cxt32KgaXEu72JQ==" + }, + "@emotion/weak-memoize": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz", + "integrity": "sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==" + }, "@eslint/eslintrc": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz", @@ -17908,6 +18576,100 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "@mui/base": { + "version": "5.0.0-alpha.73", + "resolved": "https://registry.npmjs.org/@mui/base/-/base-5.0.0-alpha.73.tgz", + "integrity": "sha512-TEUCIIEAWrngAqpIa+dY3nofGSNj70LC3KC9WcCzyXPK3M4AG2GNi7ndd/g/0DtC55kbxrudzlV8TG3vrB2Vjw==", + "requires": { + "@babel/runtime": "^7.17.2", + "@emotion/is-prop-valid": "^1.1.2", + "@mui/utils": "^5.4.4", + "@popperjs/core": "^2.11.4", + "clsx": "^1.1.1", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + } + }, + "@mui/icons-material": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.5.1.tgz", + "integrity": "sha512-40f68p5+Yhq3dCn3QYHqQt5RETPyR3AkDw+fma8PtcjqvZ+d+jF84kFmT6NqwA3he7TlwluEtkyAmPzUE4uPdA==", + "requires": { + "@babel/runtime": "^7.17.2" + } + }, + "@mui/material": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.5.2.tgz", + "integrity": "sha512-r4p1u9eDlSqW3TS/Iq9yolifWHpuW6e0BSeqEJW3EEIcKfPVVk4WNUNJ+s8DtN7dBoDcveXxcQVVjYXTIv1d9g==", + "requires": { + "@babel/runtime": "^7.17.2", + "@mui/base": "5.0.0-alpha.73", + "@mui/system": "^5.5.2", + "@mui/types": "^7.1.3", + "@mui/utils": "^5.4.4", + "@types/react-transition-group": "^4.4.4", + "clsx": "^1.1.1", + "csstype": "^3.0.11", + "hoist-non-react-statics": "^3.3.2", + "prop-types": "^15.7.2", + "react-is": "^17.0.2", + "react-transition-group": "^4.4.2" + } + }, + "@mui/private-theming": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.4.4.tgz", + "integrity": "sha512-V/gxttr6736yJoU9q+4xxXsa0K/w9Hn9pg99zsOHt7i/O904w2CX5NHh5WqDXtoUzVcayLF0RB17yr6l79CE+A==", + "requires": { + "@babel/runtime": "^7.17.2", + "@mui/utils": "^5.4.4", + "prop-types": "^15.7.2" + } + }, + "@mui/styled-engine": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.5.2.tgz", + "integrity": "sha512-jkz5AHHbA43akBo5L3y1X1/X0f+RvXvCp3eXKt+iOf3qnKSAausbtlVz7gBbC4xIWDnP1Jb/6T+t/0/7gObRYA==", + "requires": { + "@babel/runtime": "^7.17.2", + "@emotion/cache": "^11.7.1", + "prop-types": "^15.7.2" + } + }, + "@mui/system": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.5.2.tgz", + "integrity": "sha512-OATYFI36nliud8xh0u+ZNqDo0jWjxpO0vZLlzqNB+ZtkR5Q/+1X3GgboA9ruiB8Rq+udnJlMBQNGW0qqjvAOHQ==", + "requires": { + "@babel/runtime": "^7.17.2", + "@mui/private-theming": "^5.4.4", + "@mui/styled-engine": "^5.5.2", + "@mui/types": "^7.1.3", + "@mui/utils": "^5.4.4", + "clsx": "^1.1.1", + "csstype": "^3.0.11", + "prop-types": "^15.7.2" + } + }, + "@mui/types": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.1.3.tgz", + "integrity": "sha512-DDF0UhMBo4Uezlk+6QxrlDbchF79XG6Zs0zIewlR4c0Dt6GKVFfUtzPtHCH1tTbcSlq/L2bGEdiaoHBJ9Y1gSA==", + "requires": {} + }, + "@mui/utils": { + "version": "5.4.4", + "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.4.4.tgz", + "integrity": "sha512-hfYIXEuhc2mXMGN5nUPis8beH6uE/zl3uMWJcyHX0/LN/+QxO9zhYuV6l8AsAaphHFyS/fBv0SW3Nid7jw5hKQ==", + "requires": { + "@babel/runtime": "^7.17.2", + "@types/prop-types": "^15.7.4", + "@types/react-is": "^16.7.1 || ^17.0.0", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + } + }, "@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -17954,6 +18716,11 @@ } } }, + "@popperjs/core": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.4.tgz", + "integrity": "sha512-q/ytXxO5NKvyT37pmisQAItCFqA7FD/vNb8dgaJy3/630Fsc+Mz9/9f2SziBoIZ30TJooXyTwZmhi1zjXmObYg==" + }, "@rollup/plugin-babel": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz", @@ -18541,6 +19308,22 @@ "@types/react": "*" } }, + "@types/react-is": { + "version": "17.0.3", + "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.3.tgz", + "integrity": "sha512-aBTIWg1emtu95bLTLx0cpkxwGW3ueZv71nE2YFBpL8k/z5czEW8yYpOo8Dp+UUAFAtKwNaOsh/ioSeQnWlZcfw==", + "requires": { + "@types/react": "*" + } + }, + "@types/react-transition-group": { + "version": "4.4.4", + "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.4.tgz", + "integrity": "sha512-7gAPz7anVK5xzbeQW9wFBDg7G++aPLAFY0QaSMOou9rJZpbuI58WAuJrgu+qR92l61grlnCUe7AFX8KGahAgug==", + "requires": { + "@types/react": "*" + } + }, "@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -19510,6 +20293,12 @@ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=" }, + "bootstrap": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.1.3.tgz", + "integrity": "sha512-fcQztozJ8jToQWXxVuEyXWW+dSo8AiXWKwiSSrKWsRB/Qt+Ewwza+JWoLKiTuQLaEPhdNAJ7+Dosc9DOIqNy7Q==", + "requires": {} + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -19721,6 +20510,11 @@ "wrap-ansi": "^7.0.0" } }, + "clsx": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz", + "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==" + }, "co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -20443,6 +21237,15 @@ "utila": "~0.4" } }, + "dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "requires": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, "dom-serializer": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", @@ -21387,6 +22190,11 @@ "pkg-dir": "^4.1.0" } }, + "find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -21754,6 +22562,29 @@ "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==" }, + "history": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz", + "integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==", + "requires": { + "@babel/runtime": "^7.7.6" + } + }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + } + } + }, "hoopy": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", @@ -25379,6 +26210,23 @@ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==" }, + "react-router": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.2.tgz", + "integrity": "sha512-/MbxyLzd7Q7amp4gDOGaYvXwhEojkJD5BtExkuKmj39VEE0m3l/zipf6h2WIB2jyAO0lI6NGETh4RDcktRm4AQ==", + "requires": { + "history": "^5.2.0" + } + }, + "react-router-dom": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.2.2.tgz", + "integrity": "sha512-AtYEsAST7bDD4dLSQHDnk/qxWLJdad5t1HFa1qJyUrCeGgEuCSw0VB/27ARbF9Fi/W5598ujvJOm3ujUCVzuYQ==", + "requires": { + "history": "^5.2.0", + "react-router": "6.2.2" + } + }, "react-scripts": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.0.tgz", @@ -25434,6 +26282,17 @@ "workbox-webpack-plugin": "^6.4.1" } }, + "react-transition-group": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz", + "integrity": "sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==", + "requires": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + } + }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -26229,6 +27088,11 @@ "postcss-selector-parser": "^6.0.4" } }, + "stylis": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz", + "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==" + }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", diff --git a/Frontend/package.json b/Frontend/package.json index a0fcdeda..407b7508 100644 --- a/Frontend/package.json +++ b/Frontend/package.json @@ -3,6 +3,10 @@ "version": "0.1.0", "private": true, "dependencies": { + "@emotion/react": "^11.8.2", + "@emotion/styled": "^11.8.1", + "@mui/icons-material": "^5.5.1", + "@mui/material": "^5.5.2", "@testing-library/jest-dom": "^5.16.2", "@testing-library/react": "^12.1.4", "@testing-library/user-event": "^13.5.0", @@ -11,6 +15,7 @@ "@types/react": "^17.0.40", "@types/react-dom": "^17.0.13", "bootstrap": "^5.1.3", + "prop-types": "^15.8.1", "react": "^17.0.2", "react-dom": "^17.0.2", "react-router-dom": "^6.2.2", diff --git a/Frontend/public/assets/images/allianz-logo.jpeg b/Frontend/public/assets/images/allianz-logo.jpeg new file mode 100644 index 0000000000000000000000000000000000000000..47fe591fcc06cfa4252108e77ddd7561f14b08b3 GIT binary patch literal 10346 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 literal 0 HcmV?d00001 diff --git a/Frontend/src/App.css b/Frontend/src/App.css index 74b5e053..78b8850c 100644 --- a/Frontend/src/App.css +++ b/Frontend/src/App.css @@ -1,38 +1,38 @@ .App { - text-align: center; + text-align: center; } .App-logo { - height: 40vmin; - pointer-events: none; + height: 40vmin; + pointer-events: none; } @media (prefers-reduced-motion: no-preference) { - .App-logo { - animation: App-logo-spin infinite 20s linear; - } + .App-logo { + animation: App-logo-spin infinite 20s linear; + } } .App-header { - background-color: #282c34; - min-height: 100vh; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - font-size: calc(10px + 2vmin); - color: white; + background-color: #282c34; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-size: calc(10px + 2vmin); + color: white; } .App-link { - color: #61dafb; + color: #61dafb; } @keyframes App-logo-spin { - from { - transform: rotate(0deg); - } - to { - transform: rotate(360deg); - } + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } } diff --git a/Frontend/src/App.jsx b/Frontend/src/App.jsx new file mode 100644 index 00000000..01065a8b --- /dev/null +++ b/Frontend/src/App.jsx @@ -0,0 +1,18 @@ +import React, {Suspense} from 'react'; +import {BrowserRouter as Router} from 'react-router-dom'; +import AppRoutes from './routes'; +import './App.css'; + +/** + * App root component with link navigations and routes + * @constructor + */ +const App = () => ( + + Loading...}> + + + +); + +export default App; diff --git a/Frontend/src/App.test.tsx b/Frontend/src/App.test.jsx similarity index 72% rename from Frontend/src/App.test.tsx rename to Frontend/src/App.test.jsx index 2a68616d..91a8cdfb 100644 --- a/Frontend/src/App.test.tsx +++ b/Frontend/src/App.test.jsx @@ -1,9 +1,9 @@ import React from 'react'; -import { render, screen } from '@testing-library/react'; +import {render, screen} from '@testing-library/react'; import App from './App'; test('renders learn react link', () => { - render(); + render(); const linkElement = screen.getByText(/learn react/i); expect(linkElement).toBeInTheDocument(); }); diff --git a/Frontend/src/App.tsx b/Frontend/src/App.tsx deleted file mode 100644 index bc55e586..00000000 --- a/Frontend/src/App.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import React, { Suspense } from 'react'; -import { BrowserRouter as Router, Link } from 'react-router-dom'; -import AppRoutes from './routes/index'; -import './App.css'; - -/** - * App root component with link navigations and routes - * @constructor - */ -const App = () => ( - -
- - Loading...
}> - - - -
- ); - -export default App; diff --git a/Frontend/src/components/About.tsx b/Frontend/src/components/About.tsx deleted file mode 100644 index f3689675..00000000 --- a/Frontend/src/components/About.tsx +++ /dev/null @@ -1,5 +0,0 @@ -const About = () => ( -

Dummy Data in About Section!

-); - -export default About; \ No newline at end of file diff --git a/Frontend/src/components/Home.tsx b/Frontend/src/components/Home.tsx deleted file mode 100644 index 2bc41e34..00000000 --- a/Frontend/src/components/Home.tsx +++ /dev/null @@ -1,5 +0,0 @@ -const Home = () => ( -

Welcome to Finance App SWE- DHBW!

-); - -export default Home; \ No newline at end of file diff --git a/Frontend/src/components/ScreensTemplate.jsx b/Frontend/src/components/ScreensTemplate.jsx new file mode 100644 index 00000000..f038dd4a --- /dev/null +++ b/Frontend/src/components/ScreensTemplate.jsx @@ -0,0 +1,81 @@ +import React, {useState, useEffect} from 'react'; +import PropTypes from 'prop-types'; +import AppBar from '@mui/material/AppBar'; +import Box from '@mui/material/Box'; +import CssBaseline from '@mui/material/CssBaseline'; +import MenuIcon from '@mui/icons-material/Menu'; +import IconButton from '@mui/material/IconButton'; +import Toolbar from '@mui/material/Toolbar'; +import SideNavLeft from "./common/SideNavLeft"; + +const drawerWidth = 12; // This is the value in rem units, for responsiveness +/** + * Drawer navigation menu throughout the app + * @param props + * @returns {JSX.Element} + * @constructor + */ +const ScreensTemplate = (props) => { + const [openInMobile, setOpenInMobile] = useState(false); + + const handleDrawerToggle = () => { + setOpenInMobile(!openInMobile); + }; + + return ( + + + + + + + + + {props.headerComponent()} + + + + + + + + {props.bodyComponent()} + + + ); +} + +ScreensTemplate.propTypes = { + headerComponent: PropTypes.func, + bodyComponent: PropTypes.func, + selectedNavLinkIndex: PropTypes.number +}; + +export default ScreensTemplate; \ No newline at end of file diff --git a/Frontend/src/components/screens/Dashboard/DashboardScreen.jsx b/Frontend/src/components/screens/Dashboard/DashboardScreen.jsx new file mode 100644 index 00000000..b7d7a912 --- /dev/null +++ b/Frontend/src/components/screens/Dashboard/DashboardScreen.jsx @@ -0,0 +1,26 @@ +import React from 'react'; +import ScreensTemplate from '../ScreensTemplate'; +import { SearchField } from '../common/index'; + +const Dashboard = () => { + const renderHeader = () => ( + + ); + + const renderBody = () => ( +

Welcome to Dashboard!

+ ); + + return ( + + + + + ); +} + +export default Dashboard; \ No newline at end of file diff --git a/Frontend/src/components/screens/Home.jsx b/Frontend/src/components/screens/Home.jsx new file mode 100644 index 00000000..7df6389e --- /dev/null +++ b/Frontend/src/components/screens/Home.jsx @@ -0,0 +1,27 @@ +import React from 'react'; +import ScreensTemplate from "./ScreensTemplate"; +import Typography from "@mui/material/Typography"; + +const Home = () => { + const renderHeader = () => ( + + Search Bar + + ); + + const renderBody = () => ( +

Welcome to Finance App SWE- DHBW!

+ ); + + return ( + + + + + ); +} + +export default Home; \ No newline at end of file diff --git a/Frontend/src/index.css b/Frontend/src/index.css index ec2585e8..da92873c 100644 --- a/Frontend/src/index.css +++ b/Frontend/src/index.css @@ -1,13 +1,13 @@ body { - margin: 0; - font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', + margin: 0; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; } code { - font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', + font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', monospace; } diff --git a/Frontend/src/index.tsx b/Frontend/src/index.jsx similarity index 82% rename from Frontend/src/index.tsx rename to Frontend/src/index.jsx index 8d48bcea..daa4fb6c 100644 --- a/Frontend/src/index.tsx +++ b/Frontend/src/index.jsx @@ -1,5 +1,6 @@ import React from 'react'; import ReactDOM from 'react-dom'; +import 'bootstrap/dist/css/bootstrap.min.css'; import './index.css'; import App from './App'; @@ -8,7 +9,7 @@ import App from './App'; */ ReactDOM.render( - + , document.getElementById('root') ); diff --git a/Frontend/src/logo.svg b/Frontend/src/logo.svg index 9dfc1c05..63a2ad5f 100644 --- a/Frontend/src/logo.svg +++ b/Frontend/src/logo.svg @@ -1 +1,7 @@ - \ No newline at end of file + + + + + + + \ No newline at end of file diff --git a/Frontend/src/reportWebVitals.ts b/Frontend/src/reportWebVitals.ts index 49a2a16e..e28f08aa 100644 --- a/Frontend/src/reportWebVitals.ts +++ b/Frontend/src/reportWebVitals.ts @@ -1,15 +1,15 @@ -import { ReportHandler } from 'web-vitals'; +import {ReportHandler} from 'web-vitals'; const reportWebVitals = (onPerfEntry?: ReportHandler) => { - if (onPerfEntry && onPerfEntry instanceof Function) { - import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { - getCLS(onPerfEntry); - getFID(onPerfEntry); - getFCP(onPerfEntry); - getLCP(onPerfEntry); - getTTFB(onPerfEntry); - }); - } + if (onPerfEntry && onPerfEntry instanceof Function) { + import('web-vitals').then(({getCLS, getFID, getFCP, getLCP, getTTFB}) => { + getCLS(onPerfEntry); + getFID(onPerfEntry); + getFCP(onPerfEntry); + getLCP(onPerfEntry); + getTTFB(onPerfEntry); + }); + } }; export default reportWebVitals; diff --git a/Frontend/src/routes/index.tsx b/Frontend/src/routes/index.jsx similarity index 100% rename from Frontend/src/routes/index.tsx rename to Frontend/src/routes/index.jsx From e9afb265cb7a887149648e0aceb0ae10138f2e46 Mon Sep 17 00:00:00 2001 From: Juan Carlos Miranda Carruana Date: Wed, 30 Mar 2022 18:22:29 +0200 Subject: [PATCH 2/6] SPF-18: create some screens with only a header --- .../screens/Dashboard/DashboardScreen.jsx | 39 ++++++++++--------- Frontend/src/components/screens/Home.jsx | 37 +++++++++--------- .../screens/Settings/SettingsScreen.jsx | 28 +++++++++++++ Frontend/src/components/screens/index.jsx | 11 ++++++ 4 files changed, 78 insertions(+), 37 deletions(-) create mode 100644 Frontend/src/components/screens/Settings/SettingsScreen.jsx create mode 100644 Frontend/src/components/screens/index.jsx diff --git a/Frontend/src/components/screens/Dashboard/DashboardScreen.jsx b/Frontend/src/components/screens/Dashboard/DashboardScreen.jsx index b7d7a912..db272ab2 100644 --- a/Frontend/src/components/screens/Dashboard/DashboardScreen.jsx +++ b/Frontend/src/components/screens/Dashboard/DashboardScreen.jsx @@ -1,26 +1,27 @@ import React from 'react'; -import ScreensTemplate from '../ScreensTemplate'; -import { SearchField } from '../common/index'; +import ScreensTemplate from '../../ScreensTemplate'; +import {SearchField} from '../../common'; -const Dashboard = () => { - const renderHeader = () => ( - - ); +const DashboardScreen = () => { + const renderHeader = () => ( + + ); - const renderBody = () => ( -

Welcome to Dashboard!

- ); + const renderBody = () => ( +

Welcome to Dashboard!

+ ); - return ( - - - + return ( + + + - ); + ); } -export default Dashboard; \ No newline at end of file +export default DashboardScreen; \ No newline at end of file diff --git a/Frontend/src/components/screens/Home.jsx b/Frontend/src/components/screens/Home.jsx index 7df6389e..2bf6040f 100644 --- a/Frontend/src/components/screens/Home.jsx +++ b/Frontend/src/components/screens/Home.jsx @@ -1,27 +1,28 @@ import React from 'react'; -import ScreensTemplate from "./ScreensTemplate"; -import Typography from "@mui/material/Typography"; +import ScreensTemplate from '../ScreensTemplate'; +import Typography from '@mui/material/Typography'; const Home = () => { - const renderHeader = () => ( - - Search Bar - - ); + const renderHeader = () => ( + + Header of Home Page + + ); - const renderBody = () => ( -

Welcome to Finance App SWE- DHBW!

- ); + const renderBody = () => ( +

Welcome to Finance App SWE- DHBW!

+ ); - return ( - - - + return ( + + + - ); + ); } export default Home; \ No newline at end of file diff --git a/Frontend/src/components/screens/Settings/SettingsScreen.jsx b/Frontend/src/components/screens/Settings/SettingsScreen.jsx new file mode 100644 index 00000000..68cd84c9 --- /dev/null +++ b/Frontend/src/components/screens/Settings/SettingsScreen.jsx @@ -0,0 +1,28 @@ +import React from 'react'; +import ScreensTemplate from '../../ScreensTemplate'; +import Typography from '@mui/material/Typography'; + +const SettingsScreen = () => { + const renderHeader = () => ( + + Header of Settings Page + + ); + + const renderBody = () => ( +

Welcome to Settings!

+ ); + + return ( + + + + + ); +} + +export default SettingsScreen; \ No newline at end of file diff --git a/Frontend/src/components/screens/index.jsx b/Frontend/src/components/screens/index.jsx new file mode 100644 index 00000000..42a7e7c9 --- /dev/null +++ b/Frontend/src/components/screens/index.jsx @@ -0,0 +1,11 @@ +import Home from './Home'; +import DashboardScreen from './Dashboard/DashboardScreen'; +import WatchListsScreen from './WatchLists/WatchListsScreen'; +import SettingsScreen from './Settings/SettingsScreen'; + +export { + Home, + DashboardScreen, + WatchListsScreen, + SettingsScreen +} \ No newline at end of file From de1dec585c22f82e67e3017d0f81e03fb893f8bd Mon Sep 17 00:00:00 2001 From: Juan Carlos Miranda Carruana Date: Wed, 30 Mar 2022 18:25:10 +0200 Subject: [PATCH 3/6] SPF-18: create watchlist screen with the corresponding components --- .../screens/WatchLists/WatchListsScreen.jsx | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 Frontend/src/components/screens/WatchLists/WatchListsScreen.jsx diff --git a/Frontend/src/components/screens/WatchLists/WatchListsScreen.jsx b/Frontend/src/components/screens/WatchLists/WatchListsScreen.jsx new file mode 100644 index 00000000..0511af94 --- /dev/null +++ b/Frontend/src/components/screens/WatchLists/WatchListsScreen.jsx @@ -0,0 +1,62 @@ +import React, {useEffect, useState} from 'react'; +import ScreensTemplate from '../../ScreensTemplate'; +import {SearchField} from '../../common'; +import {Grid} from '@mui/material'; +import WatchLists from './WatchLists'; +import AssetsList from './AssetsList'; +import PropTypes from 'prop-types'; + +/** + * Component related to the watchLists page + * @param props + * @returns {JSX.Element} + * @constructor + */ +const WatchListsScreen = (props) => { + const [selectedListIndex, setSelectedListIndex] = useState(0); + + const renderHeader = () => ( + + ); + + const renderBody = () => ( + + + + + + + + + ); + + return ( + + + + + ); +} + +ScreensTemplate.propTypes = { + usePersistedState: PropTypes.func, + watchListsArray: PropTypes.array, + setWatchListsArray: PropTypes.func, +}; + +export default WatchListsScreen; \ No newline at end of file From 0c74e5fc3f9751715a33e1c8c1e8f4c9de0d69be Mon Sep 17 00:00:00 2001 From: Juan Carlos Miranda Carruana Date: Wed, 30 Mar 2022 18:26:33 +0200 Subject: [PATCH 4/6] SPF-18: create components regarding the view of the watchlists and the assets --- .../screens/WatchLists/AssetsList.jsx | 130 +++++++++ .../screens/WatchLists/WatchLists.jsx | 265 ++++++++++++++++++ 2 files changed, 395 insertions(+) create mode 100644 Frontend/src/components/screens/WatchLists/AssetsList.jsx create mode 100644 Frontend/src/components/screens/WatchLists/WatchLists.jsx diff --git a/Frontend/src/components/screens/WatchLists/AssetsList.jsx b/Frontend/src/components/screens/WatchLists/AssetsList.jsx new file mode 100644 index 00000000..176b4954 --- /dev/null +++ b/Frontend/src/components/screens/WatchLists/AssetsList.jsx @@ -0,0 +1,130 @@ +import React, {useState} from 'react'; +import {CustomModal} from '../../common/index'; +import { + Container, + Typography, + Stack, + Button, + IconButton, + TextField +} from '@mui/material'; +import AddIcon from '@mui/icons-material/Add'; +import PropTypes from 'prop-types'; +import CustomTable from '../../common/CustomTable'; + + +const createData = (name, price, change) => { + return { name, price, change }; +} + +const assetsArrayTest = [ + [ + createData('Allianz', '212.25$', '-1.80%'), + createData('Fuijitsu', '212.25$', '-1.80%'), + createData('Capgemini', '212.25$', '-1.80%'), + createData('IBM', '212.25$', '-1.80%'), + ], + [ + createData('Thales', '212.25$', '-1.80%'), + createData('WW', '212.25$', '-1.80%'), + createData('DHBW', '212.25$', '-1.80%'), + createData('Netto', '212.25$', '-1.80%'), + ] +]; + +/** + * Show all the assets corresponding a watchlist + * @param props + * @returns {JSX.Element} + * @constructor + */ +const AssetsList = (props) => { + //const [assetsArray, setAssetsArray] = useState([]); + //const [selectedAssetIndex, setSelectedAssetIndex] = useState(0); + const [showAssetModal, setShowAssetModal] = useState(false); + const [asset, setAsset] = useState(''); + const [errorModal, setErrorModal] = useState(false); + + + const handleClose = () => { + setErrorModal(false); + setShowAssetModal(false); + } + + const addAsset = () => { + if (asset !== '') { + setShowAssetModal(false); + setErrorModal(false); + setAsset(''); + } else { + setErrorModal(true); + } + } + + const renderAddAssetModal = () => ( + handleClose()} + labelledby='add_asset-modal-title' + modalTitle='New asset' + modalBody={() => ( + setAsset(data.target.value)} + /> + )} + modalButton={() => ( + + )} + /> + ); + + return ( + + + + {props.watchListsArray[props.selectedListIndex]}: + + { + }} + className='pe-0' + > + + + + + + {renderAddAssetModal()} + + ); +} + +AssetsList.propTypes = { + watchListsArray: PropTypes.array, + selectedListIndex: PropTypes.number, +}; + +export default AssetsList; \ No newline at end of file diff --git a/Frontend/src/components/screens/WatchLists/WatchLists.jsx b/Frontend/src/components/screens/WatchLists/WatchLists.jsx new file mode 100644 index 00000000..afb9e040 --- /dev/null +++ b/Frontend/src/components/screens/WatchLists/WatchLists.jsx @@ -0,0 +1,265 @@ +import React, {useState} from 'react'; +import {CustomModal} from '../../common/index'; +import { + Container, + Box, + ListItem, + ListItemButton, + ListItemText, + List, + Typography, + Stack, + Button, + IconButton, + TextField +} from '@mui/material'; +import AddIcon from '@mui/icons-material/Add'; +import EditIcon from '@mui/icons-material/Edit'; +import DeleteIcon from '@mui/icons-material/Delete'; +import PropTypes from 'prop-types'; +import DropdownMenu from './DropdownMenu'; + +/** + * Show all the watchLists + * @param props + * @returns {JSX.Element} + * @constructor + */ +const WatchLists = (props) => { + const [addListModal, setAddListModal] = useState(false); + const [editListModal, setEditListModal] = useState(false); + const [removeListModal, setRemoveListModal] = useState(false); + const [watchlist, setWatchlist] = useState(''); + const [errorModal, setErrorModal] = useState(false); + const [listDropdownIndex, setListDropdownIndex] = useState(0); + + const handleWatchListItemClick = (event, index) => { + props.setSelectedListIndex(index); + }; + + const handleClose = () => { + setErrorModal(false); + setAddListModal(false); + setEditListModal(false); + setRemoveListModal(false); + } + + const onTextChange = data => { + if (addListModal || editListModal) { + setWatchlist(data.target.value); + data.target.value === '' ? setErrorModal(true) : setErrorModal(false); + } + } + + const addWatchlist = () => { + if (watchlist !== '') { + props.setWatchListsArray([...props.watchListsArray, watchlist]); + setAddListModal(false); + setErrorModal(false); + setWatchlist(''); + } else { + setErrorModal(true); + } + } + + const editWatchList = () => { + let tempArray = [...props.watchListsArray]; + if (watchlist !== '') { + if (watchlist !== props.watchListsArray[listDropdownIndex]) { + tempArray[listDropdownIndex] = watchlist; + props.setWatchListsArray(tempArray); + setEditListModal(false); + setErrorModal(false); + setWatchlist(''); + } else { + setErrorModal(true); + } + } else { + setErrorModal(true); + } + } + + const removeWatchList = () => { + if (props.watchListsArray.length !== 0) { + props.setWatchListsArray(props.watchListsArray.filter( + (element, index) => index !== listDropdownIndex + )); + setRemoveListModal(false); + } + }; + + const renderAddWatchlistModal = () => ( + handleClose()} + labelledby='add_list-modal-title' + describedby='add_list-modal-description' + modalTitle='New watchlist:' + modalBody={() => ( + onTextChange(data)} + error={errorModal} + helperText={errorModal ? '*Name cannot be empty' : false} + defaultValue='' + sx={{display: 'flex', flexGrow: 2}} + /> + )} + modalButton={() => ( + + )} + /> + ); + + const renderEditListModal = () => { + return ( + handleClose()} + labelledby='edit_list-modal-title' + describedby='edit_list-modal-description' + modalTitle='Rename watchlist:' + modalBody={() => ( + onTextChange(data)} + error={errorModal} + helperText={errorModal ? '*Name is the same or empty' : false} + defaultValue={`${props.watchListsArray[listDropdownIndex]}`} + sx={{display: 'flex', flexGrow: 2}} + /> + )} + modalButton={() => ( + + )} + /> + ); + } + + const renderRemoveListModal = () => { + return ( + handleClose()} + labelledby='remove_list-modal-title' + describedby='remove_list-modal-description' + modalTitle='Watchlist will be removed:' + modalButton={() => ( + + )} + /> + ); + } + + return ( + + + + Watchlists: + + setAddListModal(true)} + className='pe-0' + > + + + + + + + {props.watchListsArray.map((element, index) => ( + + handleWatchListItemClick(event, index)} + + > + + + , ]} + functionOptions={[ + () => setEditListModal(true), + () => setRemoveListModal(true) + ]} + /> + + ))} + {renderEditListModal()} + {renderAddWatchlistModal()} + {renderRemoveListModal()} + + + + ); +} + +WatchLists.propTypes = { + watchListsArray: PropTypes.array, + setWatchListsArray: PropTypes.func, + selectedListIndex: PropTypes.number, + setSelectedListIndex: PropTypes.func, +}; + +export default WatchLists; \ No newline at end of file From b1d39431b65187180f31af96594b717864fbf2bd Mon Sep 17 00:00:00 2001 From: Juan Carlos Miranda Carruana Date: Wed, 30 Mar 2022 18:30:35 +0200 Subject: [PATCH 5/6] SPF-18: components that needs using for the watchlist --- .../src/components/common/CustomModal.jsx | 76 ++++++++++ .../src/components/common/CustomTable.jsx | 131 ++++++++++++++++ .../src/components/common/SearchField.jsx | 54 +++++++ .../src/components/common/SideNavLeft.jsx | 143 ++++++++++++++++++ Frontend/src/components/common/index.jsx | 11 ++ .../screens/WatchLists/AssetsList.jsx | 2 +- .../screens/WatchLists/DropdownMenu.jsx | 107 +++++++++++++ 7 files changed, 523 insertions(+), 1 deletion(-) create mode 100644 Frontend/src/components/common/CustomModal.jsx create mode 100644 Frontend/src/components/common/CustomTable.jsx create mode 100644 Frontend/src/components/common/SearchField.jsx create mode 100644 Frontend/src/components/common/SideNavLeft.jsx create mode 100644 Frontend/src/components/common/index.jsx create mode 100644 Frontend/src/components/screens/WatchLists/DropdownMenu.jsx diff --git a/Frontend/src/components/common/CustomModal.jsx b/Frontend/src/components/common/CustomModal.jsx new file mode 100644 index 00000000..d53bd866 --- /dev/null +++ b/Frontend/src/components/common/CustomModal.jsx @@ -0,0 +1,76 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { + Box, + Modal, + Container, + Typography, IconButton +} from '@mui/material'; +import CloseIcon from '@mui/icons-material/Close'; + +/** + * Drawer navigation menu throughout the app + * @param props + * @returns {JSX.Element} + * @constructor + */ +const CustomModal = (props) => { + return ( + props.handleClose()} + aria-labelledby={props.labelledby} + > + + + + {props.modalTitle} + + props.handleClose()} + className='px-0 py-1 align-self-start' + > + + + + + {props.modalBody ? props.modalBody() : null} + {props.modalButton()} + + + ); +} + +const style = { + position: 'absolute', + top: '50%', + left: '50%', + transform: 'translate(-50%, -50%)', + width: { + xs: '70vw', + sm: '55vw', + md: '40vw', + lg: '30vw' + }, + minHeight: '10vh', + display: 'flex', + flexDirection: 'column', + justifyContent: 'space-between', + backgroundColor: 'background.paper', + border: '2px solid #000', + boxShadow: 24, + padding: '1.5rem' +}; + +CustomModal.propTypes = { + open: PropTypes.bool, + handleClose: PropTypes.func, + labelledby: PropTypes.string, + modalTitle: PropTypes.string, + modalBody: PropTypes.func, + modalButton: PropTypes.func, +}; + +export default CustomModal; \ No newline at end of file diff --git a/Frontend/src/components/common/CustomTable.jsx b/Frontend/src/components/common/CustomTable.jsx new file mode 100644 index 00000000..4be0f2a6 --- /dev/null +++ b/Frontend/src/components/common/CustomTable.jsx @@ -0,0 +1,131 @@ +import React, {useState} from 'react'; +import { + TableContainer, + Paper, + Table, + TableBody, + TableRow, + TableCell, + Avatar, + Typography +} from '@mui/material'; +import PropTypes from 'prop-types'; +import DeleteIcon from '@mui/icons-material/Delete'; +import DropdownMenu from "../screens/WatchLists/DropdownMenu"; + + +/** + * Table to show the different assets in watchlist + * @returns {JSX.Element} + * @constructor + */ +const CustomTable = (props) => { + const [listDropdownIndex, setListDropdownIndex] = useState(0); + + return ( + + + + {props.assetsArray[props.selectedListIndex].map((row, index) => ( + + + + + + + {row.name} + + + + + {row.price} + + + + + {row.change} + + + + ]} + functionOptions={[ + () => {} + ]} + /> + + + ))} + +
+
+ ); +} + +CustomTable.propTypes = { + assetsArray: PropTypes.array, + selectedListIndex: PropTypes.number, + watchListsArray: PropTypes.array, + setWatchListsArray: PropTypes.func, +}; + +export default CustomTable; \ No newline at end of file diff --git a/Frontend/src/components/common/SearchField.jsx b/Frontend/src/components/common/SearchField.jsx new file mode 100644 index 00000000..66234cc3 --- /dev/null +++ b/Frontend/src/components/common/SearchField.jsx @@ -0,0 +1,54 @@ +import React from 'react'; +import TextField from '@mui/material/TextField'; +import {Container, InputAdornment, IconButton} from "@mui/material"; +import SearchIcon from '@mui/icons-material/Search'; + +//TODO: function for the search +const search = () => console.log('Searching for asset'); + +/** + * Component for the search field in the screens' header + * @returns {JSX.Element} + * @constructor + */ +const SearchField = () => { + return ( + + + + + + + ), + }} + /> + + ); +} + +export default SearchField; \ No newline at end of file diff --git a/Frontend/src/components/common/SideNavLeft.jsx b/Frontend/src/components/common/SideNavLeft.jsx new file mode 100644 index 00000000..136b5110 --- /dev/null +++ b/Frontend/src/components/common/SideNavLeft.jsx @@ -0,0 +1,143 @@ +import React from 'react'; +import {Link} from 'react-router-dom'; +import PropTypes from 'prop-types'; +import { + Box, + Drawer, + List, + ListItem, + ListItemIcon, + ListItemText +} from '@mui/material'; +import HomeIcon from '@mui/icons-material/Home'; +import AutoGraphIcon from '@mui/icons-material/AutoGraph'; +import ShutterSpeedIcon from '@mui/icons-material/ShutterSpeed'; +import SettingsIcon from '@mui/icons-material/Settings'; + +const drawerWidth = 12; // This is the value in rem units, for responsiveness +const routesArray = [ + {routeName: 'Home', path: '/', icon: }, + {routeName: 'Dashboard', path: '/dashboard', icon: }, + {routeName: 'Watchlists', path: '/watchlists', icon: }, + {routeName: 'Settings', path: '/settings', icon: }, +]; + +/** + * Drawer navigation menu throughout the app + * @param props + * @returns {JSX.Element} + * @constructor + */ +const SideNavLeft = (props) => { + const {window} = props; + + const handleNavLinkClick = () => { + props.setOpenInMobile(false) + }; + + const drawer = (routesArray) => ( + + + Application logo +

Portfolio

+ {routesArray.map((element, index) => ( + handleNavLinkClick()} + style={{textDecoration: 'none',}} + > + + + {element.icon} + + + + + ))} +
+
+ ); + + const container = window !== undefined ? () => window().document.body : undefined; + + return ( + + + {drawer(routesArray)} + + + {drawer(routesArray)} + + + ); +} + +SideNavLeft.propTypes = { + window: PropTypes.func, + openInMobile: PropTypes.bool, + setOpenInMobile: PropTypes.func, + handleDrawerToggle: PropTypes.func, + selectedNavLinkIndex: PropTypes.number +}; + +export default SideNavLeft; \ No newline at end of file diff --git a/Frontend/src/components/common/index.jsx b/Frontend/src/components/common/index.jsx new file mode 100644 index 00000000..920fa81f --- /dev/null +++ b/Frontend/src/components/common/index.jsx @@ -0,0 +1,11 @@ +import SideNavLeft from './SideNavLeft'; +import SearchField from './SearchField'; +import CustomModal from './CustomModal'; +import CustomTable from './CustomTable'; + +export { + SideNavLeft, + SearchField, + CustomModal, + CustomTable +} \ No newline at end of file diff --git a/Frontend/src/components/screens/WatchLists/AssetsList.jsx b/Frontend/src/components/screens/WatchLists/AssetsList.jsx index 176b4954..c5eb5352 100644 --- a/Frontend/src/components/screens/WatchLists/AssetsList.jsx +++ b/Frontend/src/components/screens/WatchLists/AssetsList.jsx @@ -10,7 +10,7 @@ import { } from '@mui/material'; import AddIcon from '@mui/icons-material/Add'; import PropTypes from 'prop-types'; -import CustomTable from '../../common/CustomTable'; +import {CustomTable} from '../../common/index'; const createData = (name, price, change) => { diff --git a/Frontend/src/components/screens/WatchLists/DropdownMenu.jsx b/Frontend/src/components/screens/WatchLists/DropdownMenu.jsx new file mode 100644 index 00000000..2148fd4e --- /dev/null +++ b/Frontend/src/components/screens/WatchLists/DropdownMenu.jsx @@ -0,0 +1,107 @@ +import React, {useState} from 'react'; +import PropTypes from 'prop-types'; +import { + Button, + Menu, + MenuItem, + Divider, + Typography, + Container +} from '@mui/material'; +import MoreHorizIcon from '@mui/icons-material/MoreHoriz'; + +/** + * Component to display a dropdown with different actions + * @param props + * @returns {JSX.Element} + * @constructor + */ +const DropdownMenu = (props) => { + const [anchorEl, setAnchorEl] = useState(null); + const [open, setOpen] = useState(false); + + const handleClick = (event) => { + setOpen(true); + setAnchorEl(event.currentTarget); + props.setListDropdownIndex(props.listIndex); + }; + + const handleClose = () => { + setAnchorEl(null); + setOpen(false); + }; + + const onOptionClick = index => { + handleClose(); + props.functionOptions[index](); + }; + + return ( + + + + {props.menuOptions.map((option, index) => ( + + onOptionClick(index)} + > + + {props.iconOptions[index]} {option} + + + { + props.menuOptions.length - 1 === index + ? null + : + } + + ))} + + + ); +} + +DropdownMenu.propTypes = { + listIndex: PropTypes.number, + selectedListIndex: PropTypes.number, + listName: PropTypes.string, + setListDropdownIndex: PropTypes.func, + menuOptions: PropTypes.array, + iconOptions: PropTypes.array, + functionOptions: PropTypes.array +}; + +export default DropdownMenu; \ No newline at end of file From 42fc173896bfaadd8cc4d91dc887a6aa843e6938 Mon Sep 17 00:00:00 2001 From: Juan Carlos Miranda Carruana Date: Wed, 30 Mar 2022 18:31:23 +0200 Subject: [PATCH 6/6] SPF-18: create function to make the watchlists persist in the local storage --- Frontend/src/routes/index.jsx | 47 +++++++++++++++++++++++++++++------ 1 file changed, 39 insertions(+), 8 deletions(-) diff --git a/Frontend/src/routes/index.jsx b/Frontend/src/routes/index.jsx index 0372856a..713a9f17 100644 --- a/Frontend/src/routes/index.jsx +++ b/Frontend/src/routes/index.jsx @@ -1,22 +1,53 @@ -import React, {lazy} from "react"; -import { Route, Routes } from 'react-router-dom'; +import React, {lazy, useEffect, useState} from "react"; +import {Route, Routes} from 'react-router-dom'; /** * Optional the component could load lazily, allowing to borrow more * time for it to completely load */ -const Home = lazy(() => import("../components/Home")); -const About = lazy(() => import("../components/About")); +const Home = lazy(() => import('../components/screens/Home')); +const DashboardScreen = lazy(() => import('../components/screens/Dashboard/DashboardScreen')); +const WatchListsScreen = lazy(() => import('../components/screens/WatchLists/WatchListsScreen')); +const SettingsScreen = lazy(() => import('../components/screens/Settings/SettingsScreen')); + +/** + * Get value from key in local storage + * @param keyName + * @param defaultValue + * @returns {any|string} + */ +const persistState = (keyName, defaultValue) => { + const savedData = localStorage.getItem(keyName); + return savedData !== '' ? JSON.parse(savedData) : defaultValue; +}; /** * Defines the routes for the different pages * @constructor */ -let AppRoutes = () => ( +const AppRoutes = () => { + const [watchListsArray, setWatchListsArray] = useState(() => persistState('watchListsArray', [])); + + useEffect(() => { + localStorage.setItem("watchListsArray", JSON.stringify(watchListsArray)); + }, [watchListsArray]); + + return ( - } /> - } /> + }/> + }/> + + } + /> + }/> -); + ); +} export default AppRoutes; \ No newline at end of file