mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-02-16 02:39:03 +00:00
1
.gitignore
vendored
1
.gitignore
vendored
@@ -45,3 +45,4 @@ next-env.d.ts
|
||||
|
||||
/cloudinary-images
|
||||
|
||||
.obsidian
|
||||
330
package-lock.json
generated
330
package-lock.json
generated
@@ -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",
|
||||
|
||||
16
package.json
16
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"
|
||||
},
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import validateEmailRequest from '@/requests/User/validateEmailRequest';
|
||||
import validateUsernameRequest from '@/requests/validateUsernameRequest';
|
||||
import validateUsernameRequest from '@/requests/users/profile/validateUsernameRequest';
|
||||
import { BaseCreateUserSchema } from '@/services/users/auth/schema/CreateUserValidationSchemas';
|
||||
import { Switch } from '@headlessui/react';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
@@ -7,7 +6,7 @@ import { Dispatch, FC, useContext } from 'react';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { z } from 'zod';
|
||||
import UserContext from '@/contexts/UserContext';
|
||||
import sendEditUserRequest from '@/requests/User/sendEditUserRequest';
|
||||
|
||||
import createErrorToast from '@/util/createErrorToast';
|
||||
import { toast } from 'react-hot-toast';
|
||||
import { AccountPageAction, AccountPageState } from '@/reducers/accountPageReducer';
|
||||
@@ -15,6 +14,7 @@ import FormError from '../ui/forms/FormError';
|
||||
import FormInfo from '../ui/forms/FormInfo';
|
||||
import FormLabel from '../ui/forms/FormLabel';
|
||||
import FormTextInput from '../ui/forms/FormTextInput';
|
||||
import { sendEditUserRequest, validateEmailRequest } from '@/requests/users/auth';
|
||||
|
||||
interface AccountInfoProps {
|
||||
pageState: AccountPageState;
|
||||
@@ -36,7 +36,7 @@ const AccountInfo: FC<AccountInfoProps> = ({ pageState, dispatch }) => {
|
||||
.refine(
|
||||
async (email) => {
|
||||
if (user!.email === email) return true;
|
||||
return validateEmailRequest(email);
|
||||
return validateEmailRequest({ email });
|
||||
},
|
||||
{ message: 'Email is already taken.' },
|
||||
),
|
||||
|
||||
@@ -4,10 +4,11 @@ import { SubmitHandler, useForm } from 'react-hook-form';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { z } from 'zod';
|
||||
import { UpdatePasswordSchema } from '@/services/users/auth/schema/CreateUserValidationSchemas';
|
||||
import sendUpdatePasswordRequest from '@/requests/User/sendUpdatePasswordRequest';
|
||||
|
||||
import { AccountPageState, AccountPageAction } from '@/reducers/accountPageReducer';
|
||||
import toast from 'react-hot-toast';
|
||||
import createErrorToast from '@/util/createErrorToast';
|
||||
import { sendUpdatePasswordRequest } from '@/requests/users/auth';
|
||||
import FormError from '../ui/forms/FormError';
|
||||
import FormInfo from '../ui/forms/FormInfo';
|
||||
import FormLabel from '../ui/forms/FormLabel';
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
import sendCreateBeerCommentRequest from '@/requests/BeerComment/sendCreateBeerCommentRequest';
|
||||
|
||||
import BeerPostQueryResult from '@/services/posts/beer-post/schema/BeerPostQueryResult';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
|
||||
@@ -11,7 +9,8 @@ import useBeerPostComments from '@/hooks/data-fetching/beer-comments/useBeerPost
|
||||
import CreateCommentValidationSchema from '@/services/schema/CommentSchema/CreateCommentValidationSchema';
|
||||
import toast from 'react-hot-toast';
|
||||
import createErrorToast from '@/util/createErrorToast';
|
||||
import CommentForm from '../ui/CommentForm';
|
||||
import { sendCreateBeerCommentRequest } from '@/requests/comments/beer-comment';
|
||||
import CommentForm from '../Comments/CommentForm';
|
||||
|
||||
interface BeerCommentFormProps {
|
||||
beerPost: z.infer<typeof BeerPostQueryResult>;
|
||||
@@ -34,11 +33,7 @@ const BeerCommentForm: FunctionComponent<BeerCommentFormProps> = ({
|
||||
) => {
|
||||
const loadingToast = toast.loading('Posting a new comment...');
|
||||
try {
|
||||
await sendCreateBeerCommentRequest({
|
||||
content: data.content,
|
||||
rating: data.rating,
|
||||
beerPostId: beerPost.id,
|
||||
});
|
||||
await sendCreateBeerCommentRequest({ body: data, beerPostId: beerPost.id });
|
||||
reset();
|
||||
toast.remove(loadingToast);
|
||||
toast.success('Comment posted successfully.');
|
||||
|
||||
@@ -6,11 +6,15 @@ import { FC, MutableRefObject, useContext, useRef } from 'react';
|
||||
import { z } from 'zod';
|
||||
import useBeerPostComments from '@/hooks/data-fetching/beer-comments/useBeerPostComments';
|
||||
import { useRouter } from 'next/router';
|
||||
import CreateCommentValidationSchema from '@/services/schema/CommentSchema/CreateCommentValidationSchema';
|
||||
|
||||
import {
|
||||
deleteBeerPostCommentRequest,
|
||||
editBeerPostCommentRequest,
|
||||
} from '@/requests/comments/beer-comment';
|
||||
import BeerCommentForm from './BeerCommentForm';
|
||||
|
||||
import LoadingComponent from './LoadingComponent';
|
||||
import CommentsComponent from '../ui/CommentsComponent';
|
||||
import CommentLoadingComponent from '../Comments/CommentLoadingComponent';
|
||||
import CommentsComponent from '../Comments/CommentsComponent';
|
||||
|
||||
interface BeerPostCommentsSectionProps {
|
||||
beerPost: z.infer<typeof BeerPostQueryResult>;
|
||||
@@ -28,29 +32,6 @@ const BeerPostCommentsSection: FC<BeerPostCommentsSectionProps> = ({ beerPost })
|
||||
|
||||
const commentSectionRef: MutableRefObject<HTMLDivElement | null> = useRef(null);
|
||||
|
||||
const handleDeleteRequest = async (id: string) => {
|
||||
const response = await fetch(`/api/beer-comments/${id}`, { method: 'DELETE' });
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to delete comment.');
|
||||
}
|
||||
};
|
||||
|
||||
const handleEditRequest = async (
|
||||
id: string,
|
||||
data: z.infer<typeof CreateCommentValidationSchema>,
|
||||
) => {
|
||||
const response = await fetch(`/api/beer-comments/${id}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ content: data.content, rating: data.rating }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to update comment.');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full space-y-3" ref={commentSectionRef}>
|
||||
<div className="card bg-base-300">
|
||||
@@ -72,7 +53,7 @@ const BeerPostCommentsSection: FC<BeerPostCommentsSectionProps> = ({ beerPost })
|
||||
*/
|
||||
isLoading ? (
|
||||
<div className="card bg-base-300 pb-6">
|
||||
<LoadingComponent length={PAGE_SIZE} />
|
||||
<CommentLoadingComponent length={PAGE_SIZE} />
|
||||
</div>
|
||||
) : (
|
||||
<CommentsComponent
|
||||
@@ -84,8 +65,19 @@ const BeerPostCommentsSection: FC<BeerPostCommentsSectionProps> = ({ beerPost })
|
||||
setSize={setSize}
|
||||
size={size}
|
||||
mutate={mutate}
|
||||
handleDeleteRequest={handleDeleteRequest}
|
||||
handleEditRequest={handleEditRequest}
|
||||
handleDeleteCommentRequest={(id) => {
|
||||
return deleteBeerPostCommentRequest({
|
||||
commentId: id,
|
||||
beerPostId: beerPost.id,
|
||||
});
|
||||
}}
|
||||
handleEditCommentRequest={(id, data) => {
|
||||
return editBeerPostCommentRequest({
|
||||
body: data,
|
||||
commentId: id,
|
||||
beerPostId: beerPost.id,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ import useCheckIfUserLikesBeerPost from '@/hooks/data-fetching/beer-likes/useChe
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
|
||||
import useGetBeerPostLikeCount from '@/hooks/data-fetching/beer-likes/useBeerPostLikeCount';
|
||||
import sendBeerPostLikeRequest from '@/requests/BeerPostLike/sendBeerPostLikeRequest';
|
||||
import sendBeerPostLikeRequest from '@/requests/likes/beer-post-like/sendBeerPostLikeRequest';
|
||||
import LikeButton from '../ui/LikeButton';
|
||||
|
||||
const BeerPostLikeButton: FC<{
|
||||
|
||||
@@ -10,8 +10,8 @@ import createErrorToast from '@/util/createErrorToast';
|
||||
|
||||
import BeerStyleQueryResult from '@/services/posts/beer-style-post/schema/BeerStyleQueryResult';
|
||||
import useBeerStyleComments from '@/hooks/data-fetching/beer-style-comments/useBeerStyleComments';
|
||||
import sendCreateBeerStyleCommentRequest from '@/requests/BeerStyleComment/sendCreateBeerStyleCommentRequest';
|
||||
import CommentForm from '../ui/CommentForm';
|
||||
import { sendCreateBeerStyleCommentRequest } from '@/requests/comments/beer-style-comment';
|
||||
import CommentForm from '../Comments/CommentForm';
|
||||
|
||||
interface BeerCommentFormProps {
|
||||
beerStyle: z.infer<typeof BeerStyleQueryResult>;
|
||||
@@ -35,8 +35,7 @@ const BeerStyleCommentForm: FunctionComponent<BeerCommentFormProps> = ({
|
||||
const loadingToast = toast.loading('Posting a new comment...');
|
||||
try {
|
||||
await sendCreateBeerStyleCommentRequest({
|
||||
content: data.content,
|
||||
rating: data.rating,
|
||||
body: { content: data.content, rating: data.rating },
|
||||
beerStyleId: beerStyle.id,
|
||||
});
|
||||
reset();
|
||||
|
||||
@@ -3,12 +3,15 @@ import UserContext from '@/contexts/UserContext';
|
||||
import { FC, MutableRefObject, useContext, useRef } from 'react';
|
||||
import { z } from 'zod';
|
||||
import { useRouter } from 'next/router';
|
||||
import CreateCommentValidationSchema from '@/services/schema/CommentSchema/CreateCommentValidationSchema';
|
||||
|
||||
import BeerStyleQueryResult from '@/services/posts/beer-style-post/schema/BeerStyleQueryResult';
|
||||
import useBeerStyleComments from '@/hooks/data-fetching/beer-style-comments/useBeerStyleComments';
|
||||
import LoadingComponent from '../BeerById/LoadingComponent';
|
||||
import CommentsComponent from '../ui/CommentsComponent';
|
||||
import {
|
||||
sendDeleteBeerStyleCommentRequest,
|
||||
sendEditBeerStyleCommentRequest,
|
||||
} from '@/requests/comments/beer-style-comment';
|
||||
import CommentLoadingComponent from '../Comments/CommentLoadingComponent';
|
||||
import CommentsComponent from '../Comments/CommentsComponent';
|
||||
import BeerStyleCommentForm from './BeerStyleCommentForm';
|
||||
|
||||
interface BeerStyleCommentsSectionProps {
|
||||
@@ -27,31 +30,6 @@ const BeerStyleCommentsSection: FC<BeerStyleCommentsSectionProps> = ({ beerStyle
|
||||
|
||||
const commentSectionRef: MutableRefObject<HTMLDivElement | null> = useRef(null);
|
||||
|
||||
const handleDeleteRequest = async (id: string) => {
|
||||
const response = await fetch(`/api/beer-style-comments/${id}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to delete comment.');
|
||||
}
|
||||
};
|
||||
|
||||
const handleEditRequest = async (
|
||||
id: string,
|
||||
data: z.infer<typeof CreateCommentValidationSchema>,
|
||||
) => {
|
||||
const response = await fetch(`/api/beer-style-comments/${id}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ content: data.content, rating: data.rating }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(response.statusText);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full space-y-3" ref={commentSectionRef}>
|
||||
<div className="card bg-base-300">
|
||||
@@ -73,7 +51,7 @@ const BeerStyleCommentsSection: FC<BeerStyleCommentsSectionProps> = ({ beerStyle
|
||||
*/
|
||||
isLoading ? (
|
||||
<div className="card bg-base-300 pb-6">
|
||||
<LoadingComponent length={PAGE_SIZE} />
|
||||
<CommentLoadingComponent length={PAGE_SIZE} />
|
||||
</div>
|
||||
) : (
|
||||
<CommentsComponent
|
||||
@@ -85,8 +63,19 @@ const BeerStyleCommentsSection: FC<BeerStyleCommentsSectionProps> = ({ beerStyle
|
||||
setSize={setSize}
|
||||
size={size}
|
||||
mutate={mutate}
|
||||
handleDeleteRequest={handleDeleteRequest}
|
||||
handleEditRequest={handleEditRequest}
|
||||
handleDeleteCommentRequest={(id) => {
|
||||
return sendDeleteBeerStyleCommentRequest({
|
||||
beerStyleId: beerStyle.id,
|
||||
commentId: id,
|
||||
});
|
||||
}}
|
||||
handleEditCommentRequest={(id, data) => {
|
||||
return sendEditBeerStyleCommentRequest({
|
||||
beerStyleId: beerStyle.id,
|
||||
commentId: id,
|
||||
body: data,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { FC, useEffect, useState } from 'react';
|
||||
|
||||
import useGetBeerPostLikeCount from '@/hooks/data-fetching/beer-likes/useBeerPostLikeCount';
|
||||
import useCheckIfUserLikesBeerStyle from '@/hooks/data-fetching/beer-style-likes/useCheckIfUserLikesBeerPost';
|
||||
import sendBeerStyleLikeRequest from '@/requests/BeerStyleLike/sendBeerStyleLikeRequest';
|
||||
import sendBeerStyleLikeRequest from '@/requests/likes/beer-style-like/sendBeerStyleLikeRequest';
|
||||
import LikeButton from '../ui/LikeButton';
|
||||
|
||||
const BeerStyleLikeButton: FC<{
|
||||
|
||||
@@ -6,9 +6,9 @@ import { FC } from 'react';
|
||||
import { useForm, SubmitHandler } from 'react-hook-form';
|
||||
import toast from 'react-hot-toast';
|
||||
import { z } from 'zod';
|
||||
import sendCreateBreweryCommentRequest from '@/requests/BreweryComment/sendCreateBreweryCommentRequest';
|
||||
import sendCreateBreweryCommentRequest from '@/requests/comments/brewery-comment/sendCreateBreweryCommentRequest';
|
||||
import createErrorToast from '@/util/createErrorToast';
|
||||
import CommentForm from '../ui/CommentForm';
|
||||
import CommentForm from '../Comments/CommentForm';
|
||||
|
||||
interface BreweryCommentFormProps {
|
||||
breweryPost: z.infer<typeof BreweryPostQueryResult>;
|
||||
|
||||
@@ -2,11 +2,14 @@ import UserContext from '@/contexts/UserContext';
|
||||
import BreweryPostQueryResult from '@/services/posts/brewery-post/schema/BreweryPostQueryResult';
|
||||
import { FC, MutableRefObject, useContext, useRef } from 'react';
|
||||
import { z } from 'zod';
|
||||
import CreateCommentValidationSchema from '@/services/schema/CommentSchema/CreateCommentValidationSchema';
|
||||
|
||||
import useBreweryPostComments from '@/hooks/data-fetching/brewery-comments/useBreweryPostComments';
|
||||
import LoadingComponent from '../BeerById/LoadingComponent';
|
||||
import CommentsComponent from '../ui/CommentsComponent';
|
||||
import {
|
||||
sendDeleteBreweryPostCommentRequest,
|
||||
sendEditBreweryPostCommentRequest,
|
||||
} from '@/requests/comments/brewery-comment';
|
||||
import CommentLoadingComponent from '../Comments/CommentLoadingComponent';
|
||||
import CommentsComponent from '../Comments/CommentsComponent';
|
||||
import BreweryCommentForm from './BreweryCommentForm';
|
||||
|
||||
interface BreweryBeerSectionProps {
|
||||
@@ -30,31 +33,6 @@ const BreweryCommentsSection: FC<BreweryBeerSectionProps> = ({ breweryPost }) =>
|
||||
|
||||
const commentSectionRef: MutableRefObject<HTMLDivElement | null> = useRef(null);
|
||||
|
||||
const handleDeleteRequest = async (commentId: string) => {
|
||||
const response = await fetch(`/api/brewery-comments/${commentId}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(response.statusText);
|
||||
}
|
||||
};
|
||||
|
||||
const handleEditRequest = async (
|
||||
commentId: string,
|
||||
data: z.infer<typeof CreateCommentValidationSchema>,
|
||||
) => {
|
||||
const response = await fetch(`/api/brewery-comments/${commentId}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ content: data.content, rating: data.rating }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(response.statusText);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="w-full space-y-3" ref={commentSectionRef}>
|
||||
<div className="card">
|
||||
@@ -75,7 +53,7 @@ const BreweryCommentsSection: FC<BreweryBeerSectionProps> = ({ breweryPost }) =>
|
||||
*/
|
||||
isLoading ? (
|
||||
<div className="card pb-6">
|
||||
<LoadingComponent length={PAGE_SIZE} />
|
||||
<CommentLoadingComponent length={PAGE_SIZE} />
|
||||
</div>
|
||||
) : (
|
||||
<CommentsComponent
|
||||
@@ -87,8 +65,19 @@ const BreweryCommentsSection: FC<BreweryBeerSectionProps> = ({ breweryPost }) =>
|
||||
size={size}
|
||||
commentSectionRef={commentSectionRef}
|
||||
mutate={mutate}
|
||||
handleDeleteRequest={handleDeleteRequest}
|
||||
handleEditRequest={handleEditRequest}
|
||||
handleDeleteCommentRequest={(id) => {
|
||||
return sendDeleteBreweryPostCommentRequest({
|
||||
breweryPostId: breweryPost.id,
|
||||
commentId: id,
|
||||
});
|
||||
}}
|
||||
handleEditCommentRequest={(commentId, data) => {
|
||||
return sendEditBreweryPostCommentRequest({
|
||||
breweryPostId: breweryPost.id,
|
||||
commentId,
|
||||
body: { content: data.content, rating: data.rating },
|
||||
});
|
||||
}}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import useCheckIfUserLikesBreweryPost from '@/hooks/data-fetching/brewery-likes/useCheckIfUserLikesBreweryPost';
|
||||
import useGetBreweryPostLikeCount from '@/hooks/data-fetching/brewery-likes/useGetBreweryPostLikeCount';
|
||||
import sendBreweryPostLikeRequest from '@/requests/BreweryPostLike/sendBreweryPostLikeRequest';
|
||||
import sendBreweryPostLikeRequest from '@/requests/likes/brewery-post-like/sendBreweryPostLikeRequest';
|
||||
import { FC, useState } from 'react';
|
||||
import LikeButton from '../ui/LikeButton';
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import sendUploadBreweryImagesRequest from '@/requests/BreweryImage/sendUploadBreweryImageRequest';
|
||||
import sendCreateBreweryPostRequest from '@/requests/BreweryPost/sendCreateBreweryPostRequest';
|
||||
import sendUploadBreweryImagesRequest from '@/requests/images/brewery-image/sendUploadBreweryImageRequest';
|
||||
|
||||
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);
|
||||
|
||||
@@ -3,28 +3,26 @@ import CommentQueryResult from '@/services/schema/CommentSchema/CommentQueryResu
|
||||
import { FC, useState } from 'react';
|
||||
import { useInView } from 'react-intersection-observer';
|
||||
import { z } from 'zod';
|
||||
import CreateCommentValidationSchema from '@/services/schema/CommentSchema/CreateCommentValidationSchema';
|
||||
|
||||
import CommentContentBody from './CommentContentBody';
|
||||
import EditCommentBody from './EditCommentBody';
|
||||
import UserAvatar from '../Account/UserAvatar';
|
||||
import { HandleDeleteCommentRequest, HandleEditCommentRequest } from './types';
|
||||
|
||||
interface CommentCardProps {
|
||||
comment: z.infer<typeof CommentQueryResult>;
|
||||
mutate: ReturnType<typeof useBeerPostComments>['mutate'];
|
||||
ref?: ReturnType<typeof useInView>['ref'];
|
||||
handleDeleteRequest: (id: string) => Promise<void>;
|
||||
handleEditRequest: (
|
||||
id: string,
|
||||
data: z.infer<typeof CreateCommentValidationSchema>,
|
||||
) => Promise<void>;
|
||||
handleDeleteCommentRequest: HandleDeleteCommentRequest;
|
||||
handleEditCommentRequest: HandleEditCommentRequest;
|
||||
}
|
||||
|
||||
const CommentCardBody: FC<CommentCardProps> = ({
|
||||
comment,
|
||||
mutate,
|
||||
ref,
|
||||
handleDeleteRequest,
|
||||
handleEditRequest,
|
||||
handleDeleteCommentRequest,
|
||||
handleEditCommentRequest,
|
||||
}) => {
|
||||
const [inEditMode, setInEditMode] = useState(false);
|
||||
|
||||
@@ -44,8 +42,8 @@ const CommentCardBody: FC<CommentCardProps> = ({
|
||||
comment={comment}
|
||||
mutate={mutate}
|
||||
setInEditMode={setInEditMode}
|
||||
handleDeleteRequest={handleDeleteRequest}
|
||||
handleEditRequest={handleEditRequest}
|
||||
handleDeleteCommentRequest={handleDeleteCommentRequest}
|
||||
handleEditCommentRequest={handleEditCommentRequest}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
@@ -8,12 +8,12 @@ import type {
|
||||
UseFormSetValue,
|
||||
UseFormWatch,
|
||||
} from 'react-hook-form';
|
||||
import FormError from './forms/FormError';
|
||||
import FormInfo from './forms/FormInfo';
|
||||
import FormLabel from './forms/FormLabel';
|
||||
import FormSegment from './forms/FormSegment';
|
||||
import FormTextArea from './forms/FormTextArea';
|
||||
import Button from './forms/Button';
|
||||
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 Button from '../ui/forms/Button';
|
||||
|
||||
interface Comment {
|
||||
content: string;
|
||||
@@ -1,12 +1,12 @@
|
||||
import { FC } from 'react';
|
||||
import Spinner from '../ui/Spinner';
|
||||
import CommentLoadingCardBody from '../BeerBreweryComments/CommentLoadingCardBody';
|
||||
import CommentLoadingCardBody from './CommentLoadingCardBody';
|
||||
|
||||
interface LoadingComponentProps {
|
||||
interface CommentLoadingComponentProps {
|
||||
length: number;
|
||||
}
|
||||
|
||||
const LoadingComponent: FC<LoadingComponentProps> = ({ length }) => {
|
||||
const CommentLoadingComponent: FC<CommentLoadingComponentProps> = ({ length }) => {
|
||||
return (
|
||||
<>
|
||||
{Array.from({ length }).map((_, i) => (
|
||||
@@ -19,4 +19,4 @@ const LoadingComponent: FC<LoadingComponentProps> = ({ length }) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default LoadingComponent;
|
||||
export default CommentLoadingComponent;
|
||||
@@ -6,53 +6,46 @@ import { useInView } from 'react-intersection-observer';
|
||||
import useBeerPostComments from '@/hooks/data-fetching/beer-comments/useBeerPostComments';
|
||||
|
||||
import useBreweryPostComments from '@/hooks/data-fetching/brewery-comments/useBreweryPostComments';
|
||||
import NoCommentsCard from '../BeerById/NoCommentsCard';
|
||||
import LoadingComponent from '../BeerById/LoadingComponent';
|
||||
import CommentCardBody from '../BeerBreweryComments/CommentCardBody';
|
||||
import useBeerStyleComments from '@/hooks/data-fetching/beer-style-comments/useBeerStyleComments';
|
||||
import NoCommentsCard from './NoCommentsCard';
|
||||
import CommentLoadingComponent from './CommentLoadingComponent';
|
||||
import CommentCardBody from './CommentCardBody';
|
||||
import { HandleDeleteCommentRequest, HandleEditCommentRequest } from './types';
|
||||
|
||||
type HookReturnType = ReturnType<
|
||||
typeof useBeerPostComments | typeof useBreweryPostComments | typeof useBeerStyleComments
|
||||
>;
|
||||
|
||||
interface CommentsComponentProps {
|
||||
comments: HookReturnType['comments'];
|
||||
isAtEnd: HookReturnType['isAtEnd'];
|
||||
isLoadingMore: HookReturnType['isLoadingMore'];
|
||||
mutate: HookReturnType['mutate'];
|
||||
setSize: HookReturnType['setSize'];
|
||||
size: HookReturnType['size'];
|
||||
commentSectionRef: MutableRefObject<HTMLDivElement | null>;
|
||||
handleDeleteCommentRequest: HandleDeleteCommentRequest;
|
||||
handleEditCommentRequest: HandleEditCommentRequest;
|
||||
pageSize: number;
|
||||
size: ReturnType<typeof useBeerPostComments | typeof useBreweryPostComments>['size'];
|
||||
setSize: ReturnType<
|
||||
typeof useBeerPostComments | typeof useBreweryPostComments
|
||||
>['setSize'];
|
||||
comments: ReturnType<
|
||||
typeof useBeerPostComments | typeof useBreweryPostComments
|
||||
>['comments'];
|
||||
isAtEnd: ReturnType<
|
||||
typeof useBeerPostComments | typeof useBreweryPostComments
|
||||
>['isAtEnd'];
|
||||
isLoadingMore: ReturnType<
|
||||
typeof useBeerPostComments | typeof useBreweryPostComments
|
||||
>['isLoadingMore'];
|
||||
mutate: ReturnType<
|
||||
typeof useBeerPostComments | typeof useBreweryPostComments
|
||||
>['mutate'];
|
||||
handleDeleteRequest: (id: string) => Promise<void>;
|
||||
handleEditRequest: (
|
||||
id: string,
|
||||
data: { content: string; rating: number },
|
||||
) => Promise<void>;
|
||||
}
|
||||
|
||||
const CommentsComponent: FC<CommentsComponentProps> = ({
|
||||
commentSectionRef,
|
||||
comments,
|
||||
commentSectionRef,
|
||||
handleDeleteCommentRequest,
|
||||
handleEditCommentRequest,
|
||||
isAtEnd,
|
||||
isLoadingMore,
|
||||
mutate,
|
||||
pageSize,
|
||||
setSize,
|
||||
size,
|
||||
mutate,
|
||||
handleDeleteRequest,
|
||||
handleEditRequest,
|
||||
}) => {
|
||||
const { ref: penultimateCommentRef } = useInView({
|
||||
threshold: 0.1,
|
||||
/**
|
||||
* When the last comment comes into view, call setSize from useBeerPostComments to
|
||||
* load more comments.
|
||||
* When the last comment comes into view, call setSize from the comment fetching hook
|
||||
* to load more comments.
|
||||
*/
|
||||
onChange: (visible) => {
|
||||
if (!visible || isAtEnd) return;
|
||||
@@ -79,8 +72,8 @@ const CommentsComponent: FC<CommentsComponentProps> = ({
|
||||
<CommentCardBody
|
||||
comment={comment}
|
||||
mutate={mutate}
|
||||
handleDeleteRequest={handleDeleteRequest}
|
||||
handleEditRequest={handleEditRequest}
|
||||
handleDeleteCommentRequest={handleDeleteCommentRequest}
|
||||
handleEditCommentRequest={handleEditCommentRequest}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
@@ -91,7 +84,7 @@ const CommentsComponent: FC<CommentsComponentProps> = ({
|
||||
* If there are more comments to load, show a loading component with a
|
||||
* skeleton loader and a loading spinner.
|
||||
*/
|
||||
!!isLoadingMore && <LoadingComponent length={pageSize} />
|
||||
!!isLoadingMore && <CommentLoadingComponent length={pageSize} />
|
||||
}
|
||||
|
||||
{
|
||||
@@ -14,6 +14,7 @@ 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 { HandleDeleteCommentRequest, HandleEditCommentRequest } from './types';
|
||||
|
||||
interface EditCommentBodyProps {
|
||||
comment: z.infer<typeof CommentQueryResult>;
|
||||
@@ -22,19 +23,16 @@ interface EditCommentBodyProps {
|
||||
mutate: ReturnType<
|
||||
typeof useBeerPostComments | typeof useBreweryPostComments
|
||||
>['mutate'];
|
||||
handleDeleteRequest: (id: string) => Promise<void>;
|
||||
handleEditRequest: (
|
||||
id: string,
|
||||
data: z.infer<typeof CreateCommentValidationSchema>,
|
||||
) => Promise<void>;
|
||||
handleDeleteCommentRequest: HandleDeleteCommentRequest;
|
||||
handleEditCommentRequest: HandleEditCommentRequest;
|
||||
}
|
||||
|
||||
const EditCommentBody: FC<EditCommentBodyProps> = ({
|
||||
comment,
|
||||
setInEditMode,
|
||||
mutate,
|
||||
handleDeleteRequest,
|
||||
handleEditRequest,
|
||||
handleDeleteCommentRequest,
|
||||
handleEditCommentRequest,
|
||||
}) => {
|
||||
const { register, handleSubmit, formState, setValue, watch } = useForm<
|
||||
z.infer<typeof CreateCommentValidationSchema>
|
||||
@@ -51,7 +49,7 @@ const EditCommentBody: FC<EditCommentBodyProps> = ({
|
||||
const loadingToast = toast.loading('Deleting comment...');
|
||||
setIsDeleting(true);
|
||||
try {
|
||||
await handleDeleteRequest(comment.id);
|
||||
await handleDeleteCommentRequest(comment.id);
|
||||
await mutate();
|
||||
toast.remove(loadingToast);
|
||||
toast.success('Deleted comment.');
|
||||
@@ -68,7 +66,7 @@ const EditCommentBody: FC<EditCommentBodyProps> = ({
|
||||
|
||||
try {
|
||||
setInEditMode(true);
|
||||
await handleEditRequest(comment.id, data);
|
||||
await handleEditCommentRequest(comment.id, data);
|
||||
await mutate();
|
||||
toast.remove(loadingToast);
|
||||
toast.success('Comment edits submitted successfully.');
|
||||
@@ -80,6 +78,8 @@ const EditCommentBody: FC<EditCommentBodyProps> = ({
|
||||
}
|
||||
};
|
||||
|
||||
const disableForm = isSubmitting || isDeleting;
|
||||
|
||||
return (
|
||||
<div className="py-4 pr-3 animate-in fade-in-10">
|
||||
<form onSubmit={handleSubmit(onEdit)} className="space-y-3">
|
||||
@@ -95,7 +95,7 @@ const EditCommentBody: FC<EditCommentBodyProps> = ({
|
||||
placeholder="Comment"
|
||||
rows={2}
|
||||
error={!!errors.content?.message}
|
||||
disabled={isSubmitting || isDeleting}
|
||||
disabled={disableForm}
|
||||
/>
|
||||
</FormSegment>
|
||||
<div className="flex flex-row items-center justify-between">
|
||||
@@ -114,8 +114,8 @@ const EditCommentBody: FC<EditCommentBodyProps> = ({
|
||||
<Rating.Item
|
||||
name="rating-1"
|
||||
className="mask mask-star cursor-default"
|
||||
disabled={isSubmitting || isDeleting}
|
||||
aria-disabled={isSubmitting || isDeleting}
|
||||
disabled={disableForm}
|
||||
aria-disabled={disableForm}
|
||||
key={index}
|
||||
/>
|
||||
))}
|
||||
@@ -125,7 +125,7 @@ const EditCommentBody: FC<EditCommentBodyProps> = ({
|
||||
<button
|
||||
type="button"
|
||||
className="btn join-item btn-xs lg:btn-sm"
|
||||
disabled={isSubmitting || isDeleting}
|
||||
disabled={disableForm}
|
||||
onClick={() => {
|
||||
setInEditMode(false);
|
||||
}}
|
||||
@@ -134,7 +134,7 @@ const EditCommentBody: FC<EditCommentBodyProps> = ({
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isSubmitting || isDeleting}
|
||||
disabled={disableForm}
|
||||
className="btn join-item btn-xs lg:btn-sm"
|
||||
>
|
||||
Save
|
||||
@@ -143,7 +143,7 @@ const EditCommentBody: FC<EditCommentBodyProps> = ({
|
||||
type="button"
|
||||
className="btn join-item btn-xs lg:btn-sm"
|
||||
onClick={onDelete}
|
||||
disabled={isDeleting || formState.isSubmitting}
|
||||
disabled={disableForm}
|
||||
>
|
||||
Delete
|
||||
</button>
|
||||
12
src/components/Comments/types/index.ts
Normal file
12
src/components/Comments/types/index.ts
Normal file
@@ -0,0 +1,12 @@
|
||||
import CreateCommentValidationSchema from '@/services/schema/CommentSchema/CreateCommentValidationSchema';
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
import { z } from 'zod';
|
||||
|
||||
type APIResponse = z.infer<typeof APIResponseValidationSchema>;
|
||||
|
||||
export type HandleEditCommentRequest = (
|
||||
id: string,
|
||||
data: z.infer<typeof CreateCommentValidationSchema>,
|
||||
) => Promise<APIResponse>;
|
||||
|
||||
export type HandleDeleteCommentRequest = (id: string) => Promise<APIResponse>;
|
||||
@@ -1,18 +1,20 @@
|
||||
import { FunctionComponent } from 'react';
|
||||
import router from 'next/router';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { BeerStyle } from '@prisma/client';
|
||||
import router from 'next/router';
|
||||
import { FunctionComponent } from 'react';
|
||||
import toast from 'react-hot-toast';
|
||||
import { useForm, SubmitHandler, FieldError } from 'react-hook-form';
|
||||
import { z } from 'zod';
|
||||
|
||||
import BreweryPostQueryResult from '@/services/posts/brewery-post/schema/BreweryPostQueryResult';
|
||||
import CreateBeerPostValidationSchema from '@/services/posts/beer-post/schema/CreateBeerPostValidationSchema';
|
||||
import sendCreateBeerPostRequest from '@/requests/BeerPost/sendCreateBeerPostRequest';
|
||||
import UploadImageValidationSchema from '@/services/schema/ImageSchema/UploadImageValidationSchema';
|
||||
import sendUploadBeerImagesRequest from '@/requests/BeerImage/sendUploadBeerImageRequest';
|
||||
|
||||
import toast from 'react-hot-toast';
|
||||
|
||||
import createErrorToast from '@/util/createErrorToast';
|
||||
|
||||
import { sendCreateBeerPostRequest } from '@/requests/posts/beer-post';
|
||||
import sendUploadBeerImagesRequest from '@/requests/images/beer-image/sendUploadBeerImageRequest';
|
||||
|
||||
import Button from './ui/forms/Button';
|
||||
import FormError from './ui/forms/FormError';
|
||||
import FormInfo from './ui/forms/FormInfo';
|
||||
@@ -53,7 +55,16 @@ const CreateBeerPostForm: FunctionComponent<BeerFormProps> = ({
|
||||
|
||||
try {
|
||||
const loadingToast = toast.loading('Creating beer post...');
|
||||
const beerPost = await sendCreateBeerPostRequest(data);
|
||||
const beerPost = await sendCreateBeerPostRequest({
|
||||
body: {
|
||||
name: data.name,
|
||||
description: data.description,
|
||||
abv: data.abv,
|
||||
ibu: data.ibu,
|
||||
},
|
||||
breweryId: data.breweryId,
|
||||
styleId: data.styleId,
|
||||
});
|
||||
await sendUploadBeerImagesRequest({ beerPost, images: data.images });
|
||||
await router.push(`/beers/${beerPost.id}`);
|
||||
toast.dismiss(loadingToast);
|
||||
|
||||
@@ -6,10 +6,13 @@ import { z } from 'zod';
|
||||
import { useForm, SubmitHandler } from 'react-hook-form';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
|
||||
import deleteBeerPostRequest from '@/requests/BeerPost/deleteBeerPostRequest';
|
||||
import EditBeerPostValidationSchema from '@/services/posts/beer-post/schema/EditBeerPostValidationSchema';
|
||||
import sendEditBeerPostRequest from '@/requests/BeerPost/sendEditBeerPostRequest';
|
||||
|
||||
import createErrorToast from '@/util/createErrorToast';
|
||||
import {
|
||||
sendEditBeerPostRequest,
|
||||
sendDeleteBeerPostRequest,
|
||||
} from '@/requests/posts/beer-post';
|
||||
import Button from './ui/forms/Button';
|
||||
import FormError from './ui/forms/FormError';
|
||||
import FormInfo from './ui/forms/FormInfo';
|
||||
@@ -35,7 +38,15 @@ const EditBeerPostForm: FC<EditBeerPostFormProps> = ({ previousValues }) => {
|
||||
const onSubmit: SubmitHandler<EditBeerPostSchema> = async (data) => {
|
||||
try {
|
||||
const loadingToast = toast.loading('Editing beer post...');
|
||||
await sendEditBeerPostRequest(data);
|
||||
await sendEditBeerPostRequest({
|
||||
beerPostId: data.id,
|
||||
body: {
|
||||
name: data.name,
|
||||
abv: data.abv,
|
||||
ibu: data.ibu,
|
||||
description: data.description,
|
||||
},
|
||||
});
|
||||
await router.push(`/beers/${data.id}`);
|
||||
toast.success('Edited beer post.');
|
||||
toast.dismiss(loadingToast);
|
||||
@@ -48,7 +59,7 @@ const EditBeerPostForm: FC<EditBeerPostFormProps> = ({ previousValues }) => {
|
||||
const onDelete = async () => {
|
||||
try {
|
||||
const loadingToast = toast.loading('Deleting beer post...');
|
||||
await deleteBeerPostRequest(previousValues.id);
|
||||
await sendDeleteBeerPostRequest({ beerPostId: previousValues.id });
|
||||
toast.dismiss(loadingToast);
|
||||
await router.push('/beers');
|
||||
toast.success('Deleted beer post.');
|
||||
|
||||
106
src/components/EditBreweryPostForm.tsx
Normal file
106
src/components/EditBreweryPostForm.tsx
Normal file
@@ -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<typeof BreweryPostQueryResult>;
|
||||
}
|
||||
const EditBreweryPostForm: FC<EditBreweryPostFormProps> = ({ breweryPost }) => {
|
||||
const router = useRouter();
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
formState: { errors, isSubmitting },
|
||||
} = useForm<z.infer<typeof EditBreweryPostValidationSchema>>({
|
||||
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<typeof EditBreweryPostValidationSchema>) => {
|
||||
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 (
|
||||
<form className="form-control space-y-4" onSubmit={handleSubmit(onSubmit)}>
|
||||
<div className="w-full">
|
||||
<FormInfo>
|
||||
<FormLabel htmlFor="name">Name</FormLabel>
|
||||
<FormError>{errors.name?.message}</FormError>
|
||||
</FormInfo>
|
||||
<FormSegment>
|
||||
<FormTextInput
|
||||
id="name"
|
||||
type="text"
|
||||
placeholder="Name"
|
||||
formValidationSchema={register('name')}
|
||||
error={!!errors.name}
|
||||
disabled={isSubmitting || isDeleting}
|
||||
/>
|
||||
</FormSegment>
|
||||
|
||||
<FormInfo>
|
||||
<FormLabel htmlFor="description">Description</FormLabel>
|
||||
<FormError>{errors.description?.message}</FormError>
|
||||
</FormInfo>
|
||||
<FormSegment>
|
||||
<FormTextArea
|
||||
disabled={isSubmitting || isDeleting}
|
||||
placeholder="Ratione cumque quas quia aut impedit ea culpa facere. Ut in sit et quas reiciendis itaque."
|
||||
error={!!errors.description}
|
||||
formValidationSchema={register('description')}
|
||||
id="description"
|
||||
rows={8}
|
||||
/>
|
||||
</FormSegment>
|
||||
</div>
|
||||
|
||||
<div className="w-full space-y-3">
|
||||
<button
|
||||
disabled={isSubmitting || isDeleting}
|
||||
className="btn btn-primary w-full"
|
||||
type="submit"
|
||||
>
|
||||
{isSubmitting ? 'Saving...' : 'Save'}
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-primary w-full"
|
||||
type="button"
|
||||
disabled={isSubmitting || isDeleting}
|
||||
onClick={handleDelete}
|
||||
>
|
||||
Delete Brewery
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
export default EditBreweryPostForm;
|
||||
@@ -1,4 +1,3 @@
|
||||
import sendLoginUserRequest from '@/requests/User/sendLoginUserRequest';
|
||||
import LoginValidationSchema from '@/services/users/auth/schema/LoginValidationSchema';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { useRouter } from 'next/router';
|
||||
@@ -15,6 +14,7 @@ import FormLabel from '../ui/forms/FormLabel';
|
||||
import FormSegment from '../ui/forms/FormSegment';
|
||||
import FormTextInput from '../ui/forms/FormTextInput';
|
||||
import Button from '../ui/forms/Button';
|
||||
import { sendLoginUserRequest } from '@/requests/users/auth';
|
||||
|
||||
type LoginT = z.infer<typeof LoginValidationSchema>;
|
||||
const LoginForm = () => {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import sendRegisterUserRequest from '@/requests/User/sendRegisterUserRequest';
|
||||
import { CreateUserValidationSchemaWithUsernameAndEmailCheck } from '@/services/users/auth/schema/CreateUserValidationSchemas';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { useRouter } from 'next/router';
|
||||
@@ -9,6 +8,7 @@ import { z } from 'zod';
|
||||
|
||||
import createErrorToast from '@/util/createErrorToast';
|
||||
import toast from 'react-hot-toast';
|
||||
import { sendRegisterUserRequest } from '@/requests/users/auth';
|
||||
import Button from './ui/forms/Button';
|
||||
import FormError from './ui/forms/FormError';
|
||||
import FormInfo from './ui/forms/FormInfo';
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import useFollowStatus from '@/hooks/data-fetching/user-follows/useFollowStatus';
|
||||
import useGetUsersFollowedByUser from '@/hooks/data-fetching/user-follows/useGetUsersFollowedByUser';
|
||||
import useGetUsersFollowingUser from '@/hooks/data-fetching/user-follows/useGetUsersFollowingUser';
|
||||
import sendUserFollowRequest from '@/requests/UserFollow/sendUserFollowRequest';
|
||||
import { sendUserFollowRequest } from '@/requests/users/auth';
|
||||
|
||||
import GetUserSchema from '@/services/users/auth/schema/GetUserSchema';
|
||||
import { FC, useState } from 'react';
|
||||
import { FaUserCheck, FaUserPlus } from 'react-icons/fa';
|
||||
@@ -25,7 +26,7 @@ const UserFollowButton: FC<UserFollowButtonProps> = ({
|
||||
const onClick = async () => {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
await sendUserFollowRequest(user.id);
|
||||
await sendUserFollowRequest({ userId: user.id });
|
||||
await Promise.all([
|
||||
mutateFollowStatus(),
|
||||
mutateFollowerCount(),
|
||||
|
||||
@@ -24,9 +24,9 @@ export const checkIfBeerCommentOwner = async <T extends CommentRequest>(
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
next: NextHandler,
|
||||
) => {
|
||||
const { id } = req.query;
|
||||
const { commentId } = req.query;
|
||||
const user = req.user!;
|
||||
const comment = await getBeerPostCommentByIdService({ beerPostCommentId: id });
|
||||
const comment = await getBeerPostCommentByIdService({ beerPostCommentId: commentId });
|
||||
|
||||
if (!comment) {
|
||||
throw new ServerError('Comment not found', 404);
|
||||
@@ -43,9 +43,9 @@ export const editBeerPostComment = async (
|
||||
req: EditAndCreateCommentRequest,
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
const { id } = req.query;
|
||||
const { commentId } = req.query;
|
||||
|
||||
await editBeerPostCommentByIdService({ body: req.body, beerPostCommentId: id });
|
||||
await editBeerPostCommentByIdService({ body: req.body, beerPostCommentId: commentId });
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
@@ -58,9 +58,9 @@ export const deleteBeerPostComment = async (
|
||||
req: CommentRequest,
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
const { id } = req.query;
|
||||
const { commentId } = req.query;
|
||||
|
||||
await deleteBeerCommentByIdService({ beerPostCommentId: id });
|
||||
await deleteBeerCommentByIdService({ beerPostCommentId: commentId });
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
@@ -73,7 +73,7 @@ export const createBeerPostComment = async (
|
||||
req: EditAndCreateCommentRequest,
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
const beerPostId = req.query.id;
|
||||
const beerPostId = req.query.postId;
|
||||
|
||||
const newBeerComment = await createBeerPostCommentService({
|
||||
body: req.body,
|
||||
@@ -93,7 +93,7 @@ export const getAllBeerPostComments = async (
|
||||
req: GetAllCommentsRequest,
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
const beerPostId = req.query.id;
|
||||
const beerPostId = req.query.postId;
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
const { page_size, page_num } = req.query;
|
||||
|
||||
|
||||
@@ -25,10 +25,12 @@ export const checkIfBeerStyleCommentOwner = async <
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
next: NextHandler,
|
||||
) => {
|
||||
const { id } = req.query;
|
||||
const { commentId } = req.query;
|
||||
const user = req.user!;
|
||||
|
||||
const beerStyleComment = await findBeerStyleCommentById({ beerStyleCommentId: id });
|
||||
const beerStyleComment = await findBeerStyleCommentById({
|
||||
beerStyleCommentId: commentId,
|
||||
});
|
||||
|
||||
if (!beerStyleComment) {
|
||||
throw new ServerError('Beer style comment not found.', 404);
|
||||
@@ -49,7 +51,7 @@ export const editBeerStyleComment = async (
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
await updateBeerStyleCommentById({
|
||||
beerStyleCommentId: req.query.id,
|
||||
beerStyleCommentId: req.query.commentId,
|
||||
body: req.body,
|
||||
});
|
||||
|
||||
@@ -64,9 +66,9 @@ export const deleteBeerStyleComment = async (
|
||||
req: CommentRequest,
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
const { id } = req.query;
|
||||
const { commentId } = req.query;
|
||||
|
||||
await deleteBeerStyleCommentById({ beerStyleCommentId: id });
|
||||
await deleteBeerStyleCommentById({ beerStyleCommentId: commentId });
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
@@ -81,7 +83,7 @@ export const createComment = async (
|
||||
) => {
|
||||
const newBeerStyleComment = await createNewBeerStyleComment({
|
||||
body: req.body,
|
||||
beerStyleId: req.query.id,
|
||||
beerStyleId: req.query.postId,
|
||||
userId: req.user!.id,
|
||||
});
|
||||
|
||||
@@ -97,7 +99,7 @@ export const getAll = async (
|
||||
req: GetAllCommentsRequest,
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
const beerStyleId = req.query.id;
|
||||
const beerStyleId = req.query.postId;
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
const { page_size, page_num } = req.query;
|
||||
|
||||
|
||||
@@ -25,9 +25,9 @@ export const checkIfBreweryCommentOwner = async <
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
next: NextHandler,
|
||||
) => {
|
||||
const { id } = req.query;
|
||||
const { commentId } = req.query;
|
||||
const user = req.user!;
|
||||
const comment = await getBreweryCommentById({ breweryCommentId: id });
|
||||
const comment = await getBreweryCommentById({ breweryCommentId: commentId });
|
||||
|
||||
if (!comment) {
|
||||
throw new ServerError('Comment not found', 404);
|
||||
@@ -44,10 +44,10 @@ export const editBreweryPostComment = async (
|
||||
req: EditAndCreateCommentRequest,
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
const { id } = req.query;
|
||||
const { commentId } = req.query;
|
||||
|
||||
const updated = updateBreweryCommentById({
|
||||
breweryCommentId: id,
|
||||
const updated = await updateBreweryCommentById({
|
||||
breweryCommentId: commentId,
|
||||
body: req.body,
|
||||
});
|
||||
|
||||
@@ -63,9 +63,9 @@ export const deleteBreweryPostComment = async (
|
||||
req: CommentRequest,
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
const { id } = req.query;
|
||||
const { commentId } = req.query;
|
||||
|
||||
await deleteBreweryCommentByIdService({ breweryCommentId: id });
|
||||
await deleteBreweryCommentByIdService({ breweryCommentId: commentId });
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
@@ -78,7 +78,7 @@ export const createComment = async (
|
||||
req: EditAndCreateCommentRequest,
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
const breweryPostId = req.query.id;
|
||||
const breweryPostId = req.query.postId;
|
||||
|
||||
const user = req.user!;
|
||||
|
||||
@@ -100,7 +100,7 @@ export const getAll = async (
|
||||
req: GetAllCommentsRequest,
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
const breweryPostId = req.query.id;
|
||||
const breweryPostId = req.query.postId;
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
const { page_size, page_num } = req.query;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import CreateCommentValidationSchema from '@/services/schema/CommentSchema/Creat
|
||||
import { z } from 'zod';
|
||||
|
||||
export interface CommentRequest extends UserExtendedNextApiRequest {
|
||||
query: { id: string };
|
||||
query: { postId: string; commentId: string };
|
||||
}
|
||||
|
||||
export interface EditAndCreateCommentRequest extends CommentRequest {
|
||||
@@ -11,5 +11,5 @@ export interface EditAndCreateCommentRequest extends CommentRequest {
|
||||
}
|
||||
|
||||
export interface GetAllCommentsRequest extends UserExtendedNextApiRequest {
|
||||
query: { id: string; page_size: string; page_num: string };
|
||||
query: { postId: string; page_size: string; page_num: string };
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ export const processBeerImageData = async (
|
||||
}
|
||||
|
||||
const beerImages = await addBeerImagesService({
|
||||
beerPostId: req.query.id,
|
||||
beerPostId: req.query.postId,
|
||||
userId: user!.id,
|
||||
body,
|
||||
files,
|
||||
|
||||
@@ -18,7 +18,7 @@ export const processBreweryImageData = async (
|
||||
}
|
||||
|
||||
const breweryImages = await addBreweryImagesService({
|
||||
breweryPostId: req.query.id,
|
||||
breweryPostId: req.query.postId,
|
||||
userId: user!.id,
|
||||
body,
|
||||
files,
|
||||
|
||||
@@ -4,7 +4,7 @@ import { z } from 'zod';
|
||||
|
||||
export interface UploadImagesRequest extends UserExtendedNextApiRequest {
|
||||
files?: Express.Multer.File[];
|
||||
query: { id: string };
|
||||
query: { postId: string };
|
||||
body: z.infer<typeof ImageMetadataValidationSchema>;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
||||
import ServerError from '@/config/util/ServerError';
|
||||
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
import { NextApiResponse, NextApiRequest } from 'next';
|
||||
import { NextApiResponse } from 'next';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { getBeerPostById } from '@/services/posts/beer-post';
|
||||
@@ -19,9 +19,9 @@ export const sendBeerPostLikeRequest = async (
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
const user = req.user!;
|
||||
const id = req.query.id as string;
|
||||
const { postId } = req.query;
|
||||
|
||||
const beer = await getBeerPostById({ beerPostId: id });
|
||||
const beer = await getBeerPostById({ beerPostId: postId });
|
||||
if (!beer) {
|
||||
throw new ServerError('Could not find a beer post with that id.', 404);
|
||||
}
|
||||
@@ -53,12 +53,12 @@ export const sendBeerPostLikeRequest = async (
|
||||
};
|
||||
|
||||
export const getBeerPostLikeCount = async (
|
||||
req: NextApiRequest,
|
||||
req: LikeRequest,
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
const id = req.query.id as string;
|
||||
const { postId } = req.query;
|
||||
|
||||
const likeCount = await getBeerPostLikeCountService({ beerPostId: id });
|
||||
const likeCount = await getBeerPostLikeCountService({ beerPostId: postId });
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import ServerError from '@/config/util/ServerError';
|
||||
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
import { NextApiResponse, NextApiRequest } from 'next';
|
||||
import { NextApiResponse } from 'next';
|
||||
import { z } from 'zod';
|
||||
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
||||
import {
|
||||
@@ -18,9 +18,9 @@ export const sendBeerStyleLikeRequest = async (
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
const user = req.user!;
|
||||
const { id } = req.query;
|
||||
const { postId } = req.query;
|
||||
|
||||
const beerStyle = await getBeerStyleByIdService({ beerStyleId: id });
|
||||
const beerStyle = await getBeerStyleByIdService({ beerStyleId: postId });
|
||||
if (!beerStyle) {
|
||||
throw new ServerError('Could not find a beer style with that id.', 404);
|
||||
}
|
||||
@@ -48,11 +48,11 @@ export const sendBeerStyleLikeRequest = async (
|
||||
};
|
||||
|
||||
export const getBeerStyleLikeCountRequest = async (
|
||||
req: NextApiRequest,
|
||||
req: LikeRequest,
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
const id = req.query.id as string;
|
||||
const likeCount = await getBeerStyleLikeCountService({ beerStyleId: id });
|
||||
const { postId } = req.query;
|
||||
const likeCount = await getBeerStyleLikeCountService({ beerStyleId: postId });
|
||||
|
||||
res.status(200).json({
|
||||
success: true,
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
||||
import ServerError from '@/config/util/ServerError';
|
||||
|
||||
import {
|
||||
@@ -9,17 +8,18 @@ import {
|
||||
} from '@/services/likes/brewery-post-like';
|
||||
import { getBreweryPostByIdService } from '@/services/posts/brewery-post';
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
import { NextApiResponse, NextApiRequest } from 'next';
|
||||
import { NextApiResponse } from 'next';
|
||||
import { z } from 'zod';
|
||||
import { LikeRequest } from '../types';
|
||||
|
||||
export const sendBreweryPostLikeRequest = async (
|
||||
req: UserExtendedNextApiRequest,
|
||||
req: LikeRequest,
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
const id = req.query.id! as string;
|
||||
const { postId } = req.query;
|
||||
const user = req.user!;
|
||||
|
||||
const breweryPost = await getBreweryPostByIdService({ breweryPostId: id });
|
||||
const breweryPost = await getBreweryPostByIdService({ breweryPostId: postId });
|
||||
|
||||
if (!breweryPost) {
|
||||
throw new ServerError('Could not find a brewery post with that id', 404);
|
||||
@@ -53,12 +53,12 @@ export const sendBreweryPostLikeRequest = async (
|
||||
};
|
||||
|
||||
export const getBreweryPostLikeCount = async (
|
||||
req: NextApiRequest,
|
||||
req: LikeRequest,
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
const id = req.query.id! as string;
|
||||
const { postId } = req.query;
|
||||
|
||||
const breweryPost = await getBreweryPostByIdService({ breweryPostId: id });
|
||||
const breweryPost = await getBreweryPostByIdService({ breweryPostId: postId });
|
||||
if (!breweryPost) {
|
||||
throw new ServerError('Could not find a brewery post with that id', 404);
|
||||
}
|
||||
@@ -76,14 +76,14 @@ export const getBreweryPostLikeCount = async (
|
||||
};
|
||||
|
||||
export const getBreweryPostLikeStatus = async (
|
||||
req: UserExtendedNextApiRequest,
|
||||
req: LikeRequest,
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
const user = req.user!;
|
||||
const id = req.query.id as string;
|
||||
const { postId } = req.query;
|
||||
|
||||
const liked = await findBreweryPostLikeService({
|
||||
breweryPostId: id,
|
||||
breweryPostId: postId,
|
||||
likedById: user.id,
|
||||
});
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
||||
|
||||
export interface LikeRequest extends UserExtendedNextApiRequest {
|
||||
query: { id: string };
|
||||
query: { postId: string };
|
||||
}
|
||||
|
||||
@@ -28,9 +28,9 @@ export const checkIfBeerPostOwner = async <BeerPostRequestType extends BeerPostR
|
||||
next: NextHandler,
|
||||
) => {
|
||||
const { user, query } = req;
|
||||
const { id } = query;
|
||||
const { postId } = query;
|
||||
|
||||
const beerPost = await getBeerPostById({ beerPostId: id });
|
||||
const beerPost = await getBeerPostById({ beerPostId: postId });
|
||||
|
||||
if (!beerPost) {
|
||||
throw new ServerError('Beer post not found', 404);
|
||||
@@ -47,7 +47,7 @@ export const editBeerPost = async (
|
||||
req: EditBeerPostRequest,
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
await editBeerPostByIdService({ beerPostId: req.query.id, body: req.body });
|
||||
await editBeerPostByIdService({ beerPostId: req.query.postId, body: req.body });
|
||||
|
||||
res.status(200).json({
|
||||
message: 'Beer post updated successfully',
|
||||
@@ -57,9 +57,9 @@ export const editBeerPost = async (
|
||||
};
|
||||
|
||||
export const deleteBeerPost = async (req: BeerPostRequest, res: NextApiResponse) => {
|
||||
const { id } = req.query;
|
||||
const { postId } = req.query;
|
||||
|
||||
const deleted = await deleteBeerPostByIdService({ beerPostId: id });
|
||||
const deleted = await deleteBeerPostByIdService({ beerPostId: postId });
|
||||
if (!deleted) {
|
||||
throw new ServerError('Beer post not found', 404);
|
||||
}
|
||||
@@ -75,9 +75,9 @@ export const getBeerPostRecommendations = async (
|
||||
req: GetBeerRecommendationsRequest,
|
||||
res: NextApiResponse<z.infer<typeof APIResponseValidationSchema>>,
|
||||
) => {
|
||||
const { id } = req.query;
|
||||
const { postId } = req.query;
|
||||
|
||||
const beerPost = await getBeerPostById({ beerPostId: id });
|
||||
const beerPost = await getBeerPostById({ beerPostId: postId });
|
||||
|
||||
if (!beerPost) {
|
||||
throw new ServerError('Beer post not found', 404);
|
||||
|
||||
@@ -5,7 +5,7 @@ import { NextApiRequest } from 'next';
|
||||
import { z } from 'zod';
|
||||
|
||||
export interface BeerPostRequest extends UserExtendedNextApiRequest {
|
||||
query: { id: string };
|
||||
query: { postId: string };
|
||||
}
|
||||
|
||||
export interface EditBeerPostRequest extends BeerPostRequest {
|
||||
@@ -17,7 +17,7 @@ export interface GetAllBeerPostsRequest extends NextApiRequest {
|
||||
}
|
||||
|
||||
export interface GetBeerRecommendationsRequest extends BeerPostRequest {
|
||||
query: { id: string; page_num: string; page_size: string };
|
||||
query: { postId: string; page_num: string; page_size: string };
|
||||
}
|
||||
|
||||
export interface CreateBeerPostRequest extends UserExtendedNextApiRequest {
|
||||
|
||||
@@ -167,9 +167,9 @@ export const checkIfBreweryPostOwner = async (
|
||||
next: NextHandler,
|
||||
) => {
|
||||
const user = req.user!;
|
||||
const { id } = req.query;
|
||||
const { postId } = req.query;
|
||||
|
||||
const breweryPost = await getBreweryPostByIdService({ breweryPostId: id });
|
||||
const breweryPost = await getBreweryPostByIdService({ breweryPostId: postId });
|
||||
if (!breweryPost) {
|
||||
throw new ServerError('Brewery post not found', 404);
|
||||
}
|
||||
@@ -187,10 +187,10 @@ export const editBreweryPost = async (
|
||||
) => {
|
||||
const {
|
||||
body,
|
||||
query: { id },
|
||||
query: { postId },
|
||||
} = req;
|
||||
|
||||
await updateBreweryPostService({ breweryPostId: id, body });
|
||||
await updateBreweryPostService({ breweryPostId: postId, body });
|
||||
|
||||
res.status(200).json({
|
||||
message: 'Brewery post updated successfully',
|
||||
@@ -203,8 +203,8 @@ export const deleteBreweryPost = async (
|
||||
req: BreweryPostRequest,
|
||||
res: NextApiResponse,
|
||||
) => {
|
||||
const { id } = req.query;
|
||||
const deleted = await deleteBreweryPostService({ breweryPostId: id });
|
||||
const { postId } = req.query;
|
||||
const deleted = await deleteBreweryPostService({ breweryPostId: postId });
|
||||
|
||||
if (!deleted) {
|
||||
throw new ServerError('Brewery post not found', 404);
|
||||
|
||||
@@ -14,7 +14,7 @@ export interface CreateBreweryPostRequest extends UserExtendedNextApiRequest {
|
||||
}
|
||||
|
||||
export interface BreweryPostRequest extends UserExtendedNextApiRequest {
|
||||
query: { id: string };
|
||||
query: { postId: string };
|
||||
}
|
||||
|
||||
export interface EditBreweryPostRequest extends BreweryPostRequest {
|
||||
|
||||
@@ -41,7 +41,7 @@ const useGetBreweryPostLikeCount = (breweryPostId: string) => {
|
||||
error: error as unknown,
|
||||
isLoading,
|
||||
mutate,
|
||||
likeCount: data as number | undefined,
|
||||
likeCount: data,
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -22,14 +22,16 @@ const router = createRouter<
|
||||
|
||||
router
|
||||
.delete(
|
||||
validateRequest({ querySchema: z.object({ id: z.string().cuid() }) }),
|
||||
validateRequest({
|
||||
querySchema: z.object({ postId: z.string().cuid(), commentId: z.string().cuid() }),
|
||||
}),
|
||||
getCurrentUser,
|
||||
checkIfBeerCommentOwner,
|
||||
deleteBeerPostComment,
|
||||
)
|
||||
.put(
|
||||
validateRequest({
|
||||
querySchema: z.object({ id: z.string().cuid() }),
|
||||
querySchema: z.object({ postId: z.string().cuid(), commentId: z.string().cuid() }),
|
||||
bodySchema: CreateCommentValidationSchema,
|
||||
}),
|
||||
getCurrentUser,
|
||||
@@ -11,6 +11,7 @@ import {
|
||||
createBeerPostComment,
|
||||
getAllBeerPostComments,
|
||||
} from '@/controllers/comments/beer-comments';
|
||||
import PaginatedQueryResponseSchema from '@/services/schema/PaginatedQueryResponseSchema';
|
||||
|
||||
const router = createRouter<
|
||||
// @TODO: Fix this any type
|
||||
@@ -21,7 +22,7 @@ const router = createRouter<
|
||||
router.post(
|
||||
validateRequest({
|
||||
bodySchema: CreateCommentValidationSchema,
|
||||
querySchema: z.object({ id: z.string().cuid() }),
|
||||
querySchema: z.object({ postId: z.string().cuid() }),
|
||||
}),
|
||||
getCurrentUser,
|
||||
createBeerPostComment,
|
||||
@@ -29,11 +30,7 @@ router.post(
|
||||
|
||||
router.get(
|
||||
validateRequest({
|
||||
querySchema: z.object({
|
||||
id: z.string().cuid(),
|
||||
page_size: z.coerce.number().int().positive(),
|
||||
page_num: z.coerce.number().int().positive(),
|
||||
}),
|
||||
querySchema: PaginatedQueryResponseSchema.extend({ postId: z.string().cuid() }),
|
||||
}),
|
||||
getAllBeerPostComments,
|
||||
);
|
||||
@@ -26,14 +26,14 @@ router
|
||||
.put(
|
||||
validateRequest({
|
||||
bodySchema: EditBeerPostValidationSchema,
|
||||
querySchema: z.object({ id: z.string() }),
|
||||
querySchema: z.object({ postId: z.string() }),
|
||||
}),
|
||||
getCurrentUser,
|
||||
checkIfBeerPostOwner,
|
||||
editBeerPost,
|
||||
)
|
||||
.delete(
|
||||
validateRequest({ querySchema: z.object({ id: z.string() }) }),
|
||||
validateRequest({ querySchema: z.object({ postId: z.string() }) }),
|
||||
getCurrentUser,
|
||||
checkIfBeerPostOwner,
|
||||
deleteBeerPost,
|
||||
@@ -19,12 +19,12 @@ const router = createRouter<
|
||||
|
||||
router.post(
|
||||
getCurrentUser,
|
||||
validateRequest({ querySchema: z.object({ id: z.string().cuid() }) }),
|
||||
validateRequest({ querySchema: z.object({ postId: z.string().cuid() }) }),
|
||||
sendBeerPostLikeRequest,
|
||||
);
|
||||
|
||||
router.get(
|
||||
validateRequest({ querySchema: z.object({ id: z.string().cuid() }) }),
|
||||
validateRequest({ querySchema: z.object({ postId: z.string().cuid() }) }),
|
||||
getBeerPostLikeCount,
|
||||
);
|
||||
|
||||
@@ -16,7 +16,7 @@ const router = createRouter<
|
||||
|
||||
router.get(
|
||||
getCurrentUser,
|
||||
validateRequest({ querySchema: z.object({ id: z.string().cuid() }) }),
|
||||
validateRequest({ querySchema: z.object({ postId: z.string().cuid() }) }),
|
||||
checkIfBeerPostIsLiked,
|
||||
);
|
||||
|
||||
@@ -2,6 +2,7 @@ import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||
import { getBeerPostRecommendations } from '@/controllers/posts/beer-posts';
|
||||
import { GetBeerRecommendationsRequest } from '@/controllers/posts/beer-posts/types';
|
||||
import PaginatedQueryResponseSchema from '@/services/schema/PaginatedQueryResponseSchema';
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
import { NextApiResponse } from 'next';
|
||||
import { createRouter } from 'next-connect';
|
||||
@@ -14,11 +15,7 @@ const router = createRouter<
|
||||
|
||||
router.get(
|
||||
validateRequest({
|
||||
querySchema: z.object({
|
||||
id: z.string().cuid(),
|
||||
page_num: z.string().regex(/^[0-9]+$/),
|
||||
page_size: z.string().regex(/^[0-9]+$/),
|
||||
}),
|
||||
querySchema: PaginatedQueryResponseSchema.extend({ postId: z.string().cuid() }),
|
||||
}),
|
||||
getBeerPostRecommendations,
|
||||
);
|
||||
@@ -1,6 +1,7 @@
|
||||
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||
import { getAllBeersByBeerStyle } from '@/controllers/posts/beer-styles';
|
||||
import PaginatedQueryResponseSchema from '@/services/schema/PaginatedQueryResponseSchema';
|
||||
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
import { NextApiRequest, NextApiResponse } from 'next';
|
||||
@@ -18,11 +19,7 @@ const router = createRouter<
|
||||
|
||||
router.get(
|
||||
validateRequest({
|
||||
querySchema: z.object({
|
||||
page_size: z.string().min(1),
|
||||
page_num: z.string().min(1),
|
||||
id: z.string().min(1),
|
||||
}),
|
||||
querySchema: PaginatedQueryResponseSchema.extend({ postId: z.string().cuid() }),
|
||||
}),
|
||||
getAllBeersByBeerStyle,
|
||||
);
|
||||
@@ -22,7 +22,7 @@ const router = createRouter<
|
||||
router
|
||||
.delete(
|
||||
validateRequest({
|
||||
querySchema: z.object({ id: z.string().cuid() }),
|
||||
querySchema: z.object({ postId: z.string().cuid(), commentId: z.string().cuid() }),
|
||||
}),
|
||||
getCurrentUser,
|
||||
checkIfBeerStyleCommentOwner,
|
||||
@@ -30,7 +30,7 @@ router
|
||||
)
|
||||
.put(
|
||||
validateRequest({
|
||||
querySchema: z.object({ id: z.string().cuid() }),
|
||||
querySchema: z.object({ postId: z.string().cuid(), commentId: z.string().cuid() }),
|
||||
bodySchema: CreateCommentValidationSchema,
|
||||
}),
|
||||
getCurrentUser,
|
||||
@@ -8,6 +8,7 @@ import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser';
|
||||
import { NextApiResponse } from 'next';
|
||||
import CreateCommentValidationSchema from '@/services/schema/CommentSchema/CreateCommentValidationSchema';
|
||||
import { createComment, getAll } from '@/controllers/comments/beer-style-comments';
|
||||
import PaginatedQueryResponseSchema from '@/services/schema/PaginatedQueryResponseSchema';
|
||||
|
||||
const router = createRouter<
|
||||
// I don't want to use any, but I can't figure out how to get the types to work
|
||||
@@ -18,7 +19,7 @@ const router = createRouter<
|
||||
router.post(
|
||||
validateRequest({
|
||||
bodySchema: CreateCommentValidationSchema,
|
||||
querySchema: z.object({ id: z.string().cuid() }),
|
||||
querySchema: z.object({ postId: z.string().cuid() }),
|
||||
}),
|
||||
getCurrentUser,
|
||||
createComment,
|
||||
@@ -26,11 +27,7 @@ router.post(
|
||||
|
||||
router.get(
|
||||
validateRequest({
|
||||
querySchema: z.object({
|
||||
id: z.string().cuid(),
|
||||
page_size: z.coerce.number().int().positive(),
|
||||
page_num: z.coerce.number().int().positive(),
|
||||
}),
|
||||
querySchema: PaginatedQueryResponseSchema.extend({ postId: z.string().cuid() }),
|
||||
}),
|
||||
getAll,
|
||||
);
|
||||
@@ -13,7 +13,7 @@ const router = createRouter<
|
||||
>();
|
||||
|
||||
router.get(
|
||||
validateRequest({ querySchema: z.object({ id: z.string().cuid() }) }),
|
||||
validateRequest({ querySchema: z.object({ postId: z.string().cuid() }) }),
|
||||
getBeerStyle,
|
||||
);
|
||||
|
||||
@@ -20,12 +20,12 @@ const router = createRouter<
|
||||
|
||||
router.post(
|
||||
getCurrentUser,
|
||||
validateRequest({ querySchema: z.object({ id: z.string().cuid() }) }),
|
||||
validateRequest({ querySchema: z.object({ postId: z.string().cuid() }) }),
|
||||
sendBeerStyleLikeRequest,
|
||||
);
|
||||
|
||||
router.get(
|
||||
validateRequest({ querySchema: z.object({ id: z.string().cuid() }) }),
|
||||
validateRequest({ querySchema: z.object({ postId: z.string().cuid() }) }),
|
||||
getBeerStyleLikeCountRequest,
|
||||
);
|
||||
|
||||
@@ -15,7 +15,7 @@ const router = createRouter<
|
||||
|
||||
router.get(
|
||||
getCurrentUser,
|
||||
validateRequest({ querySchema: z.object({ id: z.string().cuid() }) }),
|
||||
validateRequest({ querySchema: z.object({ postId: z.string().cuid() }) }),
|
||||
checkIfBeerStyleIsLiked,
|
||||
);
|
||||
|
||||
@@ -2,6 +2,7 @@ import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||
import { getAllBeersByBrewery } from '@/controllers/posts/breweries';
|
||||
import { GetAllPostsByConnectedPostId } from '@/controllers/posts/types';
|
||||
import PaginatedQueryResponseSchema from '@/services/schema/PaginatedQueryResponseSchema';
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
import { NextApiResponse } from 'next';
|
||||
import { createRouter } from 'next-connect';
|
||||
@@ -14,11 +15,7 @@ const router = createRouter<
|
||||
|
||||
router.get(
|
||||
validateRequest({
|
||||
querySchema: z.object({
|
||||
page_size: z.string().nonempty(),
|
||||
page_num: z.string().nonempty(),
|
||||
id: z.string().nonempty(),
|
||||
}),
|
||||
querySchema: PaginatedQueryResponseSchema.extend({ postId: z.string().cuid() }),
|
||||
}),
|
||||
getAllBeersByBrewery,
|
||||
);
|
||||
@@ -24,7 +24,7 @@ const router = createRouter<
|
||||
router
|
||||
.delete(
|
||||
validateRequest({
|
||||
querySchema: z.object({ id: z.string().cuid() }),
|
||||
querySchema: z.object({ commentId: z.string().cuid(), postId: z.string().cuid() }),
|
||||
}),
|
||||
getCurrentUser,
|
||||
checkIfBreweryCommentOwner,
|
||||
@@ -32,7 +32,7 @@ router
|
||||
)
|
||||
.put(
|
||||
validateRequest({
|
||||
querySchema: z.object({ id: z.string().cuid() }),
|
||||
querySchema: z.object({ commentId: z.string().cuid(), postId: z.string().cuid() }),
|
||||
bodySchema: CreateCommentValidationSchema,
|
||||
}),
|
||||
getCurrentUser,
|
||||
@@ -9,6 +9,7 @@ import { NextApiResponse } from 'next';
|
||||
|
||||
import CreateCommentValidationSchema from '@/services/schema/CommentSchema/CreateCommentValidationSchema';
|
||||
import { createComment, getAll } from '@/controllers/comments/brewery-comments';
|
||||
import PaginatedQueryResponseSchema from '@/services/schema/PaginatedQueryResponseSchema';
|
||||
|
||||
const router = createRouter<
|
||||
// I don't want to use any, but I can't figure out how to get the types to work
|
||||
@@ -19,7 +20,7 @@ const router = createRouter<
|
||||
router.post(
|
||||
validateRequest({
|
||||
bodySchema: CreateCommentValidationSchema,
|
||||
querySchema: z.object({ id: z.string().cuid() }),
|
||||
querySchema: z.object({ postId: z.string().cuid() }),
|
||||
}),
|
||||
getCurrentUser,
|
||||
createComment,
|
||||
@@ -27,11 +28,7 @@ router.post(
|
||||
|
||||
router.get(
|
||||
validateRequest({
|
||||
querySchema: z.object({
|
||||
id: z.string().cuid(),
|
||||
page_size: z.coerce.number().int().positive(),
|
||||
page_num: z.coerce.number().int().positive(),
|
||||
}),
|
||||
querySchema: PaginatedQueryResponseSchema.extend({ postId: z.string().cuid() }),
|
||||
}),
|
||||
getAll,
|
||||
);
|
||||
@@ -1,4 +1,3 @@
|
||||
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
||||
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||
import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser';
|
||||
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||
@@ -6,6 +5,7 @@ import {
|
||||
sendBreweryPostLikeRequest,
|
||||
getBreweryPostLikeCount,
|
||||
} from '@/controllers/likes/brewery-post-likes';
|
||||
import { LikeRequest } from '@/controllers/likes/types';
|
||||
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
import { NextApiResponse } from 'next';
|
||||
@@ -13,18 +13,18 @@ import { createRouter } from 'next-connect';
|
||||
import { z } from 'zod';
|
||||
|
||||
const router = createRouter<
|
||||
UserExtendedNextApiRequest,
|
||||
LikeRequest,
|
||||
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||
>();
|
||||
|
||||
router.post(
|
||||
getCurrentUser,
|
||||
validateRequest({ querySchema: z.object({ id: z.string().cuid() }) }),
|
||||
validateRequest({ querySchema: z.object({ postId: z.string().cuid() }) }),
|
||||
sendBreweryPostLikeRequest,
|
||||
);
|
||||
|
||||
router.get(
|
||||
validateRequest({ querySchema: z.object({ id: z.string().cuid() }) }),
|
||||
validateRequest({ querySchema: z.object({ postId: z.string().cuid() }) }),
|
||||
getBreweryPostLikeCount,
|
||||
);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
||||
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||
import getCurrentUser from '@/config/nextConnect/middleware/getCurrentUser';
|
||||
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||
import { getBreweryPostLikeStatus } from '@/controllers/likes/brewery-post-likes';
|
||||
import { LikeRequest } from '@/controllers/likes/types';
|
||||
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
import { NextApiResponse } from 'next';
|
||||
@@ -10,17 +10,13 @@ import { createRouter } from 'next-connect';
|
||||
import { z } from 'zod';
|
||||
|
||||
const router = createRouter<
|
||||
UserExtendedNextApiRequest,
|
||||
LikeRequest,
|
||||
NextApiResponse<z.infer<typeof APIResponseValidationSchema>>
|
||||
>();
|
||||
|
||||
router.get(
|
||||
getCurrentUser,
|
||||
validateRequest({
|
||||
querySchema: z.object({
|
||||
id: z.string().cuid(),
|
||||
}),
|
||||
}),
|
||||
validateRequest({ querySchema: z.object({ postId: z.string().cuid() }) }),
|
||||
getBreweryPostLikeStatus,
|
||||
);
|
||||
|
||||
@@ -2,6 +2,7 @@ import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||
import { getUserFollowers } from '@/controllers/users/profile';
|
||||
import { GetUserFollowInfoRequest } from '@/controllers/users/profile/types';
|
||||
import PaginatedQueryResponseSchema from '@/services/schema/PaginatedQueryResponseSchema';
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
|
||||
import { NextApiResponse } from 'next';
|
||||
@@ -15,11 +16,7 @@ const router = createRouter<
|
||||
|
||||
router.get(
|
||||
validateRequest({
|
||||
querySchema: z.object({
|
||||
id: z.string().cuid(),
|
||||
page_size: z.string().regex(/^\d+$/),
|
||||
page_num: z.string().regex(/^\d+$/),
|
||||
}),
|
||||
querySchema: PaginatedQueryResponseSchema.extend({ id: z.string().cuid() }),
|
||||
}),
|
||||
getUserFollowers,
|
||||
);
|
||||
|
||||
@@ -2,6 +2,7 @@ import { UserExtendedNextApiRequest } from '@/config/auth/types';
|
||||
import NextConnectOptions from '@/config/nextConnect/NextConnectOptions';
|
||||
import validateRequest from '@/config/nextConnect/middleware/validateRequest';
|
||||
import { getUsersFollowed } from '@/controllers/users/profile';
|
||||
import PaginatedQueryResponseSchema from '@/services/schema/PaginatedQueryResponseSchema';
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
|
||||
import { NextApiResponse } from 'next';
|
||||
@@ -19,11 +20,7 @@ const router = createRouter<
|
||||
|
||||
router.get(
|
||||
validateRequest({
|
||||
querySchema: z.object({
|
||||
id: z.string().cuid(),
|
||||
page_size: z.string().regex(/^\d+$/),
|
||||
page_num: z.string().regex(/^\d+$/),
|
||||
}),
|
||||
querySchema: PaginatedQueryResponseSchema.extend({ id: z.string().cuid() }),
|
||||
}),
|
||||
getUsersFollowed,
|
||||
);
|
||||
|
||||
@@ -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<EditPageProps> = ({ breweryPost }) => {
|
||||
const pageTitle = `Edit \u201c${breweryPost.name}\u201d`;
|
||||
|
||||
const router = useRouter();
|
||||
const {
|
||||
register,
|
||||
handleSubmit,
|
||||
formState: { errors, isSubmitting },
|
||||
} = useForm<z.infer<typeof EditBreweryPostValidationSchema>>({
|
||||
resolver: zodResolver(EditBreweryPostValidationSchema),
|
||||
defaultValues: {
|
||||
name: breweryPost.name,
|
||||
description: breweryPost.description,
|
||||
id: breweryPost.id,
|
||||
dateEstablished: breweryPost.dateEstablished,
|
||||
},
|
||||
});
|
||||
|
||||
const onSubmit = async (data: z.infer<typeof EditBreweryPostValidationSchema>) => {
|
||||
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 (
|
||||
<>
|
||||
<Head>
|
||||
@@ -81,59 +29,7 @@ const EditBreweryPostPage: NextPage<EditPageProps> = ({ breweryPost }) => {
|
||||
backLink={`/breweries/${breweryPost.id}`}
|
||||
backLinkText={`Back to "${breweryPost.name}"`}
|
||||
>
|
||||
<>
|
||||
<form className="form-control space-y-4" onSubmit={handleSubmit(onSubmit)}>
|
||||
<div className="w-full">
|
||||
<FormInfo>
|
||||
<FormLabel htmlFor="name">Name</FormLabel>
|
||||
<FormError>{errors.name?.message}</FormError>
|
||||
</FormInfo>
|
||||
<FormSegment>
|
||||
<FormTextInput
|
||||
id="name"
|
||||
type="text"
|
||||
placeholder="Name"
|
||||
formValidationSchema={register('name')}
|
||||
error={!!errors.name}
|
||||
disabled={isSubmitting}
|
||||
/>
|
||||
</FormSegment>
|
||||
|
||||
<FormInfo>
|
||||
<FormLabel htmlFor="description">Description</FormLabel>
|
||||
<FormError>{errors.description?.message}</FormError>
|
||||
</FormInfo>
|
||||
<FormSegment>
|
||||
<FormTextArea
|
||||
disabled={isSubmitting}
|
||||
placeholder="Ratione cumque quas quia aut impedit ea culpa facere. Ut in sit et quas reiciendis itaque."
|
||||
error={!!errors.description}
|
||||
formValidationSchema={register('description')}
|
||||
id="description"
|
||||
rows={8}
|
||||
/>
|
||||
</FormSegment>
|
||||
</div>
|
||||
|
||||
<div className="w-full space-y-3">
|
||||
<button
|
||||
disabled={isSubmitting}
|
||||
className="btn btn-primary w-full"
|
||||
type="submit"
|
||||
>
|
||||
{isSubmitting ? 'Saving...' : 'Save'}
|
||||
</button>
|
||||
|
||||
<button
|
||||
className="btn btn-primary w-full"
|
||||
type="button"
|
||||
onClick={handleDelete}
|
||||
>
|
||||
Delete Brewery
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</>
|
||||
<EditBreweryPostForm breweryPost={breweryPost} />
|
||||
</FormPageLayout>
|
||||
</>
|
||||
);
|
||||
|
||||
@@ -22,8 +22,8 @@ import useGetUsersFollowedByUser from '@/hooks/data-fetching/user-follows/useGet
|
||||
import useGetUsersFollowingUser from '@/hooks/data-fetching/user-follows/useGetUsersFollowingUser';
|
||||
|
||||
import UpdateProfileSchema from '@/services/users/auth/schema/UpdateProfileSchema';
|
||||
import sendUpdateUserAvatarRequest from '@/requests/Account/sendUpdateUserAvatarRequest';
|
||||
import sendUpdateUserProfileRequest from '@/requests/Account/sendUpdateUserProfileRequest';
|
||||
import sendUpdateUserAvatarRequest from '@/requests/users/profile/sendUpdateUserAvatarRequest';
|
||||
import sendUpdateUserProfileRequest from '@/requests/users/profile/sendUpdateUserProfileRequest';
|
||||
import Spinner from '@/components/ui/Spinner';
|
||||
|
||||
const ProfilePage: NextPage = () => {
|
||||
|
||||
@@ -12,8 +12,9 @@ import { NextPage } from 'next';
|
||||
import { SubmitHandler, useForm } from 'react-hook-form';
|
||||
import toast from 'react-hot-toast';
|
||||
import { useRouter } from 'next/router';
|
||||
import sendForgotPasswordRequest from '@/requests/User/sendForgotPasswordRequest';
|
||||
|
||||
import { FaUserCircle } from 'react-icons/fa';
|
||||
import { sendForgotPasswordRequest } from '@/requests/users/auth';
|
||||
|
||||
interface ForgotPasswordPageProps {}
|
||||
|
||||
@@ -29,7 +30,7 @@ const ForgotPasswordPage: NextPage<ForgotPasswordPageProps> = () => {
|
||||
const onSubmit: SubmitHandler<{ email: string }> = async (data) => {
|
||||
try {
|
||||
const loadingToast = toast.loading('Sending reset link...');
|
||||
await sendForgotPasswordRequest(data.email);
|
||||
await sendForgotPasswordRequest({ email: data.email });
|
||||
reset();
|
||||
toast.dismiss(loadingToast);
|
||||
toast.success('Password reset link sent!');
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
import CommentQueryResult from '@/services/schema/CommentSchema/CommentQueryResult';
|
||||
import CreateCommentValidationSchema from '@/services/schema/CommentSchema/CreateCommentValidationSchema';
|
||||
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
import { z } from 'zod';
|
||||
|
||||
const BeerCommentValidationSchemaWithId = CreateCommentValidationSchema.extend({
|
||||
beerPostId: z.string().cuid(),
|
||||
});
|
||||
|
||||
/**
|
||||
* Sends a POST request to the server to create a new beer comment.
|
||||
*
|
||||
* @param data The data to be sent to the server.
|
||||
* @param data.beerPostId The ID of the beer post to comment on.
|
||||
* @param data.content The content of the comment.
|
||||
* @param data.rating The rating of the beer.
|
||||
* @returns A promise that resolves to the created comment.
|
||||
* @throws An error if the request fails, the API response is invalid, or the API response
|
||||
* payload is invalid.
|
||||
*/
|
||||
const sendCreateBeerCommentRequest = async ({
|
||||
beerPostId,
|
||||
content,
|
||||
rating,
|
||||
}: z.infer<typeof BeerCommentValidationSchemaWithId>) => {
|
||||
const response = await fetch(`/api/beers/${beerPostId}/comments`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ beerPostId, content, rating }),
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error(response.statusText);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
const parsedResponse = APIResponseValidationSchema.safeParse(data);
|
||||
|
||||
if (!parsedResponse.success) {
|
||||
throw new Error('Invalid API response');
|
||||
}
|
||||
|
||||
const parsedPayload = CommentQueryResult.safeParse(parsedResponse.data.payload);
|
||||
|
||||
if (!parsedPayload.success) {
|
||||
throw new Error('Invalid API response payload');
|
||||
}
|
||||
|
||||
return parsedPayload.data;
|
||||
};
|
||||
|
||||
export default sendCreateBeerCommentRequest;
|
||||
@@ -1,29 +0,0 @@
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
|
||||
/**
|
||||
* Sends a DELETE request to the server to delete a beer post with the given ID.
|
||||
*
|
||||
* @param id The ID of the beer post to delete.
|
||||
* @returns A Promise that resolves to the parsed API response.
|
||||
* @throws An error if the response fails or the API response is invalid.
|
||||
*/
|
||||
const deleteBeerPostRequest = async (id: string) => {
|
||||
const response = await fetch(`/api/beers/${id}`, {
|
||||
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('Could not successfully parse the response.');
|
||||
}
|
||||
|
||||
return parsed;
|
||||
};
|
||||
|
||||
export default deleteBeerPostRequest;
|
||||
@@ -1,67 +0,0 @@
|
||||
import BeerPostQueryResult from '@/services/posts/beer-post/schema/BeerPostQueryResult';
|
||||
import CreateBeerPostValidationSchema from '@/services/posts/beer-post/schema/CreateBeerPostValidationSchema';
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
import { z } from 'zod';
|
||||
|
||||
/**
|
||||
* Sends a POST request to the server to create a new beer post.
|
||||
*
|
||||
* @param data Data containing the beer post information to be sent to the server.
|
||||
* @param abv The alcohol by volume of the beer.
|
||||
* @param breweryId The ID of the brewery that produces the beer.
|
||||
* @param description The description of the beer.
|
||||
* @param ibu The International Bitterness Units of the beer.
|
||||
* @param name The name of the beer.
|
||||
* @param styleId The ID of the beer style.
|
||||
* @returns A Promise that resolves to the created beer post.
|
||||
* @throws An error if the request fails, the API response is invalid, or the API response
|
||||
* payload is invalid.
|
||||
*/
|
||||
const sendCreateBeerPostRequest = async ({
|
||||
abv,
|
||||
breweryId,
|
||||
description,
|
||||
ibu,
|
||||
name,
|
||||
styleId,
|
||||
}: z.infer<typeof CreateBeerPostValidationSchema>) => {
|
||||
const response = await fetch('/api/beers/create', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
abv,
|
||||
breweryId,
|
||||
description,
|
||||
ibu,
|
||||
name,
|
||||
styleId,
|
||||
}),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(response.statusText);
|
||||
}
|
||||
|
||||
const json = await response.json();
|
||||
const parsed = APIResponseValidationSchema.safeParse(json);
|
||||
|
||||
if (!parsed.success) {
|
||||
throw new Error('Invalid API response');
|
||||
}
|
||||
|
||||
const { payload, success, message } = parsed.data;
|
||||
|
||||
if (!success) {
|
||||
throw new Error(message);
|
||||
}
|
||||
|
||||
const parsedPayload = BeerPostQueryResult.safeParse(payload);
|
||||
|
||||
if (!parsedPayload.success) {
|
||||
throw new Error('Invalid API response payload');
|
||||
}
|
||||
|
||||
return parsedPayload.data;
|
||||
};
|
||||
|
||||
export default sendCreateBeerPostRequest;
|
||||
@@ -1,42 +0,0 @@
|
||||
import EditBeerPostValidationSchema from '@/services/posts/beer-post/schema/EditBeerPostValidationSchema';
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
import { z } from 'zod';
|
||||
|
||||
/**
|
||||
* Sends a PUT request to the server to update a beer post.
|
||||
*
|
||||
* @param data Data containing the updated beer post information to be sent to the server.
|
||||
* @param data.abv The updated ABV of the beer.
|
||||
* @param data.description The updated description of the beer.
|
||||
* @param data.ibu The updated IBU of the beer.
|
||||
* @param data.id The ID of the beer post to be updated.
|
||||
* @param data.name The updated name of the beer.
|
||||
* @param data.styleId The updated style ID of the beer.
|
||||
* @throws If the response status is not ok or the API response is not successful.
|
||||
*/
|
||||
const sendEditBeerPostRequest = async ({
|
||||
abv,
|
||||
description,
|
||||
ibu,
|
||||
id,
|
||||
name,
|
||||
}: z.infer<typeof EditBeerPostValidationSchema>) => {
|
||||
const response = await fetch(`/api/beers/${id}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ abv, description, ibu, name, id }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`${response.status}: ${response.statusText}`);
|
||||
}
|
||||
|
||||
const json = await response.json();
|
||||
const parsed = APIResponseValidationSchema.safeParse(json);
|
||||
|
||||
if (!parsed.success) {
|
||||
throw new Error(parsed.error.message);
|
||||
}
|
||||
};
|
||||
|
||||
export default sendEditBeerPostRequest;
|
||||
@@ -1,53 +0,0 @@
|
||||
import CommentQueryResult from '@/services/schema/CommentSchema/CommentQueryResult';
|
||||
import CreateCommentValidationSchema from '@/services/schema/CommentSchema/CreateCommentValidationSchema';
|
||||
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
import { z } from 'zod';
|
||||
|
||||
const BeerStyleCommentValidationSchemaWithId = CreateCommentValidationSchema.extend({
|
||||
beerStyleId: z.string().cuid(),
|
||||
});
|
||||
|
||||
/**
|
||||
* Sends a POST request to the server to create a new beer comment.
|
||||
*
|
||||
* @param data The data to be sent to the server.
|
||||
* @param data.beerPostId The ID of the beer post to comment on.
|
||||
* @param data.content The content of the comment.
|
||||
* @param data.rating The rating of the beer.
|
||||
* @returns A promise that resolves to the created comment.
|
||||
* @throws An error if the request fails, the API response is invalid, or the API response
|
||||
* payload is invalid.
|
||||
*/
|
||||
const sendCreateBeerStyleCommentRequest = async ({
|
||||
beerStyleId,
|
||||
content,
|
||||
rating,
|
||||
}: z.infer<typeof BeerStyleCommentValidationSchemaWithId>) => {
|
||||
const response = await fetch(`/api/beers/styles/${beerStyleId}/comments`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ beerStyleId, content, rating }),
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error(response.statusText);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
const parsedResponse = APIResponseValidationSchema.safeParse(data);
|
||||
|
||||
if (!parsedResponse.success) {
|
||||
throw new Error('Invalid API response');
|
||||
}
|
||||
|
||||
const parsedPayload = CommentQueryResult.safeParse(parsedResponse.data.payload);
|
||||
|
||||
if (!parsedPayload.success) {
|
||||
throw new Error('Invalid API response payload');
|
||||
}
|
||||
|
||||
return parsedPayload.data;
|
||||
};
|
||||
|
||||
export default sendCreateBeerStyleCommentRequest;
|
||||
@@ -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<typeof CreateBreweryPostSchema>,
|
||||
) => {
|
||||
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;
|
||||
@@ -1,35 +0,0 @@
|
||||
import GetUserSchema from '@/services/users/auth/schema/GetUserSchema';
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
import { z } from 'zod';
|
||||
|
||||
interface SendEditUserRequestArgs {
|
||||
user: z.infer<typeof GetUserSchema>;
|
||||
data: {
|
||||
username: string;
|
||||
email: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
};
|
||||
}
|
||||
|
||||
const sendEditUserRequest = async ({ user, data }: SendEditUserRequestArgs) => {
|
||||
const response = await fetch(`/api/users/${user!.id}`, {
|
||||
body: JSON.stringify(data),
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
});
|
||||
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 validation failed.');
|
||||
}
|
||||
|
||||
return parsed;
|
||||
};
|
||||
|
||||
export default sendEditUserRequest;
|
||||
@@ -1,24 +0,0 @@
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
|
||||
const sendForgotPasswordRequest = async (email: string) => {
|
||||
const response = await fetch('/api/users/forgot-password', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ email }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error("Something went wrong and we couldn't send the reset link.");
|
||||
}
|
||||
|
||||
const json = await response.json();
|
||||
const parsed = APIResponseValidationSchema.safeParse(json);
|
||||
|
||||
if (!parsed.success) {
|
||||
throw new Error(parsed.error.message);
|
||||
}
|
||||
|
||||
return parsed.data;
|
||||
};
|
||||
|
||||
export default sendForgotPasswordRequest;
|
||||
@@ -1,31 +0,0 @@
|
||||
import { BasicUserInfoSchema } from '@/config/auth/types';
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
|
||||
const sendLoginUserRequest = async (data: { username: string; password: string }) => {
|
||||
const response = await fetch('/api/users/login', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
|
||||
const json: unknown = await response.json();
|
||||
|
||||
const parsed = APIResponseValidationSchema.safeParse(json);
|
||||
if (!parsed.success) {
|
||||
throw new Error('API response validation failed');
|
||||
}
|
||||
|
||||
if (!parsed.data.success) {
|
||||
throw new Error(parsed.data.message);
|
||||
}
|
||||
const parsedPayload = BasicUserInfoSchema.safeParse(parsed.data.payload);
|
||||
if (!parsedPayload.success) {
|
||||
throw new Error('API response payload validation failed');
|
||||
}
|
||||
|
||||
return parsedPayload.data;
|
||||
};
|
||||
|
||||
export default sendLoginUserRequest;
|
||||
@@ -1,33 +0,0 @@
|
||||
import { CreateUserValidationSchema } from '@/services/users/auth/schema/CreateUserValidationSchemas';
|
||||
import GetUserSchema from '@/services/users/auth/schema/GetUserSchema';
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
import { z } from 'zod';
|
||||
|
||||
async function sendRegisterUserRequest(data: z.infer<typeof CreateUserValidationSchema>) {
|
||||
const response = await fetch('/api/users/register', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
|
||||
const json = await response.json();
|
||||
const parsed = APIResponseValidationSchema.safeParse(json);
|
||||
|
||||
if (!parsed.success) {
|
||||
throw new Error('API response validation failed.');
|
||||
}
|
||||
|
||||
if (!parsed.data.success) {
|
||||
throw new Error(parsed.data.message);
|
||||
}
|
||||
|
||||
const parsedPayload = GetUserSchema.safeParse(parsed.data.payload);
|
||||
|
||||
if (!parsedPayload.success) {
|
||||
throw new Error('API response payload validation failed.');
|
||||
}
|
||||
|
||||
return parsedPayload.data;
|
||||
}
|
||||
|
||||
export default sendRegisterUserRequest;
|
||||
@@ -1,26 +0,0 @@
|
||||
import { UpdatePasswordSchema } from '@/services/users/auth/schema/CreateUserValidationSchemas';
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
import { z } from 'zod';
|
||||
|
||||
const sendUpdatePasswordRequest = async (data: z.infer<typeof UpdatePasswordSchema>) => {
|
||||
const response = await fetch('/api/users/edit-password', {
|
||||
body: JSON.stringify(data),
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
});
|
||||
|
||||
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 validation failed.');
|
||||
}
|
||||
|
||||
return parsed.data;
|
||||
};
|
||||
|
||||
export default sendUpdatePasswordRequest;
|
||||
@@ -1,25 +0,0 @@
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
import { z } from 'zod';
|
||||
|
||||
const validateEmailRequest = async (email: string) => {
|
||||
const response = await fetch(`/api/users/check-email?email=${email}`);
|
||||
const json = await response.json();
|
||||
|
||||
const parsed = APIResponseValidationSchema.safeParse(json);
|
||||
|
||||
if (!parsed.success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const parsedPayload = z
|
||||
.object({ emailIsTaken: z.boolean() })
|
||||
.safeParse(parsed.data.payload);
|
||||
|
||||
if (!parsedPayload.success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !parsedPayload.data.emailIsTaken;
|
||||
};
|
||||
|
||||
export default validateEmailRequest;
|
||||
@@ -1,16 +0,0 @@
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
|
||||
const sendUserFollowRequest = async (userId: string) => {
|
||||
const response = await fetch(`/api/users/${userId}/follow-user`, { method: 'POST' });
|
||||
const json = await response.json();
|
||||
|
||||
const parsed = APIResponseValidationSchema.safeParse(json);
|
||||
|
||||
if (!parsed.success) {
|
||||
throw new Error('Invalid API response.');
|
||||
}
|
||||
|
||||
return parsed;
|
||||
};
|
||||
|
||||
export default sendUserFollowRequest;
|
||||
118
src/requests/comments/beer-comment/index.ts
Normal file
118
src/requests/comments/beer-comment/index.ts
Normal file
@@ -0,0 +1,118 @@
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
import CommentQueryResult from '@/services/schema/CommentSchema/CommentQueryResult';
|
||||
import {
|
||||
SendCreateBeerCommentRequest,
|
||||
SendDeleteBeerPostCommentRequest,
|
||||
SendEditBeerPostCommentRequest,
|
||||
} from './types';
|
||||
|
||||
/**
|
||||
* Sends an api request to edit a beer post comment.
|
||||
*
|
||||
* @param params - The parameters for the request.
|
||||
* @param params.body - The body of the request.
|
||||
* @param params.body.content - The content of the comment.
|
||||
* @param params.body.rating - The rating of the beer.
|
||||
* @param params.commentId - The id of the comment to edit.
|
||||
* @param params.beerPostId - The id of the beer post the comment belongs to.
|
||||
* @returns The JSON response from the server.
|
||||
* @throws An error if the request fails or the response is invalid.
|
||||
*/
|
||||
export const editBeerPostCommentRequest: SendEditBeerPostCommentRequest = async ({
|
||||
body,
|
||||
commentId,
|
||||
beerPostId,
|
||||
}) => {
|
||||
const response = await fetch(`/api/beers/${beerPostId}/comments/${commentId}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify(body),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to edit comment');
|
||||
}
|
||||
|
||||
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 delete a beer post comment.
|
||||
*
|
||||
* @param params - The parameters for the request.
|
||||
* @param params.commentId - The id of the comment to delete.
|
||||
* @param params.beerPostId - The id of the beer post the comment belongs to.
|
||||
* @returns The JSON response from the server.
|
||||
* @throws An error if the request fails or the response is invalid.
|
||||
*/
|
||||
export const deleteBeerPostCommentRequest: SendDeleteBeerPostCommentRequest = async ({
|
||||
commentId,
|
||||
beerPostId,
|
||||
}) => {
|
||||
const response = await fetch(`/api/beers/${beerPostId}/comments/${commentId}`, {
|
||||
method: 'DELETE',
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error('Failed to delete comment');
|
||||
}
|
||||
|
||||
const json = await response.json();
|
||||
const parsed = APIResponseValidationSchema.safeParse(json);
|
||||
|
||||
if (!parsed.success) {
|
||||
throw new Error(parsed.error.message);
|
||||
}
|
||||
|
||||
return parsed.data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Send an api request to create a comment on a beer post.
|
||||
*
|
||||
* @param params - The parameters for the request.
|
||||
* @param params.beerPostId - The id of the beer post to create the comment on.
|
||||
* @param params.body - The body of the request.
|
||||
* @param params.body.content - The content of the comment.
|
||||
* @param params.body.rating - The rating of the beer.
|
||||
* @returns The created comment.
|
||||
* @throws An error if the request fails or the response is invalid.
|
||||
*/
|
||||
export const sendCreateBeerCommentRequest: SendCreateBeerCommentRequest = async ({
|
||||
beerPostId,
|
||||
body: { content, rating },
|
||||
}) => {
|
||||
const response = await fetch(`/api/beers/${beerPostId}/comments`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ beerPostId, content, rating }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(response.statusText);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const parsedResponse = APIResponseValidationSchema.safeParse(data);
|
||||
|
||||
if (!parsedResponse.success) {
|
||||
throw new Error('Invalid API response');
|
||||
}
|
||||
|
||||
const parsedPayload = CommentQueryResult.safeParse(parsedResponse.data.payload);
|
||||
|
||||
if (!parsedPayload.success) {
|
||||
throw new Error('Invalid API response payload');
|
||||
}
|
||||
|
||||
return parsedPayload.data;
|
||||
};
|
||||
|
||||
export default sendCreateBeerCommentRequest;
|
||||
19
src/requests/comments/beer-comment/types/index.ts
Normal file
19
src/requests/comments/beer-comment/types/index.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import CommentQueryResult from '@/services/schema/CommentSchema/CommentQueryResult';
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
import { z } from 'zod';
|
||||
|
||||
export type SendEditBeerPostCommentRequest = (args: {
|
||||
body: { content: string; rating: number };
|
||||
commentId: string;
|
||||
beerPostId: string;
|
||||
}) => Promise<z.infer<typeof APIResponseValidationSchema>>;
|
||||
|
||||
export type SendDeleteBeerPostCommentRequest = (args: {
|
||||
commentId: string;
|
||||
beerPostId: string;
|
||||
}) => Promise<z.infer<typeof APIResponseValidationSchema>>;
|
||||
|
||||
export type SendCreateBeerCommentRequest = (args: {
|
||||
beerPostId: string;
|
||||
body: { content: string; rating: number };
|
||||
}) => Promise<z.infer<typeof CommentQueryResult>>;
|
||||
117
src/requests/comments/beer-style-comment/index.ts
Normal file
117
src/requests/comments/beer-style-comment/index.ts
Normal file
@@ -0,0 +1,117 @@
|
||||
import CommentQueryResult from '@/services/schema/CommentSchema/CommentQueryResult';
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
import {
|
||||
SendCreateBeerStyleCommentRequest,
|
||||
SendDeleteBeerStyleCommentRequest,
|
||||
SendEditBeerStyleCommentRequest,
|
||||
} from './types';
|
||||
|
||||
/**
|
||||
* Sends an api request to edit a beer style comment.
|
||||
*
|
||||
* @param params - The parameters for the request.
|
||||
* @param params.body - The body of the request.
|
||||
* @param params.body.content - The content of the comment.
|
||||
* @param params.body.rating - The rating of the beer.
|
||||
* @param params.beerStyleId - The id of the beer style the comment belongs to.
|
||||
* @param params.commentId - The id of the comment to edit.
|
||||
* @returns The JSON response from the server.
|
||||
* @throws An error if the request fails or the response is invalid.
|
||||
*/
|
||||
export const sendEditBeerStyleCommentRequest: SendEditBeerStyleCommentRequest = async ({
|
||||
commentId,
|
||||
body: { content, rating },
|
||||
beerStyleId,
|
||||
}) => {
|
||||
const response = await fetch(`/api/beers/styles/${beerStyleId}/comments/${commentId}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ content, rating }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(response.statusText);
|
||||
}
|
||||
|
||||
const json = await response.json();
|
||||
|
||||
const parsed = APIResponseValidationSchema.safeParse(json);
|
||||
|
||||
if (!parsed.success) {
|
||||
throw new Error('Invalid API response');
|
||||
}
|
||||
|
||||
return parsed.data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sends an api request to delete a beer style comment.
|
||||
*
|
||||
* @param params - The parameters for the request.
|
||||
* @param params.beerStyleId - The id of the beer style the comment belongs to.
|
||||
* @param params.commentId - The id of the comment to delete.
|
||||
* @returns The json response from the server.
|
||||
* @throws An error if the request fails or the response is invalid.
|
||||
*/
|
||||
export const sendDeleteBeerStyleCommentRequest: SendDeleteBeerStyleCommentRequest =
|
||||
async ({ beerStyleId, commentId }) => {
|
||||
const response = await fetch(
|
||||
`/api/beers/styles/${beerStyleId}/comments/${commentId}`,
|
||||
{
|
||||
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('Invalid API response');
|
||||
}
|
||||
|
||||
return parsed.data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sends an api request to create a beer style comment.
|
||||
*
|
||||
* @param params - The parameters for the request.
|
||||
* @param params.body - The body of the request.
|
||||
* @param params.body.content - The content of the comment.
|
||||
* @param params.body.rating - The rating of the beer.
|
||||
* @param params.beerStyleId - The id of the beer style the comment belongs to.
|
||||
* @returns The created comment.
|
||||
* @throws An error if the request fails or the response is invalid.
|
||||
*/
|
||||
export const sendCreateBeerStyleCommentRequest: SendCreateBeerStyleCommentRequest =
|
||||
async ({ beerStyleId, body: { content, rating } }) => {
|
||||
const response = await fetch(`/api/beers/styles/${beerStyleId}/comments`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ beerStyleId, content, rating }),
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error(response.statusText);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
const parsedResponse = APIResponseValidationSchema.safeParse(data);
|
||||
|
||||
if (!parsedResponse.success) {
|
||||
throw new Error('Invalid API response');
|
||||
}
|
||||
|
||||
const parsedPayload = CommentQueryResult.safeParse(parsedResponse.data.payload);
|
||||
|
||||
if (!parsedPayload.success) {
|
||||
throw new Error('Invalid API response payload');
|
||||
}
|
||||
|
||||
return parsedPayload.data;
|
||||
};
|
||||
19
src/requests/comments/beer-style-comment/types/index.ts
Normal file
19
src/requests/comments/beer-style-comment/types/index.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import CommentQueryResult from '@/services/schema/CommentSchema/CommentQueryResult';
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
import { z } from 'zod';
|
||||
|
||||
export type SendEditBeerStyleCommentRequest = (args: {
|
||||
body: { content: string; rating: number };
|
||||
commentId: string;
|
||||
beerStyleId: string;
|
||||
}) => Promise<z.infer<typeof APIResponseValidationSchema>>;
|
||||
|
||||
export type SendDeleteBeerStyleCommentRequest = (args: {
|
||||
commentId: string;
|
||||
beerStyleId: string;
|
||||
}) => Promise<z.infer<typeof APIResponseValidationSchema>>;
|
||||
|
||||
export type SendCreateBeerStyleCommentRequest = (args: {
|
||||
beerStyleId: string;
|
||||
body: { content: string; rating: number };
|
||||
}) => Promise<z.infer<typeof CommentQueryResult>>;
|
||||
109
src/requests/comments/brewery-comment/index.ts
Normal file
109
src/requests/comments/brewery-comment/index.ts
Normal file
@@ -0,0 +1,109 @@
|
||||
import CommentQueryResult from '@/services/schema/CommentSchema/CommentQueryResult';
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
import {
|
||||
SendCreateBreweryPostCommentRequest,
|
||||
SendDeleteBreweryPostCommentRequest,
|
||||
SendEditBreweryPostCommentRequest,
|
||||
} from './types';
|
||||
/**
|
||||
* Sends an api request to edit a brewery comment.
|
||||
*
|
||||
* @param params - The parameters for the request.
|
||||
* @param params.breweryId - The id of the brewery the comment belongs to.
|
||||
* @param params.commentId - The id of the comment to edit.
|
||||
* @param params.body - The body of the request.
|
||||
* @param params.body.content - The content of the comment.
|
||||
* @param params.body.rating - The rating of the beer.
|
||||
*/
|
||||
export const sendEditBreweryPostCommentRequest: SendEditBreweryPostCommentRequest =
|
||||
async ({ body: { content, rating }, breweryPostId, commentId }) => {
|
||||
const response = await fetch(
|
||||
`/api/breweries/${breweryPostId}/comments/${commentId}`,
|
||||
{
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ content, rating }),
|
||||
},
|
||||
);
|
||||
|
||||
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 delete a brewery comment.
|
||||
*
|
||||
* @param params - The parameters for the request.
|
||||
* @param params.breweryId - The id of the brewery the comment belongs to.
|
||||
* @param params.commentId - The id of the comment to delete.
|
||||
* @returns The JSON response from the server.
|
||||
* @throws An error if the request fails or the response is invalid.
|
||||
*/
|
||||
export const sendDeleteBreweryPostCommentRequest: SendDeleteBreweryPostCommentRequest =
|
||||
async ({ breweryPostId, commentId }) => {
|
||||
const response = await fetch(
|
||||
`/api/breweries/${breweryPostId}/comments/${commentId}`,
|
||||
{
|
||||
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 comment.
|
||||
*
|
||||
* @param params - The parameters for the request.
|
||||
* @param params.body - The body of the request.
|
||||
* @param params.body.content - The content of the comment.
|
||||
* @param params.body.rating - The rating of the beer.
|
||||
* @param params.breweryId - The id of the brewery the comment belongs to.
|
||||
* @returns The created comment.
|
||||
* @throws An error if the request fails or the response is invalid.
|
||||
*/
|
||||
export const sendCreateBreweryCommentRequest: SendCreateBreweryPostCommentRequest =
|
||||
async ({ body: { content, rating }, breweryPostId }) => {
|
||||
const response = await fetch(`/api/breweries/${breweryPostId}/comments`, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ content, rating }),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(response.statusText);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
const parsedResponse = APIResponseValidationSchema.safeParse(data);
|
||||
if (!parsedResponse.success) {
|
||||
throw new Error('Invalid API response');
|
||||
}
|
||||
|
||||
const parsedPayload = CommentQueryResult.safeParse(parsedResponse.data.payload);
|
||||
if (!parsedPayload.success) {
|
||||
throw new Error('Invalid API response payload');
|
||||
}
|
||||
|
||||
return parsedPayload.data;
|
||||
};
|
||||
19
src/requests/comments/brewery-comment/types/index.ts
Normal file
19
src/requests/comments/brewery-comment/types/index.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import CommentQueryResult from '@/services/schema/CommentSchema/CommentQueryResult';
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
import { z } from 'zod';
|
||||
|
||||
export type SendEditBreweryPostCommentRequest = (args: {
|
||||
body: { content: string; rating: number };
|
||||
commentId: string;
|
||||
breweryPostId: string;
|
||||
}) => Promise<z.infer<typeof APIResponseValidationSchema>>;
|
||||
|
||||
export type SendDeleteBreweryPostCommentRequest = (args: {
|
||||
commentId: string;
|
||||
breweryPostId: string;
|
||||
}) => Promise<z.infer<typeof APIResponseValidationSchema>>;
|
||||
|
||||
export type SendCreateBreweryPostCommentRequest = (args: {
|
||||
breweryPostId: string;
|
||||
body: { content: string; rating: number };
|
||||
}) => Promise<z.infer<typeof CommentQueryResult>>;
|
||||
134
src/requests/posts/beer-post/index.ts
Normal file
134
src/requests/posts/beer-post/index.ts
Normal file
@@ -0,0 +1,134 @@
|
||||
import BeerPostQueryResult from '@/services/posts/beer-post/schema/BeerPostQueryResult';
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
import {
|
||||
SendCreateBeerPostRequest,
|
||||
SendDeleteBeerPostRequest,
|
||||
SendEditBeerPostRequest,
|
||||
} from './types';
|
||||
|
||||
/**
|
||||
* Sends a POST request to create a new beer post.
|
||||
*
|
||||
* @example
|
||||
* const beerPost = await sendCreateBeerPostRequest({
|
||||
* body: {
|
||||
* abv: 5.5,
|
||||
* description: 'A golden delight with a touch of citrus.',
|
||||
* ibu: 30,
|
||||
* name: 'Yerb Sunshine Ale',
|
||||
* },
|
||||
* styleId: 'clqmteqxc000008jphoy31wqw',
|
||||
* breweryId: 'clqmtexfb000108jp3nsg26c6',
|
||||
* });
|
||||
*
|
||||
* @param data - The data to send in the request.
|
||||
* @param data.body - The body of the request.
|
||||
* @param data.body.abv - The ABV of the beer.
|
||||
* @param data.body.description - The description of the beer.
|
||||
* @param data.body.ibu - The IBU of the beer.
|
||||
* @param data.body.name - The name of the beer.
|
||||
* @param data.styleId - The ID of the style of the beer.
|
||||
* @param data.breweryId - The ID of the brewery of the beer.
|
||||
* @returns The created beer post.
|
||||
* @throws An error if the request fails or the response is invalid.
|
||||
*/
|
||||
export const sendCreateBeerPostRequest: SendCreateBeerPostRequest = async ({
|
||||
body: { abv, description, ibu, name },
|
||||
styleId,
|
||||
breweryId,
|
||||
}) => {
|
||||
const response = await fetch('/api/beers/create', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ abv, description, ibu, name, styleId, breweryId }),
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error(response.statusText);
|
||||
}
|
||||
const json = await response.json();
|
||||
const parsed = APIResponseValidationSchema.safeParse(json);
|
||||
if (!parsed.success) {
|
||||
throw new Error('Invalid API response');
|
||||
}
|
||||
const { payload, success, message } = parsed.data;
|
||||
if (!success) {
|
||||
throw new Error(message);
|
||||
}
|
||||
const parsedPayload = BeerPostQueryResult.safeParse(payload);
|
||||
if (!parsedPayload.success) {
|
||||
throw new Error('Invalid API response payload');
|
||||
}
|
||||
return parsedPayload.data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sends a DELETE request to delete a beer post.
|
||||
*
|
||||
* @example
|
||||
* const response = await sendDeleteBeerPostRequest({
|
||||
* beerPostId: 'clqmtexfb000108jp3nsg26c6',
|
||||
* });
|
||||
*
|
||||
* @param args - The arguments to send in the request.
|
||||
* @param args.beerPostId - The ID of the beer post to delete.
|
||||
* @returns The response from the server.
|
||||
* @throws An error if the request fails or the response is invalid.
|
||||
*/
|
||||
export const sendDeleteBeerPostRequest: SendDeleteBeerPostRequest = async ({
|
||||
beerPostId,
|
||||
}) => {
|
||||
const response = await fetch(`/api/beers/${beerPostId}`, { 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('Could not successfully parse the response.');
|
||||
}
|
||||
return parsed.data;
|
||||
};
|
||||
|
||||
/**
|
||||
* Sends a PUT request to edit a beer post.
|
||||
*
|
||||
* @example
|
||||
* const response = await sendEditBeerPostRequest({
|
||||
* beerPostId: 'clqmtexfb000108jp3nsg26c6',
|
||||
* body: {
|
||||
* abv: 5.5,
|
||||
* description: 'A golden delight with a touch of citrus.',
|
||||
* ibu: 30,
|
||||
* name: 'Yerb Sunshine Ale',
|
||||
* },
|
||||
* });
|
||||
*
|
||||
* @param args - The arguments to send in the request.
|
||||
* @param args.beerPostId - The ID of the beer post to edit.
|
||||
* @param args.body - The body of the request.
|
||||
* @param args.body.abv - The ABV of the beer.
|
||||
* @param args.body.description - The description of the beer.
|
||||
* @param args.body.ibu - The IBU of the beer.
|
||||
* @param args.body.name - The name of the beer.
|
||||
* @returns The response from the server.
|
||||
* @throws An error if the request fails or the response is invalid.
|
||||
*/
|
||||
export const sendEditBeerPostRequest: SendEditBeerPostRequest = async ({
|
||||
beerPostId,
|
||||
body: { abv, description, ibu, name },
|
||||
}) => {
|
||||
const response = await fetch(`/api/beers/${beerPostId}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ abv, description, ibu, name }),
|
||||
});
|
||||
if (!response.ok) {
|
||||
throw new Error(response.statusText);
|
||||
}
|
||||
const json = await response.json();
|
||||
const parsed = APIResponseValidationSchema.safeParse(json);
|
||||
if (!parsed.success) {
|
||||
throw new Error('Invalid API response');
|
||||
}
|
||||
return parsed.data;
|
||||
};
|
||||
31
src/requests/posts/beer-post/types/index.ts
Normal file
31
src/requests/posts/beer-post/types/index.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import BeerPostQueryResult from '@/services/posts/beer-post/schema/BeerPostQueryResult';
|
||||
import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema';
|
||||
import { z } from 'zod';
|
||||
|
||||
type BeerPostQueryResultT = z.infer<typeof BeerPostQueryResult>;
|
||||
type APIResponse = z.infer<typeof APIResponseValidationSchema>;
|
||||
|
||||
export type SendCreateBeerPostRequest = (data: {
|
||||
body: {
|
||||
abv: number;
|
||||
description: string;
|
||||
ibu: number;
|
||||
name: string;
|
||||
};
|
||||
styleId: string;
|
||||
breweryId: string;
|
||||
}) => Promise<BeerPostQueryResultT>;
|
||||
|
||||
export type SendDeleteBeerPostRequest = (args: {
|
||||
beerPostId: string;
|
||||
}) => Promise<APIResponse>;
|
||||
|
||||
export type SendEditBeerPostRequest = (args: {
|
||||
beerPostId: string;
|
||||
body: {
|
||||
abv: number;
|
||||
description: string;
|
||||
ibu: number;
|
||||
name: string;
|
||||
};
|
||||
}) => Promise<APIResponse>;
|
||||
105
src/requests/posts/brewery-post/index.ts
Normal file
105
src/requests/posts/brewery-post/index.ts
Normal file
@@ -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;
|
||||
};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user