From 94df3ccbef3379e8c6a3473094cc9722c246e735 Mon Sep 17 00:00:00 2001 From: wisskirchenj Date: Sat, 17 Feb 2024 18:39:41 +0100 Subject: [PATCH 1/9] major frontend refactoring, useApi to consolidate REST calls --- frontend/package-lock.json | 168 +++++++++--------- frontend/package.json | 12 +- .../cards/components/CardItemScroller.vue | 1 - .../cards/composables/useCardsService.ts | 83 ++------- frontend/src/feature/cards/model/card.ts | 2 +- .../feature/cards/pages/CardDetailsPage.vue | 2 +- .../feature/cards/pages/CardOverviewPage.vue | 7 +- .../category/components/CategoryCard.vue | 7 +- .../composables/useCategoriesService.ts | 94 ++-------- .../src/feature/category/model/category.ts | 6 + .../composables/useRegistrationService.ts | 18 ++ .../registration/pages/RegistrationPage.vue | 4 +- frontend/src/layouts/SideNavigation.vue | 2 +- frontend/src/layouts/ToastLayer.vue | 6 - frontend/src/plugins/axios.ts | 2 +- .../src/shared/composables/errorService.ts | 28 +-- .../src/shared/composables/testService.ts | 44 ----- .../src/shared/composables/toastService.ts | 12 +- frontend/src/shared/composables/useApi.ts | 76 ++++++++ .../notifications/ToastNotification.vue | 13 +- frontend/src/shared/pages/ErrorNotFound.vue | 16 +- 21 files changed, 258 insertions(+), 345 deletions(-) create mode 100644 frontend/src/feature/registration/composables/useRegistrationService.ts delete mode 100644 frontend/src/shared/composables/testService.ts create mode 100644 frontend/src/shared/composables/useApi.ts diff --git a/frontend/package-lock.json b/frontend/package-lock.json index c246aa5..7127b47 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -11,21 +11,21 @@ "@mdi/font": "7.4.47", "axios": "^1.6.7", "roboto-fontface": "*", - "vue": "^3.4.15", + "vue": "^3.4.19", "vue-router": "^4.2.5", - "vuetify": "^3.5.2" + "vuetify": "^3.5.4" }, "devDependencies": { "@babel/types": "^7.23.9", - "@types/node": "^20.11.16", - "@vitejs/plugin-vue": "^5.0.3", + "@types/node": "^20.11.19", + "@vitejs/plugin-vue": "^5.0.4", "@vue/eslint-config-typescript": "^12.0.0", "eslint": "^8.0.0", "eslint-plugin-vue": "^9.21.1", - "sass": "^1.70.0", + "sass": "^1.71.0", "typescript": "^5.3.3", "unplugin-fonts": "^1.0.3", - "vite": "^5.0.12", + "vite": "^5.1.3", "vite-plugin-vuetify": "^2.0.1", "vue-tsc": "^1.8.27" } @@ -730,9 +730,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "20.11.16", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.16.tgz", - "integrity": "sha512-gKb0enTmRCzXSSUJDq6/sPcqrfCv2mkkG6Jt/clpn5eiCbKTY+SgZUxo+p8ZKMof5dCp9vHQUAB7wOUTod22wQ==", + "version": "20.11.19", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.11.19.tgz", + "integrity": "sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ==", "devOptional": true, "dependencies": { "undici-types": "~5.26.4" @@ -965,9 +965,9 @@ "dev": true }, "node_modules/@vitejs/plugin-vue": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.3.tgz", - "integrity": "sha512-b8S5dVS40rgHdDrw+DQi/xOM9ed+kSRZzfm1T74bMmBDCd8XO87NKlFYInzCtwvtWwXZvo1QxE2OSspTATWrbA==", + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-5.0.4.tgz", + "integrity": "sha512-WS3hevEszI6CEVEx28F8RjTX97k3KsrcY6kvTg7+Whm5y3oYvcqzVeGCU3hxSAn4uY2CLCkeokkGKpoctccilQ==", "dev": true, "engines": { "node": "^18.0.0 || >=20.0.0" @@ -1006,49 +1006,49 @@ } }, "node_modules/@vue/compiler-core": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.15.tgz", - "integrity": "sha512-XcJQVOaxTKCnth1vCxEChteGuwG6wqnUHxAm1DO3gCz0+uXKaJNx8/digSz4dLALCy8n2lKq24jSUs8segoqIw==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.4.19.tgz", + "integrity": "sha512-gj81785z0JNzRcU0Mq98E56e4ltO1yf8k5PQ+tV/7YHnbZkrM0fyFyuttnN8ngJZjbpofWE/m4qjKBiLl8Ju4w==", "dependencies": { - "@babel/parser": "^7.23.6", - "@vue/shared": "3.4.15", + "@babel/parser": "^7.23.9", + "@vue/shared": "3.4.19", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.0.2" } }, "node_modules/@vue/compiler-dom": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.15.tgz", - "integrity": "sha512-wox0aasVV74zoXyblarOM3AZQz/Z+OunYcIHe1OsGclCHt8RsRm04DObjefaI82u6XDzv+qGWZ24tIsRAIi5MQ==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.4.19.tgz", + "integrity": "sha512-vm6+cogWrshjqEHTzIDCp72DKtea8Ry/QVpQRYoyTIg9k7QZDX6D8+HGURjtmatfgM8xgCFtJJaOlCaRYRK3QA==", "dependencies": { - "@vue/compiler-core": "3.4.15", - "@vue/shared": "3.4.15" + "@vue/compiler-core": "3.4.19", + "@vue/shared": "3.4.19" } }, "node_modules/@vue/compiler-sfc": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.15.tgz", - "integrity": "sha512-LCn5M6QpkpFsh3GQvs2mJUOAlBQcCco8D60Bcqmf3O3w5a+KWS5GvYbrrJBkgvL1BDnTp+e8q0lXCLgHhKguBA==", - "dependencies": { - "@babel/parser": "^7.23.6", - "@vue/compiler-core": "3.4.15", - "@vue/compiler-dom": "3.4.15", - "@vue/compiler-ssr": "3.4.15", - "@vue/shared": "3.4.15", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.4.19.tgz", + "integrity": "sha512-LQ3U4SN0DlvV0xhr1lUsgLCYlwQfUfetyPxkKYu7dkfvx7g3ojrGAkw0AERLOKYXuAGnqFsEuytkdcComei3Yg==", + "dependencies": { + "@babel/parser": "^7.23.9", + "@vue/compiler-core": "3.4.19", + "@vue/compiler-dom": "3.4.19", + "@vue/compiler-ssr": "3.4.19", + "@vue/shared": "3.4.19", "estree-walker": "^2.0.2", - "magic-string": "^0.30.5", + "magic-string": "^0.30.6", "postcss": "^8.4.33", "source-map-js": "^1.0.2" } }, "node_modules/@vue/compiler-ssr": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.15.tgz", - "integrity": "sha512-1jdeQyiGznr8gjFDadVmOJqZiLNSsMa5ZgqavkPZ8O2wjHv0tVuAEsw5hTdUoUW4232vpBbL/wJhzVW/JwY1Uw==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.4.19.tgz", + "integrity": "sha512-P0PLKC4+u4OMJ8sinba/5Z/iDT84uMRRlrWzadgLA69opCpI1gG4N55qDSC+dedwq2fJtzmGald05LWR5TFfLw==", "dependencies": { - "@vue/compiler-dom": "3.4.15", - "@vue/shared": "3.4.15" + "@vue/compiler-dom": "3.4.19", + "@vue/shared": "3.4.19" } }, "node_modules/@vue/devtools-api": { @@ -1130,48 +1130,48 @@ } }, "node_modules/@vue/reactivity": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.15.tgz", - "integrity": "sha512-55yJh2bsff20K5O84MxSvXKPHHt17I2EomHznvFiJCAZpJTNW8IuLj1xZWMLELRhBK3kkFV/1ErZGHJfah7i7w==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.4.19.tgz", + "integrity": "sha512-+VcwrQvLZgEclGZRHx4O2XhyEEcKaBi50WbxdVItEezUf4fqRh838Ix6amWTdX0CNb/b6t3Gkz3eOebfcSt+UA==", "dependencies": { - "@vue/shared": "3.4.15" + "@vue/shared": "3.4.19" } }, "node_modules/@vue/runtime-core": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.15.tgz", - "integrity": "sha512-6E3by5m6v1AkW0McCeAyhHTw+3y17YCOKG0U0HDKDscV4Hs0kgNT5G+GCHak16jKgcCDHpI9xe5NKb8sdLCLdw==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.4.19.tgz", + "integrity": "sha512-/Z3tFwOrerJB/oyutmJGoYbuoadphDcJAd5jOuJE86THNZji9pYjZroQ2NFsZkTxOq0GJbb+s2kxTYToDiyZzw==", "dependencies": { - "@vue/reactivity": "3.4.15", - "@vue/shared": "3.4.15" + "@vue/reactivity": "3.4.19", + "@vue/shared": "3.4.19" } }, "node_modules/@vue/runtime-dom": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.15.tgz", - "integrity": "sha512-EVW8D6vfFVq3V/yDKNPBFkZKGMFSvZrUQmx196o/v2tHKdwWdiZjYUBS+0Ez3+ohRyF8Njwy/6FH5gYJ75liUw==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.4.19.tgz", + "integrity": "sha512-IyZzIDqfNCF0OyZOauL+F4yzjMPN2rPd8nhqPP2N1lBn3kYqJpPHHru+83Rkvo2lHz5mW+rEeIMEF9qY3PB94g==", "dependencies": { - "@vue/runtime-core": "3.4.15", - "@vue/shared": "3.4.15", + "@vue/runtime-core": "3.4.19", + "@vue/shared": "3.4.19", "csstype": "^3.1.3" } }, "node_modules/@vue/server-renderer": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.15.tgz", - "integrity": "sha512-3HYzaidu9cHjrT+qGUuDhFYvF/j643bHC6uUN9BgM11DVy+pM6ATsG6uPBLnkwOgs7BpJABReLmpL3ZPAsUaqw==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.4.19.tgz", + "integrity": "sha512-eAj2p0c429RZyyhtMRnttjcSToch+kTWxFPHlzGMkR28ZbF1PDlTcmGmlDxccBuqNd9iOQ7xPRPAGgPVj+YpQw==", "dependencies": { - "@vue/compiler-ssr": "3.4.15", - "@vue/shared": "3.4.15" + "@vue/compiler-ssr": "3.4.19", + "@vue/shared": "3.4.19" }, "peerDependencies": { - "vue": "3.4.15" + "vue": "3.4.19" } }, "node_modules/@vue/shared": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.15.tgz", - "integrity": "sha512-KzfPTxVaWfB+eGcGdbSf4CWdaXcGDqckoeXUh7SB3fZdEtzPCK2Vq9B/lRRL3yutax/LWITz+SwvgyOxz5V75g==" + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.4.19.tgz", + "integrity": "sha512-/KliRRHMF6LoiThEy+4c1Z4KB/gbPrGjWwJR+crg2otgrf/egKzRaCPvJ51S5oetgsgXLfc4Rm5ZgrKHZrtMSw==" }, "node_modules/@vuetify/loader-shared": { "version": "2.0.1", @@ -2239,9 +2239,9 @@ } }, "node_modules/magic-string": { - "version": "0.30.5", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.5.tgz", - "integrity": "sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==", + "version": "0.30.7", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.7.tgz", + "integrity": "sha512-8vBuFF/I/+OSLRmdf2wwFCJCz+nSn0m6DPvGH1fS/KiQoSaR+sETbov0eIk9KhEKy8CYqIkIAnbohxT/4H0kuA==", "dependencies": { "@jridgewell/sourcemap-codec": "^1.4.15" }, @@ -2486,9 +2486,9 @@ } }, "node_modules/postcss": { - "version": "8.4.33", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.33.tgz", - "integrity": "sha512-Kkpbhhdjw2qQs2O2DGX+8m5OVqEcbB9HRBvuYM9pgrjEFUg30A9LmXNlTAUj4S9kgtGyrMbTzVjH7E+s5Re2yg==", + "version": "8.4.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", + "integrity": "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA==", "funding": [ { "type": "opencollective", @@ -2675,9 +2675,9 @@ } }, "node_modules/sass": { - "version": "1.70.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.70.0.tgz", - "integrity": "sha512-uUxNQ3zAHeAx5nRFskBnrWzDUJrrvpCPD5FNAoRvTi0WwremlheES3tg+56PaVtCs5QDRX5CBLxxKMDJMEa1WQ==", + "version": "1.71.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.71.0.tgz", + "integrity": "sha512-HKKIKf49Vkxlrav3F/w6qRuPcmImGVbIXJ2I3Kg0VMA+3Bav+8yE9G5XmP5lMj6nl4OlqbPftGAscNaNu28b8w==", "devOptional": true, "dependencies": { "chokidar": ">=3.0.0 <4.0.0", @@ -2919,13 +2919,13 @@ "dev": true }, "node_modules/vite": { - "version": "5.0.12", - "resolved": "https://registry.npmjs.org/vite/-/vite-5.0.12.tgz", - "integrity": "sha512-4hsnEkG3q0N4Tzf1+t6NdN9dg/L3BM+q8SWgbSPnJvrgH2kgdyzfVJwbR1ic69/4uMJJ/3dqDZZE5/WwqW8U1w==", + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.1.3.tgz", + "integrity": "sha512-UfmUD36DKkqhi/F75RrxvPpry+9+tTkrXfMNZD+SboZqBCMsxKtO52XeGzzuh7ioz+Eo/SYDBbdb0Z7vgcDJew==", "devOptional": true, "dependencies": { "esbuild": "^0.19.3", - "postcss": "^8.4.32", + "postcss": "^8.4.35", "rollup": "^4.2.0" }, "bin": { @@ -2993,15 +2993,15 @@ } }, "node_modules/vue": { - "version": "3.4.15", - "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.15.tgz", - "integrity": "sha512-jC0GH4KkWLWJOEQjOpkqU1bQsBwf4R1rsFtw5GQJbjHVKWDzO6P0nWWBTmjp1xSemAioDFj1jdaK1qa3DnMQoQ==", + "version": "3.4.19", + "resolved": "https://registry.npmjs.org/vue/-/vue-3.4.19.tgz", + "integrity": "sha512-W/7Fc9KUkajFU8dBeDluM4sRGc/aa4YJnOYck8dkjgZoXtVsn3OeTGni66FV1l3+nvPA7VBFYtPioaGKUmEADw==", "dependencies": { - "@vue/compiler-dom": "3.4.15", - "@vue/compiler-sfc": "3.4.15", - "@vue/runtime-dom": "3.4.15", - "@vue/server-renderer": "3.4.15", - "@vue/shared": "3.4.15" + "@vue/compiler-dom": "3.4.19", + "@vue/compiler-sfc": "3.4.19", + "@vue/runtime-dom": "3.4.19", + "@vue/server-renderer": "3.4.19", + "@vue/shared": "3.4.19" }, "peerDependencies": { "typescript": "*" @@ -3103,9 +3103,9 @@ } }, "node_modules/vuetify": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.5.2.tgz", - "integrity": "sha512-H/g9+8Loykt50qe9mruHkwWsAIgfQ8gO+SPTAV2uaCFmfYPSFRfu0aGcZ42iWu4bZ9ZkgswIIDaVsfnKINd8yg==", + "version": "3.5.4", + "resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.5.4.tgz", + "integrity": "sha512-fHgfWMI7+z/UtbVPOezX+O1MNBOOMBW9HnKejcBIyQQ7jFRnTHbDQmbINf25FK0wrg/zkjfzyOmWWREKW39eXg==", "engines": { "node": "^12.20 || >=14.13" }, diff --git a/frontend/package.json b/frontend/package.json index d636c92..210c91d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -12,21 +12,21 @@ "@mdi/font": "7.4.47", "axios": "^1.6.7", "roboto-fontface": "*", - "vue": "^3.4.15", + "vue": "^3.4.19", "vue-router": "^4.2.5", - "vuetify": "^3.5.2" + "vuetify": "^3.5.4" }, "devDependencies": { "@babel/types": "^7.23.9", - "@types/node": "^20.11.16", - "@vitejs/plugin-vue": "^5.0.3", + "@types/node": "^20.11.19", + "@vitejs/plugin-vue": "^5.0.4", "@vue/eslint-config-typescript": "^12.0.0", "eslint": "^8.0.0", "eslint-plugin-vue": "^9.21.1", - "sass": "^1.70.0", + "sass": "^1.71.0", "typescript": "^5.3.3", "unplugin-fonts": "^1.0.3", - "vite": "^5.0.12", + "vite": "^5.1.3", "vite-plugin-vuetify": "^2.0.1", "vue-tsc": "^1.8.27" } diff --git a/frontend/src/feature/cards/components/CardItemScroller.vue b/frontend/src/feature/cards/components/CardItemScroller.vue index 50d9758..245f5fd 100644 --- a/frontend/src/feature/cards/components/CardItemScroller.vue +++ b/frontend/src/feature/cards/components/CardItemScroller.vue @@ -58,7 +58,6 @@ watch(() => props.titleFilter, async (newVal, oldVal) => { }); const openCard = (id: string) => { - console.log("Opening card with id: " + id); router.push(`/card/${props.categoryId}/${id}`); } diff --git a/frontend/src/feature/cards/composables/useCardsService.ts b/frontend/src/feature/cards/composables/useCardsService.ts index 5a7bc22..1e21eaa 100644 --- a/frontend/src/feature/cards/composables/useCardsService.ts +++ b/frontend/src/feature/cards/composables/useCardsService.ts @@ -1,87 +1,24 @@ -import apiClient from '@/plugins/axios'; -import {useErrorService} from "@/shared/composables/errorService"; -import {useToastService} from "@/shared/composables/toastService"; -import apiUrl from "@/shared/composables/baseUrl"; -import {Card, CardResponse} from "@/feature/cards/model/card"; +import {Card, CardPage} from "@/feature/cards/model/card"; +import useApi from "@/shared/composables/useApi"; const useCardsService = () => { - const postNewUser = async (email: string, password: string, errorResult: string = 'throw') => { - const postUrl = apiUrl + 'register'; + const ENDPOINT = '/cards'; - const postData = { - email: email, - password: password, - }; - - try { - const response = await apiClient.post(postUrl, postData); - if (response.status !== 200) { - useErrorService().handleAndNotify(`Error status code ${response.status}!`, 'Failed to register user'); - } else { - useToastService().showSuccess('SUCCESS', `User ${email} registered successfully!`) - } - } catch (error: any) { - errorResult === 'throw' ? useErrorService().handleAndThrow(error) - : useErrorService().handleAndNotify('custom error', 'custom message'); - } + const getCards = async (categoryId: string, titleFilter: string, page: number) => { + return await useApi().get(ENDPOINT, + {categoryId: categoryId, page: String(page), titleFilter: titleFilter}); } - const getCards = async (categoryId: string, titleFilter: string, page: number, errorResult: string = 'throw'): Promise => { - const filterQuery = titleFilter ? `&titleFilter=${titleFilter}` : ''; - const url = `${apiUrl}cards?categoryId=${categoryId}&page=${page}${filterQuery}`; - - try { - const response = await apiClient.get(url); - if (response.status !== 200) { - useErrorService().handleAndNotify(`Error status code ${response.status}!`, 'Failed to load cards'); - return {isLast: true, cards: [], currentPage: 0} as CardResponse; - } else { - return (response.data as CardResponse); - } - } catch (error: any) { - errorResult === 'throw' ? useErrorService().handleAndThrow(error) - : useErrorService().handleAndNotify('custom error', 'custom message'); - return {isLast: true, cards: [], currentPage: 0} as CardResponse; - } + const getCardById = async (cardId: string, categoryId: string) => { + return await useApi().get(`${ENDPOINT}/${cardId}`, {categoryId: categoryId}); } - const getCardById = async (cardId: string, categoryId: string, errorResult: string = 'throw'): Promise => { - const url = apiUrl + 'cards/' + cardId + '?categoryId=' + categoryId; - try { - const response = await apiClient.get(url); - if (response.status !== 200) { - useErrorService().handleAndNotify(`Error status code ${response.status}!`, 'Failed to load card'); - return {} as Card; - } else { - return (response.data as Card); - } - } catch (error: any) { - errorResult === 'throw' ? useErrorService().handleAndThrow(error) - : useErrorService().handleAndNotify('custom error', 'custom message'); - return {} as Card; - } - } - - const getCardCount = async (categoryId: string, errorResult: string = 'throw') => { - const url = apiUrl + 'cards/count?categoryId=' + categoryId; - - try { - const response = await apiClient.get(url); - if (response.status !== 200) { - useErrorService().handleAndNotify(`Error status code ${response.status}!`, 'Failed to load card count'); - } else { - return response.data as number; - } - } catch (error: any) { - errorResult === 'throw' ? useErrorService().handleAndThrow(error) - : useErrorService().handleAndNotify('custom error', 'custom message'); - return 0; - } + const getCardCount = async (categoryId: string) => { + return await useApi().get(`${ENDPOINT}/count`, {categoryId: categoryId}); } return { - postNewUser, getCards, getCardById, getCardCount diff --git a/frontend/src/feature/cards/model/card.ts b/frontend/src/feature/cards/model/card.ts index 8f2d3b6..17b144c 100644 --- a/frontend/src/feature/cards/model/card.ts +++ b/frontend/src/feature/cards/model/card.ts @@ -22,7 +22,7 @@ export type Card = { type: string, } -export type CardResponse = { +export type CardPage = { cards: CardItem[], currentPage: number, isLast: boolean, diff --git a/frontend/src/feature/cards/pages/CardDetailsPage.vue b/frontend/src/feature/cards/pages/CardDetailsPage.vue index 041eed7..3d68181 100644 --- a/frontend/src/feature/cards/pages/CardDetailsPage.vue +++ b/frontend/src/feature/cards/pages/CardDetailsPage.vue @@ -8,7 +8,7 @@ diff --git a/frontend/src/feature/category/components/CategoryCard.vue b/frontend/src/feature/category/components/CategoryCard.vue index 3a09fe1..2aa869c 100644 --- a/frontend/src/feature/category/components/CategoryCard.vue +++ b/frontend/src/feature/category/components/CategoryCard.vue @@ -42,10 +42,8 @@ - - - - + + @@ -94,6 +92,7 @@ const editCategory = () => { resetRequests(); editRequested.value = true; }; + const deleteCategory = async () => { resetRequests(); await categoryService().deleteCategory(props.category.id); diff --git a/frontend/src/feature/category/composables/useCategoriesService.ts b/frontend/src/feature/category/composables/useCategoriesService.ts index 4f94a0c..179a782 100644 --- a/frontend/src/feature/category/composables/useCategoriesService.ts +++ b/frontend/src/feature/category/composables/useCategoriesService.ts @@ -1,92 +1,29 @@ -import apiClient from '@/plugins/axios'; -import {useErrorService} from "@/shared/composables/errorService"; -import {Category, CategoryRequest} from "@/feature/category/model/category"; -import apiUrl from "@/shared/composables/baseUrl"; -import {useToastService} from "@/shared/composables/toastService"; +import {Category, CategoryPage, CategoryRequest} from "@/feature/category/model/category"; +import useApi from "@/shared/composables/useApi"; const useCategoriesService = () => { - const getCategories = async (errorResult: string = 'throw') : Promise => { - const url = `${apiUrl}categories`; - try { - const response = await apiClient.get(url); - if (response.status !== 200) { - useErrorService().handleAndNotify(`Error status code ${response.status}!`, 'Failed to load categories'); - return []; - } else { - return (response.data.categories as Category[]); - } - } catch (error: any) { - errorResult === 'throw' ? useErrorService().handleAndThrow(error) - : useErrorService().handleAndNotify('custom error', 'custom message'); - return []; - } - } - - const getCategoryById = async (id: String, errorResult: string = 'throw') : Promise => { - const url = `${apiUrl}categories/${id}`; - try { - const response = await apiClient.get(url); - if (response.status !== 200) { - useErrorService().handleAndNotify(`Error status code ${response.status}!`, 'Failed to load category'); - return {} as Category; - } else { - console.log(response.data); - return (response.data as Category); - } - } catch (error: any) { - errorResult === 'throw' ? useErrorService().handleAndThrow(error) - : useErrorService().handleAndNotify('custom error', 'custom message'); - return {} as Category; - } - } + const ENDPOINT = '/categories'; - const postNewCategory = async (data: CategoryRequest, errorResult: string = 'throw') => { - const url = `${apiUrl}categories`; + const getCategories = async () => { + const page = await useApi().get(ENDPOINT); + return page.categories; + } - try { - const response = await apiClient.post(url, data); - if (response.status !== 201) { - useErrorService().handleAndNotify(`Error status code ${response.status}!`, 'Failed to post card'); - } else { - useToastService().showSuccess('SUCCESS', `Category ${data.name} successfully created!`) - } - } catch (error: any) { - errorResult === 'throw' ? useErrorService().handleAndThrow(error) - : useErrorService().handleAndNotify('custom error', 'custom message'); - } + const getCategoryById = async (id: string) => { + return await useApi().get(`${ENDPOINT}/${id}`); } - const putCategory = async (id: string, data: CategoryRequest, errorResult: string = 'throw') => { - const url = `${apiUrl}categories/${id}`; + const postNewCategory = async (data: CategoryRequest) => { + return await useApi().post(ENDPOINT, data, `Category ${data.name} successfully created!`); + } - try { - const response = await apiClient.put(url, data); - if (response.status !== 200) { - useErrorService().handleAndNotify(`Error status code ${response.status}!`, 'Failed to update card'); - } else { - useToastService().showSuccess('SUCCESS', `Category ${data.name} successfully updated!`) - } - } catch (error: any) { - errorResult === 'throw' ? useErrorService().handleAndThrow(error) - : useErrorService().handleAndNotify('custom error', 'custom message'); - } + const putCategory = async (id: string, data: CategoryRequest) => { + return await useApi().put(`${ENDPOINT}/${id}`, data, `Category ${data.name} successfully updated!`); } const deleteCategory = async (id: string, errorResult: string = 'throw') => { - const url = `${apiUrl}categories/${id}`; - - try { - const response = await apiClient.delete(url); - if (response.status !== 200) { - useErrorService().handleAndNotify(`Error status code ${response.status}!`, 'Failed to delete card'); - } else { - useToastService().showSuccess('SUCCESS', `Category successfully removed`) - } - } catch (error: any) { - errorResult === 'throw' ? useErrorService().handleAndThrow(error) - : useErrorService().handleAndNotify('custom error', 'custom message'); - } + return await useApi().delete(`${ENDPOINT}/${id}`, 'Category successfully removed'); } return { @@ -97,4 +34,5 @@ const useCategoriesService = () => { getCategoryById } } + export default useCategoriesService; diff --git a/frontend/src/feature/category/model/category.ts b/frontend/src/feature/category/model/category.ts index 7917d88..5c08b10 100644 --- a/frontend/src/feature/category/model/category.ts +++ b/frontend/src/feature/category/model/category.ts @@ -17,6 +17,12 @@ export type Category = { description?: string, } +export type CategoryPage = { + categories: Category[], + currentPage: number, + isLast: boolean, +} + export interface CategoryRequest { name: string; description: string; diff --git a/frontend/src/feature/registration/composables/useRegistrationService.ts b/frontend/src/feature/registration/composables/useRegistrationService.ts new file mode 100644 index 0000000..ab9676d --- /dev/null +++ b/frontend/src/feature/registration/composables/useRegistrationService.ts @@ -0,0 +1,18 @@ +import useApi from "@/shared/composables/useApi"; + +const useRegistrationService = () => { + + const postNewUser = async (email: string, password: string, errorResult: string = 'throw') => { + const data = { + email: email, + password: password, + }; + await useApi().post("/register", data, `User ${email} registered successfully!`, + 'Failed to register user'); + } + + return { + postNewUser, + } +} +export default useRegistrationService; diff --git a/frontend/src/feature/registration/pages/RegistrationPage.vue b/frontend/src/feature/registration/pages/RegistrationPage.vue index e1da6a8..c706b59 100644 --- a/frontend/src/feature/registration/pages/RegistrationPage.vue +++ b/frontend/src/feature/registration/pages/RegistrationPage.vue @@ -23,14 +23,14 @@ diff --git a/frontend/src/layouts/SideNavigation.vue b/frontend/src/layouts/SideNavigation.vue index 2b8a7b8..97ced26 100644 --- a/frontend/src/layouts/SideNavigation.vue +++ b/frontend/src/layouts/SideNavigation.vue @@ -1,6 +1,6 @@