diff --git a/package-lock.json b/package-lock.json index 240aecf..cf32d71 100644 --- a/package-lock.json +++ b/package-lock.json @@ -75,6 +75,7 @@ "version": "7.18.2", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.2.tgz", "integrity": "sha512-A8pri1YJiC5UnkdrWcmfZTJTV85b4UXTAfImGmCfYmax4TR9Cw8sDS0MOk++Gp2mE/BefVJ5nwy5yzqNJbP/DQ==", + "peer": true, "dependencies": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.16.7", @@ -894,6 +895,7 @@ "version": "7.17.12", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.17.12.tgz", "integrity": "sha512-B8QIgBvkIG6G2jgsOHQUist7Sm0EBLDCx8sen072IwqNuzMegZNXrYnSv77cYzA8mLDZAfQYqsLIhimiP1s2HQ==", + "peer": true, "dependencies": { "@babel/helper-plugin-utils": "^7.17.12" }, @@ -1456,6 +1458,7 @@ "version": "7.17.12", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.17.12.tgz", "integrity": "sha512-Lcaw8bxd1DKht3thfD4A12dqo1X16he1Lm8rIv8sTwjAYNInRS1qHa9aJoqvzpscItXvftKDCfaEQzwoVyXpEQ==", + "peer": true, "dependencies": { "@babel/helper-annotate-as-pure": "^7.16.7", "@babel/helper-module-imports": "^7.16.7", @@ -3856,6 +3859,7 @@ "version": "16.14.26", "resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.26.tgz", "integrity": "sha512-c/5CYyciOO4XdFcNhZW1O2woVx86k4T+DO2RorHZL7EhitkNQgSD/SgpdZJAUJa/qjVgOmTM44gHkAdZSXeQuQ==", + "peer": true, "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -3998,6 +4002,7 @@ "version": "5.27.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.27.1.tgz", "integrity": "sha512-6dM5NKT57ZduNnJfpY81Phe9nc9wolnMCnknb1im6brWi1RYv84nbMS3olJa27B6+irUVV1X/Wb+Am0FjJdGFw==", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "5.27.1", "@typescript-eslint/type-utils": "5.27.1", @@ -4048,6 +4053,7 @@ "version": "5.27.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.27.1.tgz", "integrity": "sha512-7Va2ZOkHi5NP+AZwb5ReLgNF6nWLGTeUJfxdkVUAPPSaAdbWNnFZzLZ4EGGmmiCTg+AwlbE1KyUYTBglosSLHQ==", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "5.27.1", "@typescript-eslint/types": "5.27.1", @@ -4370,6 +4376,7 @@ "version": "8.7.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -4477,6 +4484,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -5241,6 +5249,7 @@ "url": "https://tidelift.com/funding/github/npm/browserslist" } ], + "peer": true, "dependencies": { "caniuse-lite": "^1.0.30001349", "electron-to-chromium": "^1.4.147", @@ -5914,6 +5923,7 @@ "version": "8.11.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -6228,6 +6238,7 @@ "version": "2.28.0", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.28.0.tgz", "integrity": "sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==", + "peer": true, "engines": { "node": ">=0.11" }, @@ -6848,6 +6859,7 @@ "version": "8.17.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.17.0.tgz", "integrity": "sha512-gq0m0BTJfci60Fz4nczYxNAlED+sMcihltndR8t9t1evnU/azx53x3t2UHXC/uRjcbvRw/XctpaNygSTcQD+Iw==", + "peer": true, "dependencies": { "@eslint/eslintrc": "^1.3.0", "@humanwhocodes/config-array": "^0.9.2", @@ -9264,6 +9276,7 @@ "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", + "peer": true, "dependencies": { "@jest/core": "^27.5.1", "import-local": "^3.0.2", @@ -11692,6 +11705,7 @@ "version": "8.11.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -12428,6 +12442,7 @@ "url": "https://tidelift.com/funding/github/npm/postcss" } ], + "peer": true, "dependencies": { "nanoid": "^3.3.4", "picocolors": "^1.0.0", @@ -13454,6 +13469,7 @@ "version": "6.0.10", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "peer": true, "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -13649,6 +13665,7 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "peer": true, "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -13807,6 +13824,7 @@ "version": "17.0.2", "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -13952,6 +13970,7 @@ "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -13975,6 +13994,7 @@ "version": "7.2.8", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.8.tgz", "integrity": "sha512-6+uDjhs3PSIclqoCk0kd6iX74gzrGc3W5zcAjbrFgEdIjRSQObdIwfx80unTkVUYvbQ95Y8Av3OvFHq1w5EOUw==", + "peer": true, "dependencies": { "@babel/runtime": "^7.15.4", "@types/react-redux": "^7.1.20", @@ -14004,6 +14024,7 @@ "version": "0.11.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -14153,6 +14174,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.0.tgz", "integrity": "sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==", + "peer": true, "dependencies": { "@babel/runtime": "^7.9.2" } @@ -14457,6 +14479,7 @@ "version": "2.75.6", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.75.6.tgz", "integrity": "sha512-OEf0TgpC9vU6WGROJIk1JA3LR5vk/yvqlzxqdrE2CzzXnqKXNzbAwlWUXis8RS3ZPe7LAq+YUxsRa0l3r27MLA==", + "peer": true, "bin": { "rollup": "dist/bin/rollup" }, @@ -14562,6 +14585,7 @@ "version": "1.52.3", "resolved": "https://registry.npmjs.org/sass/-/sass-1.52.3.tgz", "integrity": "sha512-LNNPJ9lafx+j1ArtA7GyEJm9eawXN8KlA1+5dF6IZyoONg1Tyo/g+muOsENWJH/2Q1FHbbV4UwliU0cXMa/VIA==", + "peer": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -15209,6 +15233,7 @@ "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.5.tgz", "integrity": "sha512-ndETJ9RKaaL6q41B69WudeqLzOpY1A/ET/glXkNZ2T7dPjPqpPCXXQjDFYZWwNnE5co0wX+gTCqx9mfxTmSIPg==", "hasInstallScript": true, + "peer": true, "dependencies": { "@babel/helper-module-imports": "^7.0.0", "@babel/traverse": "^7.4.5", @@ -15729,6 +15754,7 @@ "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "peer": true, "engines": { "node": ">=10" }, @@ -15760,6 +15786,7 @@ "version": "4.7.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.3.tgz", "integrity": "sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -15997,6 +16024,7 @@ "version": "5.73.0", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.73.0.tgz", "integrity": "sha512-svjudQRPPa0YiOYa2lM/Gacw0r6PvxptHj4FuEKQ2kX05ZLkjbVc5MnPs6its5j7IZljnIqSVo/OsY2X0IpHGA==", + "peer": true, "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^0.0.51", @@ -16065,6 +16093,7 @@ "version": "8.11.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -16114,6 +16143,7 @@ "version": "4.9.2", "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.9.2.tgz", "integrity": "sha512-H95Ns95dP24ZsEzO6G9iT+PNw4Q7ltll1GfJHV4fKphuHWgKFzGHWi4alTlTnpk1SPPk41X+l2RB7rLfIhnB9Q==", + "peer": true, "dependencies": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", @@ -16164,6 +16194,7 @@ "version": "8.11.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -16476,6 +16507,7 @@ "version": "8.11.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "peer": true, "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -16871,6 +16903,7 @@ "version": "7.18.2", "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.2.tgz", "integrity": "sha512-A8pri1YJiC5UnkdrWcmfZTJTV85b4UXTAfImGmCfYmax4TR9Cw8sDS0MOk++Gp2mE/BefVJ5nwy5yzqNJbP/DQ==", + "peer": true, "requires": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.16.7", @@ -17434,6 +17467,7 @@ "version": "7.17.12", "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.17.12.tgz", "integrity": "sha512-B8QIgBvkIG6G2jgsOHQUist7Sm0EBLDCx8sen072IwqNuzMegZNXrYnSv77cYzA8mLDZAfQYqsLIhimiP1s2HQ==", + "peer": true, "requires": { "@babel/helper-plugin-utils": "^7.17.12" } @@ -17780,6 +17814,7 @@ "version": "7.17.12", "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.17.12.tgz", "integrity": "sha512-Lcaw8bxd1DKht3thfD4A12dqo1X16he1Lm8rIv8sTwjAYNInRS1qHa9aJoqvzpscItXvftKDCfaEQzwoVyXpEQ==", + "peer": true, "requires": { "@babel/helper-annotate-as-pure": "^7.16.7", "@babel/helper-module-imports": "^7.16.7", @@ -19465,6 +19500,7 @@ "version": "16.14.26", "resolved": "https://registry.npmjs.org/@types/react/-/react-16.14.26.tgz", "integrity": "sha512-c/5CYyciOO4XdFcNhZW1O2woVx86k4T+DO2RorHZL7EhitkNQgSD/SgpdZJAUJa/qjVgOmTM44gHkAdZSXeQuQ==", + "peer": true, "requires": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -19611,6 +19647,7 @@ "version": "5.27.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.27.1.tgz", "integrity": "sha512-6dM5NKT57ZduNnJfpY81Phe9nc9wolnMCnknb1im6brWi1RYv84nbMS3olJa27B6+irUVV1X/Wb+Am0FjJdGFw==", + "peer": true, "requires": { "@typescript-eslint/scope-manager": "5.27.1", "@typescript-eslint/type-utils": "5.27.1", @@ -19635,6 +19672,7 @@ "version": "5.27.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.27.1.tgz", "integrity": "sha512-7Va2ZOkHi5NP+AZwb5ReLgNF6nWLGTeUJfxdkVUAPPSaAdbWNnFZzLZ4EGGmmiCTg+AwlbE1KyUYTBglosSLHQ==", + "peer": true, "requires": { "@typescript-eslint/scope-manager": "5.27.1", "@typescript-eslint/types": "5.27.1", @@ -19876,7 +19914,8 @@ "acorn": { "version": "8.7.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz", - "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==" + "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==", + "peer": true }, "acorn-globals": { "version": "6.0.0", @@ -19954,6 +19993,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "peer": true, "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -20525,6 +20565,7 @@ "version": "4.20.4", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.4.tgz", "integrity": "sha512-ok1d+1WpnU24XYN7oC3QWgTyMhY/avPJ/r9T00xxvUOIparA/gc+UPUMaod3i+G6s+nI2nUb9xZ5k794uIwShw==", + "peer": true, "requires": { "caniuse-lite": "^1.0.30001349", "electron-to-chromium": "^1.4.147", @@ -20996,6 +21037,7 @@ "version": "8.11.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "peer": true, "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -21231,7 +21273,8 @@ "date-fns": { "version": "2.28.0", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.28.0.tgz", - "integrity": "sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==" + "integrity": "sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==", + "peer": true }, "debug": { "version": "4.3.4", @@ -21696,6 +21739,7 @@ "version": "8.17.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.17.0.tgz", "integrity": "sha512-gq0m0BTJfci60Fz4nczYxNAlED+sMcihltndR8t9t1evnU/azx53x3t2UHXC/uRjcbvRw/XctpaNygSTcQD+Iw==", + "peer": true, "requires": { "@eslint/eslintrc": "^1.3.0", "@humanwhocodes/config-array": "^0.9.2", @@ -23419,6 +23463,7 @@ "version": "27.5.1", "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", + "peer": true, "requires": { "@jest/core": "^27.5.1", "import-local": "^3.0.2", @@ -25221,6 +25266,7 @@ "version": "8.11.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "peer": true, "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -25744,6 +25790,7 @@ "version": "8.4.14", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz", "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==", + "peer": true, "requires": { "nanoid": "^3.3.4", "picocolors": "^1.0.0", @@ -26322,6 +26369,7 @@ "version": "6.0.10", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "peer": true, "requires": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" @@ -26461,6 +26509,7 @@ "version": "15.8.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "peer": true, "requires": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -26574,6 +26623,7 @@ "version": "17.0.2", "resolved": "https://registry.npmjs.org/react/-/react-17.0.2.tgz", "integrity": "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==", + "peer": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -26682,6 +26732,7 @@ "version": "17.0.2", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz", "integrity": "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==", + "peer": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -26702,6 +26753,7 @@ "version": "7.2.8", "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.8.tgz", "integrity": "sha512-6+uDjhs3PSIclqoCk0kd6iX74gzrGc3W5zcAjbrFgEdIjRSQObdIwfx80unTkVUYvbQ95Y8Av3OvFHq1w5EOUw==", + "peer": true, "requires": { "@babel/runtime": "^7.15.4", "@types/react-redux": "^7.1.20", @@ -26721,7 +26773,8 @@ "react-refresh": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", - "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==" + "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==", + "peer": true }, "react-scripts": { "version": "5.0.1", @@ -26837,6 +26890,7 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.0.tgz", "integrity": "sha512-oSBmcKKIuIR4ME29/AeNUnl5L+hvBq7OaJWzaptTQJAntaPvxIJqfnjbaEiCzzaIz+XmVILfqAM3Ob0aXLPfjA==", + "peer": true, "requires": { "@babel/runtime": "^7.9.2" } @@ -27054,6 +27108,7 @@ "version": "2.75.6", "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.75.6.tgz", "integrity": "sha512-OEf0TgpC9vU6WGROJIk1JA3LR5vk/yvqlzxqdrE2CzzXnqKXNzbAwlWUXis8RS3ZPe7LAq+YUxsRa0l3r27MLA==", + "peer": true, "requires": { "fsevents": "~2.3.2" } @@ -27129,6 +27184,7 @@ "version": "1.52.3", "resolved": "https://registry.npmjs.org/sass/-/sass-1.52.3.tgz", "integrity": "sha512-LNNPJ9lafx+j1ArtA7GyEJm9eawXN8KlA1+5dF6IZyoONg1Tyo/g+muOsENWJH/2Q1FHbbV4UwliU0cXMa/VIA==", + "peer": true, "requires": { "chokidar": ">=3.0.0 <4.0.0", "immutable": "^4.0.0", @@ -27616,6 +27672,7 @@ "version": "5.3.5", "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.5.tgz", "integrity": "sha512-ndETJ9RKaaL6q41B69WudeqLzOpY1A/ET/glXkNZ2T7dPjPqpPCXXQjDFYZWwNnE5co0wX+gTCqx9mfxTmSIPg==", + "peer": true, "requires": { "@babel/helper-module-imports": "^7.0.0", "@babel/traverse": "^7.4.5", @@ -28004,7 +28061,8 @@ "type-fest": { "version": "0.21.3", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==" + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "peer": true }, "type-is": { "version": "1.6.18", @@ -28026,7 +28084,8 @@ "typescript": { "version": "4.7.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.3.tgz", - "integrity": "sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==" + "integrity": "sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA==", + "peer": true }, "unbox-primitive": { "version": "1.0.2", @@ -28205,6 +28264,7 @@ "version": "5.73.0", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.73.0.tgz", "integrity": "sha512-svjudQRPPa0YiOYa2lM/Gacw0r6PvxptHj4FuEKQ2kX05ZLkjbVc5MnPs6its5j7IZljnIqSVo/OsY2X0IpHGA==", + "peer": true, "requires": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^0.0.51", @@ -28264,6 +28324,7 @@ "version": "8.11.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "peer": true, "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -28301,6 +28362,7 @@ "version": "4.9.2", "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.9.2.tgz", "integrity": "sha512-H95Ns95dP24ZsEzO6G9iT+PNw4Q7ltll1GfJHV4fKphuHWgKFzGHWi4alTlTnpk1SPPk41X+l2RB7rLfIhnB9Q==", + "peer": true, "requires": { "@types/bonjour": "^3.5.9", "@types/connect-history-api-fallback": "^1.3.5", @@ -28337,6 +28399,7 @@ "version": "8.11.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "peer": true, "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", @@ -28559,6 +28622,7 @@ "version": "8.11.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "peer": true, "requires": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", diff --git a/src/api/lib.ts b/src/api/lib.ts index 3c593ca..d4125c8 100644 --- a/src/api/lib.ts +++ b/src/api/lib.ts @@ -1,53 +1,83 @@ import axios from 'axios' +// Ensure this matches your project structure for the static user data import { user } from '../data/user' import { Goal, Transaction, User } from './types' +/** + * Switch between the Azure URL and localhost depending on your environment. + * If you are running your .NET backend locally, change this to: + * export const API_ROOT = 'http://localhost:5203' + */ export const API_ROOT = 'https://fencer-commbank.azurewebsites.net' +/** + * Fetches the current user profile from the backend + */ export async function getUser(): Promise { try { const response = await axios.get(`${API_ROOT}/api/User/${user.id}`) return response.data } catch (error: any) { + console.error("Error fetching user:", error) return null } } +/** + * Fetches all transactions belonging to the current user + */ export async function getTransactions(): Promise { try { const response = await axios.get(`${API_ROOT}/api/Transaction/User/${user.id}`) return response.data } catch (error: any) { + console.error("Error fetching transactions:", error) return null } } +/** + * Fetches all goals belonging to the current user + */ export async function getGoals(): Promise { try { const response = await axios.get(`${API_ROOT}/api/Goal/User/${user.id}`) return response.data } catch (error: any) { + console.error("Error fetching goals:", error) return null } } +/** + * Creates a new goal with a default name and current date + */ export async function createGoal(): Promise { try { const response = await axios.post(`${API_ROOT}/api/Goal`, { userId: user.id, + name: "New Goal", // Providing a default name helps the backend targetDate: new Date(), + targetAmount: 0, }) return response.data } catch (error: any) { + console.error("Error creating goal:", error) return null } } +/** + * Updates an existing goal (Task 3 Core Requirement) + * This PUT request ensures your Icon changes persist in the Database. + */ export async function updateGoal(goalId: string, updatedGoal: Goal): Promise { try { + // Sends the full goal object (including the new Icon field) to the server await axios.put(`${API_ROOT}/api/Goal/${goalId}`, updatedGoal) return true } catch (error: any) { + console.error("Error updating goal:", error) return false } -} +} \ No newline at end of file diff --git a/src/api/types.ts b/src/api/types.ts index f75edad..5fe39b9 100644 --- a/src/api/types.ts +++ b/src/api/types.ts @@ -27,6 +27,7 @@ export interface Goal { accountId: string transactionIds: string[] tagIds: string[] + icon?: string // Added optional icon field } export interface Tag { @@ -65,4 +66,4 @@ export enum ApplicationStatus { } export type ModalContent = Goal -export type ModalType = 'Goal' +export type ModalType = 'Goal' \ No newline at end of file diff --git a/src/index.tsx b/src/index.tsx index 6b11d2e..4b0ebe2 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -14,4 +14,4 @@ ReactDOM.render( document.getElementById('root'), ) -export {} +export { } diff --git a/src/ui/features/goalmanager/GoalManager.tsx b/src/ui/features/goalmanager/GoalManager.tsx index 0779dda..82a4303 100644 --- a/src/ui/features/goalmanager/GoalManager.tsx +++ b/src/ui/features/goalmanager/GoalManager.tsx @@ -1,8 +1,10 @@ -import { faCalendarAlt } from '@fortawesome/free-regular-svg-icons' +import { faCalendarAlt, faSmile } from '@fortawesome/free-regular-svg-icons' import { faDollarSign, IconDefinition } from '@fortawesome/free-solid-svg-icons' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { MaterialUiPickersDate } from '@material-ui/pickers/typings/date' import 'date-fns' +import { Picker } from 'emoji-mart' +import 'emoji-mart/css/emoji-mart.css' import React, { useEffect, useState } from 'react' import styled from 'styled-components' import { updateGoal as updateGoalApi } from '../../../api/lib' @@ -21,22 +23,42 @@ export function GoalManager(props: Props) { const [name, setName] = useState(null) const [targetDate, setTargetDate] = useState(null) const [targetAmount, setTargetAmount] = useState(null) + const [icon, setIcon] = useState(undefined) + const [showEmojiPicker, setShowEmojiPicker] = useState(false) useEffect(() => { setName(props.goal.name) setTargetDate(props.goal.targetDate) setTargetAmount(props.goal.targetAmount) + setIcon(props.goal.icon) }, [ props.goal.id, props.goal.name, props.goal.targetDate, props.goal.targetAmount, + props.goal.icon ]) useEffect(() => { setName(goal.name) }, [goal.name]) + const handleIconSelect = (emoji: any) => { + const nextIcon = emoji.native + setIcon(nextIcon) + setShowEmojiPicker(false) + + const updatedGoal: Goal = { + ...props.goal, + name: name ?? props.goal.name, + targetDate: targetDate ?? props.goal.targetDate, + targetAmount: targetAmount ?? props.goal.targetAmount, + icon: nextIcon + } + dispatch(updateGoalRedux(updatedGoal)) + updateGoalApi(props.goal.id, updatedGoal) + } + const updateNameOnChange = (event: React.ChangeEvent) => { const nextName = event.target.value setName(nextName) @@ -77,7 +99,18 @@ export function GoalManager(props: Props) { return ( - + + setShowEmojiPicker(!showEmojiPicker)}> + {icon ? {icon} : } + + + + + {showEmojiPicker && ( + + + + )} @@ -110,12 +143,7 @@ export function GoalManager(props: Props) { ) } -type FieldProps = { name: string; icon: IconDefinition } -type AddIconButtonContainerProps = { shouldShow: boolean } -type GoalIconContainerProps = { shouldShow: boolean } -type EmojiPickerContainerProps = { isOpen: boolean; hasIcon: boolean } - -const Field = (props: FieldProps) => ( +const Field = (props: { name: string; icon: IconDefinition }) => ( {props.name} @@ -132,6 +160,33 @@ const GoalManagerContainer = styled.div` position: relative; ` +const Row = styled.div` + display: flex; + flex-direction: row; + align-items: center; + gap: 2rem; +` + +const EmojiTrigger = styled.div` + cursor: pointer; + color: rgba(174, 174, 174, 1); + transition: transform 0.2s; + &:hover { + transform: scale(1.1); + } +` + +const SelectedEmoji = styled.span` + font-size: 4rem; +` + +const PickerWrapper = styled.div` + position: absolute; + top: 6rem; + left: 0; + z-index: 100; +` + const Group = styled.div` display: flex; flex-direction: row; @@ -160,7 +215,6 @@ const FieldContainer = styled.div` flex-direction: row; align-items: center; width: 20rem; - svg { color: rgba(174, 174, 174, 1); } @@ -178,7 +232,6 @@ const StringInput = styled.input` font-weight: bold; color: ${({ theme }: { theme: Theme }) => theme.text}; ` - const Value = styled.div` margin-left: 2rem; -` +` \ No newline at end of file diff --git a/src/ui/pages/Main/goals/GoalCard.tsx b/src/ui/pages/Main/goals/GoalCard.tsx index e8f6d0a..fa28f61 100644 --- a/src/ui/pages/Main/goals/GoalCard.tsx +++ b/src/ui/pages/Main/goals/GoalCard.tsx @@ -27,6 +27,7 @@ export default function GoalCard(props: Props) { return ( + {goal.icon ?? '🎯'} ${goal.targetAmount} {asLocaleDateString(goal.targetDate)} @@ -43,14 +44,22 @@ const Container = styled(Card)` margin-left: 2rem; margin-right: 2rem; border-radius: 2rem; - + justify-content: center; align-items: center; ` + +const IconDisplay = styled.div` + font-size: 3rem; + margin-bottom: 0.5rem; +` + const TargetAmount = styled.h2` font-size: 2rem; + margin: 0; ` const TargetDate = styled.h4` color: rgba(174, 174, 174, 1); font-size: 1rem; -` + margin: 0.5rem 0 0 0; +` \ No newline at end of file diff --git a/src/ui/pages/Main/transactions/TransactionItem.tsx b/src/ui/pages/Main/transactions/TransactionItem.tsx index f8d4cb3..b5238bd 100644 --- a/src/ui/pages/Main/transactions/TransactionItem.tsx +++ b/src/ui/pages/Main/transactions/TransactionItem.tsx @@ -27,7 +27,7 @@ export function TransactionItem(props: Props) { } fetchAll() - }) + }, [props.transaction.tagIds]) return ( diff --git a/src/ui/pages/Main/transactions/TransactionsContent.tsx b/src/ui/pages/Main/transactions/TransactionsContent.tsx index d898517..851f69f 100644 --- a/src/ui/pages/Main/transactions/TransactionsContent.tsx +++ b/src/ui/pages/Main/transactions/TransactionsContent.tsx @@ -8,8 +8,8 @@ export default function TransactionsContent(props: Props) { if (!props.transactions) return null return ( <> - {props.transactions.sort(sortByDateDesc).map((transaction) => ( - + {[...props.transactions].sort(sortByDateDesc).map((transaction) => ( + ))} )