From 4f05504ddef59f488742faa2698122a913308735 Mon Sep 17 00:00:00 2001 From: Andreas <ae@uio.no> Date: Mon, 4 Apr 2022 12:15:43 +0200 Subject: [PATCH] Upgrade react-router-dom to v6 Refactors things to new syntax while not changing anything --- frontend/package-lock.json | 365 ++---------------- frontend/package.json | 3 +- .../src/components/protectedRoute/index.tsx | 29 -- frontend/src/components/requireAuth/index.tsx | 19 + frontend/src/hooks/useGuest/index.tsx | 2 +- .../routes/components/overviewGuestButton.tsx | 8 +- .../routes/components/sponsorGuestButtons.tsx | 8 +- .../src/routes/guest/register/index.test.tsx | 40 +- frontend/src/routes/guest/register/index.tsx | 6 +- .../routes/guest/register/steps/success.tsx | 6 +- frontend/src/routes/index.tsx | 50 ++- frontend/src/routes/invite/logout.tsx | 4 +- frontend/src/routes/landing/index.tsx | 6 +- .../routes/sponsor/guest/guestInfo/index.tsx | 15 +- .../guest/guestRoleInfo/index.test.tsx | 9 +- .../sponsor/guest/guestRoleInfo/index.tsx | 30 +- frontend/src/routes/sponsor/guest/index.tsx | 48 ++- .../sponsor/guest/newGuestRole/index.tsx | 11 +- frontend/src/routes/sponsor/index.tsx | 17 +- .../routes/sponsor/register/index.test.tsx | 12 +- .../src/routes/sponsor/register/index.tsx | 14 +- .../sponsor/register/stepRegistration.tsx | 6 +- .../sponsor/register/stepSubmitSuccess.tsx | 6 +- 23 files changed, 218 insertions(+), 496 deletions(-) delete mode 100644 frontend/src/components/protectedRoute/index.tsx create mode 100644 frontend/src/components/requireAuth/index.tsx diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 29bcd16b..eb2ea544 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -26,7 +26,6 @@ "@types/react": "^17.0.33", "@types/react-dom": "^17.0.10", "@types/react-helmet": "^6.1.4", - "@types/react-router-dom": "^5.3.2", "date-fns": "^2.24.0", "fetch-intercept": "^2.4.0", "http-proxy-middleware": "^2.0.1", @@ -42,7 +41,7 @@ "react-helmet": "^6.1.0", "react-hook-form": "^7.17.5", "react-i18next": "^11.11.4", - "react-router-dom": "^5.3.0", + "react-router-dom": "^6.3.0", "react-scripts": "4.0.3", "typeface-roboto": "^1.1.13", "typescript": "^4.4.4", @@ -4360,11 +4359,6 @@ "@types/node": "*" } }, - "node_modules/@types/history": { - "version": "4.7.9", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.9.tgz", - "integrity": "sha512-MUc6zSmU3tEVnkQ78q0peeEjKWPUADMlC/t++2bI8WnAG2tvYRPIgHG8lWkXwqc8MsUF6Z2MOf+Mh5sazOmhiQ==" - }, "node_modules/@types/hoist-non-react-statics": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", @@ -4501,25 +4495,6 @@ "@types/react": "*" } }, - "node_modules/@types/react-router": { - "version": "5.1.17", - "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.17.tgz", - "integrity": "sha512-RNSXOyb3VyRs/EOGmjBhhGKTbnN6fHWvy5FNLzWfOWOGjgVUKqJZXfpKzLmgoU8h6Hj8mpALj/mbXQASOb92wQ==", - "dependencies": { - "@types/history": "*", - "@types/react": "*" - } - }, - "node_modules/@types/react-router-dom": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.2.tgz", - "integrity": "sha512-ELEYRUie2czuJzaZ5+ziIp9Hhw+juEw8b7C11YNA4QdLCVbQ3qLi2l4aq8XnlqM7V31LZX8dxUuFUCrzHm6sqQ==", - "dependencies": { - "@types/history": "*", - "@types/react": "*", - "@types/react-router": "*" - } - }, "node_modules/@types/react-transition-group": { "version": "4.4.4", "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.4.tgz", @@ -6197,15 +6172,6 @@ "node": ">=8" } }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "optional": true, - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -10008,12 +9974,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "optional": true - }, "node_modules/filesize": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.1.0.tgz", @@ -10455,19 +10415,6 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, - "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -10860,16 +10807,11 @@ "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" }, "node_modules/history": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", - "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz", + "integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==", "dependencies": { - "@babel/runtime": "^7.1.2", - "loose-envify": "^1.2.0", - "resolve-pathname": "^3.0.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0", - "value-equal": "^1.0.1" + "@babel/runtime": "^7.7.6" } }, "node_modules/hmac-drbg": { @@ -11928,11 +11870,6 @@ "node": ">=8" } }, - "node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -15491,19 +15428,6 @@ "node": ">=4" } }, - "node_modules/mini-create-react-context": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz", - "integrity": "sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==", - "dependencies": { - "@babel/runtime": "^7.12.1", - "tiny-warning": "^1.0.3" - }, - "peerDependencies": { - "prop-types": "^15.0.0", - "react": "^0.14.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" - } - }, "node_modules/mini-css-extract-plugin": { "version": "0.11.3", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.11.3.tgz", @@ -15744,12 +15668,6 @@ "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=" }, - "node_modules/nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", - "optional": true - }, "node_modules/nanoid": { "version": "3.1.30", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz", @@ -16568,14 +16486,6 @@ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, - "node_modules/path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "dependencies": { - "isarray": "0.0.1" - } - }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -18597,47 +18507,29 @@ } }, "node_modules/react-router": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.1.tgz", - "integrity": "sha512-lIboRiOtDLFdg1VTemMwud9vRVuOCZmUIT/7lUoZiSpPODiiH1UQlfXy+vPLC/7IWdFYnhRwAyNqA/+I7wnvKQ==", - "dependencies": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "hoist-non-react-statics": "^3.1.0", - "loose-envify": "^1.3.1", - "mini-create-react-context": "^0.4.0", - "path-to-regexp": "^1.7.0", - "prop-types": "^15.6.2", - "react-is": "^16.6.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.3.0.tgz", + "integrity": "sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ==", + "dependencies": { + "history": "^5.2.0" }, "peerDependencies": { - "react": ">=15" + "react": ">=16.8" } }, "node_modules/react-router-dom": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.0.tgz", - "integrity": "sha512-ObVBLjUZsphUUMVycibxgMdh5jJ1e3o+KpAZBVeHcNQZ4W+uUGGWsokurzlF4YOldQYRQL4y6yFRWM4m3svmuQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.3.0.tgz", + "integrity": "sha512-uaJj7LKytRxZNQV8+RbzJWnJ8K2nPsOOEuX7aQstlMZKQT0164C+X2w6bnkqU3sjtLvpd5ojrezAyfZ1+0sStw==", "dependencies": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "loose-envify": "^1.3.1", - "prop-types": "^15.6.2", - "react-router": "5.2.1", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" + "history": "^5.2.0", + "react-router": "6.3.0" }, "peerDependencies": { - "react": ">=15" + "react": ">=16.8", + "react-dom": ">=16.8" } }, - "node_modules/react-router/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, "node_modules/react-scripts": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-4.0.3.tgz", @@ -19214,11 +19106,6 @@ "node": ">=4" } }, - "node_modules/resolve-pathname": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", - "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" - }, "node_modules/resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -21619,16 +21506,6 @@ "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" }, - "node_modules/tiny-invariant": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz", - "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==" - }, - "node_modules/tiny-warning": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" - }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -22268,11 +22145,6 @@ "spdx-expression-parse": "^3.0.0" } }, - "node_modules/value-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", - "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" - }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -22466,24 +22338,6 @@ "node": ">=0.10.0" } }, - "node_modules/watchpack-chokidar2/node_modules/fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - }, - "engines": { - "node": ">= 4.0" - } - }, "node_modules/watchpack-chokidar2/node_modules/glob-parent": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", @@ -22932,24 +22786,6 @@ "node": ">=6" } }, - "node_modules/webpack-dev-server/node_modules/fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "deprecated": "fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - }, - "engines": { - "node": ">= 4.0" - } - }, "node_modules/webpack-dev-server/node_modules/glob-parent": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", @@ -27252,11 +27088,6 @@ "@types/node": "*" } }, - "@types/history": { - "version": "4.7.9", - "resolved": "https://registry.npmjs.org/@types/history/-/history-4.7.9.tgz", - "integrity": "sha512-MUc6zSmU3tEVnkQ78q0peeEjKWPUADMlC/t++2bI8WnAG2tvYRPIgHG8lWkXwqc8MsUF6Z2MOf+Mh5sazOmhiQ==" - }, "@types/hoist-non-react-statics": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", @@ -27393,25 +27224,6 @@ "@types/react": "*" } }, - "@types/react-router": { - "version": "5.1.17", - "resolved": "https://registry.npmjs.org/@types/react-router/-/react-router-5.1.17.tgz", - "integrity": "sha512-RNSXOyb3VyRs/EOGmjBhhGKTbnN6fHWvy5FNLzWfOWOGjgVUKqJZXfpKzLmgoU8h6Hj8mpALj/mbXQASOb92wQ==", - "requires": { - "@types/history": "*", - "@types/react": "*" - } - }, - "@types/react-router-dom": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/@types/react-router-dom/-/react-router-dom-5.3.2.tgz", - "integrity": "sha512-ELEYRUie2czuJzaZ5+ziIp9Hhw+juEw8b7C11YNA4QdLCVbQ3qLi2l4aq8XnlqM7V31LZX8dxUuFUCrzHm6sqQ==", - "requires": { - "@types/history": "*", - "@types/react": "*", - "@types/react-router": "*" - } - }, "@types/react-transition-group": { "version": "4.4.4", "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.4.tgz", @@ -28726,15 +28538,6 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "optional": true }, - "bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "optional": true, - "requires": { - "file-uri-to-path": "1.0.0" - } - }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -31687,12 +31490,6 @@ } } }, - "file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "optional": true - }, "filesize": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/filesize/-/filesize-6.1.0.tgz", @@ -32037,12 +31834,6 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "optional": true - }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -32327,16 +32118,11 @@ "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==" }, "history": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", - "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz", + "integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==", "requires": { - "@babel/runtime": "^7.1.2", - "loose-envify": "^1.2.0", - "resolve-pathname": "^3.0.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0", - "value-equal": "^1.0.1" + "@babel/runtime": "^7.7.6" } }, "hmac-drbg": { @@ -33107,11 +32893,6 @@ "is-docker": "^2.0.0" } }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -35820,15 +35601,6 @@ "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==" }, - "mini-create-react-context": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz", - "integrity": "sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==", - "requires": { - "@babel/runtime": "^7.12.1", - "tiny-warning": "^1.0.3" - } - }, "mini-css-extract-plugin": { "version": "0.11.3", "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-0.11.3.tgz", @@ -36015,12 +35787,6 @@ "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=" }, - "nan": { - "version": "2.15.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.15.0.tgz", - "integrity": "sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==", - "optional": true - }, "nanoid": { "version": "3.1.30", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.30.tgz", @@ -36653,14 +36419,6 @@ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, - "path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "requires": { - "isarray": "0.0.1" - } - }, "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -38278,41 +38036,20 @@ "integrity": "sha512-X8jZHc7nCMjaCqoU+V2I0cOhNW+QMBwSUkeXnTi8IPe6zaRWfn60ZzvFDZqWPfmSJfjub7dDW1SP0jaHWLu/hg==" }, "react-router": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.1.tgz", - "integrity": "sha512-lIboRiOtDLFdg1VTemMwud9vRVuOCZmUIT/7lUoZiSpPODiiH1UQlfXy+vPLC/7IWdFYnhRwAyNqA/+I7wnvKQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.3.0.tgz", + "integrity": "sha512-7Wh1DzVQ+tlFjkeo+ujvjSqSJmkt1+8JO+T5xklPlgrh70y7ogx75ODRW0ThWhY7S+6yEDks8TYrtQe/aoboBQ==", "requires": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "hoist-non-react-statics": "^3.1.0", - "loose-envify": "^1.3.1", - "mini-create-react-context": "^0.4.0", - "path-to-regexp": "^1.7.0", - "prop-types": "^15.6.2", - "react-is": "^16.6.0", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" - }, - "dependencies": { - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - } + "history": "^5.2.0" } }, "react-router-dom": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.3.0.tgz", - "integrity": "sha512-ObVBLjUZsphUUMVycibxgMdh5jJ1e3o+KpAZBVeHcNQZ4W+uUGGWsokurzlF4YOldQYRQL4y6yFRWM4m3svmuQ==", + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.3.0.tgz", + "integrity": "sha512-uaJj7LKytRxZNQV8+RbzJWnJ8K2nPsOOEuX7aQstlMZKQT0164C+X2w6bnkqU3sjtLvpd5ojrezAyfZ1+0sStw==", "requires": { - "@babel/runtime": "^7.12.13", - "history": "^4.9.0", - "loose-envify": "^1.3.1", - "prop-types": "^15.6.2", - "react-router": "5.2.1", - "tiny-invariant": "^1.0.2", - "tiny-warning": "^1.0.0" + "history": "^5.2.0", + "react-router": "6.3.0" } }, "react-scripts": { @@ -38760,11 +38497,6 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" }, - "resolve-pathname": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", - "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" - }, "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", @@ -40672,16 +40404,6 @@ "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=" }, - "tiny-invariant": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz", - "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==" - }, - "tiny-warning": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" - }, "tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -41185,11 +40907,6 @@ "spdx-expression-parse": "^3.0.0" } }, - "value-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", - "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" - }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -41353,16 +41070,6 @@ } } }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, "glob-parent": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", @@ -41964,16 +41671,6 @@ "locate-path": "^3.0.0" } }, - "fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "optional": true, - "requires": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - } - }, "glob-parent": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index f51de131..b541ee4b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -21,7 +21,6 @@ "@types/react": "^17.0.33", "@types/react-dom": "^17.0.10", "@types/react-helmet": "^6.1.4", - "@types/react-router-dom": "^5.3.2", "date-fns": "^2.24.0", "fetch-intercept": "^2.4.0", "http-proxy-middleware": "^2.0.1", @@ -37,7 +36,7 @@ "react-helmet": "^6.1.0", "react-hook-form": "^7.17.5", "react-i18next": "^11.11.4", - "react-router-dom": "^5.3.0", + "react-router-dom": "^6.3.0", "react-scripts": "4.0.3", "typeface-roboto": "^1.1.13", "typescript": "^4.4.4", diff --git a/frontend/src/components/protectedRoute/index.tsx b/frontend/src/components/protectedRoute/index.tsx deleted file mode 100644 index bc7cc48c..00000000 --- a/frontend/src/components/protectedRoute/index.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import React from 'react' -import { Route, RouteProps, useLocation, useHistory } from 'react-router-dom' - -import { setCookie } from 'utils' -import { useUserContext } from 'contexts' - -interface IProtectedRoute extends RouteProps { - children: React.ReactNode -} - -function ProtectedRoute({ children, ...rest }: IProtectedRoute) { - // Simple protected route component - const { user } = useUserContext() - - if ( !user.auth ) { - const location = useLocation() - const history = useHistory() - setCookie('redirect', location.pathname) - history.push('/') - } - - return ( - <Route {...rest}> - {children} - </Route> - ) -} - -export default ProtectedRoute diff --git a/frontend/src/components/requireAuth/index.tsx b/frontend/src/components/requireAuth/index.tsx new file mode 100644 index 00000000..e57c8960 --- /dev/null +++ b/frontend/src/components/requireAuth/index.tsx @@ -0,0 +1,19 @@ +import { setCookie } from 'utils' +import { useUserContext } from 'contexts' +import { useLocation, Navigate } from 'react-router-dom' + +const isAuthenticated = () => { + const { user } = useUserContext() + + if (!user.auth) { + const location = useLocation() + setCookie('redirect', location.pathname) + return false + } + return true +} + +const RequireAuth = ({ children }: { children: JSX.Element }) => + isAuthenticated() ? children : <Navigate to="/" /> + +export default RequireAuth diff --git a/frontend/src/hooks/useGuest/index.tsx b/frontend/src/hooks/useGuest/index.tsx index 418e0b0e..d8efe7fb 100644 --- a/frontend/src/hooks/useGuest/index.tsx +++ b/frontend/src/hooks/useGuest/index.tsx @@ -2,7 +2,7 @@ import { FetchedGuest, FetchedRole, Guest } from 'interfaces' import { useEffect, useState } from 'react' import { parseRole, parseIdentity } from 'utils' -const useGuest = (pid: string) => { +const useGuest = (pid: string ) => { const [guestInfo, setGuest] = useState<Guest>({ pid: '', first: '', diff --git a/frontend/src/routes/components/overviewGuestButton.tsx b/frontend/src/routes/components/overviewGuestButton.tsx index 895f6a6c..a34922bf 100644 --- a/frontend/src/routes/components/overviewGuestButton.tsx +++ b/frontend/src/routes/components/overviewGuestButton.tsx @@ -2,7 +2,7 @@ import PersonIcon from '@mui/icons-material/Person' import { Box, IconButton } from '@mui/material' import React from 'react' import { useTranslation } from 'react-i18next' -import { useHistory } from 'react-router-dom' +import { useNavigate } from 'react-router-dom' import ArrowBackIcon from '@mui/icons-material/ArrowBack' import ArrowForwardIcon from '@mui/icons-material/ArrowForward' @@ -15,10 +15,10 @@ export default function OverviewGuestButton( ) { const { backArrow } = properties const { t } = useTranslation(['common']) - const history = useHistory() + const navigate = useNavigate() const goToGuestOverview = () => { - history.push('/guestregister') + navigate('/guestregister') } return ( @@ -33,7 +33,7 @@ export default function OverviewGuestButton( {backArrow !== undefined ? ( <ArrowBackIcon onClick={() => { - history.push(backArrow) + navigate(backArrow) }} /> ) : ( diff --git a/frontend/src/routes/components/sponsorGuestButtons.tsx b/frontend/src/routes/components/sponsorGuestButtons.tsx index 400a3bde..af30b5ba 100644 --- a/frontend/src/routes/components/sponsorGuestButtons.tsx +++ b/frontend/src/routes/components/sponsorGuestButtons.tsx @@ -3,7 +3,7 @@ import { Box, IconButton, styled, Theme } from '@mui/material' import PersonAddIcon from '@mui/icons-material/PersonAdd' import React from 'react' import { useTranslation } from 'react-i18next' -import { useHistory } from 'react-router-dom' +import { useNavigate } from 'react-router-dom' interface SponsorGuestButtonsProps { yourGuestsActive?: boolean @@ -20,14 +20,14 @@ const StyledIconButton = styled(IconButton)({ export default function SponsorGuestButtons(props: SponsorGuestButtonsProps) { const { yourGuestsActive, registerNewGuestActive } = props const { t } = useTranslation(['common']) - const history = useHistory() + const navigate = useNavigate() const goToOverview = () => { - history.push('/sponsor') + navigate('/sponsor') } const goToRegister = () => { - history.push('/register') + navigate('/register') } return ( diff --git a/frontend/src/routes/guest/register/index.test.tsx b/frontend/src/routes/guest/register/index.test.tsx index c0d41bfa..883f9a5c 100644 --- a/frontend/src/routes/guest/register/index.test.tsx +++ b/frontend/src/routes/guest/register/index.test.tsx @@ -1,8 +1,10 @@ import React from 'react' import fetchMock, { enableFetchMocks } from 'jest-fetch-mock' -import { render, screen } from 'test-utils' import AdapterDateFns from '@mui/lab/AdapterDateFns' import { LocalizationProvider } from '@mui/lab' +import { BrowserRouter } from 'react-router-dom' + +import { render, screen } from 'test-utils' import { FeatureContext } from 'contexts' import GuestRegister from './index' @@ -44,11 +46,13 @@ test('Field showing values correctly', async () => { ) render( - <FeatureContext.Provider value={allFeaturesOn}> - <LocalizationProvider dateAdapter={AdapterDateFns}> - <GuestRegister /> - </LocalizationProvider> - </FeatureContext.Provider> + <BrowserRouter> + <FeatureContext.Provider value={allFeaturesOn}> + <LocalizationProvider dateAdapter={AdapterDateFns}> + <GuestRegister /> + </LocalizationProvider> + </FeatureContext.Provider> + </BrowserRouter> ) await screen.findByDisplayValue(testData.person.first_name) @@ -88,11 +92,13 @@ test('Gender and birth date suggestions not showing if no national ID given', as Promise.resolve<any>(JSON.stringify(testData)) ) render( - <FeatureContext.Provider value={allFeaturesOn}> - <LocalizationProvider dateAdapter={AdapterDateFns}> - <GuestRegister /> - </LocalizationProvider> - </FeatureContext.Provider> + <BrowserRouter> + <FeatureContext.Provider value={allFeaturesOn}> + <LocalizationProvider dateAdapter={AdapterDateFns}> + <GuestRegister /> + </LocalizationProvider> + </FeatureContext.Provider> + </BrowserRouter> ) // Wait a bit so that all the values are showing @@ -121,11 +127,13 @@ test('Gender and birth date suggestions not overriding existing values', async ( Promise.resolve<any>(JSON.stringify(testData)) ) render( - <FeatureContext.Provider value={allFeaturesOn}> - <LocalizationProvider dateAdapter={AdapterDateFns}> - <GuestRegister /> - </LocalizationProvider> - </FeatureContext.Provider> + <BrowserRouter> + <FeatureContext.Provider value={allFeaturesOn}> + <LocalizationProvider dateAdapter={AdapterDateFns}> + <GuestRegister /> + </LocalizationProvider> + </FeatureContext.Provider> + </BrowserRouter> ) // In this a date of birth was already set, and it should not have been overridden by a suggestion diff --git a/frontend/src/routes/guest/register/index.tsx b/frontend/src/routes/guest/register/index.tsx index be680523..ce03d0e2 100644 --- a/frontend/src/routes/guest/register/index.tsx +++ b/frontend/src/routes/guest/register/index.tsx @@ -1,6 +1,6 @@ import React, { Suspense, useContext, useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' -import { useHistory } from 'react-router-dom' +import { useNavigate } from 'react-router-dom' import { CountryCode, getCountries, @@ -67,7 +67,7 @@ type InvitationData = { */ export default function GuestRegister() { const { t } = useTranslation(['common']) - const history = useHistory() + const navigate = useNavigate() const { showGenderFieldForGuest } = useContext(FeatureContext) const guestRegisterRef = useRef<GuestRegisterCallableMethods>(null) @@ -369,7 +369,7 @@ export default function GuestRegister() { // Go back to the invite page. The invitation ID does not need // to be specified here, since the user has already been // logged in and can be identified without the invitation ID - history.push('/invite') + navigate('/invite') } return ( diff --git a/frontend/src/routes/guest/register/steps/success.tsx b/frontend/src/routes/guest/register/steps/success.tsx index 95e5a49d..4ee71e6a 100644 --- a/frontend/src/routes/guest/register/steps/success.tsx +++ b/frontend/src/routes/guest/register/steps/success.tsx @@ -1,13 +1,13 @@ import React, { useEffect } from 'react' import { useTranslation } from 'react-i18next' -import { useHistory } from 'react-router-dom' +import { useNavigate } from 'react-router-dom' import { Button, Typography } from '@mui/material' import { useUserContext } from 'contexts' const GuestSuccessStep = () => { const { t } = useTranslation(['common']) - const history = useHistory() + const navigate = useNavigate() const { getUserInfo } = useUserContext() // Refetch user info after submission, so that the front page doesn't redirect us @@ -36,7 +36,7 @@ const GuestSuccessStep = () => { marginTop: '2rem', }} onClick={() => { - history.push('/') + navigate('/') }} > {t('button.backToFrontPage')} diff --git a/frontend/src/routes/index.tsx b/frontend/src/routes/index.tsx index 1276166a..167468d7 100644 --- a/frontend/src/routes/index.tsx +++ b/frontend/src/routes/index.tsx @@ -1,5 +1,5 @@ import { useEffect } from 'react' -import { Switch, Route, useHistory } from 'react-router-dom' +import { Routes, Route, useNavigate } from 'react-router-dom' import { styled } from '@mui/system' import { CssBaseline } from '@mui/material' @@ -22,7 +22,7 @@ import LogoutInviteSession from 'routes/invite/logout' import Footer from 'routes/components/footer' import Header from 'routes/components/header' import NotFound from 'routes/components/notFound' -import ProtectedRoute from 'components/protectedRoute' +import RequireAuth from 'components/requireAuth' const AppWrapper = styled('div')({ display: 'flex', @@ -34,14 +34,14 @@ const AppWrapper = styled('div')({ export default function App() { const { user, clearUserInfo } = useUserContext() - const history = useHistory() + const navigate = useNavigate() useEffect(() => { if (user.auth) { const redirect = getCookie('redirect') if (redirect) { deleteCookie('redirect') - history.push(redirect) + navigate(redirect) } } }, [user.fetched]) @@ -67,23 +67,31 @@ export default function App() { <CssBaseline /> <AppWrapper> <Header /> - <Switch> - <Route exact path="/"> - <FrontPage /> - </Route> - <ProtectedRoute path="/sponsor"> - <Sponsor /> - </ProtectedRoute> - <ProtectedRoute path="/register"> - <Register /> - </ProtectedRoute> - <Route path="/invite/logout" component={LogoutInviteSession} /> - <Route path="/invite/" component={Invite} /> - <Route path="/guestregister" component={GuestRegister} /> - <Route> - <NotFound /> - </Route> - </Switch> + <Routes> + <Route path="/" element={<FrontPage />} /> + <Route + path="/sponsor/*" + element={ + <RequireAuth> + <Sponsor /> + </RequireAuth> + } + /> + + <Route + path="/register/*" + element={ + <RequireAuth> + <Register /> + </RequireAuth> + } + /> + + <Route path="/invite/logout" element={<LogoutInviteSession />} /> + <Route path="/invite/" element={<Invite />} /> + <Route path="/guestregister" element={<GuestRegister />} /> + <Route element={<NotFound />} /> + </Routes> <Footer /> </AppWrapper> </> diff --git a/frontend/src/routes/invite/logout.tsx b/frontend/src/routes/invite/logout.tsx index f0333dde..eb3219b1 100644 --- a/frontend/src/routes/invite/logout.tsx +++ b/frontend/src/routes/invite/logout.tsx @@ -1,5 +1,5 @@ import { useEffect, useState } from 'react' -import { Redirect } from 'react-router-dom' +import { Navigate } from 'react-router-dom' import { useCookies } from 'react-cookie' import { Box, CircularProgress } from '@mui/material' @@ -20,7 +20,7 @@ export default function LogoutInviteSession() { }, []) if (loggedOut) { - return <Redirect to="/" /> + return <Navigate to="/" /> } return ( diff --git a/frontend/src/routes/landing/index.tsx b/frontend/src/routes/landing/index.tsx index f964ef84..8c1a0f76 100644 --- a/frontend/src/routes/landing/index.tsx +++ b/frontend/src/routes/landing/index.tsx @@ -13,7 +13,7 @@ import { useUserContext } from 'contexts' import { FetchedRole, Role, Consent, FetchedConsent } from 'interfaces' import { useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' -import { Redirect } from 'react-router-dom' +import { Navigate } from 'react-router-dom' import { parseRole, parseConsent } from 'utils' const GuestPage = () => { @@ -123,11 +123,11 @@ function LandingPage() { const { user } = useUserContext() if (user.sponsor_id) { - return <Redirect to="/sponsor" /> + return <Navigate to="/sponsor" /> } if (user.person_id) { if (!user.registration_completed_date) { - return <Redirect to="/guestregister" /> + return <Navigate to="/guestregister" /> } return <GuestPage /> } diff --git a/frontend/src/routes/sponsor/guest/guestInfo/index.tsx b/frontend/src/routes/sponsor/guest/guestInfo/index.tsx index bbebbfe1..43f663e1 100644 --- a/frontend/src/routes/sponsor/guest/guestInfo/index.tsx +++ b/frontend/src/routes/sponsor/guest/guestInfo/index.tsx @@ -1,4 +1,4 @@ -import { Link, useParams, useHistory } from 'react-router-dom' +import { Link, useParams, useNavigate } from 'react-router-dom' import Page from 'components/page' import RoleLine from 'components/roleLine' @@ -95,7 +95,7 @@ export default function GuestInfo({ }: GuestInfoProps) { const { pid } = useParams<GuestInfoParams>() const [t] = useTranslation(['common']) - const history = useHistory() + const navigate = useNavigate() const [confirmCancelDialogOpen, setConfirmCancelDialogOpen] = useState(false) const [emailUpdateError, setEmailUpdateError] = useState<ServerErrorReportData>() @@ -196,7 +196,7 @@ export default function GuestInfo({ if (result !== null) { // The invite for the guest has been cancelled, send the user back to the sponsor front page reloadGuests() - history.push('/sponsor') + navigate('/sponsor') } }) .catch((error) => { @@ -365,9 +365,12 @@ export default function GuestInfo({ <TableHeadCell align="left">{t('common:host')}</TableHeadCell> <TableHeadCell align="left" /> </TableRow> - {guest.roles.map((role) => ( - <RoleLine key={role.id} pid={pid} role={role} /> - ))} + {guest.roles.map((role) => { + if (pid === undefined) { + return <></> + } + return <RoleLine key={role.id} pid={pid} role={role} /> + })} </TableBody> </Table> <Button diff --git a/frontend/src/routes/sponsor/guest/guestRoleInfo/index.test.tsx b/frontend/src/routes/sponsor/guest/guestRoleInfo/index.test.tsx index b95000f1..f0687cbb 100644 --- a/frontend/src/routes/sponsor/guest/guestRoleInfo/index.test.tsx +++ b/frontend/src/routes/sponsor/guest/guestRoleInfo/index.test.tsx @@ -3,10 +3,9 @@ import { render, screen } from 'test-utils' import AdapterDateFns from '@mui/lab/AdapterDateFns' import { LocalizationProvider } from '@mui/lab' // eslint-disable-next-line import/no-extraneous-dependencies -import { createMemoryHistory } from 'history' import { Guest } from 'interfaces' import parse from 'date-fns/parse' -import { Router } from 'react-router-dom' +import { BrowserRouter } from 'react-router-dom' import GuestRoleInfo from './index' import { waitFor } from '../../../../test-utils' @@ -52,14 +51,12 @@ const guest: Guest = { } test('Button state correct on load', async () => { - const history = createMemoryHistory() - render( - <Router history={history}> + <BrowserRouter> <LocalizationProvider dateAdapter={AdapterDateFns}> <GuestRoleInfo guest={guest} reloadGuest={() => {}} /> </LocalizationProvider> - </Router> + </BrowserRouter> ) await waitFor( diff --git a/frontend/src/routes/sponsor/guest/guestRoleInfo/index.tsx b/frontend/src/routes/sponsor/guest/guestRoleInfo/index.tsx index a9ac0366..c8293c72 100644 --- a/frontend/src/routes/sponsor/guest/guestRoleInfo/index.tsx +++ b/frontend/src/routes/sponsor/guest/guestRoleInfo/index.tsx @@ -11,7 +11,7 @@ import TableCellMui from '@mui/material/TableCell' import Page from 'components/page' import { Guest, Role } from 'interfaces' import { useTranslation } from 'react-i18next' -import { useHistory, useParams } from 'react-router-dom' +import { useNavigate, useParams } from 'react-router-dom' import SponsorInfoButtons from 'routes/components/sponsorInfoButtons' import { DatePicker } from '@mui/lab' import { Controller, SubmitHandler, useForm } from 'react-hook-form' @@ -103,7 +103,7 @@ export default function GuestRoleInfo({ const { pid, id } = useParams<GuestRoleInfoParams>() const [t] = useTranslation('common') const { displayContactAtUnit, displayComment } = useFeatureContext() - const history = useHistory() + const navigate = useNavigate() const [role, setRole] = useState<Role>({ id: '', name_nb: '', @@ -122,15 +122,15 @@ export default function GuestRoleInfo({ const todayPlusMaxDays = addDays(role.max_days)(today) // Make a function for use with onClick of the end role button - const endPeriod = () => { + const endPeriod = (role_id: string) => () => { // Set the role to have ended yesterday so that the change is immediate. // If the role was set to end today, the change will not be active // until the next date since the end date is inclusive const newEndDate = addDays(-1)(today) role.end_date = newEndDate - endPeriodPost(id, { end_date: newEndDate }) + endPeriodPost(role_id, { end_date: newEndDate }) // Go back to guest overview page - history.push(`/sponsor/guest/${guest.pid}`) + navigate(`/sponsor/guest/${guest.pid}`) } const { @@ -314,14 +314,18 @@ export default function GuestRoleInfo({ > {t('sponsor.endNow')} </Button> - <ConfirmDialog - title={t('endRoleDialog.title')} - open={showEndRoleConfirmationDialog} - setOpen={setShowEndRoleConfirmationDialog} - onConfirm={endPeriod} - > - {t('endRoleDialog.text')} - </ConfirmDialog> + {typeof id === 'string' ? ( + <ConfirmDialog + title={t('endRoleDialog.title')} + open={showEndRoleConfirmationDialog} + setOpen={setShowEndRoleConfirmationDialog} + onConfirm={endPeriod(id)} + > + {t('endRoleDialog.text')} + </ConfirmDialog> + ) : ( + <></> + )} </form> </Page> ) diff --git a/frontend/src/routes/sponsor/guest/index.tsx b/frontend/src/routes/sponsor/guest/index.tsx index 8d36ad2e..3ecccbaa 100644 --- a/frontend/src/routes/sponsor/guest/index.tsx +++ b/frontend/src/routes/sponsor/guest/index.tsx @@ -1,5 +1,5 @@ import useGuest from 'hooks/useGuest' -import { Route, useParams } from 'react-router-dom' +import { Route, Routes, useParams } from 'react-router-dom' import { submitJsonOpts } from 'utils' import GuestInfo from './guestInfo' import GuestRoleInfo from './guestRoleInfo' @@ -15,6 +15,9 @@ type GuestRoutesProps = { function GuestRoutes({ reloadGuests }: GuestRoutesProps) { const { pid } = useParams<GuestInfoParams>() + if (typeof pid === 'undefined') { + return <></> + } const { guestInfo, reloadGuestInfo } = useGuest(pid) const updateEmail = ( @@ -59,23 +62,32 @@ function GuestRoutes({ reloadGuests }: GuestRoutesProps) { } return ( - <> - <Route path="/sponsor/guest/:pid/roles/:id"> - <GuestRoleInfo guest={guestInfo} reloadGuest={reloadGuestInfo} /> - </Route> - <Route exact path="/sponsor/guest/:pid/newrole"> - <NewGuestRole guest={guestInfo} reloadGuestInfo={reloadGuestInfo} /> - </Route> - <Route exact path="/sponsor/guest/:pid"> - <GuestInfo - guest={guestInfo} - updateEmail={updateEmail} - resend={resend} - reloadGuests={reloadGuests} - reloadGuest={reloadGuestInfo} - /> - </Route> - </> + <Routes> + <Route + path="/roles/:id" + element={ + <GuestRoleInfo guest={guestInfo} reloadGuest={reloadGuestInfo} /> + } + /> + <Route + path="/newrole" + element={ + <NewGuestRole guest={guestInfo} reloadGuestInfo={reloadGuestInfo} /> + } + /> + <Route + path="" + element={ + <GuestInfo + guest={guestInfo} + updateEmail={updateEmail} + resend={resend} + reloadGuests={reloadGuests} + reloadGuest={reloadGuestInfo} + /> + } + /> + </Routes> ) } diff --git a/frontend/src/routes/sponsor/guest/newGuestRole/index.tsx b/frontend/src/routes/sponsor/guest/newGuestRole/index.tsx index 819218d1..2fb5c81f 100644 --- a/frontend/src/routes/sponsor/guest/newGuestRole/index.tsx +++ b/frontend/src/routes/sponsor/guest/newGuestRole/index.tsx @@ -1,7 +1,7 @@ import { useState } from 'react' import { Controller, useForm } from 'react-hook-form' import { useTranslation } from 'react-i18next' -import { Link, useHistory, useParams } from 'react-router-dom' +import { Link, useNavigate, useParams } from 'react-router-dom' import { format } from 'date-fns' import { addDays } from 'date-fns/fp' import { DatePicker } from '@mui/lab' @@ -110,11 +110,16 @@ function NewGuestRole({ guest, reloadGuestInfo }: NewGuestRoleProps) { const { displayContactAtUnit, displayComment } = useFeatureContext() const { pid } = useParams<GuestInfoParams>() - const history = useHistory() + // Hack to make typecheck happy. The only way for pid to be undefined + // is if the Route is set up wrong, which should brake everything any way + if(typeof(pid) === "undefined"){ + return <></> + } + const navigate = useNavigate() const onSubmit = handleSubmit(async () => { await postRole(getValues(), pid) reloadGuestInfo() - history.push(`/sponsor/guest/${pid}`) + navigate(`/sponsor/guest/${pid}`) }) const ous = useOus() diff --git a/frontend/src/routes/sponsor/index.tsx b/frontend/src/routes/sponsor/index.tsx index e429db43..989d7548 100644 --- a/frontend/src/routes/sponsor/index.tsx +++ b/frontend/src/routes/sponsor/index.tsx @@ -1,4 +1,4 @@ -import { Route } from 'react-router-dom' +import { Route, Routes } from 'react-router-dom' import FrontPage from 'routes/sponsor/frontpage' import useGuests from 'hooks/useGuests' @@ -8,14 +8,13 @@ function Sponsor() { const { guests, reloadGuests } = useGuests() return ( - <> - <Route path="/sponsor/guest/:pid"> - <GuestRoutes reloadGuests={reloadGuests} /> - </Route> - <Route exact path="/sponsor"> - <FrontPage guests={guests} /> - </Route> - </> + <Routes> + <Route + path="guest/:pid/*" + element={<GuestRoutes reloadGuests={reloadGuests} />} + /> + <Route path="" element={<FrontPage guests={guests} />} /> + </Routes> ) } diff --git a/frontend/src/routes/sponsor/register/index.test.tsx b/frontend/src/routes/sponsor/register/index.test.tsx index ad6ed27d..9be38b27 100644 --- a/frontend/src/routes/sponsor/register/index.test.tsx +++ b/frontend/src/routes/sponsor/register/index.test.tsx @@ -1,15 +1,19 @@ import React from 'react' -import { render, waitFor, screen } from 'test-utils' import userEvent from '@testing-library/user-event' import AdapterDateFns from '@mui/lab/AdapterDateFns' import { LocalizationProvider } from '@mui/lab' +import { BrowserRouter } from 'react-router-dom' + +import { render, waitFor, screen } from 'test-utils' import StepRegistration from './stepRegistration' test('Validation message showing if last name is missing', async () => { render( - <LocalizationProvider dateAdapter={AdapterDateFns}> - <StepRegistration /> - </LocalizationProvider> + <BrowserRouter> + <LocalizationProvider dateAdapter={AdapterDateFns}> + <StepRegistration /> + </LocalizationProvider> + </BrowserRouter> ) // Try to go to the next step and check that the validation message is showing diff --git a/frontend/src/routes/sponsor/register/index.tsx b/frontend/src/routes/sponsor/register/index.tsx index c53b35ef..c29f4f8c 100644 --- a/frontend/src/routes/sponsor/register/index.tsx +++ b/frontend/src/routes/sponsor/register/index.tsx @@ -1,17 +1,13 @@ -import { Route } from 'react-router-dom' +import { Route, Routes } from 'react-router-dom' import FrontPage from './frontPage' import StepRegistration from './stepRegistration' function Register() { return ( - <> - <Route path="/register/new"> - <StepRegistration /> - </Route> - <Route exact path="/register"> - <FrontPage /> - </Route> - </> + <Routes> + <Route path="/new" element={<StepRegistration />} /> + <Route path="" element={<FrontPage />} /> + </Routes> ) } export default Register diff --git a/frontend/src/routes/sponsor/register/stepRegistration.tsx b/frontend/src/routes/sponsor/register/stepRegistration.tsx index 479cbb26..3aecf895 100644 --- a/frontend/src/routes/sponsor/register/stepRegistration.tsx +++ b/frontend/src/routes/sponsor/register/stepRegistration.tsx @@ -4,7 +4,7 @@ import { useTranslation } from 'react-i18next' import { Box, Button } from '@mui/material' import Page from 'components/page' -import { useHistory } from 'react-router-dom' +import { useNavigate } from 'react-router-dom' import format from 'date-fns/format' import { RegisterFormData } from './formData' import StepSummary from './stepSummary' @@ -45,7 +45,7 @@ export default function StepRegistration() { ou_id: undefined, email: undefined, }) - const history = useHistory() + const navigate = useNavigate() const [activeStep, setActiveStep] = useState(0) const personFormRef = useRef<PersonFormMethods>(null) @@ -187,7 +187,7 @@ export default function StepRegistration() { } const handleCancel = () => { - history.push('/') + navigate('/') } useEffect(() => { diff --git a/frontend/src/routes/sponsor/register/stepSubmitSuccess.tsx b/frontend/src/routes/sponsor/register/stepSubmitSuccess.tsx index f1e35d42..6c03fab1 100644 --- a/frontend/src/routes/sponsor/register/stepSubmitSuccess.tsx +++ b/frontend/src/routes/sponsor/register/stepSubmitSuccess.tsx @@ -3,11 +3,11 @@ import { useTranslation } from 'react-i18next' import { Box, Button } from '@mui/material' -import { useHistory } from 'react-router-dom' +import { useNavigate } from 'react-router-dom' const StepSubmitSuccess = () => { const { t } = useTranslation(['common']) - const history = useHistory() + const navigate = useNavigate() return ( <> @@ -32,7 +32,7 @@ const StepSubmitSuccess = () => { marginTop: '2rem', }} onClick={() => { - history.push('/') + navigate('/') }} > {t('button.backToFrontPage')} -- GitLab