diff --git a/src/api/models/UserDTO.ts b/src/api/models/UserDTO.ts index a94d14567640f5d9b30901361f5fd94097ce2f93..cdad85b76fea904e17534685232423e6a00d54ae 100644 --- a/src/api/models/UserDTO.ts +++ b/src/api/models/UserDTO.ts @@ -2,6 +2,7 @@ /* istanbul ignore file */ /* tslint:disable */ /* eslint-disable */ +import type { ConfigurationDTO } from './ConfigurationDTO'; import type { PointDTO } from './PointDTO'; import type { StreakDTO } from './StreakDTO'; export type UserDTO = { @@ -18,5 +19,6 @@ export type UserDTO = { savingsAccountBBAN?: number; point?: PointDTO; streak?: StreakDTO; + configuration?: ConfigurationDTO; }; diff --git a/src/components/BaseComponents/ConfirmationModal.vue b/src/components/BaseComponents/ConfirmationModal.vue deleted file mode 100644 index 438ff362e01d693aa2d6663c2176e167c5281de1..0000000000000000000000000000000000000000 --- a/src/components/BaseComponents/ConfirmationModal.vue +++ /dev/null @@ -1,38 +0,0 @@ -<!-- ConfirmationModal.vue --> -<template> - <div class="modal" :id="modalId" tabindex="-1" aria-labelledby="modalLabel" aria-hidden="true" - data-bs-backdrop="static" data-bs-keyboard="false"> - <div class="modal-dialog"> - <div class="modal-content"> - <div class="modal-header"> - <h5 class="modal-title" id="modalLabel">{{ title }}</h5> - <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> - </div> - <div class="modal-body"> - {{ message }} - </div> - <div class="modal-footer"> - <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">{{ cancelButtonText }}</button> - <button type="button" class="btn btn-primary" @click="confirmAction">{{ confirmButtonText }}</button> - </div> - </div> - </div> - </div> - </template> - - <script setup> - import { ref } from 'vue'; - - const modalId = ref(null); - - const title = 'Confirm Action'; - const message = 'Are you sure you want to proceed?'; - const confirmButtonText = 'Confirm'; - const cancelButtonText = 'Cancel'; - - // Methods - function confirmAction() { - emit('confirm'); - } - </script> - \ No newline at end of file diff --git a/src/components/News/NewsFeed.vue b/src/components/News/NewsFeed.vue index 99abc7c31974222468ecd2b9c7da81bccb33e6c6..a041fcfc216f240fb0eeccf0c3c2b748c84f00c3 100644 --- a/src/components/News/NewsFeed.vue +++ b/src/components/News/NewsFeed.vue @@ -33,7 +33,7 @@ export default { async fetchFinanceNews() { try { const response = await fetch( - 'https://newsapi.org/v2/everything?q=saving%20money&pageSize=10&apiKey=f092756b3b6b41369b047cb7ae980db5' + 'https://newsapi.org/v2/everything?q=spare%20penger&pageSize=10&language=no&apiKey=f092756b3b6b41369b047cb7ae980db5' ); const data = await response.json(); diff --git a/src/components/SavingGoal/SavingGoal.vue b/src/components/SavingGoal/SavingGoal.vue index 0ae8f52b788036ee227a3446f0d9050561e938f6..25eb2023c1dfe4c0ff763b451fbb5e3b7f384ed9 100644 --- a/src/components/SavingGoal/SavingGoal.vue +++ b/src/components/SavingGoal/SavingGoal.vue @@ -101,10 +101,17 @@ export default { .cont { padding-left: 10px; margin: 0; + margin-left: -140px; width: 98%; box-sizing: unset; } +@media (max-width: 768px) { + .cont { + margin-left: -20px; + } +} + .blue-background { margin-top: 20px; margin-bottom: 20px; diff --git a/src/components/Settings/SettingsAccount.vue b/src/components/Settings/SettingsAccount.vue index 68f2123af8a3d6ff930ac5efe9a97ba2d79748ed..038cf5fc7d2f004926bffd3fdbc807a7a0b7821f 100644 --- a/src/components/Settings/SettingsAccount.vue +++ b/src/components/Settings/SettingsAccount.vue @@ -1,128 +1,171 @@ <script setup lang="ts"> -import { ref, onMounted } from 'vue'; +import { ref, onMounted } from 'vue' import BaseInput from '@/components/BaseComponents/Input/BaseInput.vue'; import { useUserInfoStore } from "@/stores/UserStore"; -import { UserService } from '@/api'; +import { UserService } from '@/api' import type { UserUpdateDTO } from '@/api'; import handleUnknownError from '@/components/Exceptions/unkownErrorHandler'; import router from '@/router' -const emailRef = ref('') -const errorMsg = ref('') -const confirmationMsg = ref('') -const errorMsg2 = ref('') +const emailRef = ref(''); +const errorMsg = ref(''); +const errorMsg3 = ref(''); +const confirmationMsg = ref(''); +const confirmationMsg2 = ref(''); +const errorMsg2 = ref(''); +const commitmentRef = ref('MUCH'); +const challengesRef = ref<any>([]); + +// Represents a list of available challenges. +const challenges: string[] = [ + 'NO_COFFEE', 'NO_CAR', 'SHORTER_SHOWER', 'SPEND_LESS_ON_FOOD', + 'BUY_USED_CLOTHES', 'LESS_SHOPPING', 'DROP_SUBSCRIPTION', 'SELL_SOMETHING', + 'BUY_USED', 'EAT_PACKED_LUNCH', 'STOP_SHOPPING', 'ZERO_SPENDING', + 'RENT_YOUR_STUFF', 'MEATLESS', 'SCREEN_TIME_LIMIT', 'UNPLUGGED_ENTERTAINMENT' +]; + +const challengeMapper: any = { + "NO_COFFEE": "Droppe kaffe", + "NO_CAR": "Droppe bil", + "SHORTER_SHOWER": "Ta kortere dusjer", + "SPEND_LESS_ON_FOOD": "Bruk mindre penger på mat", + "BUY_USED_CLOTHES": "Kjøp brukte klær", + "LESS_SHOPPING": "Handle mindre", + "DROP_SUBSCRIPTION": "Si opp abonnement", + "SELL_SOMETHING": "Selg noe", + "BUY_USED": "Kjøp brukt", + "EAT_PACKED_LUNCH": "Lag niste", + "STOP_SHOPPING": "Shoppestopp", + "ZERO_SPENDING": "Null-forbruk", + "RENT_YOUR_STUFF": "Lei ut ting", + "MEATLESS": "Kjøttfritt", + "SCREEN_TIME_LIMIT": "Skjerm tidsgrense", + "UNPLUGGED_ENTERTAINMENT": "Strømløs underholdning" +}; -/** - * Handles the email input event by updating the email reference value. - * - * @param {any} newValue - The new value of the email input. - */ const handleEmailInputEvent = (newValue: any) => { - emailRef.value = newValue -} + emailRef.value = newValue; +}; -/** - * Sets up the form by fetching user data and populating the email field if available. - * Clears confirmation and error messages. - * Handles errors by displaying a generic error message and updating the error message field. - */ async function setupForm() { try { - let response = await UserService.getUser(); + const response: any = await UserService.getUser(); + console.log(response); + if (response.configuration) { + commitmentRef.value = response.configuration.commitment; + challengesRef.value = response.configuration.challengeTypes; + } if (response.email != null) { - emailRef.value = response.email + emailRef.value = response.email; } confirmationMsg.value = ''; errorMsg.value = ''; } catch (err) { errorMsg.value = handleUnknownError(err); - confirmationMsg.value = '' + confirmationMsg.value = ''; } } -/** - * Handles form submission by updating the user's email. - * Updates the confirmation message upon successful email update. - * Handles errors and updates the error message accordingly. - */ +const handleSubmitConfig = async () => { + const updateUserPayload: UserUpdateDTO = { + configuration: { + commitment: commitmentRef.value, + challengeTypes: challengesRef.value + } + }; + try { + await UserService.update({ requestBody: updateUserPayload }); + confirmationMsg2.value = 'Oppdatert!'; + errorMsg3.value = ''; + } catch (err) { + errorMsg3.value = handleUnknownError(err); + confirmationMsg2.value = ''; + } +}; + const handleSubmit = async () => { - // Construct payload for updating user email const updateUserPayload: UserUpdateDTO = { email: emailRef.value, }; try { - // Send request to update user email - UserService.update({ requestBody: updateUserPayload }) - // Update user info in the store + await UserService.update({ requestBody: updateUserPayload }); useUserInfoStore().setUserInfo({ - email: emailRef.value, - }) - confirmationMsg.value = 'Email updated successfully!' + email: emailRef.value, + }); + confirmationMsg.value = 'Email updated successfully!'; errorMsg.value = ''; } catch (err) { handleUnknownError(err); errorMsg.value = "Error updating email, try again!"; - confirmationMsg.value = '' + confirmationMsg.value = ''; } -} +}; const handleSubmit2 = async () => { try { - console.log("test") - UserService.deleteUser(); - console.log("test") + await UserService.deleteUser(); useUserInfoStore().clearUserInfo(); await router.push("/login"); } catch (err) { errorMsg2.value = handleUnknownError(err); } -} +}; + onMounted(() => { - setupForm() -}) + setupForm(); +}); + +const onChangedChallengeEvent = (value: string) => { + if (challengesRef.value.includes(value)) { + challengesRef.value = challengesRef.value.filter((item: string) => item !== value); + } else { + challengesRef.value.push(value); + } +}; </script> + <template> <div class="tab-pane active" id="account"> - <h6>KONTO</h6> - <hr> - <form @submit.prevent="handleSubmit"> - <div class="form-group"> - <BaseInput data-cy="email-input" :model-value="emailRef" - @input-change-event="handleEmailInputEvent" id="emailInput-change" - input-id="email-new" type="email" label="E-post" placeholder="Skriv inn din e-post" - invalid-message="Ugyldig e-post"/> - </div> - <p data-cy="change-email-msg-error" class="text-danger">{{ errorMsg }}</p> - <p data-cy="change-email-msg-confirm" class="text-success">{{ confirmationMsg }}</p> - <br> - <button data-cy="change-email-btn" type="submit" class="btn btn-primary classyButton">Endre - Informasjon</button> - </form> - <form @submit.prevent="handleSubmit2" style="margin-top: 20px;"> - <div class="form-group"> - <label class="d-block text-danger">Slett Bruker</label> - <p class="text-muted font-size-sm">Obs: Når du først har slettet kontoen din, er det ingen vei tilbake.</p> - </div> - <p data-cy="delete-user-msg-error" class="text-danger">{{ errorMsg2 }}</p> - <button class="btn btn-danger" type="submit">Slett Bruker</button> - </form> + <h6>KONTO</h6> + <hr> + <form @submit.prevent="handleSubmit"> + <div class="form-group"> + <BaseInput data-cy="email-input" :model-value="emailRef" @input-change-event="handleEmailInputEvent" + id="emailInput-change" input-id="email-new" type="email" label="E-post" placeholder="Skriv inn din e-post" + invalid-message="Ugyldig e-post" /> + </div> + <p data-cy="change-email-msg-error" class="text-danger">{{ errorMsg }}</p> + <p data-cy="change-email-msg-confirm" class="text-success">{{ confirmationMsg }}</p> + <br> + <button data-cy="change-email-btn" type="submit" class="btn btn-primary classyButton">Oppdater</button> + </form> + <hr> + <form @submit.prevent="handleSubmit2" style="margin-top: 20px;"> + <div class="form-group"> + <label class="d-block text-danger">Slett Bruker</label> + <p class="text-muted font-size-sm">Obs: Når du først har slettet kontoen din, er det ingen vei tilbake.</p> + </div> + <p data-cy="delete-user-msg-error" class="text-danger">{{ errorMsg2 }}</p> + <button class="btn btn-danger" type="submit">Slett Bruker</button> + </form> </div> </template> + <style scoped> - .classyButton { - background-color: #003A58; - border: #003A58; - } +.classyButton { + background-color: #003A58; + border: #003A58; +} - .classyButton:hover { - background-color: #003b58ec; - border: #003A58; - } +.classyButton:hover { + background-color: #003b58ec; + border: #003A58; +} - .classyButton:active { - background-color: #003b58d6; - border: #003A58; - } +.classyButton:active { + background-color: #003b58d6; + border: #003A58; +} </style> diff --git a/src/components/Shop/ItemShop.vue b/src/components/Shop/ItemShop.vue index 60f544d0c4897cdc076e852ecc38f2a5a629b36b..350603abae74b0c8f6e94b9d5ae33392e42938f8 100644 --- a/src/components/Shop/ItemShop.vue +++ b/src/components/Shop/ItemShop.vue @@ -10,13 +10,13 @@ <div class="container d-flex justify-content-center"> <div class="row col-md-10"> <div class="col-md-12"> - <h1>Stash</h1> + <h1>Utvidelser</h1> <div class="category row mb-2 m-2"> <div class="card text-center justify-content-center align-items-center" style="width: 8rem; border: none"> <img src="../../assets/items/adfree.png" class="card-img-top" alt="..." style="width: 100px; height: 100px;" /> <div class="card-body"> - <h5 class="card-title">Adfree</h5> + <h5 class="card-title">Reklamefri</h5> <button type="button" class="btn btn-primary" id="buttonStyle" data-toggle="modal" data-target="#adfreeModal"> +35kr @@ -37,7 +37,7 @@ </div> </div> <div class="col-md-12"> - <h1>Items</h1> + <h1>Banner</h1> <div class="category row mb-2 m-2"> <div v-for="product in products" :key="product.id" class="card text-center d-flex justify-content-center align-items-center" @@ -47,24 +47,24 @@ <div class="card-body"> <h5 class="card-title">{{ product.itemName }}</h5> <h6>{{ product.price }}<img src="../../assets/items/pigcoin.png" style="width: 2rem" /></h6> - <ShopButton v-if="!product.alreadyBought" button-text="Buy item" :disabled="product.price > points" + <ShopButton v-if="!product.alreadyBought" button-text="Kjøp gjennstand" :disabled="product.price > points" @click="buyItem(product.id)" /> - <p v-else>Owned</p> + <p v-else>Eid</p> </div> </div> </div> </div> <div class="col-md-12"> - <h1>Cool items</h1> + <h1>Tjenester</h1> <div class="category row mb-2 m-2"> <div class="card text-center d-flex justify-content-center align-items-center" style="width: 8rem; border: none"> <img src="../../assets/items/coffee.jpg" class="card-img-top" alt="..." style="width: 100px; height: 100px;"> <div class="card-body"> - <h5 class="card-title">Free Coffee</h5> + <h5 class="card-title">Gratis kaffe</h5> <h6>500<img src="../../assets/items/pigcoin.png" style="width: 2rem"></h6> - <ShopButton button-text="Buy item" :disabled="500 > points" @click="buySomething()" /> + <ShopButton button-text="Kjøp gjennstand" :disabled="500 > points" @click="buySomething()" /> </div> </div> <div class="card text-center d-flex justify-content-center align-items-center" @@ -72,9 +72,9 @@ <img src="../../assets/items/viaplay.jpg" class="card-img-top" alt="..." style="width: 100px; height: 100px;"> <div class="card-body"> - <h5 class="card-title">1 Month</h5> + <h5 class="card-title">1 Måned</h5> <h6>10 000<img src="../../assets/items/pigcoin.png" style="width: 2rem"></h6> - <ShopButton button-text="Buy item" :disabled="10000 > points" @click="buySomething()" /> + <ShopButton button-text="Kjøp gjennstand" :disabled="10000 > points" @click="buySomething()" /> </div> </div> <div class="card text-center d-flex justify-content-center align-items-center" @@ -84,7 +84,7 @@ <div class="card-body"> <h5 class="card-title">-10% rabatt</h5> <h6>1000<img src="../../assets/items/pigcoin.png" style="width: 2rem"></h6> - <ShopButton button-text="Buy item" :disabled="1000 > points" @click="buySomething()" /> + <ShopButton button-text="Kjøp gjennstand" :disabled="1000 > points" @click="buySomething()" /> </div> </div> </div> @@ -157,7 +157,7 @@ import handleUnknownError from '@/components/Exceptions/unkownErrorHandler'; let apiUrl = import.meta.env.VITE_APP_API_URL; const products = ref([] as any); -const points = ref(); +const points = ref(0 as any); /** * Retrieves the store's products and updates the products list. @@ -178,7 +178,9 @@ const getStore = async () => { const getPoints = async () => { try { const response = await UserService.getUser(); - points.value = response.point?.currentPoints; + if (response.point?.currentPoints !== null) { + points.value = response.point?.currentPoints; + } } catch (error) { handleUnknownError(error); console.log(error); diff --git a/src/components/UserProfile/MyProfile.vue b/src/components/UserProfile/MyProfile.vue index e6a4871922b77d5dd24d5903c11ce18e9645f492..9ef9add95c9d8b50f1aa400a82d3d817e584345e 100644 --- a/src/components/UserProfile/MyProfile.vue +++ b/src/components/UserProfile/MyProfile.vue @@ -334,7 +334,7 @@ const toUpdateUserSettings = () => { height: 200px; } -@media (max-width: 940px) { +@media (max-width: 980px) { #banner { height: 320px; }