diff --git a/.eslintrc.js b/.eslintrc.js
index 3480d73..21d907b 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -1,4 +1,4 @@
-module.exports = {
+/* module.exports = {
env: {
browser: true,
es2021: true,
@@ -61,3 +61,4 @@ module.exports = {
"react/prop-types": "off",
},
};
+ */
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 993b456..d91d797 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1245,6 +1245,145 @@
"resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-10.1.0.tgz",
"integrity": "sha512-ij4wRiunFfaJxjB0BdrYHIH8FxBJpOwNPhhAcunlmPdXudL1WQV1qoP9un6JsEBAgQH+7UXyyjh0g7jTxXK6tg=="
},
+ "@emotion/babel-plugin": {
+ "version": "11.3.0",
+ "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.3.0.tgz",
+ "integrity": "sha512-UZKwBV2rADuhRp+ZOGgNWg2eYgbzKzQXfQPtJbu/PLy8onurxlNCLvxMQEvlr1/GudguPI5IU9qIY1+2z1M5bA==",
+ "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.3"
+ },
+ "dependencies": {
+ "@emotion/memoize": {
+ "version": "0.7.5",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.5.tgz",
+ "integrity": "sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ=="
+ },
+ "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=="
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ }
+ }
+ },
+ "@emotion/cache": {
+ "version": "11.4.0",
+ "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.4.0.tgz",
+ "integrity": "sha512-Zx70bjE7LErRO9OaZrhf22Qye1y4F7iDl+ITjet0J+i+B88PrAOBkKvaAWhxsZf72tDLajwCgfCjJ2dvH77C3g==",
+ "requires": {
+ "@emotion/memoize": "^0.7.4",
+ "@emotion/sheet": "^1.0.0",
+ "@emotion/utils": "^1.0.0",
+ "@emotion/weak-memoize": "^0.2.5",
+ "stylis": "^4.0.3"
+ }
+ },
+ "@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": "0.8.8",
+ "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz",
+ "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==",
+ "requires": {
+ "@emotion/memoize": "0.7.4"
+ }
+ },
+ "@emotion/memoize": {
+ "version": "0.7.4",
+ "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz",
+ "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw=="
+ },
+ "@emotion/react": {
+ "version": "11.4.1",
+ "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.4.1.tgz",
+ "integrity": "sha512-pRegcsuGYj4FCdZN6j5vqCALkNytdrKw3TZMekTzNXixRg4wkLsU5QEaBG5LC6l01Vppxlp7FE3aTHpIG5phLg==",
+ "requires": {
+ "@babel/runtime": "^7.13.10",
+ "@emotion/cache": "^11.4.0",
+ "@emotion/serialize": "^1.0.2",
+ "@emotion/sheet": "^1.0.2",
+ "@emotion/utils": "^1.0.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.0.2",
+ "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.0.2.tgz",
+ "integrity": "sha512-QQPB1B70JEVUHuNtzjHftMGv6eC3Y9wqavyarj4x4lg47RACkeSfNo5pxIOKizwS9AEFLohsqoaxGQj4p0vSIw=="
+ },
+ "@emotion/styled": {
+ "version": "11.3.0",
+ "resolved": "https://registry.npmjs.org/@emotion/styled/-/styled-11.3.0.tgz",
+ "integrity": "sha512-fUoLcN3BfMiLlRhJ8CuPUMEyKkLEoM+n+UyAbnqGEsCd5IzKQ7VQFLtzpJOaCD2/VR2+1hXQTnSZXVJeiTNltA==",
+ "requires": {
+ "@babel/runtime": "^7.13.10",
+ "@emotion/babel-plugin": "^11.3.0",
+ "@emotion/is-prop-valid": "^1.1.0",
+ "@emotion/serialize": "^1.0.2",
+ "@emotion/utils": "^1.0.0"
+ },
+ "dependencies": {
+ "@emotion/is-prop-valid": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.1.0.tgz",
+ "integrity": "sha512-9RkilvXAufQHsSsjQ3PIzSns+pxuX4EW8EbGeSPjZMHuMx6z/MOzb9LpqNieQX4F3mre3NWS2+X3JNRHTQztUQ==",
+ "requires": {
+ "@emotion/memoize": "^0.7.4"
+ }
+ }
+ }
+ },
+ "@emotion/stylis": {
+ "version": "0.8.5",
+ "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz",
+ "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ=="
+ },
+ "@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.0.0",
+ "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.0.0.tgz",
+ "integrity": "sha512-mQC2b3XLDs6QCW+pDQDiyO/EdGZYOygE8s5N5rrzjSI4M3IejPE/JPndCBwRT9z982aqQNi6beWs1UeayrQxxA=="
+ },
+ "@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": "0.4.0",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.4.0.tgz",
@@ -1685,6 +1824,192 @@
"extend": "3.0.2"
}
},
+ "@mui/core": {
+ "version": "5.0.0-alpha.49",
+ "resolved": "https://registry.npmjs.org/@mui/core/-/core-5.0.0-alpha.49.tgz",
+ "integrity": "sha512-bZ7UgH84AuKf/IT0U+knHEelDxLV0lNVFg7rKkkDfXEwUpTtAZEtZPFJjNngapSB/4MuFjaFsttex+0DGC5Z1Q==",
+ "requires": {
+ "@babel/runtime": "^7.15.4",
+ "@emotion/is-prop-valid": "^1.1.0",
+ "@mui/utils": "^5.0.1",
+ "clsx": "^1.1.1",
+ "prop-types": "^15.7.2",
+ "react-is": "^17.0.2"
+ },
+ "dependencies": {
+ "@babel/runtime": {
+ "version": "7.15.4",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz",
+ "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==",
+ "requires": {
+ "regenerator-runtime": "^0.13.4"
+ }
+ },
+ "@emotion/is-prop-valid": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.1.0.tgz",
+ "integrity": "sha512-9RkilvXAufQHsSsjQ3PIzSns+pxuX4EW8EbGeSPjZMHuMx6z/MOzb9LpqNieQX4F3mre3NWS2+X3JNRHTQztUQ==",
+ "requires": {
+ "@emotion/memoize": "^0.7.4"
+ }
+ },
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
+ }
+ }
+ },
+ "@mui/icons-material": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.0.1.tgz",
+ "integrity": "sha512-AZehR/Uvi9VodsNPk9ae1lENKrf1evqx9suiP6VIqu7NxjZOlw/m/yA2gRAMmLEmIGr7EChfi/wcXuq6BpM9vw==",
+ "requires": {
+ "@babel/runtime": "^7.15.4"
+ },
+ "dependencies": {
+ "@babel/runtime": {
+ "version": "7.15.4",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz",
+ "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==",
+ "requires": {
+ "regenerator-runtime": "^0.13.4"
+ }
+ }
+ }
+ },
+ "@mui/material": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.0.2.tgz",
+ "integrity": "sha512-LD2xHSjTLmbN0UoCuKTu09L/7JjpEzg+Cophf+dVJOTNoK7VI0Eqv3bmpF/9pDIk5dVKmeU9Eh4t2lW1ZifM6A==",
+ "requires": {
+ "@babel/runtime": "^7.15.4",
+ "@mui/core": "5.0.0-alpha.49",
+ "@mui/system": "^5.0.2",
+ "@mui/types": "^7.0.0",
+ "@mui/utils": "^5.0.1",
+ "@popperjs/core": "^2.4.4",
+ "@types/react-transition-group": "^4.4.3",
+ "clsx": "^1.1.1",
+ "csstype": "^3.0.9",
+ "hoist-non-react-statics": "^3.3.2",
+ "prop-types": "^15.7.2",
+ "react-is": "^17.0.2",
+ "react-transition-group": "^4.4.2"
+ },
+ "dependencies": {
+ "@babel/runtime": {
+ "version": "7.15.4",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz",
+ "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==",
+ "requires": {
+ "regenerator-runtime": "^0.13.4"
+ }
+ },
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
+ }
+ }
+ },
+ "@mui/private-theming": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@mui/private-theming/-/private-theming-5.0.1.tgz",
+ "integrity": "sha512-R8Cf2+32cG1OXFAqTighA5Mx9R5BQ57cN1ZVaNgfgdbI87Yig2fVMdFSPrw3txcjKlnwsvFJF8AdwQMqq1tJ3Q==",
+ "requires": {
+ "@babel/runtime": "^7.15.4",
+ "@mui/utils": "^5.0.1",
+ "prop-types": "^15.7.2"
+ },
+ "dependencies": {
+ "@babel/runtime": {
+ "version": "7.15.4",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz",
+ "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==",
+ "requires": {
+ "regenerator-runtime": "^0.13.4"
+ }
+ }
+ }
+ },
+ "@mui/styled-engine": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@mui/styled-engine/-/styled-engine-5.0.1.tgz",
+ "integrity": "sha512-j40nCbaKr1HAZYqpX61XvZYsadYskjo3u6+pRFFaewSViAkkD1rjjbubpnh15nqVfYmijtHMZJ9/l1x1hamvfQ==",
+ "requires": {
+ "@babel/runtime": "^7.15.4",
+ "@emotion/cache": "^11.4.0",
+ "prop-types": "^15.7.2"
+ },
+ "dependencies": {
+ "@babel/runtime": {
+ "version": "7.15.4",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz",
+ "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==",
+ "requires": {
+ "regenerator-runtime": "^0.13.4"
+ }
+ }
+ }
+ },
+ "@mui/system": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/@mui/system/-/system-5.0.2.tgz",
+ "integrity": "sha512-K6wMbiSEYSMeYUw7zmZ2/50JFthqtuTz4OADyKc4ic2RP8ubAf/duH/nkJ4gtsKcewU4RIub0HQHl5F77WVp4Q==",
+ "requires": {
+ "@babel/runtime": "^7.15.4",
+ "@mui/private-theming": "^5.0.1",
+ "@mui/styled-engine": "^5.0.1",
+ "@mui/types": "^7.0.0",
+ "@mui/utils": "^5.0.1",
+ "clsx": "^1.1.1",
+ "csstype": "^3.0.9",
+ "prop-types": "^15.7.2"
+ },
+ "dependencies": {
+ "@babel/runtime": {
+ "version": "7.15.4",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz",
+ "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==",
+ "requires": {
+ "regenerator-runtime": "^0.13.4"
+ }
+ }
+ }
+ },
+ "@mui/types": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/@mui/types/-/types-7.0.0.tgz",
+ "integrity": "sha512-M/tkF2pZ4uoPhZ8pnNhlVnOFtz6F3dnYKIsnj8MuXKT6d26IE2u0UjA8B0275ggN74dR9rlHG5xJt5jgDx/Ung=="
+ },
+ "@mui/utils": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/@mui/utils/-/utils-5.0.1.tgz",
+ "integrity": "sha512-GWO104N+o9KG5fKiTEYnAg7kONKEg3vLN+VROAU0f3it6lFGLCVPcQYex/1gJ4QAy96u6Ez8/Hmmhi1+3cX0tQ==",
+ "requires": {
+ "@babel/runtime": "^7.15.4",
+ "@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"
+ },
+ "dependencies": {
+ "@babel/runtime": {
+ "version": "7.15.4",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz",
+ "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==",
+ "requires": {
+ "regenerator-runtime": "^0.13.4"
+ }
+ },
+ "react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w=="
+ }
+ }
+ },
"@nodelib/fs.scandir": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz",
@@ -1744,6 +2069,11 @@
}
}
},
+ "@popperjs/core": {
+ "version": "2.10.2",
+ "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.10.2.tgz",
+ "integrity": "sha512-IXf3XA7+XyN7CP9gGh/XB0UxVMlvARGEgGXLubFICsUMGz6Q+DU+i4gGlpOxTjKvXjkJDJC8YdqdKkDj9qZHEQ=="
+ },
"@rollup/plugin-node-resolve": {
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.3.tgz",
@@ -2122,11 +2452,42 @@
"resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.2.2.tgz",
"integrity": "sha512-i99hy7Ki19EqVOl77WplDrvgNugHnsSjECVR/wUrzw2TJXz1zlUfT2ngGckR6xN7yFYaijsMAqPkOLx9HgUqHg=="
},
+ "@types/prop-types": {
+ "version": "15.7.4",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz",
+ "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ=="
+ },
"@types/q": {
"version": "1.5.4",
"resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz",
"integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug=="
},
+ "@types/react": {
+ "version": "17.0.26",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.26.tgz",
+ "integrity": "sha512-MXxuXrH2xOcv5cp/su4oz69dNQnSA90JjFw5HBd5wifw6Ihi94j7dRJm7qNsB30tnruXSCPc9qmlhGop4nh9Hw==",
+ "requires": {
+ "@types/prop-types": "*",
+ "@types/scheduler": "*",
+ "csstype": "^3.0.2"
+ }
+ },
+ "@types/react-is": {
+ "version": "17.0.2",
+ "resolved": "https://registry.npmjs.org/@types/react-is/-/react-is-17.0.2.tgz",
+ "integrity": "sha512-2+L0ilcAEG8udkDnvx8B0upwXFBbNnVwOsSCTxW3SDOkmar9NyEeLG0ZLa3uOEw9zyYf/fQapcnfXAVmDKlyHw==",
+ "requires": {
+ "@types/react": "*"
+ }
+ },
+ "@types/react-transition-group": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.3.tgz",
+ "integrity": "sha512-fUx5muOWSYP8Bw2BUQ9M9RK9+W1XBK/7FLJ8PTQpnpTEkn0ccyMffyEQvan4C3h53gHdx7KE5Qrxi/LnUGQtdg==",
+ "requires": {
+ "@types/react": "*"
+ }
+ },
"@types/resolve": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-0.0.8.tgz",
@@ -2135,6 +2496,11 @@
"@types/node": "*"
}
},
+ "@types/scheduler": {
+ "version": "0.16.2",
+ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz",
+ "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew=="
+ },
"@types/source-list-map": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz",
@@ -3022,6 +3388,22 @@
"@babel/helper-define-polyfill-provider": "^0.1.5"
}
},
+ "babel-plugin-styled-components": {
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-1.13.2.tgz",
+ "integrity": "sha512-Vb1R3d4g+MUfPQPVDMCGjm3cDocJEUTR7Xq7QS95JWWeksN1wdFRYpD2kulDgI3Huuaf1CZd+NK4KQmqUFh5dA==",
+ "requires": {
+ "@babel/helper-annotate-as-pure": "^7.0.0",
+ "@babel/helper-module-imports": "^7.0.0",
+ "babel-plugin-syntax-jsx": "^6.18.0",
+ "lodash": "^4.17.11"
+ }
+ },
+ "babel-plugin-syntax-jsx": {
+ "version": "6.18.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
+ "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY="
+ },
"babel-plugin-syntax-object-rest-spread": {
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
@@ -3742,6 +4124,11 @@
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz",
"integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg=="
},
+ "camelize": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz",
+ "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs="
+ },
"caniuse-api": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
@@ -3754,9 +4141,9 @@
}
},
"caniuse-lite": {
- "version": "1.0.30001198",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001198.tgz",
- "integrity": "sha512-r5GGgESqOPZzwvdLVER374FpQu2WluCF1Z2DSiFJ89KSmGjT0LVKjgv4NcAqHmGWF9ihNpqRI9KXO9Ex4sKsgA=="
+ "version": "1.0.30001263",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001263.tgz",
+ "integrity": "sha512-doiV5dft6yzWO1WwU19kt8Qz8R0/8DgEziz6/9n2FxUasteZNwNNYSmJO3GLBH8lCVE73AB1RPDPAeYbcO5Cvw=="
},
"capture-exit": {
"version": "2.0.0",
@@ -4434,6 +4821,11 @@
"postcss": "^7.0.5"
}
},
+ "css-color-keywords": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
+ "integrity": "sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU="
+ },
"css-color-names": {
"version": "0.0.4",
"resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
@@ -4517,6 +4909,16 @@
"resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz",
"integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w=="
},
+ "css-to-react-native": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz",
+ "integrity": "sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==",
+ "requires": {
+ "camelize": "^1.0.0",
+ "css-color-keywords": "^1.0.0",
+ "postcss-value-parser": "^4.0.2"
+ }
+ },
"css-tree": {
"version": "1.0.0-alpha.37",
"resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz",
@@ -4697,6 +5099,11 @@
}
}
},
+ "csstype": {
+ "version": "3.0.9",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.9.tgz",
+ "integrity": "sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw=="
+ },
"cyclist": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz",
@@ -5026,6 +5433,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": "0.2.2",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
@@ -6548,6 +6964,11 @@
"pkg-dir": "^3.0.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": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
@@ -12252,6 +12673,17 @@
}
}
},
+ "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"
+ }
+ },
"read-pkg": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
@@ -13347,6 +13779,11 @@
"safe-buffer": "^5.0.1"
}
},
+ "shallowequal": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
+ "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ=="
+ },
"shebang-command": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
@@ -14014,6 +14451,38 @@
"schema-utils": "^2.7.0"
}
},
+ "styled-components": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.1.tgz",
+ "integrity": "sha512-JThv2JRzyH0NOIURrk9iskdxMSAAtCfj/b2Sf1WJaCUsloQkblepy1jaCLX/bYE+mhYo3unmwVSI9I5d9ncSiQ==",
+ "requires": {
+ "@babel/helper-module-imports": "^7.0.0",
+ "@babel/traverse": "^7.4.5",
+ "@emotion/is-prop-valid": "^0.8.8",
+ "@emotion/stylis": "^0.8.4",
+ "@emotion/unitless": "^0.7.4",
+ "babel-plugin-styled-components": ">= 1.12.0",
+ "css-to-react-native": "^3.0.0",
+ "hoist-non-react-statics": "^3.0.0",
+ "shallowequal": "^1.1.0",
+ "supports-color": "^5.5.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
"stylehacks": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz",
@@ -14036,6 +14505,11 @@
}
}
},
+ "stylis": {
+ "version": "4.0.10",
+ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.10.tgz",
+ "integrity": "sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg=="
+ },
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
diff --git a/package.json b/package.json
index a154f9e..927d382 100644
--- a/package.json
+++ b/package.json
@@ -9,6 +9,10 @@
"private": true,
"license": "MIT",
"dependencies": {
+ "@emotion/react": "^11.4.1",
+ "@emotion/styled": "^11.3.0",
+ "@mui/icons-material": "^5.0.1",
+ "@mui/material": "^5.0.2",
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
@@ -21,6 +25,7 @@
"react-router-dom": "^5.2.0",
"react-scripts": "4.0.3",
"sass": "^1.32.11",
+ "styled-components": "^5.3.1",
"web-vitals": "^1.0.1"
},
"devDependencies": {
diff --git a/public/index.html b/public/index.html
index aa069f2..dc3a764 100644
--- a/public/index.html
+++ b/public/index.html
@@ -25,6 +25,16 @@
Learn how to configure a non-root public URL by running `npm run build`.
-->
React App
+
+
+
+
diff --git a/src/App.js b/src/App.js
index 3a49c0e..deca482 100644
--- a/src/App.js
+++ b/src/App.js
@@ -1,9 +1,32 @@
import React from "react";
-
+import { Route, Switch } from "react-router-dom";
import Home from "./pages/Home";
+import * as routes from "./constants/routes";
+
+import Episode from "./pages/Episode/Episode";
+import Character from "./pages/Character";
+import Location from "./pages/Location/Location";
function App() {
- return ;
+ return (
+
+
+
+
+
+
+
+ );
+
+ /* return ; */
}
export default App;
diff --git a/src/components/CharacterCard/CharacterCard.js b/src/components/CharacterCard/CharacterCard.js
index 9e7e4ab..5a99f7c 100644
--- a/src/components/CharacterCard/CharacterCard.js
+++ b/src/components/CharacterCard/CharacterCard.js
@@ -6,6 +6,8 @@ import "./CharacterCard.scss";
import * as routes from "../../constants/routes";
function CharacterCard({ id, name, image, species, status, origin, location }) {
+ const url = origin.url.split("/");
+
return (

@@ -15,7 +17,7 @@ function CharacterCard({ id, name, image, species, status, origin, location }) {
{origin.name}
diff --git a/src/components/Main/Main.js b/src/components/Main/Main.js
index 43bb386..56cd585 100644
--- a/src/components/Main/Main.js
+++ b/src/components/Main/Main.js
@@ -1,6 +1,7 @@
import React from "react";
function Main({ children, ...props }) {
+
return (
{children}
diff --git a/src/pages/Character/Character.js b/src/pages/Character/Character.js
new file mode 100644
index 0000000..e675e5f
--- /dev/null
+++ b/src/pages/Character/Character.js
@@ -0,0 +1,108 @@
+import React from "react";
+import Layout from "../../components/Layout";
+import EpisodeCard from "../../components/EpisodeCard";
+
+class Character extends React.Component {
+ constructor(props) {
+ super(props);
+ this.state = {
+ episodes: [],
+ character: null,
+ hasLoaded: false,
+ hasError: false,
+ errorMessage: null,
+ };
+ }
+
+ async componentDidMount() {
+ const {
+ match: { params },
+ } = this.props;
+
+ try {
+ const response = await fetch(
+ `https://rickandmortyapi.com/api/character/${params.characterId}`,
+ );
+ const json = await response.json();
+
+ console.log(json);
+
+ this.setState({
+ character: json,
+ });
+
+ let episodes = await Promise.all(
+ json.episode.map(async (url) => {
+ const response = await fetch(url);
+ return response.json();
+ }),
+ );
+
+ console.log(episodes);
+
+ this.setState({
+ episodes: episodes,
+ hasLoaded: true,
+ });
+ } catch (error) {
+ this.setState({
+ hasError: true,
+ });
+ }
+ }
+
+ render() {
+ const { character, episodes, hasLoaded, hasError } = this.state;
+ return (
+
+ {hasLoaded && !hasError && (
+
+
+
+

+
+
+
+
{character.name}
+
+
+
+
+
CHARACTER
+ {character.species} | {character.status}
+
+
+
ORIGIN
+ {character.origin.name}
+
+
+
LOCATION
+ {character.location.name}
+
+
+
+
+
+
+
+
+ Episodes
+
+ {episodes.map((episode) => (
+
+ ))}
+
+ )}
+
+ );
+ }
+}
+
+export default Character;
diff --git a/src/pages/Character/index.js b/src/pages/Character/index.js
new file mode 100644
index 0000000..f267ceb
--- /dev/null
+++ b/src/pages/Character/index.js
@@ -0,0 +1 @@
+export { default } from "./Character";
diff --git a/src/pages/Episode/Episode.js b/src/pages/Episode/Episode.js
index 8255df5..5d00d25 100644
--- a/src/pages/Episode/Episode.js
+++ b/src/pages/Episode/Episode.js
@@ -1,38 +1,80 @@
import React, { Component } from "react";
import Layout from "../../components/Layout";
-// import CharacterCard from "../../components/CharacterCard";
+import CharacterCard from "../../components/CharacterCard";
+import { FaceRetouchingNatural } from "@mui/icons-material";
class Episode extends Component {
constructor(props) {
super(props);
- this.state = {};
- // episode: null,
- // characters: [],
- // hasLoaded: false,
- // hasError: false,
- // errorMessage: null,
+ this.state = {
+ episode: null,
+ characters: [],
+ hasLoaded: false,
+ hasError: false,
+ errorMessage: null,
+ };
+ }
+
+ async componentDidMount() {
+ const {
+ match: { params },
+ } = this.props;
+
+ try {
+ const response = await fetch(
+ `https://rickandmortyapi.com/api/episode/${params.episodeId}`,
+ );
+ const json = await response.json();
+
+ this.setState({
+ episode: json,
+ });
+
+ let characters = await Promise.all(
+ json.characters.map(async (url) => {
+ const response = await fetch(url);
+ return response.json();
+ }),
+ );
+
+ this.setState({
+ characters: characters,
+ hasLoaded: true,
+ });
+ } catch (error) {
+ console.log(error);
+ }
}
render() {
+ const { characters, episode } = this.state;
return (
- {/* {characters.map((character) => (
-
- ))} */}
+
{episode && episode.name}
+
+
+
+
+ {episode && episode.episode} | {episode && episode.air_date}
+
+
+ {characters.map((character) => (
+
+ ))}
);
diff --git a/src/pages/Home/Home.js b/src/pages/Home/Home.js
index f86e93c..3c135d0 100644
--- a/src/pages/Home/Home.js
+++ b/src/pages/Home/Home.js
@@ -1,52 +1,107 @@
import React, { Component } from "react";
import Layout from "../../components/Layout";
-// import EpisodeCard from "../../components/EpisodeCard";
+import EpisodeCard from "../../components/EpisodeCard";
+import Button from "@mui/material/Button";
+import ArrowBackIcon from '@mui/icons-material/ArrowBack';
+import ArrowForwardIcon from '@mui/icons-material/ArrowForward';
class Home extends Component {
constructor(props) {
super(props);
- this.state = {};
- // page: 1,
- // paginationInfo: null,
- // episodes: [],
- // hasLoaded: false,
- // hasError: false,
- // errorMessage: null,
+ this.state = {
+ page: 1,
+ paginationInfo: null,
+ episodes: [],
+ hasLoaded: false,
+ hasError: false,
+ errorMessage: null,
+ currentPage: 1,
+ };
}
- async componentDidMount() {
- // this.loadEpisodes();
- }
+ componentDidMount = async () => {
+ const { page } = this.state;
+ this.componentDidUpdateloadEpisodes(page);
+ };
- async loadEpisodes() {
- console.log(this);
- }
+ loadEpisodes = () => {
+ const { page } = this.state;
+ this.setState({
+ page: page + 1,
+ });
+ };
+ lessEpisodes = () => {
+ const { page } = this.state;
+ this.setState({
+ page: page - 1,
+ });
+ };
+
+ componentDidUpdate = async () => {
+ const { page, currentPage } = this.state;
+ if (page !== currentPage) {
+ this.componentDidUpdateloadEpisodes(page);
+ }
+ };
+
+ componentDidUpdateloadEpisodes = async (page) => {
+ try {
+ const response = await fetch(
+ `https://rickandmortyapi.com/api/episode?page=${page}`,
+ );
+ const json = await response.json();
+
+ this.setState((prevState) => ({
+ episodes: json.results /* [...prevState.episodes, json.results] */,
+ hasLoaded: true,
+ page: page,
+ currentPage: page,
+ paginationInfo: json.info.next,
+ }));
+ } catch (error) {
+ this.setState({
+ hasError: true,
+ });
+ }
+ };
render() {
+ const { hasLoaded, hasError, episodes, page } = this.state;
return (
- {/* {hasLoaded && !hasError && (
+ {hasLoaded && !hasError && (
Episodes loaded!
- )} */}
+ )}
- {/* {episodes.map((episode) => (
-
- ))} */}
+ {episodes.map((episode) => (
+
+ ))}
+
+ {page > 1 && (
+
+ )}
+ {page < 3 && (
+
+ )}
+
diff --git a/src/pages/Location/Location.js b/src/pages/Location/Location.js
new file mode 100644
index 0000000..6fa3fa5
--- /dev/null
+++ b/src/pages/Location/Location.js
@@ -0,0 +1,94 @@
+import React from "react";
+import CharacterCard from "../../components/CharacterCard";
+import Layout from "../../components/Layout";
+
+class Location extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {
+ location: {},
+ residents: [],
+ hasLoaded: false,
+ hasError: false,
+ errorMessage: null,
+ };
+ }
+
+ async componentDidMount() {
+ const {
+ match: { params },
+ } = this.props;
+
+ try {
+ const response = await fetch(
+ `https://rickandmortyapi.com/api/location/${params.locationId}`,
+ );
+ const json = await response.json();
+ console.log(json);
+
+ this.setState({
+ location: json,
+ });
+
+ let residents = await Promise.all(
+ json.residents.map(async (url) => {
+ const response = await fetch(url);
+ return response.json();
+ }),
+ );
+
+ this.setState({
+ residents: residents,
+ hasLoaded: true,
+ });
+ } catch (error) {
+ this.setState({
+ hasError: true,
+ });
+ }
+ }
+
+ componentDidUpdate(prevProps) {
+ /* console.log(prevProps, this.props); */
+ }
+ render() {
+ const { hasError, hasLoaded, residents, location } = this.state;
+ return (
+
+ {!hasError && hasLoaded && (
+
+
+
{location.name}
+
+
+
+
TYPE
+ {location.type}
+ DIMENSION
+ {location.dimension}
+
+
+
+ RESIDENTS
+
+ {residents.map((character) => (
+
+ ))}
+
+ )}
+
+ );
+ }
+}
+
+export default Location;
diff --git a/src/pages/Location/index.js b/src/pages/Location/index.js
new file mode 100644
index 0000000..e267389
--- /dev/null
+++ b/src/pages/Location/index.js
@@ -0,0 +1 @@
+export { default } from "./Location";
\ No newline at end of file