diff --git a/package-lock.json b/package-lock.json index 4421d68..3f03fe4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -40,7 +40,7 @@ "react-query": "^3.32.3", "react-redux": "^7.2.6", "react-responsive-carousel": "^3.2.22", - "react-router-dom": "^6.0.2", + "react-router-dom": "^6.2.2", "react-scripts": "4.0.3", "react-use": "^17.3.1", "typescript": "^4.4.4", @@ -64,6 +64,7 @@ "@types/react-copy-to-clipboard": "^5.0.2", "autoprefixer": "^9.8.8", "gh-pages": "^3.2.3", + "msw": "^0.39.1", "netlify-cli": "^8.15.0", "postcss": "^7.0.39", "tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.2.17" @@ -4058,6 +4059,33 @@ "node": ">=4" } }, + "node_modules/@mswjs/cookies": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@mswjs/cookies/-/cookies-0.1.7.tgz", + "integrity": "sha512-bDg1ReMBx+PYDB4Pk7y1Q07Zz1iKIEUWQpkEXiA2lEWg9gvOZ8UBmGXilCEUvyYoRFlmr/9iXTRR69TrgSwX/Q==", + "dev": true, + "dependencies": { + "@types/set-cookie-parser": "^2.4.0", + "set-cookie-parser": "^2.4.6" + } + }, + "node_modules/@mswjs/interceptors": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.14.1.tgz", + "integrity": "sha512-E+0qtLySvVC4cIo5vlqDXn7BAtAgyVJe9hJjGorfbbClvTRNWMym9V70jhNB11y9txcd6ZPXbgxf2dMT73jGmw==", + "dev": true, + "dependencies": { + "@open-draft/until": "^1.0.3", + "@xmldom/xmldom": "^0.7.5", + "debug": "^4.3.3", + "headers-polyfill": "^3.0.4", + "outvariant": "^1.2.1", + "strict-event-emitter": "^0.2.0" + }, + "engines": { + "node": ">=16.x" + } + }, "node_modules/@n1ru4l/graphql-live-query": { "version": "0.9.0", "integrity": "sha512-BTpWy1e+FxN82RnLz4x1+JcEewVdfmUhV1C6/XYD5AjS7PQp9QFF7K8bCD6gzPTr2l+prvqOyVueQhFJxB1vfg==", @@ -4143,6 +4171,12 @@ "node": ">=10" } }, + "node_modules/@open-draft/until": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@open-draft/until/-/until-1.0.3.tgz", + "integrity": "sha512-Aq58f5HiWdyDlFffbbSjAlv596h/cOnt2DO1w3DOC7OJ5EHs0hd/nycJfiu9RJbT6Yk6F1knnRRXNSpxoIVZ9Q==", + "dev": true + }, "node_modules/@pmmmwh/react-refresh-webpack-plugin": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.4.3.tgz", @@ -8181,6 +8215,12 @@ "@types/node": "*" } }, + "node_modules/@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", + "dev": true + }, "node_modules/@types/cors": { "version": "2.8.12", "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", @@ -8319,6 +8359,12 @@ "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.7.tgz", "integrity": "sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==" }, + "node_modules/@types/js-levenshtein": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/js-levenshtein/-/js-levenshtein-1.1.1.tgz", + "integrity": "sha512-qC4bCqYGy1y/NP7dDVr7KJarn+PbX1nSpwA7JXdu0HxT3QYjO8MJ+cntENtHFVy2dRAyBV23OZ6MxsW1AM1L8g==", + "dev": true + }, "node_modules/@types/js-yaml": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.5.tgz", @@ -8552,6 +8598,15 @@ "@types/node": "*" } }, + "node_modules/@types/set-cookie-parser": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@types/set-cookie-parser/-/set-cookie-parser-2.4.2.tgz", + "integrity": "sha512-fBZgytwhYAUkj/jC/FAV4RQ5EerRup1YQsXQCh8rZfiHkc4UahC192oH0smGwsXol3cL3A5oETuAHeQHmhXM4w==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/source-list-map": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", @@ -9061,6 +9116,15 @@ "node": ">=8" } }, + "node_modules/@xmldom/xmldom": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.5.tgz", + "integrity": "sha512-V3BIhmY36fXZ1OtVcI9W+FxQqxVLsPKcNjWigIaa81dLC9IolJl5Mt4Cvhmr0flUnjSpTdrbMTSbXqYqV5dT6A==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/@xobotyi/scrollbar-width": { "version": "1.9.5", "resolved": "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz", @@ -10815,6 +10879,55 @@ "node": ">=8.0.0" } }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -11989,6 +12102,18 @@ "node": ">=8" } }, + "node_modules/cli-spinners": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", + "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/cli-table3": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.0.tgz", @@ -12093,6 +12218,15 @@ "wrap-ansi": "^6.2.0" } }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, "node_modules/clone-deep": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", @@ -13449,8 +13583,9 @@ "dev": true }, "node_modules/debug": { - "version": "4.3.2", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "dependencies": { "ms": "2.1.2" }, @@ -13665,6 +13800,15 @@ "which": "bin/which" } }, + "node_modules/defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + } + }, "node_modules/defer-to-connect": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", @@ -17564,6 +17708,12 @@ "tslib": "^2.0.3" } }, + "node_modules/headers-polyfill": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-3.0.4.tgz", + "integrity": "sha512-I1DOM1EdWYntdrnCvqQtcKwSSuiTzoqOExy4v1mdcFixFZABlWP4IPHdmoLtPda0abMHqDOY4H9svhQ10DFR4w==", + "dev": true + }, "node_modules/hex-color-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", @@ -17584,8 +17734,9 @@ } }, "node_modules/history": { - "version": "5.1.0", - "integrity": "sha512-zPuQgPacm2vH2xdORvGGz1wQMuHSIB56yNAy5FnLuwOwgSYyPKptJtcMm6Ev+hRGeS+GzhbmRacHzvlESbFwDg==", + "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" } @@ -18693,6 +18844,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/is-lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-2.0.2.tgz", @@ -18727,6 +18887,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-node-process": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.0.1.tgz", + "integrity": "sha512-5IcdXuf++TTNt3oGl9EBdkvndXA8gmc4bz/Y+mdEpWh3Mcn/+kOw6hI7LD5CocqJWMzeb0I0ClndRVNdEPuJXQ==", + "dev": true + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -20905,6 +21071,15 @@ "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==" }, + "node_modules/js-levenshtein": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", + "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", @@ -22502,6 +22677,257 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "node_modules/msw": { + "version": "0.39.1", + "resolved": "https://registry.npmjs.org/msw/-/msw-0.39.1.tgz", + "integrity": "sha512-IiM1F94Ecp3iyHUPpbmEIUcxmNB2HHOmUaEOBsbbHNGnfSg+IGgB3VsXjXOEVPHJCgeoeJc2rJywD7u4wEgOTw==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@mswjs/cookies": "^0.1.7", + "@mswjs/interceptors": "^0.14.1", + "@open-draft/until": "^1.0.3", + "@types/cookie": "^0.4.1", + "@types/js-levenshtein": "^1.1.1", + "chalk": "4.1.1", + "chokidar": "^3.4.2", + "cookie": "^0.4.2", + "graphql": "^16.3.0", + "headers-polyfill": "^3.0.4", + "inquirer": "^8.2.0", + "is-node-process": "^1.0.1", + "js-levenshtein": "^1.1.6", + "node-fetch": "^2.6.7", + "path-to-regexp": "^6.2.0", + "statuses": "^2.0.0", + "strict-event-emitter": "^0.2.0", + "type-fest": "^1.2.2", + "yargs": "^17.3.1" + }, + "bin": { + "msw": "cli/index.js" + }, + "engines": { + "node": ">=16.x" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mswjs" + } + }, + "node_modules/msw/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/msw/node_modules/chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/msw/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/msw/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/msw/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/msw/node_modules/cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/msw/node_modules/graphql": { + "version": "16.3.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.3.0.tgz", + "integrity": "sha512-xm+ANmA16BzCT5pLjuXySbQVFwH3oJctUVdy81w1sV0vBU0KgDdBGtxQOUd5zqOBk/JayAFeG8Dlmeq74rjm/A==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.16.0 || >=16.0.0" + } + }, + "node_modules/msw/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/msw/node_modules/inquirer": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.1.tgz", + "integrity": "sha512-pxhBaw9cyTFMjwKtkjePWDhvwzvrNGAw7En4hottzlPvz80GZaMZthdDU35aA6/f5FRZf3uhE057q8w1DE3V2g==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/msw/node_modules/path-to-regexp": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.0.tgz", + "integrity": "sha512-f66KywYG6+43afgE/8j/GoiNyygk/bnoCbps++3ErRKsIYkGGupyv07R2Ok5m9i67Iqc+T2g1eAUGUPzWhYTyg==", + "dev": true + }, + "node_modules/msw/node_modules/rxjs": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", + "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/msw/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/msw/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/msw/node_modules/type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/msw/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/msw/node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/msw/node_modules/yargs": { + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz", + "integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/msw/node_modules/yargs-parser": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", + "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/multicast-dns": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", @@ -45725,14 +46151,22 @@ } }, "node_modules/node-fetch": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz", - "integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==", + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", "dependencies": { "whatwg-url": "^5.0.0" }, "engines": { "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } } }, "node_modules/node-fetch/node_modules/tr46": { @@ -46311,6 +46745,99 @@ "node": ">= 0.8.0" } }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/ora/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/ora/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/ora/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/ora/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/original": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", @@ -46333,6 +46860,12 @@ "node": ">=0.10.0" } }, + "node_modules/outvariant": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.2.1.tgz", + "integrity": "sha512-bcILvFkvpMXh66+Ubax/inxbKRyWTUiiFIW2DWkiS79wakrLGn3Ydy+GvukadiyfZjaL6C7YhIem4EZSM282wA==", + "dev": true + }, "node_modules/overlayscrollbars": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/overlayscrollbars/-/overlayscrollbars-1.13.1.tgz", @@ -49383,21 +49916,23 @@ } }, "node_modules/react-router": { - "version": "6.0.2", - "integrity": "sha512-8/Wm3Ed8t7TuedXjAvV39+c8j0vwrI5qVsYqjFr5WkJjsJpEvNSoLRUbtqSEYzqaTUj1IV+sbPJxvO+accvU0Q==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.2.tgz", + "integrity": "sha512-/MbxyLzd7Q7amp4gDOGaYvXwhEojkJD5BtExkuKmj39VEE0m3l/zipf6h2WIB2jyAO0lI6NGETh4RDcktRm4AQ==", "dependencies": { - "history": "^5.1.0" + "history": "^5.2.0" }, "peerDependencies": { "react": ">=16.8" } }, "node_modules/react-router-dom": { - "version": "6.0.2", - "integrity": "sha512-cOpJ4B6raFutr0EG8O/M2fEoyQmwvZWomf1c6W2YXBZuFBx8oTk/zqjXghwScyhfrtnt0lANXV2182NQblRxFA==", + "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.1.0", - "react-router": "6.0.2" + "history": "^5.2.0", + "react-router": "6.2.2" }, "peerDependencies": { "react": ">=16.8", @@ -51205,6 +51740,12 @@ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, + "node_modules/set-cookie-parser": { + "version": "2.4.8", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.4.8.tgz", + "integrity": "sha512-edRH8mBKEWNVIVMKejNnuJxleqYE/ZSdcT8/Nem9/mmosx12pctd80s2Oy00KNZzrogMZS5mauK2/ymL1bvlvg==", + "dev": true + }, "node_modules/set-harmonic-interval": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/set-harmonic-interval/-/set-harmonic-interval-1.0.1.tgz", @@ -52026,6 +52567,15 @@ "xtend": "^4.0.0" } }, + "node_modules/strict-event-emitter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.2.0.tgz", + "integrity": "sha512-zv7K2egoKwkQkZGEaH8m+i2D0XiKzx5jNsiSul6ja2IYFvil10A59Z9Y7PPAAe5OW53dQUf9CfsHKzjZzKkm1w==", + "dev": true, + "dependencies": { + "events": "^3.3.0" + } + }, "node_modules/strict-uri-encode": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", @@ -54671,6 +55221,15 @@ "minimalistic-assert": "^1.0.0" } }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, "node_modules/web-namespaces": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.4.tgz", @@ -58984,6 +59543,30 @@ "glob-to-regexp": "^0.3.0" } }, + "@mswjs/cookies": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/@mswjs/cookies/-/cookies-0.1.7.tgz", + "integrity": "sha512-bDg1ReMBx+PYDB4Pk7y1Q07Zz1iKIEUWQpkEXiA2lEWg9gvOZ8UBmGXilCEUvyYoRFlmr/9iXTRR69TrgSwX/Q==", + "dev": true, + "requires": { + "@types/set-cookie-parser": "^2.4.0", + "set-cookie-parser": "^2.4.6" + } + }, + "@mswjs/interceptors": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.14.1.tgz", + "integrity": "sha512-E+0qtLySvVC4cIo5vlqDXn7BAtAgyVJe9hJjGorfbbClvTRNWMym9V70jhNB11y9txcd6ZPXbgxf2dMT73jGmw==", + "dev": true, + "requires": { + "@open-draft/until": "^1.0.3", + "@xmldom/xmldom": "^0.7.5", + "debug": "^4.3.3", + "headers-polyfill": "^3.0.4", + "outvariant": "^1.2.1", + "strict-event-emitter": "^0.2.0" + } + }, "@n1ru4l/graphql-live-query": { "version": "0.9.0", "integrity": "sha512-BTpWy1e+FxN82RnLz4x1+JcEewVdfmUhV1C6/XYD5AjS7PQp9QFF7K8bCD6gzPTr2l+prvqOyVueQhFJxB1vfg==", @@ -59047,6 +59630,12 @@ } } }, + "@open-draft/until": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@open-draft/until/-/until-1.0.3.tgz", + "integrity": "sha512-Aq58f5HiWdyDlFffbbSjAlv596h/cOnt2DO1w3DOC7OJ5EHs0hd/nycJfiu9RJbT6Yk6F1knnRRXNSpxoIVZ9Q==", + "dev": true + }, "@pmmmwh/react-refresh-webpack-plugin": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.4.3.tgz", @@ -61821,6 +62410,12 @@ "@types/node": "*" } }, + "@types/cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", + "dev": true + }, "@types/cors": { "version": "2.8.12", "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", @@ -61959,6 +62554,12 @@ "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.7.tgz", "integrity": "sha512-aLkWa0C0vO5b4Sr798E26QgOkss68Un0bLjs7u9qxzPT5CG+8DuNTffWES58YzJs3hrVAOs1wonycqEBqNJubA==" }, + "@types/js-levenshtein": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/js-levenshtein/-/js-levenshtein-1.1.1.tgz", + "integrity": "sha512-qC4bCqYGy1y/NP7dDVr7KJarn+PbX1nSpwA7JXdu0HxT3QYjO8MJ+cntENtHFVy2dRAyBV23OZ6MxsW1AM1L8g==", + "dev": true + }, "@types/js-yaml": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.5.tgz", @@ -62192,6 +62793,15 @@ "@types/node": "*" } }, + "@types/set-cookie-parser": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@types/set-cookie-parser/-/set-cookie-parser-2.4.2.tgz", + "integrity": "sha512-fBZgytwhYAUkj/jC/FAV4RQ5EerRup1YQsXQCh8rZfiHkc4UahC192oH0smGwsXol3cL3A5oETuAHeQHmhXM4w==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/source-list-map": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", @@ -62601,6 +63211,12 @@ "tslib": "^2.3.0" } }, + "@xmldom/xmldom": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.5.tgz", + "integrity": "sha512-V3BIhmY36fXZ1OtVcI9W+FxQqxVLsPKcNjWigIaa81dLC9IolJl5Mt4Cvhmr0flUnjSpTdrbMTSbXqYqV5dT6A==", + "dev": true + }, "@xobotyi/scrollbar-width": { "version": "1.9.5", "resolved": "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz", @@ -63982,6 +64598,40 @@ "wif": "^2.0.1" } }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -64913,6 +65563,12 @@ "restore-cursor": "^3.1.0" } }, + "cli-spinners": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", + "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", + "dev": true + }, "cli-table3": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.0.tgz", @@ -64993,6 +65649,12 @@ "wrap-ansi": "^6.2.0" } }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + }, "clone-deep": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", @@ -66093,8 +66755,9 @@ "dev": true }, "debug": { - "version": "4.3.2", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", + "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", "requires": { "ms": "2.1.2" } @@ -66252,6 +66915,15 @@ } } }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "requires": { + "clone": "^1.0.2" + } + }, "defer-to-connect": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", @@ -69239,6 +69911,12 @@ "tslib": "^2.0.3" } }, + "headers-polyfill": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/headers-polyfill/-/headers-polyfill-3.0.4.tgz", + "integrity": "sha512-I1DOM1EdWYntdrnCvqQtcKwSSuiTzoqOExy4v1mdcFixFZABlWP4IPHdmoLtPda0abMHqDOY4H9svhQ10DFR4w==", + "dev": true + }, "hex-color-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", @@ -69256,8 +69934,9 @@ "dev": true }, "history": { - "version": "5.1.0", - "integrity": "sha512-zPuQgPacm2vH2xdORvGGz1wQMuHSIB56yNAy5FnLuwOwgSYyPKptJtcMm6Ev+hRGeS+GzhbmRacHzvlESbFwDg==", + "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" } @@ -70102,6 +70781,12 @@ "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", "dev": true }, + "is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true + }, "is-lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-2.0.2.tgz", @@ -70127,6 +70812,12 @@ "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.1.tgz", "integrity": "sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==" }, + "is-node-process": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.0.1.tgz", + "integrity": "sha512-5IcdXuf++TTNt3oGl9EBdkvndXA8gmc4bz/Y+mdEpWh3Mcn/+kOw6hI7LD5CocqJWMzeb0I0ClndRVNdEPuJXQ==", + "dev": true + }, "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -71726,6 +72417,12 @@ "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", "integrity": "sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==" }, + "js-levenshtein": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", + "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", + "dev": true + }, "js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", @@ -72983,6 +73680,194 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, + "msw": { + "version": "0.39.1", + "resolved": "https://registry.npmjs.org/msw/-/msw-0.39.1.tgz", + "integrity": "sha512-IiM1F94Ecp3iyHUPpbmEIUcxmNB2HHOmUaEOBsbbHNGnfSg+IGgB3VsXjXOEVPHJCgeoeJc2rJywD7u4wEgOTw==", + "dev": true, + "requires": { + "@mswjs/cookies": "^0.1.7", + "@mswjs/interceptors": "^0.14.1", + "@open-draft/until": "^1.0.3", + "@types/cookie": "^0.4.1", + "@types/js-levenshtein": "^1.1.1", + "chalk": "4.1.1", + "chokidar": "^3.4.2", + "cookie": "^0.4.2", + "graphql": "^16.3.0", + "headers-polyfill": "^3.0.4", + "inquirer": "^8.2.0", + "is-node-process": "^1.0.1", + "js-levenshtein": "^1.1.6", + "node-fetch": "^2.6.7", + "path-to-regexp": "^6.2.0", + "statuses": "^2.0.0", + "strict-event-emitter": "^0.2.0", + "type-fest": "^1.2.2", + "yargs": "^17.3.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "cookie": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", + "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "dev": true + }, + "graphql": { + "version": "16.3.0", + "resolved": "https://registry.npmjs.org/graphql/-/graphql-16.3.0.tgz", + "integrity": "sha512-xm+ANmA16BzCT5pLjuXySbQVFwH3oJctUVdy81w1sV0vBU0KgDdBGtxQOUd5zqOBk/JayAFeG8Dlmeq74rjm/A==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "inquirer": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.1.tgz", + "integrity": "sha512-pxhBaw9cyTFMjwKtkjePWDhvwzvrNGAw7En4hottzlPvz80GZaMZthdDU35aA6/f5FRZf3uhE057q8w1DE3V2g==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + } + }, + "path-to-regexp": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.0.tgz", + "integrity": "sha512-f66KywYG6+43afgE/8j/GoiNyygk/bnoCbps++3ErRKsIYkGGupyv07R2Ok5m9i67Iqc+T2g1eAUGUPzWhYTyg==", + "dev": true + }, + "rxjs": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", + "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "type-fest": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-1.4.0.tgz", + "integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yargs": { + "version": "17.3.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.3.1.tgz", + "integrity": "sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.0.0" + } + }, + "yargs-parser": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", + "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", + "dev": true + } + } + }, "multicast-dns": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", @@ -90808,9 +91693,9 @@ } }, "node-fetch": { - "version": "2.6.6", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.6.tgz", - "integrity": "sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==", + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", "requires": { "whatwg-url": "^5.0.0" }, @@ -91266,6 +92151,74 @@ "word-wrap": "^1.2.3" } }, + "ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "requires": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "original": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", @@ -91285,6 +92238,12 @@ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, + "outvariant": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.2.1.tgz", + "integrity": "sha512-bcILvFkvpMXh66+Ubax/inxbKRyWTUiiFIW2DWkiS79wakrLGn3Ydy+GvukadiyfZjaL6C7YhIem4EZSM282wA==", + "dev": true + }, "overlayscrollbars": { "version": "1.13.1", "resolved": "https://registry.npmjs.org/overlayscrollbars/-/overlayscrollbars-1.13.1.tgz", @@ -93671,18 +94630,20 @@ } }, "react-router": { - "version": "6.0.2", - "integrity": "sha512-8/Wm3Ed8t7TuedXjAvV39+c8j0vwrI5qVsYqjFr5WkJjsJpEvNSoLRUbtqSEYzqaTUj1IV+sbPJxvO+accvU0Q==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.2.2.tgz", + "integrity": "sha512-/MbxyLzd7Q7amp4gDOGaYvXwhEojkJD5BtExkuKmj39VEE0m3l/zipf6h2WIB2jyAO0lI6NGETh4RDcktRm4AQ==", "requires": { - "history": "^5.1.0" + "history": "^5.2.0" } }, "react-router-dom": { - "version": "6.0.2", - "integrity": "sha512-cOpJ4B6raFutr0EG8O/M2fEoyQmwvZWomf1c6W2YXBZuFBx8oTk/zqjXghwScyhfrtnt0lANXV2182NQblRxFA==", + "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.1.0", - "react-router": "6.0.2" + "history": "^5.2.0", + "react-router": "6.2.2" } }, "react-scripts": { @@ -95122,6 +96083,12 @@ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, + "set-cookie-parser": { + "version": "2.4.8", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.4.8.tgz", + "integrity": "sha512-edRH8mBKEWNVIVMKejNnuJxleqYE/ZSdcT8/Nem9/mmosx12pctd80s2Oy00KNZzrogMZS5mauK2/ymL1bvlvg==", + "dev": true + }, "set-harmonic-interval": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/set-harmonic-interval/-/set-harmonic-interval-1.0.1.tgz", @@ -95814,6 +96781,15 @@ "xtend": "^4.0.0" } }, + "strict-event-emitter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.2.0.tgz", + "integrity": "sha512-zv7K2egoKwkQkZGEaH8m+i2D0XiKzx5jNsiSul6ja2IYFvil10A59Z9Y7PPAAe5OW53dQUf9CfsHKzjZzKkm1w==", + "dev": true, + "requires": { + "events": "^3.3.0" + } + }, "strict-uri-encode": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", @@ -97823,6 +98799,15 @@ "minimalistic-assert": "^1.0.0" } }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, "web-namespaces": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.4.tgz", diff --git a/package.json b/package.json index bd1a3c2..2d86365 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "react-query": "^3.32.3", "react-redux": "^7.2.6", "react-responsive-carousel": "^3.2.22", - "react-router-dom": "^6.0.2", + "react-router-dom": "^6.2.2", "react-scripts": "4.0.3", "react-use": "^17.3.1", "typescript": "^4.4.4", @@ -107,8 +107,12 @@ "@types/react-copy-to-clipboard": "^5.0.2", "autoprefixer": "^9.8.8", "gh-pages": "^3.2.3", + "msw": "^0.39.1", "netlify-cli": "^8.15.0", "postcss": "^7.0.39", "tailwindcss": "npm:@tailwindcss/postcss7-compat@^2.2.17" + }, + "msw": { + "workerDirectory": "public" } -} +} \ No newline at end of file diff --git a/public/mockServiceWorker.js b/public/mockServiceWorker.js new file mode 100644 index 0000000..ba0c013 --- /dev/null +++ b/public/mockServiceWorker.js @@ -0,0 +1,338 @@ +/* eslint-disable */ +/* tslint:disable */ + +/** + * Mock Service Worker (0.39.1). + * @see https://github.com/mswjs/msw + * - Please do NOT modify this file. + * - Please do NOT serve this file on production. + */ + +const INTEGRITY_CHECKSUM = '02f4ad4a2797f85668baf196e553d929' +const bypassHeaderName = 'x-msw-bypass' +const activeClientIds = new Set() + +self.addEventListener('install', function () { + return self.skipWaiting() +}) + +self.addEventListener('activate', async function (event) { + return self.clients.claim() +}) + +self.addEventListener('message', async function (event) { + const clientId = event.source.id + + if (!clientId || !self.clients) { + return + } + + const client = await self.clients.get(clientId) + + if (!client) { + return + } + + const allClients = await self.clients.matchAll() + + switch (event.data) { + case 'KEEPALIVE_REQUEST': { + sendToClient(client, { + type: 'KEEPALIVE_RESPONSE', + }) + break + } + + case 'INTEGRITY_CHECK_REQUEST': { + sendToClient(client, { + type: 'INTEGRITY_CHECK_RESPONSE', + payload: INTEGRITY_CHECKSUM, + }) + break + } + + case 'MOCK_ACTIVATE': { + activeClientIds.add(clientId) + + sendToClient(client, { + type: 'MOCKING_ENABLED', + payload: true, + }) + break + } + + case 'MOCK_DEACTIVATE': { + activeClientIds.delete(clientId) + break + } + + case 'CLIENT_CLOSED': { + activeClientIds.delete(clientId) + + const remainingClients = allClients.filter((client) => { + return client.id !== clientId + }) + + // Unregister itself when there are no more clients + if (remainingClients.length === 0) { + self.registration.unregister() + } + + break + } + } +}) + +// Resolve the "main" client for the given event. +// Client that issues a request doesn't necessarily equal the client +// that registered the worker. It's with the latter the worker should +// communicate with during the response resolving phase. +async function resolveMainClient(event) { + const client = await self.clients.get(event.clientId) + + if (client.frameType === 'top-level') { + return client + } + + const allClients = await self.clients.matchAll() + + return allClients + .filter((client) => { + // Get only those clients that are currently visible. + return client.visibilityState === 'visible' + }) + .find((client) => { + // Find the client ID that's recorded in the + // set of clients that have registered the worker. + return activeClientIds.has(client.id) + }) +} + +async function handleRequest(event, requestId) { + const client = await resolveMainClient(event) + const response = await getResponse(event, client, requestId) + + // Send back the response clone for the "response:*" life-cycle events. + // Ensure MSW is active and ready to handle the message, otherwise + // this message will pend indefinitely. + if (client && activeClientIds.has(client.id)) { + ;(async function () { + const clonedResponse = response.clone() + sendToClient(client, { + type: 'RESPONSE', + payload: { + requestId, + type: clonedResponse.type, + ok: clonedResponse.ok, + status: clonedResponse.status, + statusText: clonedResponse.statusText, + body: + clonedResponse.body === null ? null : await clonedResponse.text(), + headers: serializeHeaders(clonedResponse.headers), + redirected: clonedResponse.redirected, + }, + }) + })() + } + + return response +} + +async function getResponse(event, client, requestId) { + const { request } = event + const requestClone = request.clone() + const getOriginalResponse = () => fetch(requestClone) + + // Bypass mocking when the request client is not active. + if (!client) { + return getOriginalResponse() + } + + // Bypass initial page load requests (i.e. static assets). + // The absence of the immediate/parent client in the map of the active clients + // means that MSW hasn't dispatched the "MOCK_ACTIVATE" event yet + // and is not ready to handle requests. + if (!activeClientIds.has(client.id)) { + return await getOriginalResponse() + } + + // Bypass requests with the explicit bypass header + if (requestClone.headers.get(bypassHeaderName) === 'true') { + const cleanRequestHeaders = serializeHeaders(requestClone.headers) + + // Remove the bypass header to comply with the CORS preflight check. + delete cleanRequestHeaders[bypassHeaderName] + + const originalRequest = new Request(requestClone, { + headers: new Headers(cleanRequestHeaders), + }) + + return fetch(originalRequest) + } + + // Send the request to the client-side MSW. + const reqHeaders = serializeHeaders(request.headers) + const body = await request.text() + + const clientMessage = await sendToClient(client, { + type: 'REQUEST', + payload: { + id: requestId, + url: request.url, + method: request.method, + headers: reqHeaders, + cache: request.cache, + mode: request.mode, + credentials: request.credentials, + destination: request.destination, + integrity: request.integrity, + redirect: request.redirect, + referrer: request.referrer, + referrerPolicy: request.referrerPolicy, + body, + bodyUsed: request.bodyUsed, + keepalive: request.keepalive, + }, + }) + + switch (clientMessage.type) { + case 'MOCK_SUCCESS': { + return delayPromise( + () => respondWithMock(clientMessage), + clientMessage.payload.delay, + ) + } + + case 'MOCK_NOT_FOUND': { + return getOriginalResponse() + } + + case 'NETWORK_ERROR': { + const { name, message } = clientMessage.payload + const networkError = new Error(message) + networkError.name = name + + // Rejecting a request Promise emulates a network error. + throw networkError + } + + case 'INTERNAL_ERROR': { + const parsedBody = JSON.parse(clientMessage.payload.body) + + console.error( + `\ +[MSW] Uncaught exception in the request handler for "%s %s": + +${parsedBody.location} + +This exception has been gracefully handled as a 500 response, however, it's strongly recommended to resolve this error, as it indicates a mistake in your code. If you wish to mock an error response, please see this guide: https://mswjs.io/docs/recipes/mocking-error-responses\ +`, + request.method, + request.url, + ) + + return respondWithMock(clientMessage) + } + } + + return getOriginalResponse() +} + +self.addEventListener('fetch', function (event) { + const { request } = event + const accept = request.headers.get('accept') || '' + + // Bypass server-sent events. + if (accept.includes('text/event-stream')) { + return + } + + // Bypass navigation requests. + if (request.mode === 'navigate') { + return + } + + // Opening the DevTools triggers the "only-if-cached" request + // that cannot be handled by the worker. Bypass such requests. + if (request.cache === 'only-if-cached' && request.mode !== 'same-origin') { + return + } + + // Bypass all requests when there are no active clients. + // Prevents the self-unregistered worked from handling requests + // after it's been deleted (still remains active until the next reload). + if (activeClientIds.size === 0) { + return + } + + const requestId = uuidv4() + + return event.respondWith( + handleRequest(event, requestId).catch((error) => { + if (error.name === 'NetworkError') { + console.warn( + '[MSW] Successfully emulated a network error for the "%s %s" request.', + request.method, + request.url, + ) + return + } + + // At this point, any exception indicates an issue with the original request/response. + console.error( + `\ +[MSW] Caught an exception from the "%s %s" request (%s). This is probably not a problem with Mock Service Worker. There is likely an additional logging output above.`, + request.method, + request.url, + `${error.name}: ${error.message}`, + ) + }), + ) +}) + +function serializeHeaders(headers) { + const reqHeaders = {} + headers.forEach((value, name) => { + reqHeaders[name] = reqHeaders[name] + ? [].concat(reqHeaders[name]).concat(value) + : value + }) + return reqHeaders +} + +function sendToClient(client, message) { + return new Promise((resolve, reject) => { + const channel = new MessageChannel() + + channel.port1.onmessage = (event) => { + if (event.data && event.data.error) { + return reject(event.data.error) + } + + resolve(event.data) + } + + client.postMessage(JSON.stringify(message), [channel.port2]) + }) +} + +function delayPromise(cb, duration) { + return new Promise((resolve) => { + setTimeout(() => resolve(cb()), duration) + }) +} + +function respondWithMock(clientMessage) { + return new Response(clientMessage.payload.body, { + ...clientMessage.payload, + headers: clientMessage.payload.headers, + }) +} + +function uuidv4() { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { + const r = (Math.random() * 16) | 0 + const v = c == 'x' ? r : (r & 0x3) | 0x8 + return v.toString(16) + }) +} diff --git a/src/App.tsx b/src/App.tsx index 4aafa2f..985fa98 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -4,6 +4,8 @@ import ExplorePage from "src/pages/ExplorePage"; import ModalsContainer from "src/Components/Modals/ModalsContainer/ModalsContainer"; import { useAppDispatch, useAppSelector, useResizeListener } from './utils/hooks'; import { Wallet_Service } from "./services"; +import { Route, Routes } from "react-router-dom"; +import CategoryPage from "./pages/CategoryPage/CategoryPage"; function App() { const { isWalletConnected } = useAppSelector(state => ({ @@ -34,7 +36,10 @@ function App() { return
- + + } /> + } /> +
; } diff --git a/src/Components/Cards/ProjectCardMini/ProjectCardMini.Skeleton.tsx b/src/Components/Cards/ProjectCardMini/ProjectCardMini.Skeleton.tsx index 8fc758a..784569b 100644 --- a/src/Components/Cards/ProjectCardMini/ProjectCardMini.Skeleton.tsx +++ b/src/Components/Cards/ProjectCardMini/ProjectCardMini.Skeleton.tsx @@ -3,7 +3,7 @@ import Skeleton from 'react-loading-skeleton' export default function ProjectCardMiniSkeleton() { return ( -
+

diff --git a/src/Components/Cards/ProjectCardMini/ProjectCardMini.stories.tsx b/src/Components/Cards/ProjectCardMini/ProjectCardMini.stories.tsx index 1e464fa..58a3c5d 100644 --- a/src/Components/Cards/ProjectCardMini/ProjectCardMini.stories.tsx +++ b/src/Components/Cards/ProjectCardMini/ProjectCardMini.stories.tsx @@ -1,5 +1,5 @@ import { ComponentStory, ComponentMeta } from '@storybook/react'; -import mockData from 'src/api/mockData.json' +import { MOCK_DATA } from 'src/mocks/data'; import ProjectCardMini from './ProjectCardMini'; import ProjectCardMiniSkeleton from './ProjectCardMini.Skeleton'; @@ -15,7 +15,7 @@ const Template: ComponentStory = (args) => void + onClick: (projectId: number) => void } export default function ProjectCardMini({ project, onClick }: Props) { + return (
onClick(project.id)}> {project.title} diff --git a/src/api/index.ts b/src/api/index.ts deleted file mode 100644 index eb088a0..0000000 --- a/src/api/index.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { Project, ProjectCard, ProjectCategory } from "../utils/interfaces"; -import { gql, useQuery } from "@apollo/client"; -import data from "./mockData.json"; - -export async function getAllCategories(): Promise { - // let QUERY = gql` - // query GetCategories { - // allCategories { - // id - // title - // } - // } - // `; - return data.categories; -} - -export async function getHottestProjects(): Promise { - // let QUERY = gql` - // query { - // allProject { - // id - // cover_image - // thumbnail_image - // title - // website - // votes_count - // } - // } - // `; - return data.projectsCards; -} - -export async function getProjectsByCategory( - categoryId: string -): Promise { - // let QUERY = gql` - // query Categories($categoryId: Int!){ - // projectsByCategory(category_id: ${categoryId}) { - // id - // cover_image - // thumbnail_image - // title - // website - // lightning_address - // votes_count - // } - // } - // `; - return data.projectsCards; -} - -// // returns the latest bunch of projects in each ( or some ) categories, and returns the hottest projects -// export async function getLatestProjects(): Promise< -// { category: ProjectCategory; projects: ProjectCard[] }[] -// > { -// return data.categories.slice(0, 3).map((cat) => ({ -// category: cat, -// projects: data.projectsCards, -// })) as any; -// } - -export async function getProjectById(projectId: string): Promise { - // let QUERY = gql` - // query Project(projectId: String!) { - // getProject(id: $projectId) { - // id - // cover_image - // thumbnail_image - // title - // website - // votes_count - // } - // } - // `; - return data.project; -} diff --git a/src/api/mockData.json b/src/api/mockData.json deleted file mode 100644 index e7e0bbb..0000000 --- a/src/api/mockData.json +++ /dev/null @@ -1,139 +0,0 @@ -{ - "categories": [ - { - "id": "111", - "title": "Hottest" - }, - { - "id": "123", - "title": "Art & Collectibles" - }, - { - "id": "124", - "title": "DeFi" - }, - { - "id": "311", - "title": "Entertainment" - }, - { - "id": "333", - "title": "Exchange" - }, - { - "id": "223", - "title": "News" - }, - { - "id": "451", - "title": "Shop" - }, - { - "id": "232", - "title": "Social" - }, - { - "id": "512", - "title": "Wallet" - }, - { - "id": "132", - "title": "Other" - } - ], - "projectsCards": [ - { - "id": "123", - "title": "First App", - "thumbnail_image": "https://via.placeholder.com/150", - "category": { - "id": "512", - "title": "{app.category}" - }, - "votes_count": 123 - }, - { - "id": "765", - "title": "Second App", - "thumbnail_image": "https://via.placeholder.com/150", - "category": { - "id": "512", - "title": "{app.category}" - }, - "votes_count": 123 - }, - { - "id": "55", - "title": "Third App", - "thumbnail_image": "https://via.placeholder.com/150", - "category": { - "id": "512", - "title": "{app.category}" - }, - "votes_count": 123 - }, - { - "id": "12344123", - "title": "Fourth App", - "thumbnail_image": "https://via.placeholder.com/150", - "category": { - "id": "512", - "title": "{app.category}" - }, - "votes_count": 123 - }, - { - "id": "56745", - "title": "Fifth App", - "thumbnail_image": "https://via.placeholder.com/150", - "category": { - "id": "512", - "title": "{app.category}" - }, - "votes_count": 123 - }, - { - "id": "3312431", - "title": "Sixth App", - "thumbnail_image": "https://via.placeholder.com/150", - "category": { - "id": "512", - "title": "{app.category}" - }, - "votes_count": 123 - } - ], - "project": { - "id": "1233", - "cover_image": "https://picsum.photos/id/10/1024/1024", - "thumbnail_image": "https://s3-alpha-sig.figma.com/img/be1b/cd75/1baa911b3875134c0889d6755c4ba2cb?Expires=1638748800&Signature=DOiLciAA95w8gOvAowjiiR-ZPbmV1oGSRRK8YpE4ALMoe47pL7DifQxZvL1LQn~NRa0aLMoMk61521fbbGJeDAwk~j6fIm~iZAlMzQn7DdWy0wFR0uLQagOgpIiIXO-w8CeC14VoW-hrjIX5mDmOonJzkfoftGqIF1WCOmP2EuswyJpIngFdLb15gCex4Necs3vH2cuD9iSgWG2za97KfdXZP79ROyk2EN9Q3~a7RT4FTBBIlgKDLuFGSVRxReXVNajn~XSxBJh2de9dFVa3tOXkwJXu3jb0G4x-wRCaG-KmBhUOemuGtu5Fumh6goktGh~bIDwoHeUBVKFHAzaYgw__&Key-Pair-Id=APKAINTVSUGEWH5XD5UA", - "title": "█████████", - "website": "████████", - "description": "██████████████████", - "category": { - "id": "333", - "title": "█████" - }, - "tags": [ - { - "id": "123", - "title": "█████" - }, - { - "id": "313", - "title": "██████" - }, - { - "id": "451", - "title": "█████" - } - ], - "screenShots": [ - "", - "", - "", - "" - ], - "votes_count": 0 - } -} \ No newline at end of file diff --git a/src/index.tsx b/src/index.tsx index a357eb6..d1ae203 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -5,6 +5,11 @@ import './index.css'; import App from './App'; import reportWebVitals from './reportWebVitals'; +if (process.env.NODE_ENV === 'development') { + const { worker } = require('./mocks/browser') + worker.start() +} + ReactDOM.render( diff --git a/src/mocks/browser.ts b/src/mocks/browser.ts new file mode 100644 index 0000000..bc08fdd --- /dev/null +++ b/src/mocks/browser.ts @@ -0,0 +1,4 @@ +import { setupWorker } from 'msw' +import { handlers } from './handlers' +// This configures a Service Worker with the given request handlers. +export const worker = setupWorker(...handlers) \ No newline at end of file diff --git a/src/mocks/data.ts b/src/mocks/data.ts new file mode 100644 index 0000000..f7726a7 --- /dev/null +++ b/src/mocks/data.ts @@ -0,0 +1,428 @@ +import ASSETS from "src/assets"; +import { Project, ProjectCategory } from "src/utils/interfaces"; +import { projectsByCategory } from "./resolvers"; + +let categories = [ + { + "id": 10, + "title": "Video", + cover_image: ASSETS.Images_ExploreHeader1 + }, + { + "id": 8, + "title": "Shopping", + cover_image: ASSETS.Images_ExploreHeader1 + }, + { + "id": 5, + "title": "Music", + cover_image: ASSETS.Images_ExploreHeader1 + }, + { + "id": 9, + "title": "Miscellaneous", + cover_image: ASSETS.Images_ExploreHeader1 + }, + { + "id": 4, + "title": "Gaming", + cover_image: ASSETS.Images_ExploreHeader1 + }, + { + "id": 1, + "title": "Finance", + cover_image: ASSETS.Images_ExploreHeader1 + }, + { + "id": 2, + "title": "Digital Print", + cover_image: ASSETS.Images_ExploreHeader1 + }, + { + "id": 7, + "title": "Digital Content", + cover_image: ASSETS.Images_ExploreHeader1 + }, + { + "id": 3, + "title": "Art", + cover_image: ASSETS.Images_ExploreHeader1 + }, + { + "id": 6, + "title": "Analytics", + cover_image: ASSETS.Images_ExploreHeader1 + }, + +] + +let projects = [ + { + "id": 1, + "cover_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/kollider_cover.png", + "thumbnail_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/kollider_thumbnail.png", + "title": "Kollider", + "description": "Project description", + screenShots: [], + tags: [], + "website": "https://kollider.xyz/", + "lightning_address": "johns@getalby.com", + "votes_count": 120, + "category": { + "id": 1, + "title": "Finance" + } + }, + { + "id": 16, + "cover_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/alby_cover.png", + "thumbnail_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/alby_thumbnail.png", + "title": "Alby", + "description": "Project description", + screenShots: [], + tags: [], + "website": "https://getalby.com/", + "lightning_address": "hello@getalby.com", + "votes_count": 100, + "category": { + "id": 9, + "title": "Miscellaneous" + } + }, + { + "id": 12, + "cover_image": "http://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/bitrefill_cover.png", + "thumbnail_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/bitrefill_thumbnail.png", + "title": "Bitrefill", + "description": "Project description", + screenShots: [], + tags: [], + "website": "https://www.bitrefill.com/buy", + "lightning_address": "moritz@getalby.com", + "votes_count": 25, + "category": { + "id": 8, + "title": "Shopping" + } + }, + { + "id": 20, + "cover_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/lightning-video_cover.png", + "thumbnail_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/lightning-video_thumbnail.png", + "title": "Lightning.Video", + "description": "Project description", + screenShots: [], + tags: [], + "website": "https://lightning.video/", + "lightning_address": "moritz@getalby.com", + "votes_count": 15, + "category": { + "id": 7, + "title": "Digital Content" + } + }, + { + "id": 3, + "cover_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/sparkshot_cover.png", + "thumbnail_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/sparkshot_thumbnail.png", + "title": "Sparkshot", + "description": "Project description", + screenShots: [], + tags: [], + "website": "https://sparkshot.io/", + "lightning_address": "johns@getalby.com", + "votes_count": 11, + "category": { + "id": 3, + "title": "Art" + } + }, + { + "id": 17, + "cover_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/lightning-gifts_cover.png", + "thumbnail_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/lightning-gifts_thumbnail.png", + "title": "Lightning Gifts", + "description": "Project description", + screenShots: [], + tags: [], + "website": "https://lightning.gifts/", + "lightning_address": "moritz@getalby.com", + "votes_count": 10, + "category": { + "id": 8, + "title": "Shopping" + } + }, + { + "id": 18, + "cover_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/scarce-city_cover.png", + "thumbnail_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/scarce-city_thumbnail.png", + "title": "Scarce City", + "description": "Project description", + screenShots: [], + tags: [], + "website": "https://scarce.city/", + "lightning_address": "moritz@getalby.com", + "votes_count": 0, + "category": { + "id": 3, + "title": "Art" + } + }, + { + "id": 15, + "cover_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/lnshort-it_cover.png", + "thumbnail_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/lnshort-it_thumbnail.png", + "title": "lnshort.it", + "description": "Project description", + screenShots: [], + tags: [], + "website": "https://lnshort.it/", + "lightning_address": "moritz@getalby.com", + "votes_count": 0, + "category": { + "id": 9, + "title": "Miscellaneous" + } + }, + { + "id": 11, + "cover_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/stacker-news_cover.png", + "thumbnail_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/stacker-news_thumbnail.png", + "title": "Stacker News", + "description": "Project description", + screenShots: [], + tags: [], + "website": "https://stacker.news/", + "lightning_address": "moritz@getalby.com", + "votes_count": 0, + "category": { + "id": 7, + "title": "Digital Content" + } + }, + { + "id": 21, + "cover_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/starbackr_cover.png", + "thumbnail_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/starbackr_thumbail.png", + "title": "Starbackr", + "description": "Project description", + screenShots: [], + tags: [], + "website": "https://www.starbackr.com/", + "lightning_address": "moritz@geralby.com", + "votes_count": 0, + "category": { + "id": 7, + "title": "Digital Content" + } + }, + { + "id": 2, + "cover_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/lnmarkets_cover.png", + "thumbnail_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/lnmarkets_thumbnail.png", + "title": "LN Markets", + "description": "Project description", + screenShots: [], + tags: [], + "website": "https://lnmarkets.com/", + "lightning_address": "johns@getalby.com", + "votes_count": 0, + "category": { + "id": 1, + "title": "Finance" + } + }, + { + "id": 5, + "cover_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/lnblackjack_cover.png", + "thumbnail_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/lnblackjack_thumbnail.png", + "title": "LN Blackjack", + "description": "Project description", + screenShots: [], + tags: [], + "website": "https://www.lnblackjack.com/", + "lightning_address": "moritz@getalby.com", + "votes_count": 0, + "category": { + "id": 4, + "title": "Gaming" + } + }, + { + "id": 19, + "cover_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/yalls_cover.png", + "thumbnail_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/yalls_thumbnail.png", + "title": "Y'alls ", + "description": "Project description", + screenShots: [], + tags: [], + "website": "https://yalls.org/", + "lightning_address": "moritz@getalby.com", + "votes_count": 0, + "category": { + "id": 2, + "title": "Digital Print" + } + }, + { + "id": 13, + "cover_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/lightning-network-stores_cover.png", + "thumbnail_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/lightning-network-stores_thumbnail.png", + "title": "Lightning Network Stores", + "description": "Project description", + screenShots: [], + tags: [], + "website": "https://lightningnetworkstores.com/", + "lightning_address": "moritz@getalby.com", + "votes_count": 0, + "category": { + "id": 8, + "title": "Shopping" + } + }, + { + "id": 9, + "cover_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/lightning-poker_cover.png", + "thumbnail_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/lightning-poker_thumbnail.png", + "title": "Lightning Poker", + "description": "Project description", + screenShots: [], + tags: [], + "website": "https://lightning-poker.com/", + "lightning_address": "moritz@getalby.com", + "votes_count": 0, + "category": { + "id": 4, + "title": "Gaming" + } + }, + { + "id": 6, + "cover_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/lngames_cover.png", + "thumbnail_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/lngames_thumbnail.png", + "title": "LNGames", + "description": "Project description", + screenShots: [], + tags: [], + "website": "https://lngames.net/", + "lightning_address": "moritz@getalby.com", + "votes_count": 0, + "category": { + "id": 4, + "title": "Gaming" + } + }, + { + "id": 4, + "cover_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/amboss-space_cover.png", + "thumbnail_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/amboss-space_thumbnail.png", + "title": "Amboss Space", + "description": "Project description", + screenShots: [], + tags: [], + "website": "https://amboss.space/", + "lightning_address": "moritz@getalby.com", + "votes_count": 0, + "category": { + "id": 6, + "title": "Analytics" + } + }, + { + "id": 8, + "cover_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/loft-trade_cover.png", + "thumbnail_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/loft-trade_thumbnail.png", + "title": "LOFT", + "description": "Project description", + screenShots: [], + tags: [], + "website": "https://loft.trade/", + "lightning_address": "moritz@getalby.com", + "votes_count": 0, + "category": { + "id": 1, + "title": "Finance" + } + }, + { + "id": 10, + "cover_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/lightning-roulette_cover.png", + "thumbnail_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/lightning-roulette_thumbnail.png", + "title": "Lightning Roulette", + "description": "Project description", + screenShots: [], + tags: [], + "website": "https://lightning-roulette.com/", + "lightning_address": "moritz@getalby.com", + "votes_count": 0, + "category": { + "id": 4, + "title": "Gaming" + } + }, + { + "id": 14, + "cover_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/sats-4-likes-cover.png", + "thumbnail_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/sats-4-likes_thumbnail.png", + "title": "Sats 4 Likes", + "description": "Project description", + screenShots: [], + tags: [], + "website": "https://kriptode.com/satsforlikes/index.html", + "lightning_address": "moritz@getalby.com", + "votes_count": 0, + "category": { + "id": 9, + "title": "Miscellaneous" + } + }, + { + "id": 7, + "cover_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/wavlake_cover.png", + "thumbnail_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/wavlake_thumbnail.png", + "title": "Wavlake", + "description": "Project description", + screenShots: [], + tags: [], + "website": "https://www.wavlake.com/", + "lightning_address": "moritz@getalby.com", + "votes_count": 0, + "category": { + "id": 7, + "title": "Digital Content" + } + }, + { + "id": 22, + "cover_image": "https://fra1.digitaloceanspaces.com/alby-storage/makers-bolt-fun/bolt.fund_thumbnails_covers/geyser-fund_cover.png", + "thumbnail_image": "https://user-images.githubusercontent.com/36778205/157433567-4b1e41db-23d4-4a80-b48f-ee248ee87f1e.jpg", + "title": "Geyser Fund", + "description": "Project description", + screenShots: [], + tags: [], + "website": "https://geyser.fund/", + "lightning_address": "0272e8731c6feda7fb7e2b8dbe0fbf1322f9e3b60cc2727f4ee4ca0f820b9cd169@35.206.90.207:9735", + "votes_count": 0, + "category": { + "id": 9, + "title": "Miscellaneous" + } + } +] + +// Process Data +// ------------ + + +// 1- Add Typenames +categories = categories.map(c => ({ ...c, __typename: "Category" })) +projects = projects.map(p => ({ ...p, __typename: "Project" })) + +// 2- Computed Fields +categories = categories.map(c => ({ ...c, apps_count: projects.reduce((acc, p) => acc + (p.category.id === c.id ? 1 : 0), 0) })) + +export const MOCK_DATA = { + projects: projects as Project[], + categories: categories as ProjectCategory[] +} \ No newline at end of file diff --git a/src/mocks/handlers.ts b/src/mocks/handlers.ts new file mode 100644 index 0000000..ba47117 --- /dev/null +++ b/src/mocks/handlers.ts @@ -0,0 +1,45 @@ + +import { graphql } from 'msw' +import { allCategories, getCategory, getProject, newProjects, projectsByCategory } from './resolvers' + +export const handlers = [ + + graphql.query('PROJECTS_IN_CATEGORY_QUERY', (req, res, ctx) => { + const { categoryId } = req.variables + + + return res( + ctx.data({ + projectsByCategory: projectsByCategory(categoryId), + getCategory: getCategory(categoryId) + }) + ) + }), + + graphql.query('AllCategoriesProjects', (req, res, ctx) => { + return res( + ctx.data({ + allCategories: allCategories(), + newProjects: newProjects() + }) + ) + }), + + graphql.query('AllCategories', (req, res, ctx) => { + return res( + ctx.data({ + allCategories: allCategories() + }) + ) + }), + + graphql.query('Project', (req, res, ctx) => { + const { projectId } = req.variables + + return res( + ctx.data({ + getProject: getProject(projectId) + }) + ) + }), +] \ No newline at end of file diff --git a/src/mocks/resolvers.ts b/src/mocks/resolvers.ts new file mode 100644 index 0000000..ea2276b --- /dev/null +++ b/src/mocks/resolvers.ts @@ -0,0 +1,28 @@ +import { MOCK_DATA } from "./data"; + +export function getCategory(id: number) { + return { + ...MOCK_DATA.categories.find(c => c.id === id), + project: MOCK_DATA.projects.filter(p => p.category.id === id) + } +} + + +export function projectsByCategory(id: number) { + return MOCK_DATA.projects.filter(p => p.category.id === id) +} + +export function allCategories() { + return MOCK_DATA.categories.map(c => ({ + ...c, + project: projectsByCategory(c.id) + })) +} + +export function newProjects() { + return MOCK_DATA.projects; +} + +export function getProject(projectId: number) { + return MOCK_DATA.projects.find(p => p.id === projectId) +} \ No newline at end of file diff --git a/src/pages/CategoryPage/CategoryPage.tsx b/src/pages/CategoryPage/CategoryPage.tsx index 3deda80..1073418 100644 --- a/src/pages/CategoryPage/CategoryPage.tsx +++ b/src/pages/CategoryPage/CategoryPage.tsx @@ -1 +1,46 @@ -export { } \ No newline at end of file +import { useQuery } from '@apollo/client'; +import { useParams, Navigate } from 'react-router-dom' +import HeaderImage from './HeaderImage/HeaderImage'; +import ProjectsGrid from './ProjectsGrid/ProjectsGrid'; +import { PROJECTS_IN_CATEGORY_QUERY, PROJECTS_IN_CATEGORY_QUERY_RES_TYPE, PROJECTS_IN_CATEGORY_QUERY_VARS } from './query'; + +export default function CategoryPage() { + + const { id } = useParams(); + + + const { data, loading } = useQuery(PROJECTS_IN_CATEGORY_QUERY, { + skip: !id, + variables: { + categoryId: Number(id) + }, + onCompleted: data => { + console.log('--------------'); + + console.log(data); + + } + }); + + if (!id || (!loading && !data)) + + + + + return ( +
+ +
+ +
+
+ ) +} diff --git a/src/pages/CategoryPage/HeaderImage/HeaderImage.tsx b/src/pages/CategoryPage/HeaderImage/HeaderImage.tsx index f098f7e..969ec9e 100644 --- a/src/pages/CategoryPage/HeaderImage/HeaderImage.tsx +++ b/src/pages/CategoryPage/HeaderImage/HeaderImage.tsx @@ -1,20 +1,41 @@ import React from 'react' import { FiArrowLeft } from 'react-icons/fi' +import Skeleton from 'react-loading-skeleton' +import { Link } from 'react-router-dom' -interface Props { +type Props = { + isLoading: boolean title: string apps_count: number img: string } -export default function HeaderImage({ title, apps_count, img }: Props) { +export default function HeaderImage(props: Props) { + + if (props.isLoading) + return ( +
+ {/*
*/} + +
+ ) + + + const { title, img, apps_count } = props; + return (
{`${title}
- + +

{title}

= (args) => { + dispatch(openModal({ Modal: "ProjectDetailsCard", props: { projectId } })) + } -export default function ProjectsGrid() { return (

- {Array(30).fill(0).map((_, idx) => { }} />)} + {isLoading && Array(12).fill(0).map((_, idx) => )} + {!isLoading && projects.map((project) => )}
) } diff --git a/src/pages/CategoryPage/query.ts b/src/pages/CategoryPage/query.ts new file mode 100644 index 0000000..bdea2d1 --- /dev/null +++ b/src/pages/CategoryPage/query.ts @@ -0,0 +1,40 @@ +import { gql } from "@apollo/client"; +import { ProjectCard, ProjectCategory } from "src/utils/interfaces"; + +export const PROJECTS_IN_CATEGORY_QUERY = gql` +query PROJECTS_IN_CATEGORY_QUERY($categoryId: Int!) { + + projectsByCategory(category_id: $categoryId) { + id + thumbnail_image + title + votes_count + category { + title + id + } + } + + getCategory(id: $categoryId) { + id + title + cover_image + apps_count + } + +} +` +export type PROJECTS_IN_CATEGORY_QUERY_VARS = { + categoryId: number; +} + +export type PROJECTS_IN_CATEGORY_QUERY_RES_TYPE = { + projectsByCategory: ProjectCard[], + + getCategory: { + id: ProjectCategory['id'] + title: ProjectCategory['title'] + cover_image: ProjectCategory['cover_image'] + apps_count: ProjectCategory['apps_count'] + } +} \ No newline at end of file diff --git a/src/pages/ExplorePage/Categories/Categories.tsx b/src/pages/ExplorePage/Categories/Categories.tsx index 1909129..ddf47ef 100644 --- a/src/pages/ExplorePage/Categories/Categories.tsx +++ b/src/pages/ExplorePage/Categories/Categories.tsx @@ -2,12 +2,13 @@ import { useQuery } from '@apollo/client'; import { ALL_CATEGORIES_QUERY, ALL_CATEGORIES_QUERY_RES } from './query'; import Badge from 'src/Components/Badge/Badge' import Slider from 'src/Components/Slider/Slider' +import { useNavigate } from 'react-router-dom'; export default function Categories() { const { data, loading } = useQuery(ALL_CATEGORIES_QUERY); - + const navigate = useNavigate(); if (loading || !data) return
@@ -20,7 +21,7 @@ export default function Categories() { return ( {data?.allCategories.map(category => - document.getElementById(category.title.toLowerCase())?.scrollIntoView({ behavior: 'smooth', block: 'center' })} >{category.title} + navigate(`/category/${category.id}`)}>{category.title} )} ) diff --git a/src/pages/ExplorePage/ExplorePage.tsx b/src/pages/ExplorePage/ExplorePage.tsx index d88c8b3..428ce69 100644 --- a/src/pages/ExplorePage/ExplorePage.tsx +++ b/src/pages/ExplorePage/ExplorePage.tsx @@ -9,9 +9,9 @@ export default function ExplorePage() {
- {/*
+
-
*/} +
) diff --git a/src/pages/ExplorePage/Header/Header.tsx b/src/pages/ExplorePage/Header/Header.tsx index 1854ab5..4afaf8d 100644 --- a/src/pages/ExplorePage/Header/Header.tsx +++ b/src/pages/ExplorePage/Header/Header.tsx @@ -31,7 +31,7 @@ export default function Header() { alt="" />
-

+

{headerLinks[0].title}

@@ -46,7 +46,7 @@ export default function Header() { alt="" />
-

+

{headerLinks[1].title}