From 0771498ca4c7e386a5f38ac172f5807fd3d28b83 Mon Sep 17 00:00:00 2001 From: Nyior Date: Sat, 8 Oct 2022 07:00:39 +0100 Subject: [PATCH 1/9] Add basic auth codes --- package-lock.json | 75 ++++++++++++++++++----- package.json | 1 + src/components/Auth/LoginForm.vue | 76 +++++++++++++++-------- src/components/Auth/SignupForm.vue | 96 ++++++++++++++++++++---------- src/utils/apiService.ts | 21 +++++++ yarn.lock | 19 ++++++ 6 files changed, 215 insertions(+), 73 deletions(-) create mode 100644 src/utils/apiService.ts diff --git a/package-lock.json b/package-lock.json index 41fd172..61064bd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "dependencies": { "@logue/vue2-helpers": "^2.0.3", "@mdi/font": "^7.0.96", + "axios": "^1.1.2", "vue": "^2.7.10", "vue-class-component": "^7.2.6", "vue-property-decorator": "^9.1.2", @@ -1279,8 +1280,17 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/axios": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.1.2.tgz", + "integrity": "sha512-bznQyETwElsXl2RK7HLLwb5GPpOLlycxHCtrpDR/4RqqBzjARaOTo3jz4IgtntWUYee7Ne4S8UHd92VCuzPaWA==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } }, "node_modules/balanced-match": { "version": "1.0.2", @@ -1611,7 +1621,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -1915,7 +1924,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, "engines": { "node": ">=0.4.0" } @@ -3447,6 +3455,25 @@ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" }, + "node_modules/follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/foreground-child": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", @@ -3464,7 +3491,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -5170,7 +5196,6 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, "engines": { "node": ">= 0.6" } @@ -5179,7 +5204,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "dependencies": { "mime-db": "1.52.0" }, @@ -5815,6 +5839,11 @@ "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", "dev": true }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", @@ -8997,8 +9026,17 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "axios": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.1.2.tgz", + "integrity": "sha512-bznQyETwElsXl2RK7HLLwb5GPpOLlycxHCtrpDR/4RqqBzjARaOTo3jz4IgtntWUYee7Ne4S8UHd92VCuzPaWA==", + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } }, "balanced-match": { "version": "1.0.2", @@ -9256,7 +9294,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -9497,8 +9534,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, "dir-glob": { "version": "3.0.1", @@ -10544,6 +10580,11 @@ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + }, "foreground-child": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", @@ -10558,7 +10599,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dev": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -11813,14 +11853,12 @@ "mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" }, "mime-types": { "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "requires": { "mime-db": "1.52.0" } @@ -12250,6 +12288,11 @@ "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", "dev": true }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", diff --git a/package.json b/package.json index 24172a6..cbf6fc1 100644 --- a/package.json +++ b/package.json @@ -42,6 +42,7 @@ "dependencies": { "@logue/vue2-helpers": "^2.0.3", "@mdi/font": "^7.0.96", + "axios": "^1.1.2", "vue": "^2.7.10", "vue-class-component": "^7.2.6", "vue-property-decorator": "^9.1.2", diff --git a/src/components/Auth/LoginForm.vue b/src/components/Auth/LoginForm.vue index b8253e4..c8d8e37 100644 --- a/src/components/Auth/LoginForm.vue +++ b/src/components/Auth/LoginForm.vue @@ -34,6 +34,7 @@ submit @@ -41,39 +42,64 @@ diff --git a/src/components/Auth/SignupForm.vue b/src/components/Auth/SignupForm.vue index 187479e..5c2358b 100644 --- a/src/components/Auth/SignupForm.vue +++ b/src/components/Auth/SignupForm.vue @@ -17,8 +17,7 @@ > submit @@ -56,10 +52,12 @@ diff --git a/src/utils/apiService.ts b/src/utils/apiService.ts new file mode 100644 index 0000000..682b26a --- /dev/null +++ b/src/utils/apiService.ts @@ -0,0 +1,21 @@ +const API_URL = "http://127.0.0.1:8000"; + +async function apiService(endpoint, method, data) { + endpoint = `${API_URL}/${endpoint}`; + + const response = await fetch( + endpoint, + { + method: method, + // credentials:"include", + headers: { + 'Content-Type': 'application/json' + }, + body: data !== undefined ? JSON.stringify(data) : null, + } + ); + + return response.json(); +} + +export { apiService }; diff --git a/yarn.lock b/yarn.lock index 01fe533..7416932 100644 --- a/yarn.lock +++ b/yarn.lock @@ -648,6 +648,15 @@ "resolved" "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" "version" "0.4.0" +"axios@^1.1.2": + "integrity" "sha512-bznQyETwElsXl2RK7HLLwb5GPpOLlycxHCtrpDR/4RqqBzjARaOTo3jz4IgtntWUYee7Ne4S8UHd92VCuzPaWA==" + "resolved" "https://registry.npmjs.org/axios/-/axios-1.1.2.tgz" + "version" "1.1.2" + dependencies: + "follow-redirects" "^1.15.0" + "form-data" "^4.0.0" + "proxy-from-env" "^1.1.0" + "balanced-match@^1.0.0": "integrity" "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" "resolved" "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz" @@ -1763,6 +1772,11 @@ "resolved" "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz" "version" "3.2.7" +"follow-redirects@^1.15.0": + "integrity" "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + "resolved" "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz" + "version" "1.15.2" + "foreground-child@^2.0.0": "integrity" "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==" "resolved" "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz" @@ -3138,6 +3152,11 @@ "resolved" "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz" "version" "1.2.4" +"proxy-from-env@^1.1.0": + "integrity" "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + "resolved" "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz" + "version" "1.1.0" + "pseudomap@^1.0.2": "integrity" "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==" "resolved" "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz" From 6251da1ad283f9ff6f2c3c72aa7a31eb6ad919d6 Mon Sep 17 00:00:00 2001 From: Nyior Date: Wed, 12 Oct 2022 23:04:33 +0100 Subject: [PATCH 2/9] Modularize vuex store --- src/App.vue | 10 +- src/components/Auth/LoginForm.vue | 51 ++++----- src/components/Auth/SignupForm.vue | 38 +++---- src/middlewares/protected.ts | 3 +- src/plugins/vuetify.ts | 25 ++--- src/router/router.ts | 8 +- src/store/ConfigModule.ts | 74 ------------- src/store/actions.ts | 48 ++++++++ src/store/getters.ts | 10 ++ src/store/index.ts | 152 +++----------------------- src/store/modules/config/actions.ts | 25 +++++ src/store/modules/config/getters.ts | 10 ++ src/store/modules/config/index.ts | 18 +++ src/store/modules/config/mutations.ts | 13 +++ src/store/modules/config/state.ts | 15 +++ src/store/modules/user/actions.ts | 24 ++++ src/store/modules/user/getters.ts | 6 + src/store/modules/user/index.ts | 18 +++ src/store/modules/user/mutations.ts | 5 + src/store/modules/user/state.ts | 19 ++++ src/store/mutations.ts | 43 ++++++++ src/store/state.ts | 19 ++++ src/utils/apiService.ts | 28 ++--- src/views/Auth/Auth.vue | 25 ++--- 24 files changed, 368 insertions(+), 319 deletions(-) delete mode 100644 src/store/ConfigModule.ts create mode 100644 src/store/actions.ts create mode 100644 src/store/getters.ts create mode 100644 src/store/modules/config/actions.ts create mode 100644 src/store/modules/config/getters.ts create mode 100644 src/store/modules/config/index.ts create mode 100644 src/store/modules/config/mutations.ts create mode 100644 src/store/modules/config/state.ts create mode 100644 src/store/modules/user/actions.ts create mode 100644 src/store/modules/user/getters.ts create mode 100644 src/store/modules/user/index.ts create mode 100644 src/store/modules/user/mutations.ts create mode 100644 src/store/modules/user/state.ts create mode 100644 src/store/mutations.ts create mode 100644 src/store/state.ts diff --git a/src/App.vue b/src/App.vue index ec6639a..8ca78a3 100644 --- a/src/App.vue +++ b/src/App.vue @@ -3,7 +3,7 @@ {{ title }} - + mdi-theme-light-dark - + Home mdi-home-circle @@ -208,7 +204,7 @@ html { scrollbar-color: map-get($grey, 'lighten-2') map-get($grey, 'base'); } -a{ +a { text-decoration: none !important; } diff --git a/src/components/Auth/LoginForm.vue b/src/components/Auth/LoginForm.vue index c8d8e37..454484f 100644 --- a/src/components/Auth/LoginForm.vue +++ b/src/components/Auth/LoginForm.vue @@ -31,11 +31,7 @@ @click:append="state.show = !state.show" > - + submit @@ -45,13 +41,11 @@ import { defineComponent, reactive } from 'vue'; import { apiService } from '@/utils/apiService'; - export default defineComponent({ components: {}, props: {}, setup(props) { - const state = reactive({ show: false, valid: false, @@ -67,39 +61,38 @@ export default defineComponent({ ], }); - const login= () => { + const login = () => { const userLoginUrl = `api/v1/auth/login`; - const method = "POST"; + const method = 'POST'; const payload = { - "email": state.email, - "password": state.email - } + email: state.email, + password: state.email, + }; apiService(userLoginUrl, method, payload) .then(data => { - console.log("User Logged In: ", data) - // let payload = { - // authToken: data.token, - // userId: data.id, - // username: data.username - // }; - // this.$store.dispatch("joinAction", payload); - // this.isLoading = false; - // this.$router.push({ - // name: "home" - // }); + console.log('User Logged In: ', data); + // let payload = { + // authToken: data.token, + // userId: data.id, + // username: data.username + // }; + // this.$store.dispatch("joinAction", payload); + // this.isLoading = false; + // this.$router.push({ + // name: "home" + // }); }) .catch(error => { - console.log(`User not created due to: ${error}`) + console.log(`User not created due to: ${error}`); }); - } + }; return { state, - login - } - } - + login, + }; + }, }); diff --git a/src/components/Auth/SignupForm.vue b/src/components/Auth/SignupForm.vue index 5c2358b..6082243 100644 --- a/src/components/Auth/SignupForm.vue +++ b/src/components/Auth/SignupForm.vue @@ -55,19 +55,12 @@ import { defineComponent, reactive } from 'vue'; import { apiService } from '@/utils/apiService'; - - export default defineComponent({ - components: { - - }, - - props: { + components: {}, - }, + props: {}, setup(props) { - const state = reactive({ show: false, valid: false, @@ -82,24 +75,22 @@ export default defineComponent({ v => /.+@.+/.test(v) || 'E-mail must be valid', ], username: '', - usernameRules: [ - v => !!v || 'Username is required' - ], + usernameRules: [v => !!v || 'Username is required'], }); - const createUser= () => { + const createUser = () => { let createUserUrl = `api/v1/auth/signup`; - let method = "POST"; + let method = 'POST'; const payload = { - "email": state.email, - "password": state.email, - "display_name": state.username - } + email: state.email, + password: state.email, + display_name: state.username, + }; apiService(createUserUrl, method, payload) .then(data => { - console.log("User Successfully created: ", data) + console.log('User Successfully created: ', data); // let payload = { // authToken: data.token, // userId: data.id, @@ -112,15 +103,14 @@ export default defineComponent({ // }); }) .catch(error => { - console.log(`User not created due to: ${error}`) + console.log(`User not created due to: ${error}`); }); - } + }; return { state, - createUser + createUser, }; - } - + }, }); diff --git a/src/middlewares/protected.ts b/src/middlewares/protected.ts index 16b5b6b..0890a1e 100644 --- a/src/middlewares/protected.ts +++ b/src/middlewares/protected.ts @@ -4,7 +4,6 @@ // } from 'vue-router' // import store from '@/store' - // export default ( // to: RouteLocationNormalized, // from: RouteLocationNormalized, @@ -17,4 +16,4 @@ // } // } -export {} +export {}; diff --git a/src/plugins/vuetify.ts b/src/plugins/vuetify.ts index 4546fb7..b860ce7 100644 --- a/src/plugins/vuetify.ts +++ b/src/plugins/vuetify.ts @@ -23,17 +23,17 @@ export default createVuetify({ theme: { themes: { dark: { - // primary: '#fed163', - primary: '#b390e9', - background: '#222831', - error: '#d63031', - info: '#0984e3', - secondary: '#fdcb6e', - success: '#00cec9', - surface: '#6c5ce7', - warning: '#FFDD93', - text: '#FFD369', - dominant: '#b390e9', + // primary: '#fed163', + primary: '#b390e9', + background: '#222831', + error: '#d63031', + info: '#0984e3', + secondary: '#fdcb6e', + success: '#00cec9', + surface: '#6c5ce7', + warning: '#FFDD93', + text: '#FFD369', + dominant: '#b390e9', }, light: { // primary: '#FFDD93', @@ -47,7 +47,7 @@ export default createVuetify({ warning: '#FFDD93', text: '#FFD369', dominant: '#6929cc', - }, + }, }, dark: true, // options: { @@ -63,7 +63,6 @@ export default createVuetify({ // customProperties: true, // }, }, - }); /** Create Vuetify */ diff --git a/src/router/router.ts b/src/router/router.ts index 6199551..f3ce94a 100644 --- a/src/router/router.ts +++ b/src/router/router.ts @@ -12,10 +12,10 @@ import type { VuetifyGoToTarget } from 'vuetify/types/services/goto'; import goTo from 'vuetify/lib/services/goto'; import store from '@/store'; -import HomePage from '@/views/Home/HomePage.vue' -import About from '@/views/Misc/AboutPage.vue' -import ErrorPage from '@/views/Misc/ErrorPage.vue' -import Auth from '@/views/Auth/Auth.vue' +import HomePage from '@/views/Home/HomePage.vue'; +import About from '@/views/Misc/AboutPage.vue'; +import ErrorPage from '@/views/Misc/ErrorPage.vue'; +import Auth from '@/views/Auth/Auth.vue'; /** Router Config */ const routes: RouteRecordRaw[] = [ diff --git a/src/store/ConfigModule.ts b/src/store/ConfigModule.ts deleted file mode 100644 index adae363..0000000 --- a/src/store/ConfigModule.ts +++ /dev/null @@ -1,74 +0,0 @@ -/** Config store */ -import type { - ActionContext, - ActionTree, - GetterTree, - Module, - MutationTree, -} from 'vuex'; - -import type { RootState } from '.'; - -/** Config State */ -export interface ConfigState { - /** Dark Theme mode */ - themeDark: boolean; - /** Language */ - locale: string; -} - -/** Default Configure state value */ -const state: ConfigState = { - themeDark: window.matchMedia('(prefers-color-scheme: dark)').matches, - locale: - (window.navigator.languages && window.navigator.languages[0]) || - window.navigator.language, -}; - -/** Getters */ -const getters: GetterTree = { - themeDark: (s): boolean => s.themeDark, - locale: (s): string => s.locale, -}; - -/** Mutations */ -const mutations: MutationTree = { - storeThemeDark(s) { - s.themeDark = !s.themeDark; - }, - storeLocale(s, locale: string) { - s.locale = locale; - }, -}; - -/** Action */ -const actions: ActionTree = { - /** - * Switch Dark/Light mode. - * - * @param context - Vuex Context - */ - setThemeDark(context: ActionContext, mode: boolean) { - context.commit('storeThemeDark', mode); - }, - /** - * Change locale. - * - * @param context - Vuex Context - * @param locale - Locale code - */ - setLocale(context: ActionContext, locale: string) { - context.commit('storeLocale', locale); - }, -}; - -/** VuexStore */ -const ConfigModule: Module = { - namespaced: true, - state, - getters, - mutations, - actions, -}; - -export default ConfigModule; diff --git a/src/store/actions.ts b/src/store/actions.ts new file mode 100644 index 0000000..caad8bb --- /dev/null +++ b/src/store/actions.ts @@ -0,0 +1,48 @@ +import type { ActionContext, ActionTree } from 'vuex'; +import type { RootState } from './state'; + +/** Actions */ +export const actions: ActionTree = { + /** + * Loading overlay visibility + * + * @param context - Vuex Context + * @param display - Visibility + */ + setLoading( + context: ActionContext, + display: boolean = false + ) { + context.commit('storeLoading', display); + }, + /** + * Loading progress bar value + * + * @param context - Vuex Context + * @param progress - Percentage(0~100) + */ + setProgress( + context: ActionContext, + progress: number = 0 + ) { + context.commit('storeProgress', progress); + }, + /** + * Set snackbar message. + * + * @param context - Vuex Context + * @param message - Message text + */ + setMessage(context: ActionContext, message?: string) { + context.commit('storeMessage', message); + }, + /** + * Set Error message + * + * @param context - Vuex Context + * @param error - Error message etc. + */ + setError(context: ActionContext, error) { + context.commit('storeError', error); + }, +}; diff --git a/src/store/getters.ts b/src/store/getters.ts new file mode 100644 index 0000000..ed395f5 --- /dev/null +++ b/src/store/getters.ts @@ -0,0 +1,10 @@ +import type { GetterTree } from 'vuex'; +import type { RootState } from './state'; + +/** Getters */ +export const getters: GetterTree = { + loading: (s): boolean => s.loading, + progress: (s): number => s.progress, + message: (s): string | undefined => s.message, + error: (s): string | undefined => s.error, +}; diff --git a/src/store/index.ts b/src/store/index.ts index 790b45e..2b93891 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -1,130 +1,22 @@ -import type { - ActionContext, - ActionTree, - GetterTree, - MutationTree, - StoreOptions, -} from 'vuex'; -import { createStore } from '@logue/vue2-helpers/vuex'; -import VuexPersistence from 'vuex-persist'; - -// Modules -import ConfigModule from './ConfigModule'; +// Follow this tutorial to learn how to modularize the store +// https://medium.com/swlh/building-large-scale-applications-with-vuex-6d7e8ce0dfef -/** Root State Interface */ -export interface RootState { - /* + Loading overlay */ - loading: boolean; - /** ProgressBar Percentage */ - progress: number; - /** SnackBar Text */ - message?: string; - /** Error Message */ - error?: string; -} +// Also follow this Stackoverflow link -/** State Default value */ -const state: RootState = { - loading: false, - progress: 0, - message: undefined, - error: undefined, -}; +// https://stackoverflow.com/questions/64404599/how-to-modularize-vuex-into-different-folders-and-files -/** Getters */ -const getters: GetterTree = { - loading: (s): boolean => s.loading, - progress: (s): number => s.progress, - message: (s): string | undefined => s.message, - error: (s): string | undefined => s.error, -}; - -/** Mutations */ -const mutations: MutationTree = { - /** - * Store loading - * - * @param s - Vuex state - * @param display - Payload - */ - storeLoading(s, display: boolean) { - s.loading = display; - }, - /** - * Store progress - * - * @param s - Vuex state - * @param progress - Payload - */ - storeProgress(s, progress: number) { - s.progress = progress; - s.loading = true; - }, - /** - * Store snackbar text - * - * @param s - Vuex state - * @param message - Payload - */ - storeMessage(s, message: string) { - s.message = message; - }, - /** - * Store error message - * - * @param s - Vuex state - * @param error - Payload - */ - storeError(s, error: string) { - s.error = error; - }, -}; +import type { StoreOptions } from 'vuex'; +import { createStore } from '@logue/vue2-helpers/vuex'; +import VuexPersistence from 'vuex-persist'; +import type { RootState } from './state'; +import { state } from './state'; +import { getters } from './getters'; +import { mutations } from './mutations'; +import { actions } from './actions'; -/** Actions */ -const actions: ActionTree = { - /** - * Loading overlay visibility - * - * @param context - Vuex Context - * @param display - Visibility - */ - setLoading( - context: ActionContext, - display: boolean = false - ) { - context.commit('storeLoading', display); - }, - /** - * Loading progress bar value - * - * @param context - Vuex Context - * @param progress - Percentage(0~100) - */ - setProgress( - context: ActionContext, - progress: number = 0 - ) { - context.commit('storeProgress', progress); - }, - /** - * Set snackbar message. - * - * @param context - Vuex Context - * @param message - Message text - */ - setMessage(context: ActionContext, message?: string) { - context.commit('storeMessage', message); - }, - /** - * Set Error message - * - * @param context - Vuex Context - * @param error - Error message etc. - */ - setError(context: ActionContext, error) { - context.commit('storeError', error); - }, -}; +// Modules +import ConfigModule from './modules/config'; +import UserModule from './modules/user'; /** VuexStore */ const store: StoreOptions = { @@ -136,6 +28,7 @@ const store: StoreOptions = { actions, modules: { ConfigModule, + UserModule, }, plugins: [ new VuexPersistence({ @@ -143,19 +36,6 @@ const store: StoreOptions = { storage: window.localStorage, modules: ['ConfigModule'], }).plugin, - /* - // store as session storage - new VuexPersistence({ - key: import.meta.env.VITE_APP_WEBSTORAGE_NAMESPACE, - storage: window.sessionStorage, - modules: ['SomeModule'], - }).plugin, - // store as Indexed DB (using vuex-persist-indexeddb) - createPersistedState({ - key: import.meta.env.VITE_APP_WEBSTORAGE_NAMESPACE, - paths: ['SomeLargeModule'], - }), - */ ], }; diff --git a/src/store/modules/config/actions.ts b/src/store/modules/config/actions.ts new file mode 100644 index 0000000..0459db0 --- /dev/null +++ b/src/store/modules/config/actions.ts @@ -0,0 +1,25 @@ +/** Config store */ +import type { ActionContext, ActionTree } from 'vuex'; +import type { ConfigState } from './state'; +import type { RootState } from '@/store/state'; + +/** Action */ +export const actions: ActionTree = { + /** + * Switch Dark/Light mode. + * + * @param context - Vuex Context + */ + setThemeDark(context: ActionContext, mode: boolean) { + context.commit('storeThemeDark', mode); + }, + /** + * Change locale. + * + * @param context - Vuex Context + * @param locale - Locale code + */ + setLocale(context: ActionContext, locale: string) { + context.commit('storeLocale', locale); + }, +}; diff --git a/src/store/modules/config/getters.ts b/src/store/modules/config/getters.ts new file mode 100644 index 0000000..4349eac --- /dev/null +++ b/src/store/modules/config/getters.ts @@ -0,0 +1,10 @@ +/** Config store */ +import type { GetterTree } from 'vuex'; +import type { RootState } from '@/store/state'; +import type { ConfigState } from './state'; + +/** Getters */ +export const getters: GetterTree = { + themeDark: (s): boolean => s.themeDark, + locale: (s): string => s.locale, +}; diff --git a/src/store/modules/config/index.ts b/src/store/modules/config/index.ts new file mode 100644 index 0000000..218f6d0 --- /dev/null +++ b/src/store/modules/config/index.ts @@ -0,0 +1,18 @@ +import type { Module } from 'vuex'; +import type { ConfigState } from './state'; +import type { RootState } from '@/store/state'; +import { state } from './state'; +import { mutations } from './mutations'; +import { getters } from './getters'; +import { actions } from './actions'; + +/** VuexStore */ +const ConfigModule: Module = { + namespaced: true, + state, + getters, + mutations, + actions, +}; + +export default ConfigModule; diff --git a/src/store/modules/config/mutations.ts b/src/store/modules/config/mutations.ts new file mode 100644 index 0000000..2dd78db --- /dev/null +++ b/src/store/modules/config/mutations.ts @@ -0,0 +1,13 @@ +/** Config store */ +import type { MutationTree } from 'vuex'; +import type { ConfigState } from './state'; + +/** Mutations */ +export const mutations: MutationTree = { + storeThemeDark(s) { + s.themeDark = !s.themeDark; + }, + storeLocale(s, locale: string) { + s.locale = locale; + }, +}; diff --git a/src/store/modules/config/state.ts b/src/store/modules/config/state.ts new file mode 100644 index 0000000..7518652 --- /dev/null +++ b/src/store/modules/config/state.ts @@ -0,0 +1,15 @@ +/** Config State */ +export interface ConfigState { + /** Dark Theme mode */ + themeDark: boolean; + /** Language */ + locale: string; +} + +/** Default Configure state value */ +export const state: ConfigState = { + themeDark: window.matchMedia('(prefers-color-scheme: dark)').matches, + locale: + (window.navigator.languages && window.navigator.languages[0]) || + window.navigator.language, +}; diff --git a/src/store/modules/user/actions.ts b/src/store/modules/user/actions.ts new file mode 100644 index 0000000..367e25e --- /dev/null +++ b/src/store/modules/user/actions.ts @@ -0,0 +1,24 @@ +import type { ActionContext, ActionTree } from 'vuex'; +import type { UserState } from './state'; +import type { RootState } from '@/store/state'; + +/** Action */ +export const actions: ActionTree = { + /** + * Switch Dark/Light mode. + * + * @param context - Vuex Context + */ + setThemeDark(context: ActionContext, mode: boolean) { + context.commit('storeThemeDark', mode); + }, + /** + * Change locale. + * + * @param context - Vuex Context + * @param locale - Locale code + */ + setLocale(context: ActionContext, locale: string) { + context.commit('storeLocale', locale); + }, +}; diff --git a/src/store/modules/user/getters.ts b/src/store/modules/user/getters.ts new file mode 100644 index 0000000..efca4c7 --- /dev/null +++ b/src/store/modules/user/getters.ts @@ -0,0 +1,6 @@ +import type { GetterTree } from 'vuex'; +import type { RootState } from '@/store/state'; +import type { UserState } from './state'; + +/** Getters */ +export const getters: GetterTree = {}; diff --git a/src/store/modules/user/index.ts b/src/store/modules/user/index.ts new file mode 100644 index 0000000..7d443fa --- /dev/null +++ b/src/store/modules/user/index.ts @@ -0,0 +1,18 @@ +import type { Module } from 'vuex'; +import type { UserState } from './state'; +import { state } from './state'; +import { getters } from './getters'; +import { mutations } from './mutations'; +import { actions } from './actions'; +import type { RootState } from '@/store/state'; + +/** VuexStore */ +const UserModule: Module = { + namespaced: true, + state, + getters, + mutations, + actions, +}; + +export default UserModule; diff --git a/src/store/modules/user/mutations.ts b/src/store/modules/user/mutations.ts new file mode 100644 index 0000000..506fa13 --- /dev/null +++ b/src/store/modules/user/mutations.ts @@ -0,0 +1,5 @@ +import type { MutationTree } from 'vuex'; +import type { UserState } from './state'; + +/** Mutations */ +export const mutations: MutationTree = {}; diff --git a/src/store/modules/user/state.ts b/src/store/modules/user/state.ts new file mode 100644 index 0000000..e828cbd --- /dev/null +++ b/src/store/modules/user/state.ts @@ -0,0 +1,19 @@ +/** Root State Interface */ +export interface UserState { + /* + Loading overlay */ + loading: boolean; + /** ProgressBar Percentage */ + progress: number; + /** SnackBar Text */ + message?: string; + /** Error Message */ + error?: string; +} + +/** State Default value */ +export const state: UserState = { + loading: false, + progress: 0, + message: undefined, + error: undefined, +}; diff --git a/src/store/mutations.ts b/src/store/mutations.ts new file mode 100644 index 0000000..2d092f2 --- /dev/null +++ b/src/store/mutations.ts @@ -0,0 +1,43 @@ +import type { MutationTree } from 'vuex'; +import type { RootState } from './state'; + +/** Mutations */ +export const mutations: MutationTree = { + /** + * Store loading + * + * @param s - Vuex state + * @param display - Payload + */ + storeLoading(s, display: boolean) { + s.loading = display; + }, + /** + * Store progress + * + * @param s - Vuex state + * @param progress - Payload + */ + storeProgress(s, progress: number) { + s.progress = progress; + s.loading = true; + }, + /** + * Store snackbar text + * + * @param s - Vuex state + * @param message - Payload + */ + storeMessage(s, message: string) { + s.message = message; + }, + /** + * Store error message + * + * @param s - Vuex state + * @param error - Payload + */ + storeError(s, error: string) { + s.error = error; + }, +}; diff --git a/src/store/state.ts b/src/store/state.ts new file mode 100644 index 0000000..736fcb6 --- /dev/null +++ b/src/store/state.ts @@ -0,0 +1,19 @@ +/** Root State Interface */ +export interface RootState { + /* + Loading overlay */ + loading: boolean; + /** ProgressBar Percentage */ + progress: number; + /** SnackBar Text */ + message?: string; + /** Error Message */ + error?: string; +} + +/** State Default value */ +export const state: RootState = { + loading: false, + progress: 0, + message: undefined, + error: undefined, +}; diff --git a/src/utils/apiService.ts b/src/utils/apiService.ts index 682b26a..c7732e7 100644 --- a/src/utils/apiService.ts +++ b/src/utils/apiService.ts @@ -1,21 +1,21 @@ -const API_URL = "http://127.0.0.1:8000"; +const API_URL = 'http://127.0.0.1:8000'; +/** + * + */ async function apiService(endpoint, method, data) { - endpoint = `${API_URL}/${endpoint}`; + endpoint = `${API_URL}/${endpoint}`; - const response = await fetch( - endpoint, - { - method: method, - // credentials:"include", - headers: { - 'Content-Type': 'application/json' - }, - body: data !== undefined ? JSON.stringify(data) : null, - } - ); + const response = await fetch(endpoint, { + method: method, + // credentials:"include", + headers: { + 'Content-Type': 'application/json', + }, + body: data !== undefined ? JSON.stringify(data) : null, + }); - return response.json(); + return response.json(); } export { apiService }; diff --git a/src/views/Auth/Auth.vue b/src/views/Auth/Auth.vue index fda116a..4af2021 100644 --- a/src/views/Auth/Auth.vue +++ b/src/views/Auth/Auth.vue @@ -1,9 +1,7 @@