diff --git a/package-lock.json b/package-lock.json index 754092f..0bc327b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -45,6 +45,7 @@ "react-icons": "^4.10.1", "react-intersection-observer": "^9.5.2", "react-map-gl": "^7.1.2", + "react-page-scroller": "^3.0.1", "react-responsive-carousel": "^3.2.23", "swr": "^2.2.0", "theme-change": "^2.5.0", @@ -3205,6 +3206,49 @@ "dequal": "^2.0.3" } }, + "node_modules/babel-polyfill": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", + "integrity": "sha512-F2rZGQnAdaHWQ8YAoeRbukc7HS9QgdgeyJ0rQDd485v9opwuPvjpPFcOOT/WmkKTdgy9ESgSPXDcTNpzrGr6iQ==", + "dependencies": { + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "regenerator-runtime": "^0.10.5" + } + }, + "node_modules/babel-polyfill/node_modules/core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", + "hasInstallScript": true + }, + "node_modules/babel-polyfill/node_modules/regenerator-runtime": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha512-02YopEIhAgiBHWeoTiA8aitHDt8z6w+rQqNuIftlM+ZtvSl/brTouaU7DW6GO/cHtvxJvS4Hwv2ibKdxIRi24w==" + }, + "node_modules/babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", + "dependencies": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "node_modules/babel-runtime/node_modules/core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", + "hasInstallScript": true + }, + "node_modules/babel-runtime/node_modules/regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -5744,6 +5788,26 @@ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" }, + "node_modules/history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "peer": true, + "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" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz", + "integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==", + "peer": true + }, "node_modules/hosted-git-info": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", @@ -5951,6 +6015,15 @@ "node": ">= 0.10" } }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "peer": true, + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/is-array-buffer": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", @@ -8128,6 +8201,21 @@ "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==", + "peer": true, + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/path-to-regexp/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "peer": true + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -8897,6 +8985,21 @@ } } }, + "node_modules/react-page-scroller": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/react-page-scroller/-/react-page-scroller-3.0.1.tgz", + "integrity": "sha512-1OTlUHOSFCG8wmYzy3wo4dUIugXORzgZZ/Pj4BbkxN3n+Nv5tynfo7kygUiLYgE0QhDJslzZ4lntpCONAlv/vA==", + "dependencies": { + "babel-polyfill": "^6.26.0" + }, + "peerDependencies": { + "babel-polyfill": "^6.26.0", + "prop-types": "^15.6.2", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-router-dom": "^4.3.1" + } + }, "node_modules/react-responsive-carousel": { "version": "3.2.23", "resolved": "https://registry.npmjs.org/react-responsive-carousel/-/react-responsive-carousel-3.2.23.tgz", @@ -8907,6 +9010,41 @@ "react-easy-swipe": "^0.0.21" } }, + "node_modules/react-router": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-4.3.1.tgz", + "integrity": "sha512-yrvL8AogDh2X42Dt9iknk4wF4V8bWREPirFfS9gLU1huk6qK41sg7Z/1S81jjTrGHxa3B8R3J6xIkDAA6CVarg==", + "peer": true, + "dependencies": { + "history": "^4.7.2", + "hoist-non-react-statics": "^2.5.0", + "invariant": "^2.2.4", + "loose-envify": "^1.3.1", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.1", + "warning": "^4.0.1" + }, + "peerDependencies": { + "react": ">=15" + } + }, + "node_modules/react-router-dom": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-4.3.1.tgz", + "integrity": "sha512-c/MlywfxDdCp7EnB7YfPMOfMD3tOtIjrQlj/CKfNMBxdmpJP8xcz5P/UAFn3JbnQCNUxsHyVVqllF9LhgVyFCA==", + "peer": true, + "dependencies": { + "history": "^4.7.2", + "invariant": "^2.2.4", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.1", + "react-router": "^4.3.1", + "warning": "^4.0.1" + }, + "peerDependencies": { + "react": ">=15" + } + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -9216,6 +9354,12 @@ "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==", + "peer": true + }, "node_modules/resolve-pkg-maps": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", @@ -10097,6 +10241,18 @@ "real-require": "^0.2.0" } }, + "node_modules/tiny-invariant": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", + "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==", + "peer": true + }, + "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==", + "peer": true + }, "node_modules/tinyqueue": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-2.0.3.tgz", @@ -10584,6 +10740,12 @@ "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==", + "peer": true + }, "node_modules/vt-pbf": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/vt-pbf/-/vt-pbf-3.1.3.tgz", @@ -10594,6 +10756,15 @@ "pbf": "^3.2.1" } }, + "node_modules/warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "peer": true, + "dependencies": { + "loose-envify": "^1.0.0" + } + }, "node_modules/watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", @@ -13092,6 +13263,49 @@ "dequal": "^2.0.3" } }, + "babel-polyfill": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", + "integrity": "sha512-F2rZGQnAdaHWQ8YAoeRbukc7HS9QgdgeyJ0rQDd485v9opwuPvjpPFcOOT/WmkKTdgy9ESgSPXDcTNpzrGr6iQ==", + "requires": { + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "regenerator-runtime": "^0.10.5" + }, + "dependencies": { + "core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==" + }, + "regenerator-runtime": { + "version": "0.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha512-02YopEIhAgiBHWeoTiA8aitHDt8z6w+rQqNuIftlM+ZtvSl/brTouaU7DW6GO/cHtvxJvS4Hwv2ibKdxIRi24w==" + } + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + }, + "dependencies": { + "core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==" + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + } + } + }, "balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -14957,6 +15171,26 @@ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" }, + "history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "peer": true, + "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" + } + }, + "hoist-non-react-statics": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.5.tgz", + "integrity": "sha512-rqcy4pJo55FTTLWt+bU8ukscqHeE/e9KWvsOW2b/a3afxQZhwkQdT1rPPCJ0rYXdj4vNcasY8zHTH+jF/qStxw==", + "peer": true + }, "hosted-git-info": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", @@ -15106,6 +15340,15 @@ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==" }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "peer": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, "is-array-buffer": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", @@ -16592,6 +16835,23 @@ "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==", + "peer": true, + "requires": { + "isarray": "0.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "peer": true + } + } + }, "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -17055,6 +17315,14 @@ "@types/mapbox-gl": ">=1.0.0" } }, + "react-page-scroller": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/react-page-scroller/-/react-page-scroller-3.0.1.tgz", + "integrity": "sha512-1OTlUHOSFCG8wmYzy3wo4dUIugXORzgZZ/Pj4BbkxN3n+Nv5tynfo7kygUiLYgE0QhDJslzZ4lntpCONAlv/vA==", + "requires": { + "babel-polyfill": "^6.26.0" + } + }, "react-responsive-carousel": { "version": "3.2.23", "resolved": "https://registry.npmjs.org/react-responsive-carousel/-/react-responsive-carousel-3.2.23.tgz", @@ -17065,6 +17333,35 @@ "react-easy-swipe": "^0.0.21" } }, + "react-router": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-4.3.1.tgz", + "integrity": "sha512-yrvL8AogDh2X42Dt9iknk4wF4V8bWREPirFfS9gLU1huk6qK41sg7Z/1S81jjTrGHxa3B8R3J6xIkDAA6CVarg==", + "peer": true, + "requires": { + "history": "^4.7.2", + "hoist-non-react-statics": "^2.5.0", + "invariant": "^2.2.4", + "loose-envify": "^1.3.1", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.1", + "warning": "^4.0.1" + } + }, + "react-router-dom": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-4.3.1.tgz", + "integrity": "sha512-c/MlywfxDdCp7EnB7YfPMOfMD3tOtIjrQlj/CKfNMBxdmpJP8xcz5P/UAFn3JbnQCNUxsHyVVqllF9LhgVyFCA==", + "peer": true, + "requires": { + "history": "^4.7.2", + "invariant": "^2.2.4", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.1", + "react-router": "^4.3.1", + "warning": "^4.0.1" + } + }, "read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -17306,6 +17603,12 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "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==", + "peer": true + }, "resolve-pkg-maps": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", @@ -17969,6 +18272,18 @@ "real-require": "^0.2.0" } }, + "tiny-invariant": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.3.1.tgz", + "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==", + "peer": true + }, + "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==", + "peer": true + }, "tinyqueue": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/tinyqueue/-/tinyqueue-2.0.3.tgz", @@ -18326,6 +18641,12 @@ "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==", + "peer": true + }, "vt-pbf": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/vt-pbf/-/vt-pbf-3.1.3.tgz", @@ -18336,6 +18657,15 @@ "pbf": "^3.2.1" } }, + "warning": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", + "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==", + "peer": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, "watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", diff --git a/package.json b/package.json index 15272cc..7fe47f4 100644 --- a/package.json +++ b/package.json @@ -36,12 +36,13 @@ "lodash": "^4.17.21", "mapbox-gl": "^2.15.0", "multer": "^1.4.5-lts.1", + "next": "^14.0.3", "next-cloudinary": "^5.10.0", "next-connect": "^1.0.0-next.3", - "next": "^14.0.3", - "passport-local": "^1.0.0", "passport": "^0.6.0", + "passport-local": "^1.0.0", "pino": "^8.14.1", + "react": "^18.2.0", "react-daisyui": "^4.1.2", "react-dom": "^18.2.0", "react-email": "^1.9.5", @@ -50,8 +51,8 @@ "react-icons": "^4.10.1", "react-intersection-observer": "^9.5.2", "react-map-gl": "^7.1.2", + "react-page-scroller": "^3.0.1", "react-responsive-carousel": "^3.2.23", - "react": "^18.2.0", "swr": "^2.2.0", "theme-change": "^2.5.0", "zod": "^3.21.4" @@ -66,28 +67,27 @@ "@types/multer": "^1.4.7", "@types/node": "^20.4.2", "@types/passport-local": "^1.0.35", - "@types/react-dom": "^18.2.7", "@types/react": "^18.2.15", - "@types/sparkpost": "^2.1.5", + "@types/react-dom": "^18.2.7", "@vercel/fetch": "^7.0.0", "autoprefixer": "^10.4.14", "daisyui": "^3.9.2", "dotenv-cli": "^7.2.1", + "eslint": "^8.51.0", "eslint-config-airbnb-base": "15.0.0", "eslint-config-airbnb-typescript": "17.1.0", "eslint-config-next": "^13.5.4", "eslint-config-prettier": "^9.0.0", "eslint-plugin-react": "^7.33.2", - "eslint": "^8.51.0", "generate-password": "^1.7.1", "onchange": "^7.1.0", "postcss": "^8.4.26", + "prettier": "^3.0.0", "prettier-plugin-jsdoc": "^1.0.2", "prettier-plugin-tailwindcss": "^0.5.7", - "prettier": "^3.0.0", "prisma": "^5.7.0", - "tailwindcss-animate": "^1.0.6", "tailwindcss": "^3.3.3", + "tailwindcss-animate": "^1.0.6", "ts-node": "^10.9.1", "typescript": "^5.3.2" }, diff --git a/src/components/BreweryPost/CreateBreweryPostForm.tsx b/src/components/BreweryPost/CreateBreweryPostForm.tsx index 7a7aaae..d61e444 100644 --- a/src/components/BreweryPost/CreateBreweryPostForm.tsx +++ b/src/components/BreweryPost/CreateBreweryPostForm.tsx @@ -1,5 +1,5 @@ import sendUploadBreweryImagesRequest from '@/requests/images/brewery-image/sendUploadBreweryImageRequest'; -import sendCreateBreweryPostRequest from '@/requests/posts/brewery-post/sendCreateBreweryPostRequest'; + import CreateBreweryPostSchema from '@/services/posts/brewery-post/schema/CreateBreweryPostSchema'; import UploadImageValidationSchema from '@/services/schema/ImageSchema/UploadImageValidationSchema'; import createErrorToast from '@/util/createErrorToast'; @@ -27,6 +27,7 @@ import FormSegment from '../ui/forms/FormSegment'; import FormTextArea from '../ui/forms/FormTextArea'; import FormTextInput from '../ui/forms/FormTextInput'; import Button from '../ui/forms/Button'; +import { sendCreateBreweryPostRequest } from '@/requests/posts/brewery-post'; const AddressAutofill = dynamic( // @ts-expect-error @@ -225,7 +226,7 @@ const CreateBreweryPostForm: FC<{ if (!(data.images instanceof FileList)) { return; } - const breweryPost = await sendCreateBreweryPostRequest(data); + const breweryPost = await sendCreateBreweryPostRequest({ body: data }); await sendUploadBreweryImagesRequest({ breweryPost, images: data.images }); await router.push(`/breweries/${breweryPost.id}`); toast.remove(loadingToast); diff --git a/src/components/EditBreweryPostForm.tsx b/src/components/EditBreweryPostForm.tsx new file mode 100644 index 0000000..4837be9 --- /dev/null +++ b/src/components/EditBreweryPostForm.tsx @@ -0,0 +1,106 @@ +import EditBreweryPostValidationSchema from '@/services/posts/brewery-post/schema/EditBreweryPostValidationSchema'; +import { zodResolver } from '@hookform/resolvers/zod'; +import { useRouter } from 'next/router'; +import { useForm } from 'react-hook-form'; +import { z } from 'zod'; +import { FC, useState } from 'react'; +import BreweryPostQueryResult from '@/services/posts/brewery-post/schema/BreweryPostQueryResult'; +import { + sendDeleteBreweryPostRequest, + sendEditBreweryPostRequest, +} from '@/requests/posts/brewery-post'; +import FormError from './ui/forms/FormError'; +import FormInfo from './ui/forms/FormInfo'; +import FormLabel from './ui/forms/FormLabel'; +import FormSegment from './ui/forms/FormSegment'; +import FormTextArea from './ui/forms/FormTextArea'; +import FormTextInput from './ui/forms/FormTextInput'; + +interface EditBreweryPostFormProps { + breweryPost: z.infer; +} +const EditBreweryPostForm: FC = ({ breweryPost }) => { + const router = useRouter(); + const { + register, + handleSubmit, + formState: { errors, isSubmitting }, + } = useForm>({ + resolver: zodResolver(EditBreweryPostValidationSchema), + defaultValues: { + name: breweryPost.name, + description: breweryPost.description, + id: breweryPost.id, + dateEstablished: breweryPost.dateEstablished, + }, + }); + + const [isDeleting, setIsDeleting] = useState(false); + + const onSubmit = async (data: z.infer) => { + await sendEditBreweryPostRequest({ breweryPostId: breweryPost.id, body: data }); + await router.push(`/breweries/${breweryPost.id}`); + }; + + const handleDelete = async () => { + setIsDeleting(true); + await sendDeleteBreweryPostRequest({ breweryPostId: breweryPost.id }); + await router.push('/breweries'); + }; + + return ( +
+
+ + Name + {errors.name?.message} + + + + + + + Description + {errors.description?.message} + + + + +
+ +
+ + +
+
+ ); +}; + +export default EditBreweryPostForm; diff --git a/src/pages/breweries/[id]/edit.tsx b/src/pages/breweries/[id]/edit.tsx index 5f2c493..e6487c6 100644 --- a/src/pages/breweries/[id]/edit.tsx +++ b/src/pages/breweries/[id]/edit.tsx @@ -1,20 +1,11 @@ -import FormError from '@/components/ui/forms/FormError'; -import FormInfo from '@/components/ui/forms/FormInfo'; -import FormLabel from '@/components/ui/forms/FormLabel'; +import EditBreweryPostForm from '@/components/EditBreweryPostForm'; import FormPageLayout from '@/components/ui/forms/FormPageLayout'; -import FormSegment from '@/components/ui/forms/FormSegment'; -import FormTextArea from '@/components/ui/forms/FormTextArea'; -import FormTextInput from '@/components/ui/forms/FormTextInput'; import { getBreweryPostByIdService } from '@/services/posts/brewery-post'; import BreweryPostQueryResult from '@/services/posts/brewery-post/schema/BreweryPostQueryResult'; -import EditBreweryPostValidationSchema from '@/services/posts/brewery-post/schema/EditBreweryPostValidationSchema'; import withPageAuthRequired from '@/util/withPageAuthRequired'; -import { zodResolver } from '@hookform/resolvers/zod'; import { NextPage } from 'next'; import Head from 'next/head'; -import { useRouter } from 'next/router'; -import { useForm } from 'react-hook-form'; import { BiBeer } from 'react-icons/bi'; import { z } from 'zod'; @@ -25,49 +16,6 @@ interface EditPageProps { const EditBreweryPostPage: NextPage = ({ breweryPost }) => { const pageTitle = `Edit \u201c${breweryPost.name}\u201d`; - const router = useRouter(); - const { - register, - handleSubmit, - formState: { errors, isSubmitting }, - } = useForm>({ - resolver: zodResolver(EditBreweryPostValidationSchema), - defaultValues: { - name: breweryPost.name, - description: breweryPost.description, - id: breweryPost.id, - dateEstablished: breweryPost.dateEstablished, - }, - }); - - const onSubmit = async (data: z.infer) => { - const response = await fetch(`/api/breweries/${breweryPost.id}`, { - method: 'PUT', - headers: { - 'Content-Type': 'application/json', - }, - body: JSON.stringify(data), - }); - - if (!response.ok) { - throw new Error('Something went wrong'); - } - - router.push(`/breweries/${breweryPost.id}`); - }; - - const handleDelete = async () => { - const response = await fetch(`/api/breweries/${breweryPost.id}`, { - method: 'DELETE', - }); - - if (!response.ok) { - throw new Error('Something went wrong'); - } - - router.push('/breweries'); - }; - return ( <> @@ -81,59 +29,7 @@ const EditBreweryPostPage: NextPage = ({ breweryPost }) => { backLink={`/breweries/${breweryPost.id}`} backLinkText={`Back to "${breweryPost.name}"`} > - <> -
-
- - Name - {errors.name?.message} - - - - - - - Description - {errors.description?.message} - - - - -
- -
- - - -
-
- + ); diff --git a/src/requests/posts/brewery-post/index.ts b/src/requests/posts/brewery-post/index.ts new file mode 100644 index 0000000..4e5b4c6 --- /dev/null +++ b/src/requests/posts/brewery-post/index.ts @@ -0,0 +1,105 @@ +import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; +import BreweryPostQueryResult from '@/services/posts/brewery-post/schema/BreweryPostQueryResult'; +import { + SendEditBreweryPostRequest, + SendDeleteBreweryPostRequest, + SendCreateBreweryPostRequest, +} from './types'; + +/** + * Sends an api request to edit a brewery post. + * + * @param args - The arguments for the request. + * @param args.body - The body of the request. + * @param args.body.name - The name of the brewery. + * @param args.body.description - The description of the brewery. + * @param args.body.dateEstablished - The date the brewery was established. + * @param args.breweryPostId - The id of the brewery post to edit. + */ +export const sendEditBreweryPostRequest: SendEditBreweryPostRequest = async ({ + body, + breweryPostId, +}) => { + const response = await fetch(`/api/breweries/${breweryPostId}`, { + method: 'PUT', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(body), + }); + + if (!response.ok) { + throw new Error('Something went wrong'); + } + + const json = await response.json(); + const parsed = APIResponseValidationSchema.safeParse(json); + + if (!parsed.success) { + throw new Error('Something went wrong'); + } + + return parsed.data; +}; + +/** + * Sends an api request to delete a brewery post. + * + * @param args - The arguments for the request. + * @param args.breweryPostId - The id of the brewery post to delete. + */ +export const sendDeleteBreweryPostRequest: SendDeleteBreweryPostRequest = async ({ + breweryPostId, +}) => { + const response = await fetch(`/api/breweries/${breweryPostId}`, { + method: 'DELETE', + }); + + if (!response.ok) { + throw new Error(response.statusText); + } + + const json = await response.json(); + const parsed = APIResponseValidationSchema.safeParse(json); + + if (!parsed.success) { + throw new Error(parsed.error.message); + } + + return parsed.data; +}; + +/** + * Sends an api request to create a brewery post. + * + * @param args - The arguments for the request. + * @param args.body - The body of the request. + * @param args.body.name - The name of the brewery. + * @param args.body.description - The description of the brewery. + * @param args.body.dateEstablished - The date the brewery was established. + */ +export const sendCreateBreweryPostRequest: SendCreateBreweryPostRequest = async ({ + body, +}) => { + const response = await fetch('/api/breweries/create', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify(body), + }); + + if (!response.ok) { + throw new Error(response.statusText); + } + + const json = await response.json(); + + const parsed = APIResponseValidationSchema.safeParse(json); + if (!parsed.success) { + throw new Error('API response parsing failed'); + } + + const parsedPayload = BreweryPostQueryResult.safeParse(parsed.data.payload); + if (!parsedPayload.success) { + throw new Error('API response payload parsing failed'); + } + + return parsedPayload.data; +}; diff --git a/src/requests/posts/brewery-post/sendCreateBreweryPostRequest.ts b/src/requests/posts/brewery-post/sendCreateBreweryPostRequest.ts deleted file mode 100644 index 5477035..0000000 --- a/src/requests/posts/brewery-post/sendCreateBreweryPostRequest.ts +++ /dev/null @@ -1,34 +0,0 @@ -import BreweryPostQueryResult from '@/services/posts/brewery-post/schema/BreweryPostQueryResult'; -import CreateBreweryPostSchema from '@/services/posts/brewery-post/schema/CreateBreweryPostSchema'; -import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; -import { z } from 'zod'; - -const sendCreateBreweryPostRequest = async ( - data: z.infer, -) => { - const response = await fetch('/api/breweries/create', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(data), - }); - - if (!response.ok) { - throw new Error(response.statusText); - } - - const json = await response.json(); - - const parsed = APIResponseValidationSchema.safeParse(json); - if (!parsed.success) { - throw new Error('API response parsing failed'); - } - - const parsedPayload = BreweryPostQueryResult.safeParse(parsed.data.payload); - if (!parsedPayload.success) { - throw new Error('API response payload parsing failed'); - } - - return parsedPayload.data; -}; - -export default sendCreateBreweryPostRequest; diff --git a/src/requests/posts/brewery-post/types/index.ts b/src/requests/posts/brewery-post/types/index.ts new file mode 100644 index 0000000..4a3d375 --- /dev/null +++ b/src/requests/posts/brewery-post/types/index.ts @@ -0,0 +1,23 @@ +import BreweryPostQueryResult from '@/services/posts/brewery-post/schema/BreweryPostQueryResult'; +import CreateBreweryPostSchema from '@/services/posts/brewery-post/schema/CreateBreweryPostSchema'; +import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; +import { z } from 'zod'; + +type APIResponse = z.infer; + +export type SendDeleteBreweryPostRequest = (args: { + breweryPostId: string; +}) => Promise; + +export type SendEditBreweryPostRequest = (args: { + body: { + name: string; + description: string; + dateEstablished: Date; + }; + breweryPostId: string; +}) => Promise; + +export type SendCreateBreweryPostRequest = (args: { + body: z.infer; +}) => Promise>;