diff --git a/src/App.vue b/src/App.vue index dc693f471ad9c9828c6519d81cea07c8bd5ce5ee..12ad03a6b286a47ed6a392e7338562c82b213f64 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,6 +1,6 @@ <script setup lang="ts"> import { RouterView } from 'vue-router' -// import ErrorBoundaryCatcher from '@/components/Exceptions/ErrorBoundaryCatcher.vue'; +import ErrorBoundaryCatcher from '@/components/Exceptions/ErrorBoundaryCatcher.vue'; </script> <template> diff --git a/src/components/BaseComponents/Menu.vue b/src/components/BaseComponents/Menu.vue index 1edc325513c43ee7c2373874f229f42bfd07033c..01f51f6d27942905236879a50568050475cfe3e8 100644 --- a/src/components/BaseComponents/Menu.vue +++ b/src/components/BaseComponents/Menu.vue @@ -28,10 +28,10 @@ <a class="nav-link text-white" href="#" @click="toStore"><img src="@/assets/icons/storefront.svg">Store</a> </li> - <li class="nav-item dropdown"> + <li v-if="userStore.isLoggedIn" class="nav-item dropdown"> <a class="nav-link dropdown-toggle username-text text-white " href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false"> - <img src="@/assets/icons/person.svg">Username + <img src="@/assets/icons/person.svg">{{ userStore.firstname }} </a> <ul class="dropdown-menu dropdown-username-content"> <li><a class="dropdown-item text-white dropdown-username-link" href="#" @@ -41,9 +41,12 @@ <li><a class="dropdown-item text-white dropdown-username-link" href="#" @click="toFeedback"><img src="@/assets/icons/feedback.svg">Feedback</a></li> <li><a class="dropdown-item text-white dropdown-username-link" href="#" - @click="toFeedback"><img src="@/assets/icons/logout.svg">Log out</a></li> + @click="toLogout"><img src="@/assets/icons/logout.svg">Log out</a></li> </ul> </li> + <li v-else class="nav-item"> + <a class="nav-link text-white" href="#" @click="toLogout">Login</a> + </li> </ul> </div> </div> @@ -51,9 +54,12 @@ </template> <script setup lang="ts"> import { useRouter } from "vue-router"; +import { useUserInfoStore } from '@/stores/UserStore'; const router = useRouter(); +const userStore = useUserInfoStore(); + function toHome() { router.push('/') } @@ -83,8 +89,13 @@ function toFeedback() { } -function toUserProfile(){ - router.push('/profile') +function toUserProfile() { + router.push('/profile') +} + +function toLogout() { + userStore.clearUserInfo(); + router.push('/login') } @@ -127,6 +138,11 @@ function toUserProfile(){ .dropdown-menu { background-color: #0A58CA; + right: -0.5rem; +} + +.dropdown-menu[data-bs-popper] { + left: auto; } .dropdown-username-link { diff --git a/src/components/Exceptions/ErrorBoundaryCatcher.vue b/src/components/Exceptions/ErrorBoundaryCatcher.vue index 3bc046fb271f7d3b3ce3acee559329d18dce53bb..fa80d8db5bcc4694fb10be7ad2ae1fad08af48aa 100644 --- a/src/components/Exceptions/ErrorBoundaryCatcher.vue +++ b/src/components/Exceptions/ErrorBoundaryCatcher.vue @@ -1,19 +1,19 @@ <template> - <error-box :error-message="errorStore.getFirstError" @update:errorMessage="errorStore.removeCurrentError" /> - <slot /> - </template> - - <script setup lang="ts"> - import { onErrorCaptured } from 'vue'; - import { useErrorStore } from '@/stores/ErrorStore'; - import ErrorBox from '@/components/Exceptions/ErrorBox.vue'; - import handleUnknownError from '@/components/Exceptions/unkownErrorHandler'; - - const errorStore = useErrorStore(); - - onErrorCaptured((err, _vm, _info): boolean => { - const message = handleUnknownError(err.message); - errorStore.addError(message); //If no openAPI axios error, use err.message - return false; - }); - </script> \ No newline at end of file + <error-box :error-message="errorStore.getFirstError" @update:errorMessage="errorStore.removeCurrentError" /> + <slot /> +</template> + +<script setup lang="ts"> +import { onErrorCaptured } from 'vue'; +import { useErrorStore } from '@/stores/ErrorStore'; +import ErrorBox from '@/components/Exceptions/ErrorBox.vue'; +import handleUnknownError from '@/components/Exceptions/unkownErrorHandler'; + +const errorStore = useErrorStore(); + +onErrorCaptured((err, _vm, _info): boolean => { + const message = handleUnknownError(err); + errorStore.addError(message); + return false; +}); +</script> \ No newline at end of file diff --git a/src/components/Exceptions/ErrorBox.vue b/src/components/Exceptions/ErrorBox.vue index f6dbe0d4adfb07e7ae1b4720ecf322b08fa3de71..d73c8b5feea6dd4e35bf86bb84ea042cce6081d5 100644 --- a/src/components/Exceptions/ErrorBox.vue +++ b/src/components/Exceptions/ErrorBox.vue @@ -1,90 +1,90 @@ <template> - <div class="error-box" v-if="errorMessage" data-testid="error-box"> - <span> - <v-icon name="bi-exclamation-triangle" /> - <button @click="wrapText = !wrapText" class="error-message-button"> - <h4>{{ errorMessage }}</h4> - </button> - <button class="error-remove-button" @click="$emit('update:errorMessage', '')" data-testid="hide-button"> - <v-icon scale="2" name="bi-dash" /> - </button> - </span> - </div> - </template> - - <script lang="ts"> - import { defineComponent } from 'vue'; - import { OhVueIcon, addIcons } from 'oh-vue-icons'; - import { BiDash, BiExclamationTriangle } from 'oh-vue-icons/icons'; - - addIcons(BiDash, BiExclamationTriangle); - - export default defineComponent({ - components: { - 'v-icon': OhVueIcon, + <div class="error-box" v-if="errorMessage" data-testid="error-box"> + <span> + <v-icon name="bi-exclamation-triangle" /> + <button @click="wrapText = !wrapText" class="error-message-button"> + <h4>{{ errorMessage }}</h4> + </button> + <button class="error-remove-button" @click="$emit('update:errorMessage', '')" data-testid="hide-button"> + <v-icon scale="2" name="bi-dash" /> + </button> + </span> + </div> +</template> + +<script lang="ts"> +import { defineComponent } from 'vue'; +import { OhVueIcon, addIcons } from 'oh-vue-icons'; +import { BiDash, BiExclamationTriangle } from 'oh-vue-icons/icons'; + +addIcons(BiDash, BiExclamationTriangle); + +export default defineComponent({ + components: { + 'v-icon': OhVueIcon, + }, + props: { + errorMessage: { + type: String, + default: '', }, - props: { - errorMessage: { - type: String, - default: '', - }, - }, - data() { - return { - wrapText: false, - }; - }, - }); - </script> - - <style scoped> - .error-box { - position: fixed; - top: 2em; - left: 50%; - transform: translate(-50%, 0); - width: min(100%, 700px); - background-color: var(--red-color); - padding: 7px; - border-radius: 5px; - z-index: 1000; - } - - .error-box span { - display: flex; - justify-content: space-between; - align-items: center; - } - - .error-message-button { - white-space: v-bind('wrapText ? "normal" : "nowrap"'); - overflow: hidden; - border: none; - } - - .error-message-button h4 { - overflow: hidden; - text-overflow: ellipsis; - } - - .error-box * { - margin: 2px; - } - - .error-box button { - background-color: transparent; - box-shadow: none; - color: black; - cursor: pointer; - } - - .error-remove-button { - color: rgb(79, 77, 77); - border: solid black 0.5px; - padding: 0.3em; - } - - .error-box button:hover { - color: rgb(40, 38, 38); - } - </style> \ No newline at end of file + }, + data() { + return { + wrapText: false, + }; + }, +}); +</script> + +<style scoped> +.error-box { + position: fixed; + top: 2em; + left: 50%; + transform: translate(-50%, 0); + width: min(100%, 700px); + background-color: var(--red-color); + padding: 7px; + border-radius: 5px; + z-index: 1000; +} + +.error-box span { + display: flex; + justify-content: space-between; + align-items: center; +} + +.error-message-button { + white-space: v-bind('wrapText ? "normal" : "nowrap"'); + overflow: hidden; + border: none; +} + +.error-message-button h4 { + overflow: hidden; + text-overflow: ellipsis; +} + +.error-box * { + margin: 2px; +} + +.error-box button { + background-color: transparent; + box-shadow: none; + color: black; + cursor: pointer; +} + +.error-remove-button { + color: rgb(79, 77, 77); + border: solid black 0.5px; + padding: 0.3em; +} + +.error-box button:hover { + color: rgb(40, 38, 38); +} +</style> \ No newline at end of file diff --git a/src/components/Exceptions/unkownErrorHandler.ts b/src/components/Exceptions/unkownErrorHandler.ts index 6f7b6d914edc88b03029a68b907f7ef45f05ee7e..68ecb6e09a91141f60b4641f7f38854a5aa0ca42 100644 --- a/src/components/Exceptions/unkownErrorHandler.ts +++ b/src/components/Exceptions/unkownErrorHandler.ts @@ -11,9 +11,9 @@ const handleUnknownError = (error: any): string => { if (error instanceof AxiosError) { return error.code!!; } else if (error instanceof BackendApiError) { - return error.body.detail ?? error.body; + return error.body.message ?? error.body; } - return 'ContextErrorMessage'; + return error; }; export default handleUnknownError; \ No newline at end of file diff --git a/src/components/Login/LoginForm.vue b/src/components/Login/LoginForm.vue index 22d6bfcc01d426a98a51dae4b110fe5216deb3e8..3b08c7d7c114206ad3b292cfc86c918beea7f670 100644 --- a/src/components/Login/LoginForm.vue +++ b/src/components/Login/LoginForm.vue @@ -11,6 +11,7 @@ import { useErrorStore } from '@/stores/ErrorStore'; const emailRef = ref() const passwordRef = ref() const formRef = ref() +let errorMsg = ref(''); const errorStore = useErrorStore(); const router = useRouter(); @@ -49,7 +50,7 @@ const handleSubmit = async () => { }); router.push({ name: 'home' }); } catch (error: any) { - console.log(error); + errorMsg.value = handleUnknownError(error); } } @@ -57,11 +58,12 @@ const handleSubmit = async () => { <template> <div class="container-fluid"> - <form ref="formRef" id="loginForm" @submit.prevent="handleSubmit"> + <form ref="formRef" id="loginForm" @submit.prevent="handleSubmit" novalidate> <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" /> + <p class="text-danger">{{ errorMsg }}</p> <button1 id="confirmButton" type="submit" @click="handleSubmit" button-text="Login"></button1> </form> </div> diff --git a/src/views/Authentication/LoginView.vue b/src/views/Authentication/LoginView.vue index a2aa0f410c32b81ef253338a1b657b19d732e442..92ff4ea8f2288a9e61950c797add14dfd0e20ac7 100644 --- a/src/views/Authentication/LoginView.vue +++ b/src/views/Authentication/LoginView.vue @@ -5,9 +5,7 @@ import Login from '@/components/Login/Login.vue' </script> <template> - <Menu/> <Login/> - <Footer/> </template> <style scoped>