diff --git a/src/App.vue b/src/App.vue index fce63710ce53e6e5aed841c01ee4cb833b187fe6..510b3b1f5301d25a1974acfeb8a52a64abaee399 100644 --- a/src/App.vue +++ b/src/App.vue @@ -2,6 +2,7 @@ import NavBarComponent from '@/components/NavBarComponent.vue' import { RouterView, useRoute } from 'vue-router' import { computed } from 'vue' +import HelpComponent from '@/components/HelpComponent.vue' const route = useRoute() @@ -14,6 +15,106 @@ const showNavBar = computed(() => { route.path.startsWith('/konfigurasjon') ) }) + +const showHelp = computed(() => { + return !( + route.path == '/' || + route.path == '/registrer' || + route.path == '/logginn' || + route.path == '/forgotPassword' || + route.path.startsWith('/konfigurasjon') + ) +}) + +const helpMessages = computed(() => { + let messages = [] + + if (route.path == '/hjem') { + messages.push('Heisann, jeg er Spare!') + messages.push('Jeg skal hjelpe deg med Ã¥ spare penger 💵') + messages.push('Du kan legge til sparemÃ¥l og spareutfordringer!') + messages.push('Sammen kan vi spare penger og nÃ¥ dine mÃ¥l! 🚀') + } else if (route.path == '/profil') { + messages.push('Du har kommet til profilen din ðŸ·') + messages.push('Her kan du se en oversikt over dine profilinstillinger âš™ï¸') + messages.push('Du kan ogsÃ¥ se dine fullførte sparemÃ¥l og utfordringer!') + messages.push('Du kan redigere profilen din ved Ã¥ trykke pÃ¥ "Rediger bruker" 💎') + } else if (route.path == '/profil/rediger') { + messages.push('ï¸Her kan du se og redigere dine profil-instillinger 🪄') + messages.push('For Ã¥ lagre endringene dine, trykk pÃ¥ "Lagre endringer" i høyre hjørne') + messages.push( + 'Husk at passordet ditt mÃ¥ være minst 8 tegn langt, og inneholde minst ett tall, en stor bokstav, en liten bokstav, og et spesialtegn' + ) + } else if (route.path == '/sparemaal') { + messages.push('Du har kommet til sparemÃ¥lene dine 🎯') + messages.push( + 'Et sparemÃ¥l kan være noe du ønsker Ã¥ spare penger til, for eksempel en ferie ðŸ–ï¸ eller en ny sykkel 🚴ðŸ»' + ) + messages.push( + 'Du kan lage nye sparemÃ¥l ved Ã¥ trykke pÃ¥ knappen "Opprett et nytt sparemÃ¥l".' + ) + messages.push( + 'Du kan ogsÃ¥ endre rekkefølgen pÃ¥ sparemÃ¥lene dine ved Ã¥ trykke pÃ¥ "Endre rekkefølge".' + ) + messages.push( + 'NÃ¥r du har fullført et sparemÃ¥l, vil det dukke opp under "Fullførte sparemÃ¥l".' + ) + messages.push('Lykke til med mÃ¥lene dine! 🎀') + } else if (route.path == '/spareutfordringer') { + messages.push('Du har kommet til spareutfordringene dine 💰') + messages.push( + 'En spareutfordring er en mÃ¥te Ã¥ bli kvitt dÃ¥rlige vaner, samtidig spare penger for Ã¥ nÃ¥ dine mÃ¥l ✨' + ) + messages.push('Du kan opprette en ny utfordring ved Ã¥ trykke pÃ¥ "Opprett en ny utfordring"') + messages.push( + 'Du kan ogsÃ¥ endre rekkefølgen pÃ¥ utfordringene dine ved Ã¥ trykke pÃ¥ "Endre rekkefølge".' + ) + messages.push( + 'NÃ¥r du har fullført en utfordring, vil den dukke opp under "Fullførte utfordringer".' + ) + messages.push('Lykke til med utfordringene dine ðŸ†') + } else if (route.path.startsWith('/sparemaal/oversikt')) { + messages.push('Her har du en oversikt over sparemÃ¥let ditt 🗽') + messages.push('Du kan redigere mÃ¥let, markere det som ferdig eller slette det') + messages.push( + 'Du kan ogsÃ¥ se hvor mye du har spart av mÃ¥let ditt, og hvor mye du har igjen' + ) + } else if (route.path.startsWith('/spareutfordringer/oversikt')) { + messages.push('Her har du en oversikt over spareutfordringen din ðŸ”ï¸') + messages.push('Du kan redigere utfordringen, markere det som ferdig eller slette det') + messages.push( + 'Du kan ogsÃ¥ se hvor mye du har spart av utfordringen din, og hvor mye du har igjen' + ) + } else if (route.path.startsWith('/sparemaal/rediger')) { + messages.push('Her kan du opprette et nytt sparemÃ¥l 🌸') + messages.push( + 'Tittel er navnet pÃ¥ sparemÃ¥let, og beskrivelse er en kort forklaring pÃ¥ hva sparemÃ¥let gÃ¥r ut pÃ¥.' + ) + messages.push( + 'Kroner spart er hvor mye du har spart til nÃ¥, og av mÃ¥lbeløp er hvor mye du ønsker Ã¥ spare.' + ) + messages.push('Forfallsdato er datoen du ønsker Ã¥ ha nÃ¥dd sparemÃ¥let ditt.') + messages.push('Lykke til med sparingen! 🌴') + } else if (route.path.startsWith('/spareutfordring/rediger')) { + messages.push('Her kan du opprette en ny utfordring ☕ï¸') + messages.push( + 'Tittel er navnet pÃ¥ utfordringen, og beskrivelse er en kort forklaring pÃ¥ hva utfordringen gÃ¥r ut pÃ¥.' + ) + messages.push( + 'Pris per sparing er hvor mye du sparer hver gang du sparer, og antall sparinger er hvor mange ganger du har spart.' + ) + messages.push( + 'Av mÃ¥lbeløp er hvor mye du har spart til nÃ¥, og forfallsdato er nÃ¥r utfordringen skal være fullført.' + ) + messages.push('Du kan selvsagt endre pÃ¥ dette senere!') + messages.push('Lykke til med utfordringen din! 🎉') + } else { + messages.push('Hei! Jeg er Spare ðŸ·') + messages.push('Jeg er her for Ã¥ hjelpe deg med sparingen din 💰') + messages.push('Kom igang nÃ¥ 🔥') + } + return messages +}) </script> <template> @@ -21,6 +122,7 @@ const showNavBar = computed(() => { <main class="mb-10"> <RouterView /> + <HelpComponent v-if="showHelp" :speech="helpMessages" /> </main> </template> diff --git a/src/components/HelpComponent.vue b/src/components/HelpComponent.vue new file mode 100644 index 0000000000000000000000000000000000000000..54d5cd0b6e8dd90882edf1ba7818337989d0bb29 --- /dev/null +++ b/src/components/HelpComponent.vue @@ -0,0 +1,39 @@ +<template> + <div class="fixed bottom-5 left-5"> + <div @click="isModalOpen = true" class="hover:cursor-pointer"> + <img + alt="Hjelp" + class="w-1/12 transition-transform duration-300 ease-in-out hover:scale-110" + src="@/assets/hjelp.png" + /> + </div> + </div> + <ModalComponent v-if="isModalOpen" @close="isModalOpen = false"> + <InteractiveSpare + :speech="speech" + :png-size="15" + direction="right" + @emit:close="isModalOpen = false" + /> + + <div class="-mb-5 mt-8 text-xs text-gray-500"> + <p class="justify-center items-center">Trykk for Ã¥ se hva Spare har Ã¥ si!</p> + <a + @click="isModalOpen = false" + class="underline hover:bg-transparent font-normal text-gray-500 cursor-pointer transition-none hover:transition-none hover:p-0" + > + Skip + </a> + </div> + </ModalComponent> +</template> + +<script setup lang="ts"> +import InteractiveSpare from '@/components/InteractiveSpare.vue' +import { ref } from 'vue' +import ModalComponent from '@/components/ModalComponent.vue' + +const isModalOpen = ref(false) + +defineProps(['speech']) +</script> diff --git a/src/components/InteractiveSpare.vue b/src/components/InteractiveSpare.vue index e494738e8df5f7ec5c7a6a22f419b9825f71ccd8..ee727c5b0bc753c478f2b60cdc730476af8aa729 100644 --- a/src/components/InteractiveSpare.vue +++ b/src/components/InteractiveSpare.vue @@ -1,97 +1,54 @@ <template> - <ModalComponent :is-modal-open="isModalOpen" @close="isModalOpen = false"> - <template v-slot:input> - <div - class="spareDiv flex items-center mr-10 max-w-[60vh] cursor-pointer" - :class="{ - 'flex-row': direction === 'right', - 'flex-row-reverse': direction === 'left' - }" - @click="nextSpeech" - > - <!-- Image --> - <img - :src="spareImageSrc" - :style="{ width: pngSize + 'rem', height: pngSize + 'rem' }" - :class="['object-contain', ...imageClass]" - alt="Spare" - class="w-dynamic h-dynamic object-contain" - /> - - <!-- Speech Bubble --> - <div - v-if="currentSpeech" - :class="`mb-40 inline-block relative w-64 bg-white p-4 rounded-3xl border border-gray-600 tri-right round ${bubbleDirection}`" - > - <div class="text-left leading-6"> - <p class="speech m-0">{{ currentSpeech }}</p> - </div> - </div> - </div> - <div class="-mb-5 mt-8 text-xs text-gray-500"> - <p class="justify-center items-center">Trykk for Ã¥ se hva Spare har Ã¥ si!</p> - <a - @click="clearSpeeches" - class="underline hover:bg-transparent font-normal text-gray-500 cursor-pointer transition-none hover:transition-none hover:p-0" - > - Skip - </a> + <div + class="spareDiv flex items-center mr-10 max-w-[60vh] cursor-pointer" + :class="{ + 'flex-row': direction === 'right', + 'flex-row-reverse': direction === 'left' + }" + @click="nextSpeech" + > + <!-- Image --> + <img + :src="spareImageSrc" + :style="{ width: pngSize + 'rem', height: pngSize + 'rem' }" + :class="['object-contain', ...imageClass]" + alt="Spare" + class="w-dynamic h-dynamic object-contain" + /> + + <!-- Speech Bubble --> + <div + :class="`mb-40 inline-block relative w-64 bg-white p-4 rounded-3xl border border-gray-600 tri-right round ${bubbleDirection}`" + > + <div class="text-left leading-6"> + <p class="speech m-0">{{ currentSpeech }}</p> </div> - </template> - </ModalComponent> + </div> + </div> </template> <script setup lang="ts"> -import { computed, defineProps, ref, watch } from 'vue' +import { computed, defineProps, ref } from 'vue' import spareImageSrc from '@/assets/spare.png' -import ModalComponent from '@/components/ModalComponent.vue' interface Props { - speech: string[] | null + speech?: Array<string> direction: 'left' | 'right' pngSize: number - isModalOpen: boolean } const props = defineProps<Props>() - const speech = ref<string[]>(props.speech || []) -const isModalOpen = ref(props.isModalOpen) - -// Watch the speech prop for changes -watch( - () => props.speech, - (newVal) => { - if (newVal) { - // Check if the new value is not null - speech.value = newVal // Update the reactive speech array - currentSpeechIndex.value = 0 // Reset the speech index - isModalOpen.value = true // Open the modal if new speech is available - } else { - speech.value = [] // Clear the speech array if null is received - isModalOpen.value = false // Close the modal if there's no speech - } - } -) - const currentSpeechIndex = ref(0) const currentSpeech = computed(() => speech.value[currentSpeechIndex.value]) -const nextSpeech = () => { - if (speech.value.length > 0) { - // Remove the currently displayed speech first - speech.value.splice(currentSpeechIndex.value, 1) +const emit = defineEmits(['emit:close']) - // Check if there are any speeches left after removal - if (speech.value.length > 0) { - // Move to the next speech or reset to the beginning if the current index is out of range - currentSpeechIndex.value = currentSpeechIndex.value % speech.value.length - } else { - // If no speeches left, reset index to indicate no available speech - currentSpeechIndex.value = -1 - // Close the modal if there are no speeches left - modalClosed() - } +const nextSpeech = () => { + if (currentSpeechIndex.value < speech.value.length - 1) { + currentSpeechIndex.value++ + } else { + emit('emit:close') } } @@ -105,16 +62,6 @@ const imageClass = computed(() => { const bubbleDirection = computed(() => { return props.direction === 'right' ? 'btm-left-in' : 'btm-right-in' }) - -const clearSpeeches = () => { - currentSpeechIndex.value = -1 - modalClosed() -} - -const modalClosed = () => { - isModalOpen.value = false - currentSpeechIndex.value = -1 -} </script> <style scoped> /* CSS talk bubble */ diff --git a/src/components/ModalComponent.vue b/src/components/ModalComponent.vue index 18538c9a9a51de006ed33ea44e39cfc385a47bb0..548eaf395fbedef621288794a777c1ac1af258de 100644 --- a/src/components/ModalComponent.vue +++ b/src/components/ModalComponent.vue @@ -17,6 +17,8 @@ </template> <script setup lang="ts"> +import { onMounted } from 'vue' + defineProps({ title: String, message: String, @@ -26,4 +28,8 @@ defineProps({ required: false } }) + +onMounted(() => { + console.log('ModalComponent mounted') +}) </script> diff --git a/src/components/SpareComponent.vue b/src/components/SpareComponent.vue new file mode 100644 index 0000000000000000000000000000000000000000..50c2b1fe742f659541ab0bcc75d9d9eb9fc31f15 --- /dev/null +++ b/src/components/SpareComponent.vue @@ -0,0 +1,63 @@ +<template> + <div> + <!-- This is the clickable image that will trigger the modal to open --> + <div + class="flex items-center" + :class="{ + 'flex-row scale-x-[-1]': imageDirection === 'right', + 'flex-row-reverse': imageDirection === 'left' + }" + > + <a @click="isModalOpen = true" class="hover:bg-transparent z-20"> + <img + alt="Spare" + class="md:h-5/6 md:w-5/6 w-2/3 h-2/3 cursor-pointer ml-14 md:ml-10" + src="@/assets/spare.png" + /> + </a> + </div> + + <!-- InteractiveSpare modal component --> + <ModalComponent v-if="isModalOpen" @close="isModalOpen = false"> + <InteractiveSpare + :speech="speech" + :png-size="pngSize!" + direction="left" + @emit:close="isModalOpen = false" + /> + + <div class="-mb-5 mt-8 text-xs text-gray-500"> + <p class="justify-center items-center">Trykk for Ã¥ se hva Spare har Ã¥ si!</p> + <a + @click="isModalOpen = false" + class="underline hover:bg-transparent font-normal text-gray-500 cursor-pointer transition-none hover:transition-none hover:p-0" + > + Skip + </a> + </div> + </ModalComponent> + </div> +</template> + +<script setup lang="ts"> +import InteractiveSpare from '@/components/InteractiveSpare.vue' +import { defineProps, ref, watchEffect } from 'vue' +import ModalComponent from '@/components/ModalComponent.vue' + +const isModalOpen = ref(false) + +const props = defineProps({ + speech: Array<string>, + pngSize: Number, + direction: String, + imageDirection: String, + show: { + type: Boolean, + default: false, + required: false + } +}) +watchEffect(() => { + isModalOpen.value = props.show +}) +</script> diff --git a/src/views/ConfigAccountNumberView.vue b/src/views/ConfigAccountNumberView.vue index 1a7a4ae9d3951d390dc26cda9c2405a141e1b2f8..6b827b1fafaa4713011fe7b11fd696caa8695260 100644 --- a/src/views/ConfigAccountNumberView.vue +++ b/src/views/ConfigAccountNumberView.vue @@ -5,6 +5,20 @@ <h1 class="mb-8 lg:mb-12 text-4xl font-bold"> Legg til kontonummer for sparekonto og brukskonto </h1> + <div class="absolute bottom-0 md:bottom-40 left-0 w-40 h-40 md:w-52 md:h-52 ml-4"> + <SpareComponent + :speech="[ + 'Her skriver du inn kontonummer for sparekonto og brukskonto. 🪩', + 'Sparekonto er kontoen du vil legge alle dine oppsparte penger pÃ¥!', + 'Brukskonto er kontoen du ønsker at pangene skal gÃ¥ ut fra', + 'Du kan endre dette senere hvis du ønsker det!' + ]" + :png-size="10" + :direction="'right'" + :imageDirection="'right'" + ></SpareComponent> + <p class="text-xs absolute left-0 md:ml-3 ml-1 mt-2">Trykk pÃ¥ meg for hjelp â—ï¸</p> + </div> <div class="flex flex-col items-center justify-center bg-white rounded-lg p-8 shadow-lg w-full md:w-[45%]" > @@ -50,6 +64,7 @@ import { computed, ref } from 'vue' import { useUserConfigStore } from '@/stores/userConfigStore' import ContinueButtonComponent from '@/components/ContinueButtonComponent.vue' import router from '@/router' +import SpareComponent from '@/components/SpareComponent.vue' const MAX_DIGITS = 11 const userConfigStore = useUserConfigStore() diff --git a/src/views/ConfigBiometricView.vue b/src/views/ConfigBiometricView.vue index 015ff20075da80e59a4bd5d15d6974663b8eced5..a1421d8720873bb902cc9fd212953661deeab80f 100644 --- a/src/views/ConfigBiometricView.vue +++ b/src/views/ConfigBiometricView.vue @@ -8,7 +8,7 @@ </div> <div class="flex flex-col gap-5"> <button @click="userStore.bioRegister()">Legg til nÃ¥!</button> - <button @click="router.push('konfigurasjonSteg1')">Jeg gjør det senere</button> + <button @click="router.push({ name: 'configurations1' })">Jeg gjør det senere</button> </div> </div> </template> diff --git a/src/views/ConfigFamiliarWithSavingsView.vue b/src/views/ConfigFamiliarWithSavingsView.vue index ecbd66aa41acbc1aa29f2fd9405ec17cb0c00213..693200e8d5a7744b4e4d1468889167d8a7dd33db 100644 --- a/src/views/ConfigFamiliarWithSavingsView.vue +++ b/src/views/ConfigFamiliarWithSavingsView.vue @@ -3,6 +3,17 @@ <h1 class="mb-8 text-2xl font-bold sm:mb-16 sm:text-4xl"> Hvor kjent er du med sparing fra før? </h1> + <div class="absolute bottom-0 md:bottom-40 left-0 w-40 h-40 md:w-52 md:h-52 ml-4"> + <SpareComponent + :speech="[ + 'Her kan du fylle inn hvor kjent du er med sparing fra før, slik at vi kan hjelpe deg pÃ¥ best mulig mÃ¥te! 💡' + ]" + :png-size="10" + :direction="'right'" + :imageDirection="'right'" + ></SpareComponent> + <p class="text-xs absolute left-0 md:ml-3 ml-1 mt-2">Trykk pÃ¥ meg for hjelp â—ï¸</p> + </div> <div class="grid grid-cols-1 gap-8 mb-16 sm:gap-14 sm:mb-20 md:grid-cols-3"> <div :class="{ @@ -51,6 +62,7 @@ import { ref } from 'vue' import ContinueButtonComponent from '@/components/ContinueButtonComponent.vue' import router from '@/router' import { useUserConfigStore } from '@/stores/userConfigStore' +import SpareComponent from '@/components/SpareComponent.vue' const selectedOption = ref<string | null>(null) const userConfigStore = useUserConfigStore() diff --git a/src/views/ConfigHabitChangeView.vue b/src/views/ConfigHabitChangeView.vue index a1e8b37350d385d2c3f31db77f2b8c81b56b6e41..fec0b011cbd1d06208b65381f54d4a318a93843c 100644 --- a/src/views/ConfigHabitChangeView.vue +++ b/src/views/ConfigHabitChangeView.vue @@ -3,6 +3,17 @@ <h1 class="mb-8 text-2xl font-bold sm:mb-16 sm:text-4xl"> Hvor store vaneedringer er du villig til Ã¥ gjøre? </h1> + <div class="absolute bottom-0 md:bottom-40 left-0 w-40 h-40 md:w-52 md:h-52 ml-4"> + <SpareComponent + :speech="[ + 'Her kan du velge hvor mye innsats du er villig til Ã¥ legge inn for Ã¥ endre vanene dine! 📚' + ]" + :png-size="10" + :direction="'right'" + :imageDirection="'right'" + ></SpareComponent> + <p class="text-xs absolute left-0 md:ml-3 ml-1 mt-2">Trykk pÃ¥ meg for hjelp â—ï¸</p> + </div> <div class="grid grid-cols-1 gap-8 mb-16 sm:gap-14 sm:mb-20 md:grid-cols-3"> <div :class="{ @@ -51,6 +62,7 @@ import { ref } from 'vue' import ContinueButtonComponent from '@/components/ContinueButtonComponent.vue' import router from '@/router' import { useUserConfigStore } from '@/stores/userConfigStore' +import SpareComponent from '@/components/SpareComponent.vue' const selectedOption = ref<string | null>(null) const userConfigStore = useUserConfigStore() diff --git a/src/views/ConfigSpendingItemsAmountView.vue b/src/views/ConfigSpendingItemsAmountView.vue index aa77feb1371de00b5a70dfe7815dd86e77f939c5..b1f28b295aca4e3dec917faece5d9d333f2fa4d0 100644 --- a/src/views/ConfigSpendingItemsAmountView.vue +++ b/src/views/ConfigSpendingItemsAmountView.vue @@ -3,6 +3,18 @@ <h1 class="mb-8 text-2xl font-bold sm:mb-16 sm:text-4xl"> Hvor mye bruker du per kjøp pÃ¥ ... </h1> + <div class="absolute bottom-0 md:bottom-40 left-0 w-40 h-40 md:w-52 md:h-52 ml-4"> + <SpareComponent + :speech="[ + 'Her kan du skrive inn hvor mye penger du bruker per kjøp pÃ¥ ulike ting. ðŸ”', + 'For eksempel koster en kopp kaffe â˜•ï¸ kanskje 30 kr, mens en kinobillett ðŸŽŸï¸ koster 100 kr.' + ]" + :png-size="10" + :direction="'right'" + :imageDirection="'right'" + ></SpareComponent> + <p class="text-xs absolute left-0 md:ml-3 ml-1 mt-2">Trykk pÃ¥ meg for hjelp â—ï¸</p> + </div> <div class="w-full flex justify-center"> <div :class="[showSecondBox ? 'md:grid md:grid-cols-2 md:gap-4 sm:gap-8 mb-6' : '']"> <div @@ -79,6 +91,7 @@ import { computed, ref } from 'vue' import ContinueButtonComponent from '@/components/ContinueButtonComponent.vue' import router from '@/router' import { useUserConfigStore } from '@/stores/userConfigStore' +import SpareComponent from '@/components/SpareComponent.vue' const userConfigStore = useUserConfigStore() diff --git a/src/views/ConfigSpendingItemsTotalAmountView.vue b/src/views/ConfigSpendingItemsTotalAmountView.vue index 366a3422a2299a21271c7733526b086475ac0c8e..e416dc51dd2791923831261a953569890c1ebc6f 100644 --- a/src/views/ConfigSpendingItemsTotalAmountView.vue +++ b/src/views/ConfigSpendingItemsTotalAmountView.vue @@ -3,6 +3,18 @@ <h1 class="mb-8 text-2xl font-bold sm:mb-16 sm:text-4xl"> Hvor mye bruker du per uke pÃ¥ ... </h1> + <div class="absolute bottom-0 md:bottom-40 left-0 w-40 h-40 md:w-52 md:h-52 ml-4"> + <SpareComponent + :speech="[ + 'Her skal du skrive inn hvor mye du bruker per uke pÃ¥ ulike kategorier. 🗓ï¸', + 'Hvis du kjøper kaffe hver dag, kan du skrive inn hvor mye du bruker pÃ¥ kaffe per uke.' + ]" + :png-size="10" + :direction="'right'" + :imageDirection="'right'" + ></SpareComponent> + <p class="text-xs absolute left-0 md:ml-3 ml-1 mt-2">Trykk pÃ¥ meg for hjelp â—ï¸</p> + </div> <div class="w-full flex justify-center"> <div :class="[showSecondBox ? 'md:grid md:grid-cols-2 md:gap-4 sm:gap-8 mb-6' : '']"> <div @@ -79,6 +91,7 @@ import { computed, ref } from 'vue' import ContinueButtonComponent from '@/components/ContinueButtonComponent.vue' import router from '@/router' import { useUserConfigStore } from '@/stores/userConfigStore' +import SpareComponent from '@/components/SpareComponent.vue' const userConfigStore = useUserConfigStore() diff --git a/src/views/ConfigSpendingItemsView.vue b/src/views/ConfigSpendingItemsView.vue index fbeda5f09011b4a3f8639d752c02eab917c32e14..7313cc1719c4f6d6f1700ecca5ab5ace4988e821 100644 --- a/src/views/ConfigSpendingItemsView.vue +++ b/src/views/ConfigSpendingItemsView.vue @@ -1,6 +1,19 @@ <template> <div class="flex flex-col items-center justify-center min-h-screen text-center"> <h1 class="mb-8 text-2xl font-bold sm:mb-16 sm:text-4xl">Hva bruker du mye penger pÃ¥?</h1> + <div class="absolute bottom-0 md:bottom-40 left-0 w-40 h-40 md:w-52 md:h-52 ml-4"> + <SpareComponent + :speech="[ + 'Her kan du velge hva du bruker mye penger pÃ¥, slik at vi kan hjelpe deg med Ã¥ spare penger! 💸', + 'Hvis du ikke finner noe som passer, kan du skrive inn egne kategorier i \'Annet ...\' feltet', + 'Du mÃ¥ minst velge en kategori!' + ]" + :png-size="10" + :direction="'right'" + :imageDirection="'right'" + ></SpareComponent> + <p class="text-xs absolute left-0 md:ml-3 ml-1 mt-2">Trykk pÃ¥ meg for hjelp â—ï¸</p> + </div> <div class="flex flex-wrap justify-center gap-8 mb-8"> <div class="flex flex-col items-center justify-center bg-white rounded-lg sm:p-8 shadow-lg sm:w-full md:w-[45%]" @@ -68,6 +81,7 @@ import { computed, ref } from 'vue' import ContinueButtonComponent from '@/components/ContinueButtonComponent.vue' import router from '@/router' import { useUserConfigStore } from '@/stores/userConfigStore' +import SpareComponent from '@/components/SpareComponent.vue' const userConfigStore = useUserConfigStore() const selectedOptions = ref<string[]>([]) diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue index 3292731aecb55ed31b7d36b422aa7cd79c8d44b6..bdc50b355aced666ef64b00159ddd3f3a699d9cf 100644 --- a/src/views/HomeView.vue +++ b/src/views/HomeView.vue @@ -9,7 +9,9 @@ :imageDirection="'right'" class="mt-24" ></SpareComponent> - <div class="flex flex-row gap-2 items-center mx-auto my-4 md:flex-col md:gap-4 md:m-8"> + <div + class="flex flex-row gap-2 items-center mx-auto mt-4 mb-20 md:flex-col md:gap-4 md:m-8" + > <ButtonAddGoalOrChallenge :buttonText="'Legg til sparemÃ¥l'" :type="'goal'" /> <ButtonAddGoalOrChallenge :buttonText="'Legg til spareutfordring'" @@ -39,16 +41,18 @@ import { useChallengeStore } from '@/stores/challengeStore' import SavingsPath from '@/components/SavingsPath.vue' import router from '@/router' import GeneratedChallengesModal from '@/components/GeneratedChallengesModal.vue' +import SpareComponent from '@/components/SpareComponent.vue' const showModal = ref(false) const goalStore = useGoalStore() const challengeStore = useChallengeStore() -const isModalOpen = ref(false) const speech = ref<string[]>([]) -const showWelcome = ref<boolean>(false) const challenges = ref<Challenge[]>([]) +const goals = ref<Goal[]>([]) +const showWelcome = ref<boolean>(false) + const goal = ref<Goal | null | undefined>(null) const isMounted = ref(false) @@ -69,12 +73,10 @@ onMounted(async () => { const firstLoggedInSpeech = () => { const isFirstLogin = router.currentRoute.value.query.firstLogin === 'true' if (isFirstLogin) { - speech.value = [ - 'Hei, jeg er Spare!', - 'Jeg skal hjelpe deg med Ã¥ spare penger.', - 'Du fÃ¥r varsel nÃ¥r jeg har noe Ã¥ si!' - ] - isModalOpen.value = true + showWelcome.value = true + speech.value.push('Hei, jeg er Spare!') + speech.value.push('Jeg skal hjelpe deg med Ã¥ spare penger.') + speech.value.push('Trykk pÃ¥ meg for Ã¥ høre hva jeg har Ã¥ si ðŸ·') router.replace({ name: 'home', query: { firstLogin: 'false' } }) } } @@ -87,19 +89,3 @@ const SpareSpeech = () => { ] } </script> - -<style> -@keyframes jump { - 0%, - 100% { - transform: translateY(0); - } - 50% { - transform: translateY(-10px); - } -} - -.jump { - animation: jump 0.6s infinite ease-in-out; -} -</style> diff --git a/src/views/ManageProfileView.vue b/src/views/ManageProfileView.vue index bf4b1e436ea03ef7a0a52a605e313a7b6402da79..6ddce344664e5226925b535a2f5343f432f49c31 100644 --- a/src/views/ManageProfileView.vue +++ b/src/views/ManageProfileView.vue @@ -251,5 +251,3 @@ const saveChanges = async () => { </div> </div> </template> - -<style scoped></style> diff --git a/src/views/UserGoalsView.vue b/src/views/UserGoalsView.vue index 80d893de8e834265f2e81645d5226223fecf60d1..4d882ae6c3d40972e2b7c74fa02a06ed00b1480e 100644 --- a/src/views/UserGoalsView.vue +++ b/src/views/UserGoalsView.vue @@ -97,5 +97,3 @@ const changeOrder = async () => { /> </div> </template> - -<style scoped></style> diff --git a/src/views/ViewChallengeView.vue b/src/views/ViewChallengeView.vue index 71b2a67e67c73f158626efb25d67a80bb0e78edc..6efadbcaefac2f4660ca1e50c0baf931941dabcc 100644 --- a/src/views/ViewChallengeView.vue +++ b/src/views/ViewChallengeView.vue @@ -4,12 +4,12 @@ import { computed, onMounted, ref } from 'vue' import ProgressBar from '@/components/ProgressBar.vue' import authInterceptor from '@/services/authInterceptor' import type { Challenge } from '@/types/challenge' -import InteractiveSpare from '@/components/InteractiveSpare.vue' +import SpareComponent from '@/components/SpareComponent.vue' const router = useRouter() const challengeInstance = ref<Challenge>({ - title: 'Test titel', + title: 'Tittel', perPurchase: 20, saved: 0, target: 100, @@ -29,8 +29,6 @@ const isCompleted = computed(() => challengeInstance.value.completedOn != null) const motivation = ref<string[]>([]) -const isModalOpen = ref(false) - const calculateSpeech = () => { if (completion.value === 0) { return motivation.value.push( @@ -142,12 +140,13 @@ const completeChallenge = () => { </button> </div> </div> - <InteractiveSpare - :png-size="10" + <SpareComponent :speech="motivation" - direction="left" - :isModalOpen="isModalOpen" - /> + :png-size="15" + :imageDirection="'left'" + :direction="'right'" + class="mb-5" + ></SpareComponent> </div> </template> diff --git a/src/views/ViewGoalView.vue b/src/views/ViewGoalView.vue index 50ec73bb87ee4c101808f113f552a58e90ca94db..430a9d5cd35c13724a46c4b75e9c7722d87b1c39 100644 --- a/src/views/ViewGoalView.vue +++ b/src/views/ViewGoalView.vue @@ -4,7 +4,7 @@ import { computed, onMounted, ref } from 'vue' import ProgressBar from '@/components/ProgressBar.vue' import authInterceptor from '@/services/authInterceptor' import type { Goal } from '@/types/goal' -import InteractiveSpare from '@/components/InteractiveSpare.vue' +import SpareComponent from '@/components/SpareComponent.vue' const router = useRouter() @@ -20,11 +20,6 @@ const completion = computed(() => (goalInstance.value.saved / goalInstance.value const isCompleted = computed(() => goalInstance.value.completedOn != null) const motivation = ref<string[]>([]) -const isModalOpen = ref(false) - -const openInteractiveSpare = () => { - isModalOpen.value = true -} const calculateSpeech = () => { if (completion.value === 0) { @@ -45,7 +40,7 @@ const calculateSpeech = () => { ) } else if (completion.value >= 100) { return motivation.value.push( - `Fantastisk! Du har nÃ¥dd mÃ¥let ditt! Du har spart ${goalInstance.value.saved}kr av ${goalInstance.value.target}kr.` + `!Fantastisk Du har nÃ¥dd mÃ¥let ditt! Du har spart ${goalInstance.value.saved}kr av ${goalInstance.value.target}kr.` ) } } @@ -131,21 +126,13 @@ const completeGoal = () => { </button> </div> </div> - <div class="flex items-center"> - <a @click="openInteractiveSpare" class="hover:bg-transparent z-20"> - <img - alt="Spare" - class="scale-x-[-1] md:h-5/6 md:w-5/6 w-2/3 h-2/3 cursor-pointer ml-14 md:ml-10" - src="@/assets/spare.png" - /> - </a> - </div> - <InteractiveSpare - :png-size="10" + <SpareComponent :speech="motivation" - direction="left" - :isModalOpen="isModalOpen" - /> + :png-size="15" + :imageDirection="'left'" + :direction="'right'" + class="mb-5" + ></SpareComponent> </div> </template> diff --git a/src/views/ViewProfileView.vue b/src/views/ViewProfileView.vue index ce7f9cf7150553705ef17aac7115129430e55a52..6993e7d21e75ef166287754e724686434d228467 100644 --- a/src/views/ViewProfileView.vue +++ b/src/views/ViewProfileView.vue @@ -1,19 +1,19 @@ <script lang="ts" setup> import authInterceptor from '@/services/authInterceptor' -import { computed, onMounted, ref } from 'vue' +import { onMounted, ref } from 'vue' import type { Profile } from '@/types/profile' import CardTemplate from '@/components/CardTemplate.vue' -import InteractiveSpare from '@/components/InteractiveSpare.vue' import type { Challenge } from '@/types/challenge' import type { Goal } from '@/types/goal' import CardGoal from '@/components/CardGoal.vue' import router from '@/router' +import SpareComponent from '@/components/SpareComponent.vue' import { useUserStore } from '@/stores/userStore' const profile = ref<Profile>() const completedGoals = ref<Goal[]>([]) const completedChallenges = ref<Challenge[]>([]) -const isModalOpen = ref(false) +const speech = ref<string[]>([]) const updateUser = async () => { authInterceptor('/profile') @@ -44,19 +44,20 @@ onMounted(async () => { .catch((error) => { return console.log(error) }) -}) + openSpare() +}) const updateBiometrics = async () => { await useUserStore().bioRegister() await updateUser() } -const welcome = computed(() => { - return [`Velkommen, ${profile.value?.firstName} ${profile.value?.lastName} !`] -}) - -const openInteractiveSpare = () => { - isModalOpen.value = true +const openSpare = () => { + speech.value = [ + `Velkommen, ${profile.value?.firstName} ${profile.value?.lastName} !`, + 'Her kan du finne en oversikt over dine profilinstillinger!', + 'Du kan ogsÃ¥ se dine fullførte sparemÃ¥l og utfordringer!' + ] } </script> @@ -109,21 +110,13 @@ const openInteractiveSpare = () => { </div> <div class="flex flex-col"> - <InteractiveSpare - :png-size="10" - :speech="welcome" - direction="left" - :isModalOpen="isModalOpen" - /> - <div class="flex items-center"> - <a @click="openInteractiveSpare" class="hover:bg-transparent z-20"> - <img - alt="Spare" - class="scale-x-[-1] md:h-5/6 md:w-5/6 w-2/3 h-2/3 cursor-pointer ml-14 md:ml-10" - src="@/assets/spare.png" - /> - </a> - </div> + <SpareComponent + :speech="speech" + :png-size="15" + :imageDirection="'left'" + :direction="'right'" + class="mb-5" + ></SpareComponent> <div class="flex flex-row justify-between mx-4"> <p class="font-bold">Fullførte sparemÃ¥l</p> <a class="hover:p-0 cursor-pointer" v-text="'Se alle'" /> @@ -147,5 +140,3 @@ const openInteractiveSpare = () => { </div> </div> </template> - -<style scoped></style>