diff --git a/next.config.js b/next.config.js index 79a0359..39d2b47 100644 --- a/next.config.js +++ b/next.config.js @@ -5,5 +5,8 @@ const nextConfig = { domains: ['picsum.photos', 'res.cloudinary.com'], }, }; +const withBundleAnalyzer = require('@next/bundle-analyzer')({ + enabled: process.env.ANALYZE === 'true', +}); -module.exports = nextConfig; +module.exports = withBundleAnalyzer(nextConfig); diff --git a/package-lock.json b/package-lock.json index ba81f1f..1cfce31 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,6 +13,7 @@ "@headlessui/tailwindcss": "^0.1.3", "@hookform/resolvers": "^3.1.0", "@mapbox/mapbox-sdk": "^0.15.1", + "@next/bundle-analyzer": "^13.4.3", "@prisma/client": "^4.13.0", "@react-email/components": "^0.0.6", "@react-email/render": "^0.0.7", @@ -996,6 +997,14 @@ "node": ">=6.0.0" } }, + "node_modules/@next/bundle-analyzer": { + "version": "13.4.3", + "resolved": "https://registry.npmjs.org/@next/bundle-analyzer/-/bundle-analyzer-13.4.3.tgz", + "integrity": "sha512-jzWk6eaCFaIXfIswyQQWnR6FN22HpWoSWe3nLa3JCNkNd2ksriJgn86oQyZRxgAPaEbVKQXBp8GZi8e5DrhVJg==", + "dependencies": { + "webpack-bundle-analyzer": "4.7.0" + } + }, "node_modules/@next/env": { "version": "13.3.4", "resolved": "https://registry.npmjs.org/@next/env/-/env-13.3.4.tgz", @@ -1352,6 +1361,11 @@ "url": "https://opencollective.com/unts" } }, + "node_modules/@polka/url": { + "version": "1.0.0-next.21", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", + "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==" + }, "node_modules/@prisma/client": { "version": "4.13.0", "resolved": "https://registry.npmjs.org/@prisma/client/-/client-4.13.0.tgz", @@ -2382,7 +2396,6 @@ "version": "8.8.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", - "devOptional": true, "bin": { "acorn": "bin/acorn" }, @@ -2432,7 +2445,6 @@ "version": "8.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "devOptional": true, "engines": { "node": ">=0.4.0" } @@ -4162,6 +4174,11 @@ "node": ">=12" } }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + }, "node_modules/duplexer2": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", @@ -5779,6 +5796,20 @@ "resolved": "https://registry.npmjs.org/grid-index/-/grid-index-1.1.0.tgz", "integrity": "sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA==" }, + "node_modules/gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -7807,6 +7838,14 @@ "node": ">=4" } }, + "node_modules/mrmime": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", + "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==", + "engines": { + "node": ">=10" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -8281,6 +8320,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "bin": { + "opener": "bin/opener-bin.js" + } + }, "node_modules/optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", @@ -10032,6 +10079,19 @@ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==" }, + "node_modules/sirv": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.19.tgz", + "integrity": "sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==", + "dependencies": { + "@polka/url": "^1.0.0-next.20", + "mrmime": "^1.0.0", + "totalist": "^1.0.0" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -10648,6 +10708,14 @@ "node": ">=0.6" } }, + "node_modules/totalist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", + "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==", + "engines": { + "node": ">=6" + } + }, "node_modules/tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", @@ -11294,6 +11362,36 @@ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, + "node_modules/webpack-bundle-analyzer": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.7.0.tgz", + "integrity": "sha512-j9b8ynpJS4K+zfO5GGwsAcQX4ZHpWV+yRiHDiL+bE0XHJ8NiPYLTNVQdlFYWxtpg9lfAQNlwJg16J9AJtFSXRg==", + "dependencies": { + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "chalk": "^4.1.0", + "commander": "^7.2.0", + "gzip-size": "^6.0.0", + "lodash": "^4.17.20", + "opener": "^1.5.2", + "sirv": "^1.0.7", + "ws": "^7.3.1" + }, + "bin": { + "webpack-bundle-analyzer": "lib/bin/analyzer.js" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/webpack-bundle-analyzer/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "engines": { + "node": ">= 10" + } + }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", @@ -11390,6 +11488,26 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/xregexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", @@ -12050,6 +12168,14 @@ "resolved": "https://registry.npmjs.org/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz", "integrity": "sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==" }, + "@next/bundle-analyzer": { + "version": "13.4.3", + "resolved": "https://registry.npmjs.org/@next/bundle-analyzer/-/bundle-analyzer-13.4.3.tgz", + "integrity": "sha512-jzWk6eaCFaIXfIswyQQWnR6FN22HpWoSWe3nLa3JCNkNd2ksriJgn86oQyZRxgAPaEbVKQXBp8GZi8e5DrhVJg==", + "requires": { + "webpack-bundle-analyzer": "4.7.0" + } + }, "@next/env": { "version": "13.3.4", "resolved": "https://registry.npmjs.org/@next/env/-/env-13.3.4.tgz", @@ -12272,6 +12398,11 @@ "tslib": "^2.5.0" } }, + "@polka/url": { + "version": "1.0.0-next.21", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", + "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==" + }, "@prisma/client": { "version": "4.13.0", "resolved": "https://registry.npmjs.org/@prisma/client/-/client-4.13.0.tgz", @@ -13113,8 +13244,7 @@ "acorn": { "version": "8.8.2", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", - "devOptional": true + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==" }, "acorn-jsx": { "version": "5.3.2", @@ -13148,8 +13278,7 @@ "acorn-walk": { "version": "8.2.0", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "devOptional": true + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==" }, "agent-base": { "version": "6.0.2", @@ -14373,6 +14502,11 @@ "integrity": "sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A==", "dev": true }, + "duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==" + }, "duplexer2": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", @@ -15628,6 +15762,14 @@ "resolved": "https://registry.npmjs.org/grid-index/-/grid-index-1.1.0.tgz", "integrity": "sha512-HZRwumpOGUrHyxO5bqKZL0B0GlUpwtCAzZ42sgxUPniu33R1LSFH5yrIcBCHjkctCAh3mtWKcKd9J4vDDdeVHA==" }, + "gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "requires": { + "duplexer": "^0.1.2" + } + }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -17009,6 +17151,11 @@ "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", "dev": true }, + "mrmime": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.1.tgz", + "integrity": "sha512-hzzEagAgDyoU1Q6yg5uI+AorQgdvMCur3FcKf7NhMKWsaYg+RnbTyHRa/9IlLF9rf455MOCtcqqrQQ83pPP7Uw==" + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -17328,6 +17475,11 @@ "is-wsl": "^2.2.0" } }, + "opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==" + }, "optionator": { "version": "0.9.1", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", @@ -18528,6 +18680,16 @@ } } }, + "sirv": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.19.tgz", + "integrity": "sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==", + "requires": { + "@polka/url": "^1.0.0-next.20", + "mrmime": "^1.0.0", + "totalist": "^1.0.0" + } + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -18995,6 +19157,11 @@ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "optional": true }, + "totalist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", + "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==" + }, "tough-cookie": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", @@ -19457,6 +19624,29 @@ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" }, + "webpack-bundle-analyzer": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.7.0.tgz", + "integrity": "sha512-j9b8ynpJS4K+zfO5GGwsAcQX4ZHpWV+yRiHDiL+bE0XHJ8NiPYLTNVQdlFYWxtpg9lfAQNlwJg16J9AJtFSXRg==", + "requires": { + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "chalk": "^4.1.0", + "commander": "^7.2.0", + "gzip-size": "^6.0.0", + "lodash": "^4.17.20", + "opener": "^1.5.2", + "sirv": "^1.0.7", + "ws": "^7.3.1" + }, + "dependencies": { + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==" + } + } + }, "whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", @@ -19532,6 +19722,12 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "ws": { + "version": "7.5.9", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "requires": {} + }, "xregexp": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", diff --git a/package.json b/package.json index 7f1b4a2..ae633c8 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "@headlessui/tailwindcss": "^0.1.3", "@hookform/resolvers": "^3.1.0", "@mapbox/mapbox-sdk": "^0.15.1", + "@next/bundle-analyzer": "^13.4.3", "@prisma/client": "^4.13.0", "@react-email/components": "^0.0.6", "@react-email/render": "^0.0.7", diff --git a/src/components/Account/AccountInfo.tsx b/src/components/Account/AccountInfo.tsx index 52ac646..570c715 100644 --- a/src/components/Account/AccountInfo.tsx +++ b/src/components/Account/AccountInfo.tsx @@ -1,5 +1,5 @@ -import validateEmail from '@/requests/valdiateEmail'; -import validateUsername from '@/requests/validateUsername'; +import validateEmailRequest from '@/requests/User/validateEmailRequest'; +import validateUsernameRequest from '@/requests/validateUsernameRequest'; import { BaseCreateUserSchema } from '@/services/User/schema/CreateUserValidationSchemas'; import GetUserSchema from '@/services/User/schema/GetUserSchema'; import { Switch } from '@headlessui/react'; @@ -31,7 +31,7 @@ const AccountInfo: FC = ({ user }) => { .refine( async (email) => { if (user.email === email) return true; - return validateEmail(email); + return validateEmailRequest(email); }, { message: 'Email is already taken.' }, ), @@ -42,7 +42,7 @@ const AccountInfo: FC = ({ user }) => { .refine( async (username) => { if (user.username === username) return true; - return validateUsername(username); + return validateUsernameRequest(username); }, { message: 'Username is already taken.' }, ), diff --git a/src/components/BeerBreweryComments/EditCommentBody.tsx b/src/components/BeerBreweryComments/EditCommentBody.tsx index 4b3938b..5bb1e85 100644 --- a/src/components/BeerBreweryComments/EditCommentBody.tsx +++ b/src/components/BeerBreweryComments/EditCommentBody.tsx @@ -1,5 +1,5 @@ import { zodResolver } from '@hookform/resolvers/zod'; -import { FC, useState, Dispatch, SetStateAction, useContext } from 'react'; +import { FC, useState, Dispatch, SetStateAction } from 'react'; import { Rating } from 'react-daisyui'; import { useForm, SubmitHandler } from 'react-hook-form'; import { z } from 'zod'; @@ -7,7 +7,7 @@ import useBeerPostComments from '@/hooks/data-fetching/beer-comments/useBeerPost import CommentQueryResult from '@/services/types/CommentSchema/CommentQueryResult'; import CreateCommentValidationSchema from '@/services/types/CommentSchema/CreateCommentValidationSchema'; import useBreweryPostComments from '@/hooks/data-fetching/brewery-comments/useBreweryPostComments'; -import ToastContext from '@/contexts/ToastContext'; +import toast from 'react-hot-toast'; import FormError from '../ui/forms/FormError'; import FormInfo from '../ui/forms/FormInfo'; import FormLabel from '../ui/forms/FormLabel'; @@ -43,7 +43,6 @@ const EditCommentBody: FC = ({ resolver: zodResolver(CreateCommentValidationSchema), }); - const { toast } = useContext(ToastContext); const { errors } = formState; const [isDeleting, setIsDeleting] = useState(false); diff --git a/src/components/BeerById/BeerCommentForm.tsx b/src/components/BeerById/BeerCommentForm.tsx index 34357e1..871b93a 100644 --- a/src/components/BeerById/BeerCommentForm.tsx +++ b/src/components/BeerById/BeerCommentForm.tsx @@ -1,4 +1,4 @@ -import sendCreateBeerCommentRequest from '@/requests/sendCreateBeerCommentRequest'; +import sendCreateBeerCommentRequest from '@/requests/BeerComment/sendCreateBeerCommentRequest'; import beerPostQueryResult from '@/services/BeerPost/schema/BeerPostQueryResult'; import { zodResolver } from '@hookform/resolvers/zod'; @@ -9,6 +9,7 @@ import { z } from 'zod'; import useBeerPostComments from '@/hooks/data-fetching/beer-comments/useBeerPostComments'; import CreateCommentValidationSchema from '@/services/types/CommentSchema/CreateCommentValidationSchema'; +import toast from 'react-hot-toast'; import CommentForm from '../ui/CommentForm'; interface BeerCommentFormProps { @@ -30,13 +31,22 @@ const BeerCommentForm: FunctionComponent = ({ const onSubmit: SubmitHandler> = async ( data, ) => { - await sendCreateBeerCommentRequest({ - content: data.content, - rating: data.rating, - beerPostId: beerPost.id, - }); - await mutate(); - reset(); + try { + await sendCreateBeerCommentRequest({ + content: data.content, + rating: data.rating, + beerPostId: beerPost.id, + }); + await mutate(); + reset(); + toast.success('Created a new comment!'); + } catch (error) { + const errorMessage = + error instanceof Error ? error.message : 'Something went wrong.'; + toast.error(errorMessage); + + reset(); + } }; return ( diff --git a/src/components/BeerById/BeerPostLikeButton.tsx b/src/components/BeerById/BeerPostLikeButton.tsx index 14a2070..a24eedb 100644 --- a/src/components/BeerById/BeerPostLikeButton.tsx +++ b/src/components/BeerById/BeerPostLikeButton.tsx @@ -1,8 +1,9 @@ import useCheckIfUserLikesBeerPost from '@/hooks/data-fetching/beer-likes/useCheckIfUserLikesBeerPost'; -import sendBeerPostLikeRequest from '@/requests/sendBeerPostLikeRequest'; + import { FC, useEffect, useState } from 'react'; import useGetBeerPostLikeCount from '@/hooks/data-fetching/beer-likes/useBeerPostLikeCount'; +import sendBeerPostLikeRequest from '@/requests/BeerPost/sendBeerPostLikeRequest'; import LikeButton from '../ui/LikeButton'; const BeerPostLikeButton: FC<{ diff --git a/src/components/BreweryById/BreweryCommentsSection.tsx b/src/components/BreweryById/BreweryCommentsSection.tsx index 80c770b..d00c035 100644 --- a/src/components/BreweryById/BreweryCommentsSection.tsx +++ b/src/components/BreweryById/BreweryCommentsSection.tsx @@ -9,7 +9,7 @@ import APIResponseValidationSchema from '@/validation/APIResponseValidationSchem import CommentQueryResult from '@/services/types/CommentSchema/CommentQueryResult'; import useBreweryPostComments from '@/hooks/data-fetching/brewery-comments/useBreweryPostComments'; -import ToastContext from '@/contexts/ToastContext'; +import toast from 'react-hot-toast'; import LoadingComponent from '../BeerById/LoadingComponent'; import CommentsComponent from '../ui/CommentsComponent'; import CommentForm from '../ui/CommentForm'; @@ -64,7 +64,6 @@ const BreweryCommentForm: FC = ({ breweryPost, mutate } resolver: zodResolver(CreateCommentValidationSchema), }); - const { toast } = useContext(ToastContext); const onSubmit: SubmitHandler> = async ( data, ) => { diff --git a/src/components/BreweryIndex/BreweryPostLikeButton.tsx b/src/components/BreweryIndex/BreweryPostLikeButton.tsx index 0a58b04..c52c263 100644 --- a/src/components/BreweryIndex/BreweryPostLikeButton.tsx +++ b/src/components/BreweryIndex/BreweryPostLikeButton.tsx @@ -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/sendBreweryPostLikeRequest'; +import sendBreweryPostLikeRequest from '@/requests/BreweryPostLike/sendBreweryPostLikeRequest'; import { FC, useState } from 'react'; import LikeButton from '../ui/LikeButton'; diff --git a/src/components/CreateBeerPostForm.tsx b/src/components/CreateBeerPostForm.tsx index e45c12b..a7ff91c 100644 --- a/src/components/CreateBeerPostForm.tsx +++ b/src/components/CreateBeerPostForm.tsx @@ -1,15 +1,17 @@ import { zodResolver } from '@hookform/resolvers/zod'; import { BeerType } from '@prisma/client'; import router from 'next/router'; -import { FunctionComponent, useState } from 'react'; +import { FunctionComponent } from 'react'; import { useForm, SubmitHandler, FieldError } from 'react-hook-form'; import { z } from 'zod'; import BreweryPostQueryResult from '@/services/BreweryPost/types/BreweryPostQueryResult'; import CreateBeerPostValidationSchema from '@/services/BeerPost/schema/CreateBeerPostValidationSchema'; -import sendCreateBeerPostRequest from '@/requests/sendCreateBeerPostRequest'; +import sendCreateBeerPostRequest from '@/requests/BeerPost/sendCreateBeerPostRequest'; import UploadImageValidationSchema from '@/services/types/ImageSchema/UploadImageValidationSchema'; -import sendUploadBeerImagesRequest from '@/requests/sendUploadBeerImageRequest'; -import ErrorAlert from './ui/alerts/ErrorAlert'; +import sendUploadBeerImagesRequest from '@/requests/BeerImage/sendUploadBeerImageRequest'; + +import toast from 'react-hot-toast'; + import Button from './ui/forms/Button'; import FormError from './ui/forms/FormError'; import FormInfo from './ui/forms/FormInfo'; @@ -40,7 +42,6 @@ const CreateBeerPostForm: FunctionComponent = ({ }); const { errors, isSubmitting } = formState; - const [error, setError] = useState(''); const onSubmit: SubmitHandler< z.infer @@ -52,19 +53,17 @@ const CreateBeerPostForm: FunctionComponent = ({ try { const response = await sendCreateBeerPostRequest(data); await sendUploadBeerImagesRequest({ beerPost: response, images: data.images }); - router.push(`/beers/${response.id}`); + await router.push(`/beers/${response.id}`); + toast.success('Created beer post.'); } catch (e) { - if (!(e instanceof Error)) { - setError('Something went wrong'); - return; - } - setError(e.message); + const errorMessage = e instanceof Error ? e.message : 'Something went wrong.'; + + toast.error(errorMessage); } }; return (
-
{error && }
Name {errors.name?.message} diff --git a/src/components/EditBeerPostForm.tsx b/src/components/EditBeerPostForm.tsx index 195dad2..1897c8f 100644 --- a/src/components/EditBeerPostForm.tsx +++ b/src/components/EditBeerPostForm.tsx @@ -1,12 +1,14 @@ -import sendEditBeerPostRequest from '@/requests/sendEditBeerPostRequest'; -import EditBeerPostValidationSchema from '@/services/BeerPost/schema/EditBeerPostValidationSchema'; -import { zodResolver } from '@hookform/resolvers/zod'; +import { FC } from 'react'; import { useRouter } from 'next/router'; -import { FC, useState } from 'react'; -import { useForm, SubmitHandler } from 'react-hook-form'; +import toast from 'react-hot-toast'; import { z } from 'zod'; -import ErrorAlert from './ui/alerts/ErrorAlert'; +import { useForm, SubmitHandler } from 'react-hook-form'; +import { zodResolver } from '@hookform/resolvers/zod'; + +import deleteBeerPostRequest from '@/requests/BeerPost/deleteBeerPostRequest'; +import EditBeerPostValidationSchema from '@/services/BeerPost/schema/EditBeerPostValidationSchema'; +import sendEditBeerPostRequest from '@/requests/BeerPost/sendEditBeerPostRequest'; import Button from './ui/forms/Button'; import FormError from './ui/forms/FormError'; import FormInfo from './ui/forms/FormInfo'; @@ -23,54 +25,36 @@ interface EditBeerPostFormProps { const EditBeerPostForm: FC = ({ previousValues }) => { const router = useRouter(); - const { - register, - handleSubmit, - formState: { errors }, - } = useForm({ + const { register, handleSubmit, formState } = useForm({ resolver: zodResolver(EditBeerPostValidationSchema), defaultValues: previousValues, }); - const [error, setError] = useState(''); - const [isSubmitting, setIsSubmitting] = useState(false); - + const { isSubmitting, errors } = formState; const onSubmit: SubmitHandler = async (data) => { try { - setIsSubmitting(true); await sendEditBeerPostRequest(data); - router.push(`/beers/${data.id}`); + await router.push(`/beers/${data.id}`); + toast.success('Edited beer post.'); } catch (e) { - setIsSubmitting(false); - if (!(e instanceof Error)) { - setError('Something went wrong'); - return; - } - setError(e.message); + const errorMessage = e instanceof Error ? e.message : 'Something went wrong.'; + toast.error(errorMessage); + await router.push(`/beers/${data.id}`); } }; const onDelete = async () => { try { - const response = await fetch(`/api/beers/${previousValues.id}`, { - method: 'DELETE', - }); - if (response.status === 200) { - router.push('/beers'); - } + await deleteBeerPostRequest(previousValues.id); + await router.push('/beers'); } catch (e) { - if (!(e instanceof Error)) { - setError('Something went wrong'); - return; - } - setError(e.message); + const errorMessage = e instanceof Error ? e.message : 'Something went wrong.'; + toast.error(errorMessage); + await router.push(`/beers`); } }; return ( -
- {error && } -
Name {errors.name?.message} diff --git a/src/components/Login/LoginForm.tsx b/src/components/Login/LoginForm.tsx index 915f2e8..b841553 100644 --- a/src/components/Login/LoginForm.tsx +++ b/src/components/Login/LoginForm.tsx @@ -1,13 +1,14 @@ -import sendLoginUserRequest from '@/requests/sendLoginUserRequest'; +import sendLoginUserRequest from '@/requests/User/sendLoginUserRequest'; import LoginValidationSchema from '@/services/User/schema/LoginValidationSchema'; import { zodResolver } from '@hookform/resolvers/zod'; import { useRouter } from 'next/router'; -import { useContext, useState } from 'react'; +import { useContext } from 'react'; import { useForm, SubmitHandler } from 'react-hook-form'; import { z } from 'zod'; import UserContext from '@/contexts/UserContext'; -import ToastContext from '@/contexts/ToastContext'; -import ErrorAlert from '../ui/alerts/ErrorAlert'; +import toast from 'react-hot-toast'; + +import createErrorToast from '@/util/createErrorToast'; import FormError from '../ui/forms/FormError'; import FormInfo from '../ui/forms/FormInfo'; import FormLabel from '../ui/forms/FormLabel'; @@ -28,23 +29,20 @@ const LoginForm = () => { const { errors } = formState; - const [responseError, setResponseError] = useState(''); - const { mutate } = useContext(UserContext); - const { toast } = useContext(ToastContext); const onSubmit: SubmitHandler = async (data) => { + const id = toast.loading('Logging in.'); try { - const id = toast.loading('Logging in.'); await sendLoginUserRequest(data); await mutate!(); - await router.push(`/user/current`); toast.remove(id); + toast.success('Logged in!'); + await router.push(`/user/current`); } catch (error) { - if (error instanceof Error) { - setResponseError(error.message); - reset(); - } + toast.remove(id); + createErrorToast(error); + reset(); } }; @@ -82,7 +80,6 @@ const LoginForm = () => { - {responseError && }
-
+
+

{resolveValue(t.message, t)}

+ {t.type !== 'loading' && ( +
+ +
+ )}
); }} {children} - + ); }; export default CustomToast; diff --git a/src/components/ui/alerts/ErrorAlert.tsx b/src/components/ui/alerts/ErrorAlert.tsx deleted file mode 100644 index b19b922..0000000 --- a/src/components/ui/alerts/ErrorAlert.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { Dispatch, FC, SetStateAction } from 'react'; -import { FiAlertTriangle } from 'react-icons/fi'; - -interface ErrorAlertProps { - error: string; - setError: Dispatch>; -} - -const ErrorAlert: FC = ({ error, setError }) => { - return ( -
-
- - {error} -
- -
- -
-
- ); -}; - -export default ErrorAlert; diff --git a/src/contexts/ToastContext.ts b/src/contexts/ToastContext.ts deleted file mode 100644 index e5b5c5e..0000000 --- a/src/contexts/ToastContext.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { createContext } from 'react'; -import toast from 'react-hot-toast'; - -const ToastContext = createContext<{ - toast: typeof toast; -}>({ toast }); - -export default ToastContext; diff --git a/src/requests/sendCreateBeerCommentRequest.ts b/src/requests/BeerComment/sendCreateBeerCommentRequest.ts similarity index 100% rename from src/requests/sendCreateBeerCommentRequest.ts rename to src/requests/BeerComment/sendCreateBeerCommentRequest.ts diff --git a/src/requests/sendUploadBeerImageRequest.ts b/src/requests/BeerImage/sendUploadBeerImageRequest.ts similarity index 100% rename from src/requests/sendUploadBeerImageRequest.ts rename to src/requests/BeerImage/sendUploadBeerImageRequest.ts diff --git a/src/requests/BeerPost/deleteBeerPostRequest.ts b/src/requests/BeerPost/deleteBeerPostRequest.ts new file mode 100644 index 0000000..62c7666 --- /dev/null +++ b/src/requests/BeerPost/deleteBeerPostRequest.ts @@ -0,0 +1,22 @@ +import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; + +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; diff --git a/src/requests/sendBeerPostLikeRequest.ts b/src/requests/BeerPost/sendBeerPostLikeRequest.ts similarity index 100% rename from src/requests/sendBeerPostLikeRequest.ts rename to src/requests/BeerPost/sendBeerPostLikeRequest.ts diff --git a/src/requests/sendCreateBeerPostRequest.ts b/src/requests/BeerPost/sendCreateBeerPostRequest.ts similarity index 100% rename from src/requests/sendCreateBeerPostRequest.ts rename to src/requests/BeerPost/sendCreateBeerPostRequest.ts diff --git a/src/requests/sendEditBeerPostRequest.ts b/src/requests/BeerPost/sendEditBeerPostRequest.ts similarity index 100% rename from src/requests/sendEditBeerPostRequest.ts rename to src/requests/BeerPost/sendEditBeerPostRequest.ts diff --git a/src/requests/sendBreweryPostLikeRequest.ts b/src/requests/BreweryPostLike/sendBreweryPostLikeRequest.ts similarity index 100% rename from src/requests/sendBreweryPostLikeRequest.ts rename to src/requests/BreweryPostLike/sendBreweryPostLikeRequest.ts diff --git a/src/requests/sendLoginUserRequest.ts b/src/requests/User/sendLoginUserRequest.ts similarity index 100% rename from src/requests/sendLoginUserRequest.ts rename to src/requests/User/sendLoginUserRequest.ts diff --git a/src/requests/sendRegisterUserRequest.ts b/src/requests/User/sendRegisterUserRequest.ts similarity index 100% rename from src/requests/sendRegisterUserRequest.ts rename to src/requests/User/sendRegisterUserRequest.ts diff --git a/src/requests/valdiateEmail.ts b/src/requests/User/validateEmailRequest.ts similarity index 85% rename from src/requests/valdiateEmail.ts rename to src/requests/User/validateEmailRequest.ts index dbd8fc0..4e87291 100644 --- a/src/requests/valdiateEmail.ts +++ b/src/requests/User/validateEmailRequest.ts @@ -1,7 +1,7 @@ import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; import { z } from 'zod'; -const validateEmail = async (email: string) => { +const validateEmailRequest = async (email: string) => { const response = await fetch(`/api/users/check-email?email=${email}`); const json = await response.json(); @@ -22,4 +22,4 @@ const validateEmail = async (email: string) => { return !parsedPayload.data.emailIsTaken; }; -export default validateEmail; +export default validateEmailRequest; diff --git a/src/requests/validateUsername.ts b/src/requests/validateUsernameRequest.ts similarity index 84% rename from src/requests/validateUsername.ts rename to src/requests/validateUsernameRequest.ts index 264c010..85be206 100644 --- a/src/requests/validateUsername.ts +++ b/src/requests/validateUsernameRequest.ts @@ -1,7 +1,7 @@ import APIResponseValidationSchema from '@/validation/APIResponseValidationSchema'; import { z } from 'zod'; -const validateUsername = async (username: string) => { +const validateUsernameRequest = async (username: string) => { const response = await fetch(`/api/users/check-username?username=${username}`); const json = await response.json(); @@ -22,4 +22,4 @@ const validateUsername = async (username: string) => { return !parsedPayload.data.usernameIsTaken; }; -export default validateUsername; +export default validateUsernameRequest; diff --git a/src/services/BeerPost/schema/BeerRecommendationQueryResult.ts b/src/services/BeerPost/schema/BeerRecommendationQueryResult.ts deleted file mode 100644 index 3f57c49..0000000 --- a/src/services/BeerPost/schema/BeerRecommendationQueryResult.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { BeerPost } from '@prisma/client'; - -type BeerRecommendationQueryResult = BeerPost & { - brewery: { - id: string; - name: string; - }; - beerImages: { - id: string; - alt: string; - url: string; - }[]; -}; - -export default BeerRecommendationQueryResult; diff --git a/src/services/User/schema/CreateUserValidationSchemas.ts b/src/services/User/schema/CreateUserValidationSchemas.ts index 1488673..f9b421d 100644 --- a/src/services/User/schema/CreateUserValidationSchemas.ts +++ b/src/services/User/schema/CreateUserValidationSchemas.ts @@ -1,5 +1,5 @@ -import validateEmail from '@/requests/valdiateEmail'; -import validateUsername from '@/requests/validateUsername'; +import validateEmailRequest from '@/requests/User/validateEmailRequest'; +import validateUsernameRequest from '@/requests/validateUsernameRequest'; import sub from 'date-fns/sub'; import { z } from 'zod'; @@ -55,14 +55,14 @@ export const CreateUserValidationSchemaWithUsernameAndEmailCheck = email: z .string() .email({ message: 'Email must be a valid email address.' }) - .refine(async (email) => validateEmail(email), { + .refine(async (email) => validateEmailRequest(email), { message: 'Email is already taken.', }), username: z .string() .min(1, { message: 'Username must not be empty.' }) .max(20, { message: 'Username must be less than 20 characters.' }) - .refine(async (username) => validateUsername(username), { + .refine(async (username) => validateUsernameRequest(username), { message: 'Username is already taken.', }), }).refine((data) => data.password === data.confirmPassword, { diff --git a/src/util/createErrorToast.ts b/src/util/createErrorToast.ts new file mode 100644 index 0000000..dce6b60 --- /dev/null +++ b/src/util/createErrorToast.ts @@ -0,0 +1,13 @@ +import toast from 'react-hot-toast'; + +/** + * @param error - The error to display. + * + * Creates a toast message with the error message. + */ +const createErrorToast = (error: unknown) => { + const errorMessage = error instanceof Error ? error.message : 'Something went wrong.'; + toast.error(errorMessage); +}; + +export default createErrorToast;