diff --git a/src/assets/icons/template.svg b/src/assets/icons/template.svg new file mode 100644 index 0000000000000000000000000000000000000000..a1b6aed6090f0a233c6f5361b99dee7cc93fab01 --- /dev/null +++ b/src/assets/icons/template.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="m438-240 226-226-58-58-169 169-84-84-57 57 142 142ZM240-80q-33 0-56.5-23.5T160-160v-640q0-33 23.5-56.5T240-880h320l240 240v480q0 33-23.5 56.5T720-80H240Zm280-520v-200H240v640h480v-440H520ZM240-800v200-200 640-640Z"/></svg> \ No newline at end of file diff --git a/src/components/Admin/AdminFeedback.vue b/src/components/Admin/AdminFeedback.vue new file mode 100644 index 0000000000000000000000000000000000000000..677b77ae69a4d443df6d46ec1722d910284163fc --- /dev/null +++ b/src/components/Admin/AdminFeedback.vue @@ -0,0 +1,73 @@ +<script setup lang="ts"> +import { onMounted, ref } from 'vue' +import { type FeedbackResponseDTO, UserService } from '@/api' +import handleUnknownError from '@/components/Exceptions/unkownErrorHandler' + +const feedbacks = ref<FeedbackResponseDTO[]>([]); + +onMounted(async () => { + try { + feedbacks.value = await UserService.getFeedback(); + console.log(feedbacks.value) + } catch (error) { + handleUnknownError(error); + } +}) + +const formattedDate = (dateStr?: string): string => { + if (!dateStr) return ''; + return new Date(dateStr).toLocaleString(); +}; +</script> + +<template> + <div class="feedback-container"> + <h1>Feedback List</h1> + <div class="feedback-list"> + <!-- Loop through feedback items --> + <div class="feedback-item" v-for="feedback in feedbacks" :key="feedback.id"> + <div class="email">{{ feedback.email }}</div> + <div class="message">{{ feedback.message }}</div> + <div class="created-at">{{ formattedDate(feedback.createdAt) }}</div> + </div> + </div> + </div> +</template> + +<style scoped> +.feedback-container { + max-width: 800px; + margin: auto; + padding: 20px; +} + +.feedback-list { + margin-top: 20px; + border-top: 1px solid #ccc; +} + +.feedback-item { + padding: 10px; + border-bottom: 1px solid #ccc; +} + +.email, .message, .created-at { + padding: 5px 0; +} + +.email { + font-weight: bold; + color: #333; +} + +.message { + margin: 5px 0; + line-height: 1.5; + color: #666; +} + +.created-at { + font-size: 0.8rem; + color: #999; +} +</style> \ No newline at end of file diff --git a/src/components/BaseComponents/NavBar.vue b/src/components/BaseComponents/NavBar.vue index 27a9753ff0bc895d9adac389a9b1f47e9ee621a8..1bbaaeee286b2a6edeb3cef9fd35003243b7eb99 100644 --- a/src/components/BaseComponents/NavBar.vue +++ b/src/components/BaseComponents/NavBar.vue @@ -122,7 +122,7 @@ <li> <router-link data-cy="admin" class="dropdown-item dropdown-username-link" - :to="toSetting()" + :to="toAdmin()" exact-active-class="active-link" @click="toggleDropdown"> <img src="@/assets/icons/admin.svg">Admin @@ -313,6 +313,15 @@ function toFeedback(): string { return '/feedback'; } +/** + * Redirects to the admin page. + * + * @returns {string} The URL for the admin page. + */ +function toAdmin(): string { + return '/admin'; +} + /** * Redirects to the friends page. * diff --git a/src/components/Settings/SettingsBank.vue b/src/components/Settings/SettingsBank.vue index c923b7005efd5b4286edd9a4b26fe11954cb8f30..ba2f237634f03bd85f77aeae8342d0a4971d9c77 100644 --- a/src/components/Settings/SettingsBank.vue +++ b/src/components/Settings/SettingsBank.vue @@ -52,7 +52,7 @@ <script setup lang="ts"> import { ref, onMounted } from 'vue'; import BaseInput from '@/components/BaseComponents/Input/BaseInput.vue'; -import type { UserUpdateDTO } from '@/api' +import { AccountControllerService, type BalanceDTO, BankProfileControllerService, type UserUpdateDTO } from '@/api' import { UserService } from '@/api'; import handleUnknownError from '@/components/Exceptions/unkownErrorHandler' @@ -128,13 +128,16 @@ async function getAccountInfo() { try { let response = await UserService.getUser(); savingsAccount.value = response.savingsAccountBBAN; - /*if (response.savingsAccount?.balance) { - savingsAccountBalance.value = response.savingsAccount?.balance - }*/ + let bban1: any = response.savingsAccountBBAN; + AccountControllerService.getAccountsByBban({bban: bban1}).then((balance: BalanceDTO) => { + savingsAccountBalance.value = balance.balance; + }) + spendingAccount.value = response.checkingAccountBBAN; - /*if (response.checkingAccount?.balance) { - spendingAccountBalance.value = response.checkingAccountBBAN?.balance - }*/ + let bban2: any = response.checkingAccountBBAN; + AccountControllerService.getAccountsByBban({bban: bban2}).then((balance: BalanceDTO) => { + spendingAccountBalance.value = balance.balance; + }) } catch (err) { handleUnknownError(err) } diff --git a/src/router/index.ts b/src/router/index.ts index 2d1284aa1da81f104b6d9a22c238228ccdf5d568..5d22daa14e0a814cca8b96f4ab79038b31bb128c 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -28,6 +28,12 @@ const routes = [ name: 'profile', component: () => import('@/views/User/MyProfileView.vue'), }, + { + path: 'admin', + name: 'admin', + component: () => import('@/views/Admin/AdminDashboardView.vue'), + meta: { requiresAdmin: true } + }, { path: '/settings', name: 'settings', @@ -186,7 +192,7 @@ router.beforeEach((to, from, next) => { if (requiresAuth && !isAuthenticated) { next({ name: 'login', query: { redirect: to.fullPath } }); - } else if (requiresAdmin && userRole !== 'admin') { + } else if (requiresAdmin && userRole !== 'ADMIN') { next({ name: 'unauthorized' }); } else if (requiresPremium && userSubscription !== 'PREMIUM') { next({ name: 'home' }); diff --git a/src/views/Admin/AdminDashboardView.vue b/src/views/Admin/AdminDashboardView.vue new file mode 100644 index 0000000000000000000000000000000000000000..32398130be99dcff38e8c13d264b1cec6aa8c8e1 --- /dev/null +++ b/src/views/Admin/AdminDashboardView.vue @@ -0,0 +1,11 @@ +<script setup lang="ts"> +import AddminFeedback from "@/components/Admin/AdminFeedback.vue"; +</script> + +<template> + <AddminFeedback></AddminFeedback> +</template> + +<style scoped> + +</style> \ No newline at end of file diff --git a/src/views/User/UserFeedbackView.vue b/src/views/User/UserFeedbackView.vue index 3c28adbed9221b1b24edd8a33a6638531c293ffd..28a19b184a94fdede4f48198142ccf53da06e92d 100644 --- a/src/views/User/UserFeedbackView.vue +++ b/src/views/User/UserFeedbackView.vue @@ -2,15 +2,25 @@ <main> <div class="wrapper"> <div id="formFrame"> - <h1>TIlbakemelding</h1> - <form @submit.prevent="submitForm"> - <BaseInput v-model="email" label="Email" type="email" placeholder="Enter your email" inputId="email" required /> + <h1>Tilbakemelding</h1> + <form ref="formRef" id="loginForm" @submit.prevent="submitForm" novalidate> + <BaseInput :model-value="emailRef" + @input-change-event="handleEmailInputEvent" + id="emailInput" + input-id="email" + type="email" + label="E-post" + placeholder="Skriv inn din e-post" + invalid-message="Ugyldig e-post" + /> + <br> <label for="feedback">Din tilbakemelding:</label> - <textarea v-model="message" placeholder="Write here" rows="5" name="comment[text]" id="comment_text" cols="33" + <textarea v-model="messageRef" placeholder="Skriv meldingen din her" rows="5" name="comment[text]" id="comment_text" cols="33" required></textarea> - <BaseButton button-text="Send" @click="submitForm">Send inn</BaseButton> - <p v-if="submissionStatus">{{ submissionStatus }}</p> + <p data-cy="change-email-msg-error" class="text-danger">{{ errorMsg }}</p> + <BaseButton button-text="Send" @click="submitForm" style="padding: 10px 30px; font-size: 18px; font-weight: normal;">Send inn</BaseButton> + <p data-cy="change-email-msg-confirm" class="text-success">{{ confirmationMsg }}</p> </form> </div> </div> @@ -21,13 +31,33 @@ import { ref } from 'vue'; import BaseInput from '@/components/BaseComponents/Input/BaseInput.vue'; import BaseButton from '@/components/BaseComponents/Buttons/BaseButton.vue'; +import { type FeedbackRequestDTO, UserService } from '@/api' +import handleUnknownError from '@/components/Exceptions/unkownErrorHandler' + +const emailRef = ref(""); +const messageRef = ref(""); +const errorMsg = ref('') +const confirmationMsg = ref('') -const email = ref(""); -const message = ref(""); -const submissionStatus = ref(""); +const handleEmailInputEvent = (newValue: any) => { + emailRef.value = newValue +} const submitForm = async () => { - + try { + const feedbackRequest: FeedbackRequestDTO = { + email: emailRef.value, + message: messageRef.value + }; + console.log("feedbackRequest", feedbackRequest); + UserService.sendFeedback({ requestBody: feedbackRequest }); + messageRef.value = '' + errorMsg.value = '' + confirmationMsg.value = 'Tilbakemeldingen ble sendt!' + } catch (err) { + errorMsg.value = handleUnknownError(err); + confirmationMsg.value = '' + } }; </script>