diff --git a/src/App.vue b/src/App.vue index 6aeb0e570757a0879a907d81c7de19094bb5b86f..77cb1f689169df792ed4d3f3a3431e247d4e29f0 100644 --- a/src/App.vue +++ b/src/App.vue @@ -110,7 +110,7 @@ const helpMessages = computed(() => { 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')) { + } else if (route.path.startsWith('/sparemaal/rediger/ny')) { 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Ã¥.' @@ -120,7 +120,7 @@ const helpMessages = computed(() => { ) 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')) { + } else if (route.path.startsWith('/spareutfordringer/ny')) { 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Ã¥.' diff --git a/src/assets/bakgrunn.png b/src/assets/bakgrunn.png new file mode 100644 index 0000000000000000000000000000000000000000..7c002fbb47bcef42217ac561c68abca83362d828 Binary files /dev/null and b/src/assets/bakgrunn.png differ diff --git a/src/assets/finishline2.png b/src/assets/finishline2.png new file mode 100644 index 0000000000000000000000000000000000000000..251d099d41b7887bde06385be18e548d727d0ec6 Binary files /dev/null and b/src/assets/finishline2.png differ diff --git a/src/assets/logo.svg b/src/assets/logo.svg deleted file mode 100644 index 7565660356e5b3723c9c33d508b830c9cfbea29f..0000000000000000000000000000000000000000 --- a/src/assets/logo.svg +++ /dev/null @@ -1 +0,0 @@ -<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 261.76 226.69"><path d="M161.096.001l-30.225 52.351L100.647.001H-.005l130.877 226.688L261.749.001z" fill="#41b883"/><path d="M161.096.001l-30.225 52.351L100.647.001H52.346l78.526 136.01L209.398.001z" fill="#34495e"/></svg> diff --git a/src/assets/savingsPathBg.png b/src/assets/savingsPathBg.png deleted file mode 100644 index fb1994e981fffba4df9736cd50ccd71d00e70340..0000000000000000000000000000000000000000 Binary files a/src/assets/savingsPathBg.png and /dev/null differ diff --git a/src/assets/start-sign.png b/src/assets/start-sign.png new file mode 100644 index 0000000000000000000000000000000000000000..ece9e3aab84d9a320ed803d9db25b04723fcfa06 Binary files /dev/null and b/src/assets/start-sign.png differ diff --git a/src/assets/varsel.png b/src/assets/varsel.png deleted file mode 100644 index 2e8c6538317c5812731abefa426216f8a0244698..0000000000000000000000000000000000000000 Binary files a/src/assets/varsel.png and /dev/null differ diff --git a/src/components/ButtonAddGoalOrChallenge.vue b/src/components/ButtonAddGoalOrChallenge.vue index 548a7f68ea2c648a1f9a46b0f160568d8e1dd1bf..b45122455c7ab63798231acee20c92ea9198f9e5 100644 --- a/src/components/ButtonAddGoalOrChallenge.vue +++ b/src/components/ButtonAddGoalOrChallenge.vue @@ -1,6 +1,6 @@ <template> <button - class="primary w-full max-w-60 py-2 flex items-center justify-start pl-4 space-x-2 focus:outline-none focus:ring-2 focus:ring-opacity-50 shadow-md text-xs md:text-sm lg:text-base" + class="primary w-full max-w-64 py-2 flex items-center justify-start pl-4 space-x-2 focus:outline-none focus:ring-2 focus:ring-opacity-50 shadow-md text-xs md:text-sm lg:text-base" @click="routeToGoalOrChallenge" > <svg diff --git a/src/components/ButtonDisplayStreak.vue b/src/components/ButtonDisplayStreak.vue index d8fd8b3eb7008d91b30b554172060e8e44e0edda..883fcea10530af3c8288adea0220652b26ce7f10 100644 --- a/src/components/ButtonDisplayStreak.vue +++ b/src/components/ButtonDisplayStreak.vue @@ -21,12 +21,9 @@ > <span class="text-xs md:text-2xl font-bold text-black" >{{ currentStreak - }}{{ - currentStreak === 1 ? ' utfodring fullført' : ' utfodringer fullført' - }} - streak</span - > - <p class="text-black text-xs md:text-1xl md:font-bold"> + }}{{ currentStreak === 1 ? ' utfordring fullført' : ' utfordringer fullført' }} + </span> + <p class="text-black text-xs md:text-1xl md:font-bold my-2"> {{ currentStreak! > 0 ? 'Bra jobba du har fullført ' + currentStreak + ' utfordringer pÃ¥ rad!' diff --git a/src/components/CardChallengeSavingsPath.vue b/src/components/CardChallengeSavingsPath.vue index 651ce0c21071bd1acd4343d3eade84a8606c88ff..3acd26ccedfea9407170c929ca5f8e7733adae52 100644 --- a/src/components/CardChallengeSavingsPath.vue +++ b/src/components/CardChallengeSavingsPath.vue @@ -33,7 +33,7 @@ @click="editChallenge(challenge)" :data-cy="'challenge-icon-' + challenge.id" :src="challengeImageUrl" - class="max-w-12 max-h-12 md:max-h-8 md:max-w-8 lg:max-w-10 lg:max-h-10 cursor-pointer hover:scale-125 rounded-sm" + class="max-w-8 max-h-12 md:max-h-8 md:max-w-8 lg:max-w-10 lg:max-h-10 cursor-pointer hover:scale-125 rounded-sm" :alt="challenge.title" /> <!-- Progress Bar, if the challenge is not complete --> @@ -45,7 +45,7 @@ <div class="flex flex-col"> <div class="bg-gray-200 rounded-full h-2.5 dark:bg-gray-700"> <div - class="bg-green-600 h-2.5 rounded-full" + class="bg-lime-400 h-2.5 rounded-full" data-cy="challenge-progress" :style="{ width: (challenge.saved / challenge.target) * 100 + '%' @@ -55,16 +55,15 @@ <div class="text-center text-nowrap text-xs md:text-base"> {{ challenge.saved }}kr / {{ challenge.target }}kr </div> + <button + @click="incrementSaved(challenge)" + :data-cy="'increment-challenge' + challenge.id" + type="button" + class="primary text-xs ml-2 z-10 relative" + > + + {{ challenge.perPurchase }}kr pÃ¥ {{ challenge.title }} + </button> </div> - - <button - @click="incrementSaved(challenge)" - :data-cy="'increment-challenge' + challenge.id" - type="button" - class="inline-block mb-2 ml-2 h-7 w-8 rounded-full p-1 uppercase leading-normal transition duration-150 ease-in-out focus:bg-green-accent-300 focus:shadow-green-2 focus:outline-none focus:ring-0 active:bg-green-600 active:shadow-green-200 motion-reduce:transition-none dark:shadow-black/30 dark:hover:shadow-dark-strong dark:focus:shadow-dark-strong dark:active:shadow-dark-strong" - > - + - </button> </div> </div> <span v-else class="text-center text-xs md:text-base" @@ -112,7 +111,6 @@ const getChallengeIcon = async (challengeId: number) => { }) challengeImageUrl.value = URL.createObjectURL(imageResponse.data) } catch (error) { - console.error('Failed to load challenge icon:', error) challengeImageUrl.value = '/src/assets/star.png' // Fallback on error } } diff --git a/src/components/FormLogin.vue b/src/components/FormLogin.vue index 3295165e4da1d9b64376d364d468055a35d81452..df5c5f49ba17cf284a3f6d40a6b6de3b5e123479 100644 --- a/src/components/FormLogin.vue +++ b/src/components/FormLogin.vue @@ -84,7 +84,7 @@ watch( placeholder="Skriv inn passord" /> <button - class="absolute right-0 top-1 bg-transparent hover:bg-transparent" + class="absolute right-0 top-1 bg-transparent hover:bg-transparent mr-4 mt-1" @click="toggleShowPassword" > {{ showPassword ? '🔓' : '🔒' }} diff --git a/src/components/FormRegister.vue b/src/components/FormRegister.vue index f28be87ece27d5a2f706b421a457b01787c855b0..5d8e75434066ff02c4e0db27d7fd308b722435cb 100644 --- a/src/components/FormRegister.vue +++ b/src/components/FormRegister.vue @@ -12,6 +12,7 @@ const confirm = ref<string>('') const showPassword = ref<boolean>(false) const errorMessage = ref<string>('') +const passwordValidations = ref<string[]>([]) const userStore = useUserStore() @@ -42,6 +43,39 @@ const toggleShowPassword = () => { showPassword.value = !showPassword.value } +const validatePassword = () => { + const messages = [] + const lengthValid = password.value.length >= 8 && password.value.length <= 30 + const numberValid = /[0-9]/.test(password.value) + const lowercaseValid = /[a-zæøå]/.test(password.value) + const uppercaseValid = /[ÆØÅA-Z]/.test(password.value) + const specialCharacterValid = /[@#$%^&+=!]/.test(password.value) + const noSpacesValid = !/\s/.test(password.value) + + if (!lengthValid) { + messages.push('MÃ¥ være mellom 8 og 30 karakterer. ') + } + if (!numberValid) { + messages.push('MÃ¥ inneholde minst ett tall. ') + } + if (!lowercaseValid) { + messages.push('MÃ¥ inneholde minst én liten bokstav. ') + } + if (!uppercaseValid) { + messages.push('MÃ¥ inneholde minst én stor bokstav. ') + } + if (!specialCharacterValid) { + messages.push('MÃ¥ inneholde minst ett spesialtegn (@#$%^&+=!). ') + } + if (!noSpacesValid) { + messages.push('MÃ¥ ikke inneholde mellomrom. ') + } + + passwordValidations.value = messages +} + +watch(password, validatePassword) + watch( () => userStore.errorMessage, (newValue: string) => { @@ -56,7 +90,7 @@ watch( <div class="flex flex-row justify-between mx-4"> <p>Fornavn*</p> <ToolTip - :message="'Must include only letters, spaces, commas, apostrophes, periods, and hyphens. 1-30 characters long'" + :message="'MÃ¥ kun inneholde bokstaver, mellomrom, komma, apostrof, punktum, og bindestrek. 1-30 karakterer langt'" /> </div> <input @@ -71,7 +105,7 @@ watch( <div class="flex flex-row justify-between mx-4"> <p>Etternavn*</p> <ToolTip - :message="'Must include only letters, spaces, commas, apostrophes, periods, and hyphens. 1-30 characters long'" + :message="'MÃ¥ kun inneholde bokstaver, mellomrom, komma, apostrof, punktum, og bindestrek. 1-30 karakterer langt'" /> </div> <input @@ -86,7 +120,7 @@ watch( <div class="flex flex-row justify-between mx-4"> <p>E-post*</p> <ToolTip - :message="'Valid email: Starts with Norwegian letters, numbers, or special characters. Includes \@\ followed by a domain. Ends with 2-7 letters.'" + :message="'Gyldig email: MÃ¥ starte med norske bokstaver, tall, eller spesielle karakterer. Inkluderer \@\ fulgt av et domene. Ender med 2-7 bokstaver.'" /> </div> <input @@ -101,7 +135,7 @@ watch( <div class="flex flex-row justify-between mx-4"> <p>Brukernavn*</p> <ToolTip - :message="'Must start with a letter and can include numbers and underscores. 3-30 characters long.'" + :message="'MÃ¥ starte med en bokstav og kan inneholde tall og understrek. 3-30 karakterer langt.'" /> </div> <input @@ -116,7 +150,7 @@ watch( <div class="flex flex-row justify-between mx-4"> <p>Passord*</p> <ToolTip - :message="'Must be at least 8 characters, including at least one number, one lowercase letter, one uppercase letter, one special character (@#$%^&+=!), and no spaces.'" + :message="'MÃ¥ være minst 8 karakterer, inkludert et tall, en liten bokstav, en stor bokstav, et spesialtegn (@#$%^&+=!), og ingen mellomrom.'" /> </div> <div class="relative"> @@ -129,7 +163,7 @@ watch( :class="{ 'border-2 border-lime-400': isPasswordValid }" /> <button - class="absolute right-0 top-1 bg-transparent hover:bg-transparent" + class="absolute right-0 top-1 bg-transparent hover:bg-transparent mr-4 mt-1" @click="toggleShowPassword" > {{ showPassword ? '🔓' : '🔒' }} @@ -145,6 +179,11 @@ watch( placeholder="Bekreft passord" type="password" /> + <div class="ml-4"> + <p class="text-sm"> + <span v-for="message in passwordValidations" :key="message">{{ message }}</span> + </p> + </div> </div> <div class="flex flex-row gap-5"> <button @@ -155,7 +194,6 @@ watch( > Registrer deg </button> - <p>{{ errorMessage }}</p> </div> </div> </template> diff --git a/src/components/GeneratedChallengesModal.vue b/src/components/GeneratedChallengesModal.vue index cdb9e59327d0e5f58ada0b3002cf69f8082bf424..d1bfdd52c66a8dccc8c73bd2bcd2d917f480216c 100644 --- a/src/components/GeneratedChallengesModal.vue +++ b/src/components/GeneratedChallengesModal.vue @@ -4,7 +4,7 @@ class="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 z-50" > <div class="relative bg-white pt-10 p-4 rounded-lg shadow-xl" style="width: 40rem"> - <button @click="closeModal" class="absolute top-0 right-0 m-2 text-white"> + <button @click="closeModal" class="absolute top-0 right-0 m-2 primary"> <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" @@ -61,7 +61,7 @@ > <button @click="acceptChallenge(challenge)" - class="text-white font-bold py-1 px-4 mt-[-14px] sm:mt-0" + class="font-bold py-1 px-4 mt-[-14px] sm:mt-0 primary" > Godta </button> diff --git a/src/components/HelpComponent.vue b/src/components/HelpComponent.vue index 90182c9df571e9f5517529c93da5bc92ab0342fb..f1ebac400adf9ea7be83fd0a43c3c3c20b41e588 100644 --- a/src/components/HelpComponent.vue +++ b/src/components/HelpComponent.vue @@ -1,15 +1,15 @@ <template> - <div class="fixed bottom-5 right-5 hover:cursor-pointer z-50" @click="isModalOpen = true"> + <div class="fixed bottom-10 right-10 hover:cursor-pointer z-50" @click="isModalOpen = true"> <img alt="Hjelp" - class="h-10 transition-transform duration-300 ease-in-out hover:scale-110" + class="h-12 transition-transform duration-300 ease-in-out hover:scale-110" src="@/assets/hjelp.png" /> </div> <ModalComponent v-if="isModalOpen" @close="isModalOpen = false"> <InteractiveSpare :speech="speech" - :png-size="15" + :png-size="12" direction="right" @emit:close="isModalOpen = false" /> diff --git a/src/components/ImgGifTemplate.vue b/src/components/ImgGifTemplate.vue index f23f1723afa3e37e176788ddc3c565729e455fa0..23cf21c7bc264d98f124834fded6dcdc8d31ca3a 100644 --- a/src/components/ImgGifTemplate.vue +++ b/src/components/ImgGifTemplate.vue @@ -4,7 +4,7 @@ v-if="index % 6 === modValue" :src="url" alt="could not load" - class="min-w-24 w-full h-auto min-h-24 max-w-32 max-h-32 md:min-h-32 md:max-h-44 md:min-w-32 md:max-w-44 border-2 rounded-lg border-stale-400 shadow-md shadow-black" + class="min-w-24 w-full h-auto min-h-24 max-w-32 max-h-32 md:min-h-32 md:max-h-44 md:min-w-32 md:max-w-44 rounded-lg border-stale-400 shadow-md shadow-gray-500" /> </div> </template> diff --git a/src/components/SavingsPath.vue b/src/components/SavingsPath.vue index 23aef04f4e32035fcc9e20ce1bf16aa436027e89..be7ba589faa90f71c35c286a6fc2e3c9fa4dcb83 100644 --- a/src/components/SavingsPath.vue +++ b/src/components/SavingsPath.vue @@ -12,7 +12,7 @@ </div> <button v-if="!allChallengesCompleted()" - class="h-auto w-auto absolute flex text-center self-end mr-10 md:mr-20 text-wrap shadow-sm shadow-black sm:top-50 sm:text-xs sm:mr-20 lg:mr-32 top-60 z-50 p-2 text-xs md:text-sm" + class="h-auto w-auto absolute flex text-center self-end mr-10 md:mr-20 text-wrap border-2 border-gray-200 rounded-xl shadow-black sm:top-50 sm:text-xs sm:mr-20 lg:mr-32 top-60 z-50 p-2 text-xs md:text-sm hover:scale-105" @click="scrollToFirstUncompleted" v-show="!isAtFirstUncompleted" > @@ -22,11 +22,11 @@ <div v-if="challengesLocal" ref="containerRef" - class="container relative pt-6 w-4/5 bg-cover bg-[center] md:[background-position: center;] mx-auto md:w-4/5 no-scrollbar h-full max-h-[60vh] md:max-h-[60vh] md:min-w-2/5 overflow-y-auto border-2 border-transparent rounded-xl bg-white shadow-lg shadow-slate-400" - style="background-image: url('src/assets/backgroundSavingsPath.png')" + class="container relative pt-6 w-4/5 bg-cover bg-[center] md:[background-position: center;] mx-auto md:w-4/5 no-scrollbar h-full max-h-[60vh] md:max-h-[60vh] md:min-w-2/5 overflow-y-auto border-transparent rounded-lg bg-white shadow-md shadow-slate-400" + style="background-image: url('src/assets/bakgrunn.png')" > <div> - <img src="@/assets/start.png" alt="Spare" class="md:w-1/6 md:h-auto h-20" /> + <img src="@/assets/start-sign.png" alt="Spare" class="md:w-1/6 md:h-auto h-20" /> </div> <div @@ -41,7 +41,7 @@ 'justify-center mx-auto md:justify-between': index % 2 === 1, 'justify-center md:justify-between mx-auto': index % 2 === 0 }" - class="flex flex-row w-full md:w-4/5 justify-start gap-4 md:gap-8" + class="flex flex-row w-full md:w-4/5 justify-start gap-4 md:gap-8 h-auto" > <div class="flex"> <img-gif-template @@ -97,22 +97,24 @@ v-if="index === challengesLocal.length - 1 && index % 2 === 0" class="flex flex-row mt-2" > - <button class="text-2xl ml-48" @click="addSpareUtfordring">+</button> + <button class="text-2xl ml-48 mr-2 primary" @click="addSpareUtfordring"> + + + </button> <p class="">Legg til <br />Spareutfordring</p> </div> <div v-else-if="index === challengesLocal.length - 1 && index % 2 !== 0" class="mr-20 flex flex-row" > - <button class="text-2xl ml-10 rounded-full" @click="addSpareUtfordring"> + <button class="text-2xl ml-10 rounded-full primary" @click="addSpareUtfordring"> + </button> - <p class="">Legg til <br />Spareutfordring</p> + <p class="pl-2">Legg til <br />Spareutfordring</p> </div> <!-- Finish line --> </div> <img - src="@/assets/finishLine.png" + src="@/assets/finishline2.png" class="w-full max-h-auto mx-auto mt-4" alt="Finish Line" /> diff --git a/src/components/SpareComponent.vue b/src/components/SpareComponent.vue index 50c2b1fe742f659541ab0bcc75d9d9eb9fc31f15..d5e7a829bb27560bcd87a992c9bc2b17a6c41047 100644 --- a/src/components/SpareComponent.vue +++ b/src/components/SpareComponent.vue @@ -8,7 +8,10 @@ 'flex-row-reverse': imageDirection === 'left' }" > - <a @click="isModalOpen = true" class="hover:bg-transparent z-20"> + <a + @click="isModalOpen = true" + class="hover:bg-transparent hover:p-0 hover:scale-105 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" diff --git a/src/components/__tests__/ButtonDisplayStreakTest.spec.ts b/src/components/__tests__/ButtonDisplayStreakTest.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..e7e3122b70704441ffe13262b6ff945adf61c29c --- /dev/null +++ b/src/components/__tests__/ButtonDisplayStreakTest.spec.ts @@ -0,0 +1,20 @@ +import { describe, expect, it, beforeEach } from 'vitest' +import { mount } from '@vue/test-utils' +import { createPinia, setActivePinia } from 'pinia' +import ButtonComponent from '@/components/ButtonDisplayStreak.vue' + +describe('ButtonComponent', () => { + beforeEach(() => { + setActivePinia(createPinia()) + }) + + it('renders correctly', () => { + const wrapper = mount(ButtonComponent, { + props: { + buttonText: 'Click me', + type: 'goal' + } + }) + expect(wrapper.exists()).toBe(true) + }) +}) diff --git a/src/views/ConfigAccountNumberView.vue b/src/views/ConfigAccountNumberView.vue index f49e366564cb43461ce767971d4522dffce55939..a869677084d0673fa9c63044977a93682538cfe3 100644 --- a/src/views/ConfigAccountNumberView.vue +++ b/src/views/ConfigAccountNumberView.vue @@ -6,6 +6,7 @@ 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"> + <p class="text-sm font-bold mb-3 animate-bounce">Trykk pÃ¥ meg for hjelp â—ï¸</p> <SpareComponent :speech="[ 'Her skriver du inn kontonummer for sparekonto og brukskonto. 🪩', @@ -17,7 +18,6 @@ :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%]" @@ -49,6 +49,7 @@ /> </div> </div> + <p class="mt-10">Husk at du kan endre dette senere!</p> <div class="absolute bottom-36 right-2"> <ContinueButtonComponent @click="onButtonClick" diff --git a/src/views/ConfigFamiliarWithSavingsView.vue b/src/views/ConfigFamiliarWithSavingsView.vue index 693200e8d5a7744b4e4d1468889167d8a7dd33db..5153c3ac65cedf57806206624ed5a8abee92fa02 100644 --- a/src/views/ConfigFamiliarWithSavingsView.vue +++ b/src/views/ConfigFamiliarWithSavingsView.vue @@ -1,26 +1,31 @@ <template> <div class="flex flex-col items-center justify-center min-h-screen px-4 text-center"> - <h1 class="mb-8 text-2xl font-bold sm:mb-16 sm:text-4xl"> + <h1 class="mb-8 md:mb-16 mt-2 text-2xl font-bold 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"> + <div + class="absolute bottom-4 md:bottom-40 left-2 w-28 h-28 md:w-40 md:h-40 lg:w-52 lg:h-52 ml-4" + > + <p class="md:text-sm text-xs font-bold mb-3 animate-bounce invisible sm:visible"> + Trykk pÃ¥ meg for hjelp â—ï¸ + </p> <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! 💡' + '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! 💡', + 'Hvis du er usikker, velg det alternativet som passer best. Du kan endre dette senere!' ]" :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="grid grid-cols-1 gap-8 mb-2 sm:gap-10 sm:mb-12 md:grid-cols-3"> <div :class="{ 'border-[var(--green)] border-4': selectedOption === 'litt', 'border-gray-300 border-2': selectedOption !== 'litt' }" - class="flex flex-col items-center justify-center w-40 h-40 p-2 sm:w-64 sm:h-64 transition-colors rounded-lg cursor-pointer hover:border-[var(--green)]" + class="flex flex-col items-center justify-center w-32 h-32 p-2 sm:w-60 sm:h-60 transition-colors rounded-lg cursor-pointer hover:border-[var(--green)]" @click="selectOption('litt')" > <img src="@/assets/nose.png" alt="Pig nose" class="h-12 sm:h-1/3" /> @@ -31,7 +36,7 @@ 'border-[var(--green)] border-4': selectedOption === 'noe', 'border-gray-300 border-2': selectedOption !== 'noe' }" - class="flex flex-col items-center justify-center w-40 h-40 p-2 sm:w-64 sm:h-64 transition-colors rounded-lg cursor-pointer hover:border-[var(--green)]" + class="flex flex-col items-center justify-center w-32 h-32 p-2 sm:w-60 sm:h-60 transition-colors rounded-lg cursor-pointer hover:border-[var(--green)]" @click="selectOption('noe')" > <img src="@/assets/head.png" alt="Pig face" class="h-12 sm:h-1/3" /> @@ -42,17 +47,18 @@ 'border-[var(--green)] border-4': selectedOption === 'godt', 'border-gray-300 border-2': selectedOption !== 'godt' }" - class="flex flex-col items-center justify-center w-40 h-40 p-2 sm:w-64 sm:h-64 transition-colors rounded-lg cursor-pointer hover:border-[var(--green)]" + class="flex flex-col items-center justify-center w-32 h-32 p-2 sm:w-60 sm:h-60 transition-colors rounded-lg cursor-pointer hover:border-[var(--green)]" @click="selectOption('godt')" > <img src="@/assets/pig.png" alt="Whole pig" class="h-12 sm:h-1/3" /> <p class="mt-2 text-lg font-bold">Godt kjent</p> </div> </div> + <p class="mb-4 md:mb-10">Husk at du kan endre dette senere!</p> <ContinueButtonComponent :disabled="selectedOption === null" @click="onButtonClick" - class="px-10 py-3 text-2xl self-end" + class="md:px-10 px-8 md:py-3 py-2 text-2xl self-end" ></ContinueButtonComponent> </div> </template> diff --git a/src/views/ConfigHabitChangeView.vue b/src/views/ConfigHabitChangeView.vue index fec0b011cbd1d06208b65381f54d4a318a93843c..937398bdc6f082b3b27344d241dc940545583432 100644 --- a/src/views/ConfigHabitChangeView.vue +++ b/src/views/ConfigHabitChangeView.vue @@ -1,26 +1,31 @@ <template> <div class="flex flex-col items-center justify-center min-h-screen px-4 text-center"> - <h1 class="mb-8 text-2xl font-bold sm:mb-16 sm:text-4xl"> + <h1 class="mb-8 md:mb-16 mt-2 text-2xl font-bold 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"> + <div + class="absolute bottom-4 md:bottom-40 left-2 w-28 h-28 md:w-40 md:h-40 lg:w-52 lg:h-52 ml-4" + > + <p class="md:text-sm text-xs font-bold mb-3 animate-bounce invisible sm:visible"> + Trykk pÃ¥ meg for hjelp â—ï¸ + </p> <SpareComponent :speech="[ - 'Her kan du velge hvor mye innsats du er villig til Ã¥ legge inn for Ã¥ endre vanene dine! 📚' + 'Her kan du velge hvor mye innsats du er villig til Ã¥ legge inn for Ã¥ endre vanene dine! 📚', + 'Hvis du er usikker, velg det alternativet som passer best. Du kan endre dette senere!' ]" :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="grid grid-cols-1 gap-8 mb-2 sm:gap-10 sm:mb-12 md:grid-cols-3"> <div :class="{ 'border-[var(--green)] border-4': selectedOption === 'litt', 'border-gray-300 border-2': selectedOption !== 'litt' }" - class="flex flex-col items-center justify-center w-40 h-40 p-2 sm:w-64 sm:h-64 transition-colors rounded-lg cursor-pointer hover:border-[var(--green)]" + class="flex flex-col items-center justify-center w-32 h-32 p-2 sm:w-60 sm:h-60 transition-colors rounded-lg cursor-pointer hover:border-[var(--green)]" @click="selectOption('litt')" > <img src="@/assets/litt.png" alt="Thumbs down emoji" class="h-12 sm:h-1/3" /> @@ -31,7 +36,7 @@ 'border-[var(--green)] border-4': selectedOption === 'passe', 'border-gray-300 border-2': selectedOption !== 'passe' }" - class="flex flex-col items-center justify-center w-40 h-40 p-2 sm:w-64 sm:h-64 transition-colors rounded-lg cursor-pointer hover:border-[var(--green)]" + class="flex flex-col items-center justify-center w-32 h-32 p-2 sm:w-60 sm:h-60 transition-colors rounded-lg cursor-pointer hover:border-[var(--green)]" @click="selectOption('passe')" > <img src="@/assets/passe.png" alt="A little bit emoji" class="h-12 sm:h-1/3" /> @@ -42,17 +47,18 @@ 'border-[var(--green)] border-4': selectedOption === 'store', 'border-gray-300 border-2': selectedOption !== 'store' }" - class="flex flex-col items-center justify-center w-40 h-40 p-2 sm:w-64 sm:h-64 transition-colors rounded-lg cursor-pointer hover:border-[var(--green)]" + class="flex flex-col items-center justify-center w-32 h-32 p-2 sm:w-60 sm:h-60 transition-colors rounded-lg cursor-pointer hover:border-[var(--green)]" @click="selectOption('store')" > <img src="@/assets/store.png" alt="Thumbs up emoji" class="h-12 sm:h-1/3" /> <p class="mt-2 text-md sm:text-lg font-bold">Store</p> </div> </div> + <p class="mb-4 md:mb-10">Husk at du kan endre dette senere!</p> <ContinueButtonComponent :disabled="selectedOption === null" @click="onButtonClick" - class="px-10 py-3 text-2xl self-end" + class="md:px-10 px-8 md:py-3 py-2 text-2xl self-end" ></ContinueButtonComponent> </div> </template> diff --git a/src/views/ConfigSpendingItemsAmountView.vue b/src/views/ConfigSpendingItemsAmountView.vue index ef2ac42c27859374f0ab7f4e07115e07093e950d..0b1e3e4e9280b21e52fba9d066e51a46211d195d 100644 --- a/src/views/ConfigSpendingItemsAmountView.vue +++ b/src/views/ConfigSpendingItemsAmountView.vue @@ -1,19 +1,25 @@ <template> <div class="flex flex-col items-center justify-center min-h-screen px-4 text-center relative"> - <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"> + <h1 class="mb-2 text-2xl font-bold sm:text-4xl">Hvor mye bruker du per kjøp pÃ¥ ...</h1> + <p class="text-sm mb-8 md:mb-10"> + Her kan du skrive inn hvor mye du bruker per kjøp pÃ¥ ulike kategorier + </p> + <div + class="md:absolute fixed bottom-3 md:bottom-40 left-2 w-28 h-28 md:w-40 md:h-40 lg:w-52 lg:h-52 ml-4" + > + <p class="md:text-sm text-xs font-bold mb-3 animate-bounce invisible sm:visible"> + Trykk pÃ¥ meg for hjelp â—ï¸ + </p> <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.' + 'For eksempel koster en kopp kaffe â˜•ï¸ kanskje 30 kr, mens en kinobillett ðŸŽŸï¸ koster 100 kr.', + 'Du kan redigere dette senere!' ]" :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' : '']"> @@ -76,6 +82,7 @@ </div> </div> </div> + <p class="mt-10">Husk at du kan endre dette senere!</p> <div class="w-full text-right"> <ContinueButtonComponent @click="onButtonClick" diff --git a/src/views/ConfigSpendingItemsTotalAmountView.vue b/src/views/ConfigSpendingItemsTotalAmountView.vue index 0291e9e917bf503a4ff77a066b0062b43c23172f..d3f0c9ecacfab72ab96a755663a121f6ff4ce575 100644 --- a/src/views/ConfigSpendingItemsTotalAmountView.vue +++ b/src/views/ConfigSpendingItemsTotalAmountView.vue @@ -1,19 +1,21 @@ <template> <div class="flex flex-col items-center justify-center min-h-screen px-4 text-center relative"> - <h1 class="mb-8 text-2xl font-bold sm:mb-16 sm:text-4xl"> - Hvor mye bruker du per uke pÃ¥ ... - </h1> + <h1 class="mb-2 text-2xl font-bold sm:text-4xl">Hvor mye bruker du per uke pÃ¥ ...</h1> + <p class="text-sm mb-8 md:mb-10"> + Her kan du skrive inn hvor mye du bruker per uke pÃ¥ ulike kategorier + </p> <div class="absolute bottom-0 md:bottom-40 left-0 w-40 h-40 md:w-52 md:h-52 ml-4"> + <p class="text-sm font-bold mb-3 animate-bounce">Trykk pÃ¥ meg for hjelp â—ï¸</p> <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.' + 'Hvis du kjøper kaffe hver dag, kan du skrive inn hvor mye du bruker pÃ¥ kaffe per uke.', + 'Du kan redigere dette senere!' ]" :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' : '']"> @@ -76,6 +78,7 @@ </div> </div> </div> + <p class="mt-10">Husk at du kan endre dette senere!</p> <div class="w-full text-right"> <ContinueButtonComponent @click="onButtonClick" diff --git a/src/views/ConfigSpendingItemsView.vue b/src/views/ConfigSpendingItemsView.vue index d3e032d9b5bf5d74bd9b3b46cc88ed83f57544e7..f95b2915ae3600577ceb4a48eeab3e6cf8c2769f 100644 --- a/src/views/ConfigSpendingItemsView.vue +++ b/src/views/ConfigSpendingItemsView.vue @@ -1,18 +1,29 @@ <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"> + <h1 class="mb-3 text-2xl font-bold sm:text-4xl mt-0 md:mt-7"> + Hva bruker du mye penger pÃ¥? + </h1> + <p class="text-sm mb-8 md:mb-10"> + Hvis du ikke finner noe som passer, kan du skrive inn egne kategorier i "Annet ..." + feltet + </p> + <div + class="md:absolute fixed bottom-3 md:bottom-40 left-2 w-28 h-28 md:w-40 md:h-40 lg:w-52 lg:h-52 ml-4" + > + <p class="md:text-sm text-xs font-bold mb-3 animate-bounce invisible sm:visible"> + Trykk pÃ¥ meg for hjelp â—ï¸ + </p> <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!' + 'Du mÃ¥ minst velge en kategori!', + 'Du kan redigere dette senere!' ]" :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 @@ -66,11 +77,12 @@ </div> </div> </div> + <p class="mb-1">Husk at du kan endre dette senere!</p> <div class="w-full text-right"> <ContinueButtonComponent @click="onButtonClick" :disabled="!isFormValid" - class="px-10 py-3 text-2xl font-bold mt-36 mr-4 sm:mb-12 sm:mt-10" + class="md:px-10 md:py-3 px-7 py-2 text-2xl font-bold md:mt-12 mt-4 mr-4 sm:mb-12 sm:mt-10" ></ContinueButtonComponent> </div> </div> diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue index 2aae863d362ac964b2e3b00a2da7cae122b6f178..188e8fca5a7da2d9cd928c728834f8c42bfe805e 100644 --- a/src/views/HomeView.vue +++ b/src/views/HomeView.vue @@ -7,10 +7,10 @@ :png-size="12" :direction="'right'" :imageDirection="'right'" - class="mt-24" + class="my-10 md:ml-5" ></SpareComponent> <div - class="flex flex-row gap-2 items-center mx-auto mt-4 mb-20 md:flex-col md:gap-4 md:m-8" + class="flex flex-col gap-2 items-center mx-auto mt-4 mb-20 md:gap-4 md:m-0 md:ml-4 w-full" > <ButtonAddGoalOrChallenge :buttonText="'Legg til sparemÃ¥l'" :type="'goal'" /> <ButtonAddGoalOrChallenge @@ -76,6 +76,7 @@ const firstLoggedInSpeech = () => { 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 ðŸ·') + speech.value.push('Trenger du hjelp? Trykk pÃ¥ â“ nede i høyre hjørne') router.replace({ name: 'home', query: { firstLogin: 'false' } }) } } @@ -84,7 +85,8 @@ const SpareSpeech = () => { speech.value = [ 'Hei! Jeg er sparegrisen, Spare!', 'Valkommen til SpareSti 👑', - 'Du kan trykke pÃ¥ meg for Ã¥ høre hva jeg har Ã¥ si ðŸ·' + 'Du kan trykke pÃ¥ meg for Ã¥ høre hva jeg har Ã¥ si ðŸ·', + 'Trenger du hjelp? Trykk pÃ¥ â“ nede i høyre hjørne' ] } </script> diff --git a/src/views/ManageChallengeView.vue b/src/views/ManageChallengeView.vue index 063e269da023844231f9255dad53fa65abea74c5..5da2394990b9f3c8edb73bd6611e1a60c73012d4 100644 --- a/src/views/ManageChallengeView.vue +++ b/src/views/ManageChallengeView.vue @@ -5,6 +5,7 @@ import ProgressBar from '@/components/ProgressBar.vue' import authInterceptor from '@/services/authInterceptor' import type { Challenge } from '@/types/challenge' import ModalComponent from '@/components/ModalComponent.vue' +import InteractiveSpare from '@/components/InteractiveSpare.vue' const router = useRouter() const uploadedFile = ref<File | null>(null) @@ -174,127 +175,149 @@ const removeUploadedFile = () => { </script> <template> - <div class="flex flex-col justify-center items-center"> - <h1 class="font-bold" v-text="pageTitle" /> - <div class="flex flex-col gap-5 items-center justify-center"> - <div class="flex flex-col"> - <p class="mx-4">Tittel*</p> - <input - v-model="challengeInstance.title" - placeholder="Skriv en tittel" - type="text" - /> - </div> - - <div class="flex flex-col"> - <p class="mx-4">Beskrivelse (valgfri)</p> - <textarea - v-model="challengeInstance.description" - class="w-80 h-20 no-rezise" - placeholder="Beskriv sparemÃ¥let" - /> - </div> - - <div class="flex flex-col sm:flex-row gap-3"> + <div class="relative flex-1"> + <h1 class="font-bold flex justify-center items-center" v-text="pageTitle" /> + <div class="flex md:flex-row flex-col justify-center md:items-start items-center"> + <div class="flex flex-col gap-5 items-center justify-center"> <div class="flex flex-col"> - <p class="mx-4">Spare per gang</p> + <p class="mx-4">Tittel*</p> <input - v-model="challengeInstance.perPurchase" - class="w-40 text-right" - placeholder="Kr spart per sparing" - type="number" + v-model="challengeInstance.title" + placeholder="Skriv en tittel" + type="text" /> </div> <div class="flex flex-col"> - <div class="flex flex-row justify-between mx-4"> - <p>Kroner spart💸</p> - </div> - <input - v-model="challengeInstance.saved" - class="w-40 text-right" - placeholder="Sparebeløp" - type="number" + <p class="mx-4">Beskrivelse (valgfri)</p> + <textarea + v-model="challengeInstance.description" + class="w-80 h-20 no-rezise" + placeholder="Beskriv sparemÃ¥let" /> </div> - <div class="flex flex-col"> - <p class="mx-4">Av mÃ¥lbeløp💯*</p> - <input - v-model="challengeInstance.target" - class="w-40 text-right" - placeholder="MÃ¥lbeløp" - type="number" - /> - </div> - </div> - <ProgressBar :completion="completion" /> + <div class="flex flex-col sm:flex-row gap-3"> + <div class="flex flex-col"> + <p class="mx-4">Spare per gang</p> + <input + v-model="challengeInstance.perPurchase" + class="w-40 text-right" + placeholder="Kr spart per sparing" + type="number" + /> + </div> - <div class="flex flex-row gap-4"> - <div class="flex flex-col"> - <p class="mx-4">Forfallsdato*</p> - <input - :min="minDate" - :max="maxDate" - v-model="selectedDate" - placeholder="Forfallsdato" - type="date" - /> - </div> + <div class="flex flex-col"> + <div class="flex flex-row justify-between mx-4"> + <p>Kroner spart💸</p> + </div> + <input + v-model="challengeInstance.saved" + class="w-40 text-right" + placeholder="Sparebeløp" + type="number" + /> + </div> - <div class="flex flex-col items-center"> - <p>Last opp ikon for utfordringen📸</p> - <label - for="fileUpload" - class="bg-white text-black text-lg p-1 mt-2 rounded cursor-pointer leading-none" - > - 💾 - </label> - <input - id="fileUpload" - type="file" - accept=".jpg" - hidden - @change="handleFileChange" - /> - <div v-if="uploadedFile" class="flex justify-center items-center mt-2"> - <p class="text-sm">{{ uploadedFile.name }}</p> - <button - @click="removeUploadedFile" - class="ml-2 text-xs font-bold border-2 p-1 rounded text-red-500" + <div class="flex flex-col"> + <p class="mx-4">Av mÃ¥lbeløp💯*</p> + <input + v-model="challengeInstance.target" + class="w-40 text-right" + placeholder="MÃ¥lbeløp" + type="number" + /> + </div> + </div> + <ProgressBar :completion="completion" /> + + <div class="flex flex-row gap-4"> + <div class="flex flex-col"> + <p class="mx-4">Forfallsdato*</p> + <input + :min="minDate" + v-model="selectedDate" + placeholder="Forfallsdato" + type="date" + /> + </div> + <div class="flex flex-col items-center"> + <p>Last opp ikon for utfordringen📸</p> + <label + for="fileUpload" + class="bg-white text-black text-lg cursor-pointer leading-none rounded-full border p-3 border-black" > - Fjern fil - </button> + Legg til 💾 + </label> + <input + id="fileUpload" + type="file" + accept=".jpg, .png" + hidden + @change="handleFileChange" + /> + <div v-if="uploadedFile" class="flex justify-center items-center mt-2"> + <p class="text-sm">{{ uploadedFile.name }}</p> + <button + @click="removeUploadedFile" + class="ml-2 text-xs font-bold border-2 p-1 rounded text-red-500" + > + Fjern fil + </button> + </div> </div> </div> - </div> - <div class="flex flex-row justify-between w-full"> - <button class="primary danger" @click="cancelCreation" v-text="'Avbryt'" /> - <button class="primary" @click="submitAction" v-text="submitButton" /> + <div class="flex flex-row justify-between w-full"> + <button class="primary danger" @click="cancelCreation" v-text="'Avbryt'" /> + + <button class="primary" @click="submitAction" v-text="submitButton" /> + </div> + <ModalComponent + :title="modalTitle" + :message="modalMessage" + :isModalOpen="errorModalOpen" + @close="errorModalOpen = false" + > + <template v-slot:input> + <div class="flex justify-center items-center"> + <div class="flex flex-col gap-5"> + <button class="primary" @click="errorModalOpen = false"> + Lukk + </button> + </div> + </div> + </template> + </ModalComponent> + + <ModalComponent + :title="modalTitle" + :message="modalMessage" + :isModalOpen="confirmModalOpen" + @close="confirmModalOpen = false" + > + <template v-slot:input> + <div class="flex justify-center items-center"> + <div class="flex flex-col gap-5"> + <button class="primary" @click="confirmCancel">Bekreft</button> + <button class="primary danger" @click="confirmModalOpen = false"> + Avbryt + </button> + </div> + </div> + </template> + </ModalComponent> </div> - <ModalComponent - :title="modalTitle" - :message="modalMessage" - :isModalOpen="errorModalOpen" - @close="errorModalOpen = false" - > - <template v-slot:buttons> - <button class="primary" @click="errorModalOpen = false">Lukk</button> - </template> - </ModalComponent> - - <ModalComponent - :title="modalTitle" - :message="modalMessage" - :isModalOpen="confirmModalOpen" - @close="confirmModalOpen = false" - > - <template v-slot:buttons> - <button class="primary" @click="confirmCancel">Bekreft</button> - <button class="primary danger" @click="confirmModalOpen = false">Avbryt</button> - </template> - </ModalComponent> + </div> + <div + class="lg:absolute right-5 lg:top-1/3 max-lg:bottom-0 max-lg:mt-44 transform -translate-y-1/2 lg:w-1/4 lg:max-w-xs" + > + <InteractiveSpare + :png-size="10" + :speech="[`Trenger du hjelp? Trykk pÃ¥ â“ nede i høyre hjørne!`]" + direction="left" + /> </div> </div> </template> diff --git a/src/views/ManageConfigView.vue b/src/views/ManageConfigView.vue index 5e5f634de622323ebaae2fc6f5e0783b12b9d3c1..2a5ad08eaf1f68ff0d5e299965567082fb8c635e 100644 --- a/src/views/ManageConfigView.vue +++ b/src/views/ManageConfigView.vue @@ -159,12 +159,16 @@ onMounted(() => { class="flex flex-row flex-wrap justify-center gap-5 border-2 p-4" > <input v-model="item.type" placeholder="Type" type="text" /> - <input v-model="item.specificAmount" placeholder="Pris per uke" type="number" /> - <input v-model="item.generalAmount" placeholder="Generell pris" type="number" /> + <input + v-model="item.specificAmount" + placeholder="Generell pris" + type="number" + /> + <input v-model="item.generalAmount" placeholder="Pris per uke" type="number" /> <button class="primary danger w-min items-center" @click="deleteChallengeType(item.type)" - v-text="'x'" + v-text="'Slett'" /> </CardTemplate> <button diff --git a/src/views/ManageGoalView.vue b/src/views/ManageGoalView.vue index 3014d64b82176850de7eb982ffda89e0a8cbd8df..25e1af89597a9be1bd028ed5b2628abe5de1896d 100644 --- a/src/views/ManageGoalView.vue +++ b/src/views/ManageGoalView.vue @@ -5,6 +5,7 @@ import type { Goal } from '@/types/goal' import ProgressBar from '@/components/ProgressBar.vue' import authInterceptor from '@/services/authInterceptor' import ModalComponent from '@/components/ModalComponent.vue' +import InteractiveSpare from '@/components/InteractiveSpare.vue' const router = useRouter() const uploadedFile: Ref<File | null> = ref(null) @@ -213,120 +214,133 @@ onMounted(async () => { </script> <template> - <div class="flex flex-col justify-center items-center"> - <h1 class="font-bold" v-text="pageTitle" /> - <div class="flex flex-col gap-5 items-center justify-center"> - <div class="flex flex-col"> - <p class="mx-4">Tittel*</p> - <input v-model="goalInstance.title" placeholder="Skriv en tittel" type="text" /> - </div> - - <div class="flex flex-col"> - <p class="mx-4">Beskrivelse (valgfri)</p> - <textarea - v-model="goalInstance.description" - class="w-80 h-20 no-rezise" - placeholder="Beskriv sparemÃ¥let" - /> - </div> - - <div class="flex flex-col sm:flex-row gap-3"> + <div class="relative flex-1 min-h-screen"> + <h1 class="font-bold flex justify-center items-center" v-text="pageTitle" /> + <div class="flex md:flex-row flex-col justify-center md:items-start items-center"> + <div class="flex flex-col gap-5 items-center justify-center"> <div class="flex flex-col"> - <p class="mx-4">Kroner spart💸</p> - <input - v-model="goalInstance.saved" - class="w-40 text-right" - placeholder="Sparebeløp" - type="number" - /> + <p class="mx-4">Tittel*</p> + <input v-model="goalInstance.title" placeholder="Skriv en tittel" type="text" /> </div> <div class="flex flex-col"> - <p class="mx-4">Av mÃ¥lbeløp💯*</p> - <input - v-model="goalInstance.target" - class="w-40 text-right" - placeholder="MÃ¥lbeløp" - type="number" + <p class="mx-4">Beskrivelse (valgfri)</p> + <textarea + v-model="goalInstance.description" + class="w-80 h-20 no-rezise" + placeholder="Beskriv sparemÃ¥let" /> </div> - </div> - <ProgressBar :completion="completion" /> - <div class="flex flex-row gap-4"> - <div class="flex flex-col"> - <p class="mx-4">Forfallsdato*</p> - <input - :min="minDate" - v-model="selectedDate" - placeholder="Forfallsdato" - type="date" - /> + <div class="flex flex-col sm:flex-row gap-3"> + <div class="flex flex-col"> + <p class="mx-4">Kroner spart💸</p> + <input + v-model="goalInstance.saved" + class="w-40 text-right" + placeholder="Sparebeløp" + type="number" + /> + </div> + + <div class="flex flex-col"> + <p class="mx-4">Av mÃ¥lbeløp💯*</p> + <input + v-model="goalInstance.target" + class="w-40 text-right" + placeholder="MÃ¥lbeløp" + type="number" + /> + </div> </div> - <div class="flex flex-col items-center"> - <p>Last opp ikon for utfordringen📸</p> - <label - for="fileUpload" - class="bg-white text-black text-lg p-1 mt-2 rounded cursor-pointer leading-none" - > - 💾 - </label> - <input - id="fileUpload" - type="file" - accept=".jpg" - hidden - @change="handleFileChange" - /> - <div v-if="uploadedFile" class="flex justify-center items-center mt-2"> - <p class="text-sm">{{ uploadedFile.name }}</p> - <button - @click="removeUploadedFile" - class="ml-2 text-xs font-bold border-2 p-1 rounded text-red-500" + <ProgressBar :completion="completion" /> + + <div class="flex flex-row gap-4"> + <div class="flex flex-col"> + <p class="mx-4">Forfallsdato*</p> + <input + :min="minDate" + v-model="selectedDate" + placeholder="Forfallsdato" + type="date" + /> + </div> + <div class="flex flex-col items-center"> + <p>Last opp ikon for utfordringen📸</p> + <label + for="fileUpload" + class="bg-white text-black text-lg cursor-pointer leading-none rounded-full border p-3 border-black" > - Fjern fil - </button> + Legg til 💾 + </label> + <input + id="fileUpload" + type="file" + accept=".jpg, .png" + hidden + @change="handleFileChange" + /> + <div v-if="uploadedFile" class="flex justify-center items-center mt-2"> + <p class="text-sm">{{ uploadedFile.name }}</p> + <button + @click="removeUploadedFile" + class="ml-2 text-xs font-bold border-2 p-1 rounded text-red-500" + > + Fjern fil + </button> + </div> </div> </div> - </div> - <div class="flex flex-row justify-between w-full"> - <button - v-if="isEdit" - class="ml-2 primary danger" - @click="deleteGoal" - v-text="'Slett'" - /> - <button - v-else - class="ml-2 primary danger" - @click="cancelCreation" - v-text="'Avbryt'" - /> - <button class="primary" @click="submitAction" v-text="submitButton" /> + <div class="flex flex-row justify-between w-full"> + <button + v-if="isEdit" + class="ml-2 primary danger" + @click="deleteGoal" + v-text="'Slett'" + /> + <button + v-else + class="ml-2 primary danger" + @click="cancelCreation" + v-text="'Avbryt'" + /> + <button class="primary" @click="submitAction" v-text="submitButton" /> + </div> + <ModalComponent + :title="modalTitle" + :message="modalMessage" + :isModalOpen="errorModalOpen" + @close="errorModalOpen = false" + > + <template v-slot:buttons> + <button class="primary" @click="errorModalOpen = false">Lukk</button> + </template> + </ModalComponent> + + <ModalComponent + :title="modalTitle" + :message="modalMessage" + :isModalOpen="confirmModalOpen" + @close="confirmModalOpen = false" + > + <template v-slot:buttons> + <button class="primary" @click="confirmCancel">Bekreft</button> + <button class="primary danger" @click="confirmModalOpen = false"> + Avbryt + </button> + </template> + </ModalComponent> </div> - <ModalComponent - :title="modalTitle" - :message="modalMessage" - :isModalOpen="errorModalOpen" - @close="errorModalOpen = false" + <div + class="lg:absolute right-5 lg:top-1/4 max-lg:bottom-0 max-lg:mt-44 transform -translate-y-1/2 lg:w-1/4 lg:max-w-xs" > - <template v-slot:buttons> - <button class="primary" @click="errorModalOpen = false">Lukk</button> - </template> - </ModalComponent> - - <ModalComponent - :title="modalTitle" - :message="modalMessage" - :isModalOpen="confirmModalOpen" - @close="confirmModalOpen = false" - > - <template v-slot:buttons> - <button class="primary" @click="confirmCancel">Bekreft</button> - <button class="primary danger" @click="confirmModalOpen = false">Avbryt</button> - </template> - </ModalComponent> + <InteractiveSpare + :png-size="10" + :speech="[`Trenger du hjelp? Trykk pÃ¥ â“ nede i høyre hjørne!`]" + direction="left" + /> + </div> </div> </div> </template> diff --git a/src/views/NotFoundView.vue b/src/views/NotFoundView.vue index 12372705ccd7b4f6f5f71e15f61bbeef5765f3e9..89b08e7fe479daa6d480bc832120cbb44b50851b 100644 --- a/src/views/NotFoundView.vue +++ b/src/views/NotFoundView.vue @@ -1,8 +1,8 @@ <script lang="ts" setup></script> <template> - <h1>404 - Siden finnes ikke</h1> - <p>Denne siden finnes ikke. GÃ¥ tilbake til <RouterLink to="/">hjem</RouterLink>.</p> + <div class="flex flex-col justify-center items-center mt-16"> + <h1>404 - Siden finnes ikke</h1> + <p>Denne siden finnes ikke. GÃ¥ tilbake til <RouterLink to="/">hjem</RouterLink>.</p> + </div> </template> - -<style scoped></style> diff --git a/src/views/ViewChallengeView.vue b/src/views/ViewChallengeView.vue index ced556dd7ed141d24d4e8356cd56494ddee9669d..2547802e104ced7cf68dcc7b586c19e165affb2c 100644 --- a/src/views/ViewChallengeView.vue +++ b/src/views/ViewChallengeView.vue @@ -112,14 +112,14 @@ const completeChallenge = () => { <h2 class="font-light"> {{ challengeInstance.title }} </h2> - <div class="flex flex-row gap-4 justify-center"> + <div class="flex flex-col gap-4 justify-center"> <p class="text-wrap break-words">{{ challengeInstance.description }}</p> - <div> + <div class="flex justify-center items-center"> <img v-if="isImageLoaded" :src="challengeImageUrl || '@/assets/star.png'" alt="Goal Image" - class="w-full h-40 object-cover rounded-lg" + class="w-44 h-44 object-cover rounded-lg" /> </div> </div> @@ -134,7 +134,7 @@ const completeChallenge = () => { <br /> <p> Du sparer {{ challengeInstance.perPurchase }}kr hver gang du dropper Ã¥ bruke - penger pÃ¥ {{ challengeInstance.type }} + penger pÃ¥ {{ challengeInstance.title }} </p> <div class="justify-center pl-20"> <button diff --git a/src/views/ViewGoalView.vue b/src/views/ViewGoalView.vue index d6addf823c91da1164ba6e5a6c72cd99dfa0538d..446069857f8830a9ad32cea2da97e22e314e495e 100644 --- a/src/views/ViewGoalView.vue +++ b/src/views/ViewGoalView.vue @@ -101,14 +101,14 @@ const completeGoal = () => { <h2 class="font-light"> {{ goalInstance.title }} </h2> - <div class="flex flex-row gap-4 justify-center"> + <div class="flex flex-col gap-4 justify-center"> <p class="text-wrap break-words">{{ goalInstance.description }}</p> - <div> + <div class="flex justify-center items-center"> <img v-if="isImageLoaded" :src="goalImageUrl || '@/assets/star.png'" alt="Goal Image" - class="w-full h-40 object-cover rounded-lg" + class="w-44 h-44 object-cover rounded-lg" /> </div> </div> diff --git a/src/views/ViewProfileView.vue b/src/views/ViewProfileView.vue index b8c9f974717b9fd77c285b1c237abbe9fa0208e3..d166da3316e4e1bdbe270c177ccfe95a12a783df 100644 --- a/src/views/ViewProfileView.vue +++ b/src/views/ViewProfileView.vue @@ -23,7 +23,6 @@ const updateUser = async () => { authInterceptor('/profile') .then((response) => { profile.value = response.data - console.log(profile.value) }) .catch((error) => { return console.log(error) @@ -53,6 +52,7 @@ onMounted(async () => { profilePicture.value = userStore.profilePicture openSpare() }) + const updateBiometrics = async () => { await useUserStore().bioRegister() await updateUser() @@ -66,7 +66,7 @@ const updateProfilePicture = async () => { const openSpare = () => { speech.value = [ - `Velkommen, ${profile.value?.firstName} ${profile.value?.lastName} !`, + `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!' ] @@ -88,17 +88,17 @@ const openSpare = () => { <ModalEditAvatar @update-profile-picture="updateProfilePicture" /> </div> <div class="w-full flex flex-col justify-between"> - <h3 class="font-thin my-0">{{ profile?.username }}</h3> - <h3 class="font-thin my-0"> + <h3 class="font-thin my-0 md:text-xl text-lg">{{ profile?.username }}</h3> + <h3 class="font-thin my-0 md:text-xl text-lg"> {{ profile?.firstName + ' ' + profile?.lastName }} </h3> - <h3 class="font-thin my-0">{{ profile?.email }}</h3> + <h3 class="font-thin my-0 md:text-xl text-lg">{{ profile?.email }}</h3> </div> </div> <h3 class="font-bold" - v-text="'Du har totalt spart ' + profile?.savedAmount + 'kr'" + v-text="'Du har spart ' + profile?.savedAmount + ' kr totalt'" /> <CardTemplate> @@ -120,20 +120,21 @@ const openSpare = () => { v-text="profile?.savingAccount.accNumber || 'Ingen sparekonto oppkoblet'" /> </CardTemplate> - - <button - class="primary secondary" - @click="router.push({ name: 'edit-profile' })" - v-text="'Rediger bruker'" - /> - <button - class="primary secondary" - @click="router.push({ name: 'edit-configuration' })" - v-text="'Rediger konfigurasjon'" - /> - <button class="primary" @click="updateBiometrics"> - {{ profile?.hasPasskey ? 'Endre biometri' : 'Legg til biometri' }} - </button> + <div class="flex flex-col justify-center items-center space-y-2"> + <button + class="primary secondary w-2/3" + @click="router.push({ name: 'edit-profile' })" + v-text="'Rediger bruker'" + /> + <button + class="primary secondary w-2/3" + @click="router.push({ name: 'edit-configuration' })" + v-text="'Rediger konfigurasjon'" + /> + <button class="primary w-2/3" @click="updateBiometrics"> + {{ profile?.hasPasskey ? 'Endre biometri' : 'Legg til biometri' }} + </button> + </div> </div> <div class="flex flex-col"> @@ -146,7 +147,11 @@ const openSpare = () => { ></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'" /> + <a + @click="router.push({ name: 'goals' })" + class="hover:p-0 cursor-pointer text-blue-500" + v-text="'Se alle'" + /> </div> <CardTemplate class="p-4 flex flex-row flex-wrap justify-center gap-2 mb-4 mt-2"> <CardGoal v-for="goal in completedGoals" :key="goal.id" :goal-instance="goal" /> @@ -154,7 +159,11 @@ const openSpare = () => { <div class="flex flex-row justify-between mx-4"> <p class="font-bold">Fullførte utfordringer</p> - <a class="hover:p-0 cursor-pointer" v-text="'Se alle'" /> + <a + @click="router.push({ name: 'challenges' })" + class="hover:p-0 cursor-pointer text-blue-500" + v-text="'Se alle'" + /> </div> <CardTemplate class="p-4 flex flex-row flex-wrap justify-center gap-2 mb-4 mt-2"> <CardGoal