diff --git a/package-lock.json b/package-lock.json index 380793cab4d9aec8226d36377a5a0f5f9ef907f5..05f3e7c65d110dbcb2eaa13715d7dac5e3c88dc5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "js-cookie": "^3.0.5", "oh-vue-icons": "^1.0.0-rc3", "pinia": "^2.1.7", + "pinia-plugin-persist": "^1.0.0", "vue": "^3.4.21", "vue-router": "^4.3.0", "xml2js": "^0.6.2" @@ -6412,6 +6413,49 @@ } } }, + "node_modules/pinia-plugin-persist": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pinia-plugin-persist/-/pinia-plugin-persist-1.0.0.tgz", + "integrity": "sha512-M4hBBd8fz/GgNmUPaaUsC29y1M09lqbXrMAHcusVoU8xlQi1TqgkWnnhvMikZwr7Le/hVyMx8KUcumGGrR6GVw==", + "dependencies": { + "vue-demi": "^0.12.1" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0", + "pinia": "^2.0.0", + "vue": "^2.0.0 || >=3.0.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, + "node_modules/pinia-plugin-persist/node_modules/vue-demi": { + "version": "0.12.5", + "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.12.5.tgz", + "integrity": "sha512-BREuTgTYlUr0zw0EZn3hnhC3I6gPWv+Kwh4MCih6QcAeaTlaIX0DwOVN0wHej7hSvDPecz4jygy/idsgKfW58Q==", + "hasInstallScript": true, + "bin": { + "vue-demi-fix": "bin/vue-demi-fix.js", + "vue-demi-switch": "bin/vue-demi-switch.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/antfu" + }, + "peerDependencies": { + "@vue/composition-api": "^1.0.0-rc.1", + "vue": "^3.0.0-0 || ^2.6.0" + }, + "peerDependenciesMeta": { + "@vue/composition-api": { + "optional": true + } + } + }, "node_modules/pinia/node_modules/vue-demi": { "version": "0.14.7", "resolved": "https://registry.npmjs.org/vue-demi/-/vue-demi-0.14.7.tgz", diff --git a/package.json b/package.json index abf7692db221f6ba8f6bcb90e1978cafe97b4ee2..fe648fd2342c222ce21ce8de1351ed04156581de 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "js-cookie": "^3.0.5", "oh-vue-icons": "^1.0.0-rc3", "pinia": "^2.1.7", + "pinia-plugin-persist": "^1.0.0", "vue": "^3.4.21", "vue-router": "^4.3.0", "xml2js": "^0.6.2" diff --git a/src/components/Login/LoginForm.vue b/src/components/Login/LoginForm.vue index b5198d4d2bee4fc6169eb58a845fe469e5ffdd3d..22d6bfcc01d426a98a51dae4b110fe5216deb3e8 100644 --- a/src/components/Login/LoginForm.vue +++ b/src/components/Login/LoginForm.vue @@ -2,11 +2,20 @@ import BaseInput from '@/components/InputFields/BaseInput.vue' import Button1 from '@/components/Buttons/Button1.vue' import { ref } from 'vue' +import { useUserInfoStore } from '@/stores/UserStore'; +import { AuthenticationService, OpenAPI, LoginRequest } from '@/api'; +import { useRouter, useRoute } from 'vue-router'; +import handleUnknownError from '@/components/Exceptions/unkownErrorHandler'; +import { useErrorStore } from '@/stores/ErrorStore'; const emailRef = ref() const passwordRef = ref() const formRef = ref() +const errorStore = useErrorStore(); +const router = useRouter(); +const userStore = useUserInfoStore(); + const handleEmailInputEvent = (newValue: any) => { emailRef.value = newValue } @@ -15,9 +24,33 @@ const handlePasswordInputEvent = (newValue: any) => { passwordRef.value = newValue } -const handleSubmit = () => { - formRef.value.classList.add("was-validated") - alert("Expected to be logged in when backend are finished") // Todo remove this line +const handleSubmit = async () => { + const loginUserPayload: LoginRequest = { + email: emailRef.value, + password: passwordRef.value + }; + + try { + let response = await AuthenticationService.login({ requestBody: loginUserPayload }); + + if (response.token == null || response.token == undefined) { + //errorBoxMsg.value = 'A valid token could not be created'; + return; + } + + OpenAPI.TOKEN = response.token; + + userStore.setUserInfo({ + accessToken: response.token, + firstname: response.firstName, + lastname: response.lastName, + email: emailRef.value, + role: response.role, + }); + router.push({ name: 'home' }); + } catch (error: any) { + console.log(error); + } } </script> @@ -25,20 +58,10 @@ const handleSubmit = () => { <template> <div class="container-fluid"> <form ref="formRef" id="loginForm" @submit.prevent="handleSubmit"> - <BaseInput :model-value="emailRef" - @input-change-event="handleEmailInputEvent" - id="emailInput" - input-id="email" - type="email" - label="Email" - placeholder="Enter your email"/> - <BaseInput :model-value="passwordRef" - @input-change-event="handlePasswordInputEvent" - id="passwordInput" - input-id="password" - type="password" - label="Password" - placeholder="Enter password"/> + <BaseInput :model-value="emailRef" @input-change-event="handleEmailInputEvent" id="emailInput" input-id="email" + type="email" label="Email" placeholder="Enter your email" /> + <BaseInput :model-value="passwordRef" @input-change-event="handlePasswordInputEvent" id="passwordInput" + input-id="password" type="password" label="Password" placeholder="Enter password" /> <button1 id="confirmButton" type="submit" @click="handleSubmit" button-text="Login"></button1> </form> </div> @@ -46,7 +69,7 @@ const handleSubmit = () => { <style scoped> .container-fluid { - max-width: 450px; + max-width: 450px; } #loginForm { @@ -55,7 +78,9 @@ const handleSubmit = () => { justify-items: center; } -#emailInput, #passwordInput, #confirmButton { +#emailInput, +#passwordInput, +#confirmButton { margin: 1rem 0; } </style> \ No newline at end of file diff --git a/src/main.ts b/src/main.ts index 8b82528c65bb6e04e29daae216ab4c2abc227105..c97fa3b809456298fe0d0dbb0b7c87658d0b796a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -2,6 +2,7 @@ import './assets/main.css' import { createApp } from 'vue' import { createPinia } from 'pinia' +import piniaPersist from 'pinia-plugin-persist'; import App from './App.vue' import router from './router' @@ -9,9 +10,10 @@ import router from './router' import 'bootstrap/dist/css/bootstrap.min.css'; import 'bootstrap'; -const app = createApp(App) +const app = createApp(App); +const pinia = createPinia(); +pinia.use(piniaPersist); -app.use(createPinia()) +app.use(pinia) app.use(router) - app.mount('#app') diff --git a/src/stores/UserStore.ts b/src/stores/UserStore.ts index bd1a32d7b5dab2a33b1b73b1df068f9688fd9415..5fbdf1e65bb7759f4434051694661543033900e1 100644 --- a/src/stores/UserStore.ts +++ b/src/stores/UserStore.ts @@ -2,6 +2,7 @@ import { OpenAPI } from '@/api'; import Cookies from 'js-cookie'; import { defineStore } from 'pinia'; + const cookiesStorage: Storage = { setItem(key, state) { return Cookies.set(key, state, { expires: 3 }); @@ -29,7 +30,7 @@ const cookiesStorage: Storage = { }; export type UserStoreInfo = { - username?: string; + email?: string; firstname?: string; lastname?: string; accessToken?: string; @@ -38,7 +39,7 @@ export type UserStoreInfo = { export const useUserInfoStore = defineStore('UserInfoStore', { state: () => ({ - username: '', + email: '', firstname: '', lastname: '', accessToken: '', @@ -46,7 +47,7 @@ export const useUserInfoStore = defineStore('UserInfoStore', { }), actions: { setUserInfo(userinfo: UserStoreInfo) { - userinfo.username && (this.$state.username = userinfo.username); + userinfo.email && (this.$state.email = userinfo.email); userinfo.firstname && (this.$state.firstname = userinfo.firstname); userinfo.lastname && (this.$state.lastname = userinfo.lastname); userinfo.accessToken && (this.$state.accessToken = userinfo.accessToken); @@ -54,7 +55,7 @@ export const useUserInfoStore = defineStore('UserInfoStore', { userinfo.role && (this.$state.role = userinfo.role); }, clearUserInfo() { - this.$state.username = ''; + this.$state.email = ''; this.$state.firstname = ''; this.$state.lastname = ''; this.$state.accessToken = ''; @@ -69,6 +70,6 @@ export const useUserInfoStore = defineStore('UserInfoStore', { }, persist: { enabled: true, - strategies: [{ key: 'userInfo', storage: cookiesStorage }], + strategies: [{ key: 'userInfo', storage: cookiesStorage }] }, }); \ No newline at end of file