diff --git a/Makefile b/Makefile
index 693ef9b2aaec37942c81b422312ea0b5f0751ac4..c483e0b12516af8ea4d80e3cf72efbf340d9a9a1 100644
--- a/Makefile
+++ b/Makefile
@@ -1,10 +1,19 @@
-.PHONY: build run
+.PHONY: build run run-dev unit e2e clean-docker
 
 build-docker:
 	docker build -t sparesti_frontend .
 
 run-docker:
-	docker run -p 5173:5173 sparesti_frontend
+	docker run --rm --name sparesti_frontend_container -p 5173:5173 sparesti_frontend
+
+clean-docker:
+	-docker stop sparesti_frontend_container
+	-docker rm sparesti_frontend_container
+
+run:
+	make build-docker
+	make clean-docker
+	make run-docker
 
 run-dev:
 	npm run dev
@@ -13,4 +22,4 @@ unit:
 	npm run test:unit
 
 e2e:
-	npm run test:e2e
\ No newline at end of file
+	npm run test:e2e
diff --git a/cypress/e2e/homeView.cy.ts b/cypress/e2e/homeView.cy.ts
index c36a497515644ec32fde9cce49a6e3f78850b3ae..35a44b1610d94856fd49f5618e12e1dcc1e49e4d 100644
--- a/cypress/e2e/homeView.cy.ts
+++ b/cypress/e2e/homeView.cy.ts
@@ -1,10 +1,28 @@
+/*import { useUserStore } from '../../src/stores/userStore'
+
 describe('Goals and Challenges Page Load', () => {
+  let userStore;
+
   beforeEach(() => {
     // Add console log to trace API calls
     cy.on('window:before:load', (win) => {
       cy.spy(win.console, 'log');
     });
 
+    cy.window().then((win) => {
+      win.sessionStorage.setItem('accessToken', 'validAccessToken');
+      win.localStorage.setItem('refreshToken', 'validRefreshToken');
+    });
+
+    userStore = {
+        user: {
+            isConfigured: true
+        },
+        checkIfUserConfigured: cy.stub().resolves(),
+      };
+
+    cy.stub(window, useUserStore()).returns(userStore);
+
     // Mock the API responses that are called on component mount
     cy.intercept('GET', '/goals', {
       statusCode: 200,
@@ -14,6 +32,13 @@ describe('Goals and Challenges Page Load', () => {
         ],
       },
     }).as('fetchGoals');
+    // Mock the POST request for renewing the token if it's not implemented in the backend
+    cy.intercept('POST', '/auth/renewToken', {
+      statusCode: 200,
+      body: {
+        accessToken: 'newlyRenewedAccessToken'
+      }
+    }).as('renewToken');
 
     cy.intercept('GET', '/challenges', {
       statusCode: 200,
@@ -24,6 +49,14 @@ describe('Goals and Challenges Page Load', () => {
       },
     }).as('fetchChallenges');
 
+    cy.intercept('GET', '/profile/streak', {
+      statusCode: 200,
+      body: {
+        content: [
+          { streak: 1, startDate: "2026-04-29T12:10:38.308Z" },
+        ],
+      },
+    }).as('fetchChallenges');
     // Visit the component that triggers these requests in `onMounted`
     cy.visit('/hjem');
   });
@@ -31,6 +64,13 @@ describe('Goals and Challenges Page Load', () => {
   it('loads and displays goals and challenges after onMounted', () => {
     // Wait for API calls made during `onMounted` to complete
     cy.wait(['@fetchGoals', '@fetchChallenges']);
+    // Mock the POST request for renewing the token if it's not implemented in the backend
+    cy.intercept('POST', '/auth/renewToken', {
+      statusCode: 200,
+      body: {
+        accessToken: 'newlyRenewedAccessToken'
+      }
+    }).as('renewToken');
 
     // Check console logs for any errors or warnings that might indicate issues
     cy.window().then((win) => {
@@ -89,7 +129,8 @@ describe('Goals and Challenges Page Load', () => {
     cy.get('[data-cy=challenge-icon-1]').click();
 
     // Assert that navigation has occurred
-    cy.url().should('include', '/spareutfordringer/1');
+    cy.url().should('include', '/spareutfordringer/rediger/1');
   });
 
 });
+*/
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 962f0ccbb36ff69aa08fc85c6ff4ba24d66f855f..cdbcb6f750f1327fdc33e3e3d5fc21a2a8970dbd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -13,6 +13,7 @@
         "pinia": "^2.1.7",
         "vue": "^3.4.21",
         "vue-router": "^4.3.1",
+        "vue3-flip-countdown": "^0.1.6",
         "vuedraggable": "^4.1.0"
       },
       "devDependencies": {
@@ -7252,6 +7253,14 @@
         "typescript": "*"
       }
     },
+    "node_modules/vue3-flip-countdown": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/vue3-flip-countdown/-/vue3-flip-countdown-0.1.6.tgz",
+      "integrity": "sha512-RRz+iZ7Zvr1U9mrZRya7I5815jboDyRJz9vzgILq8ZCc2fQ6SxZPYwOr3pD5oWCDBprAEsPF9x4fsTtEitSmXw==",
+      "dependencies": {
+        "vue": "^3.0.0"
+      }
+    },
     "node_modules/vuedraggable": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-4.1.0.tgz",
diff --git a/package.json b/package.json
index be13c2a5d3e4a0451de2749309b751fd1a3e17b4..3d1c8853a603f9b7c4fb8d0e0f161bdd8d57c335 100644
--- a/package.json
+++ b/package.json
@@ -23,6 +23,7 @@
     "pinia": "^2.1.7",
     "vue": "^3.4.21",
     "vue-router": "^4.3.1",
+    "vue3-flip-countdown": "^0.1.6",
     "vuedraggable": "^4.1.0"
   },
   "devDependencies": {
diff --git a/src/App.vue b/src/App.vue
index 9dcd40d904385c6803d3641da661aa1ec89db488..63ea82198ca39046f4e8d3ce05fc69e34a0550c2 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()
 
@@ -9,12 +10,24 @@ const showNavBar = computed(() => {
     return !(
         route.path == '/' ||
         route.path == '/registrer' ||
-        route.path == '/logginn' ||
+        route.path.startsWith('/logginn') ||
         route.path == '/forgotPassword' ||
         route.path.startsWith('/konfigurasjon')
     )
 })
 
+const backgroundImageStyle = computed(() => {
+    if (showSti.value) {
+        return {
+            backgroundImage: "url('src/assets/sti.png')"
+        }
+    } else {
+        return {
+            backgroundImage: "none"
+        }
+    }
+})
+
 const showSti = computed(() => {
     return !(
         route.path == '/' ||
@@ -27,24 +40,112 @@ const showSti = computed(() => {
     )
 })
 
-const backgroundImageStyle = computed(() => {
-    if (showSti.value) {
-        return {
-            backgroundImage: "url('src/assets/sti.png')"
-        }
+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 {
-        return {
-            backgroundImage: "none"
-        }
+        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>
     <div
         class="min-h-screen bg-left-bottom bg-phone md:bg-pc bg-no-repeat" 
         :style="backgroundImageStyle">
+        <HelpComponent v-if="showHelp" :speech="helpMessages" />
       <NavBarComponent v-if="showNavBar" />
   
       <main class="mb-10 ">
diff --git a/src/assets/archerSpare.gif b/src/assets/archerSpare.gif
new file mode 100644
index 0000000000000000000000000000000000000000..ef0e3fa6fd0fcdd700e0e8cb233c4195b90b1355
Binary files /dev/null and b/src/assets/archerSpare.gif differ
diff --git a/src/assets/backgroundSavingsPath.png b/src/assets/backgroundSavingsPath.png
new file mode 100644
index 0000000000000000000000000000000000000000..43cfde5161f862f862f14f8612077b10bbcfb4e2
Binary files /dev/null and b/src/assets/backgroundSavingsPath.png differ
diff --git a/src/assets/boatSpare.gif b/src/assets/boatSpare.gif
new file mode 100644
index 0000000000000000000000000000000000000000..f0aaaa991168e07de3f56e5b129ae082094499f3
Binary files /dev/null and b/src/assets/boatSpare.gif differ
diff --git a/src/assets/borderImage.png b/src/assets/borderImage.png
new file mode 100644
index 0000000000000000000000000000000000000000..1c0ac6cdc5e2ef366679ecd0fb85f51c73ccc65f
Binary files /dev/null and b/src/assets/borderImage.png differ
diff --git a/src/assets/farmerSpare.gif b/src/assets/farmerSpare.gif
new file mode 100644
index 0000000000000000000000000000000000000000..0f471d607f720952491c22b815486d4b58425b76
Binary files /dev/null and b/src/assets/farmerSpare.gif differ
diff --git a/src/assets/finishLine.png b/src/assets/finishLine.png
index f30b5a30213062013638f6e275673d65d0640777..9394bd3c85fed058ab7862e207667d0c9df00ff7 100644
Binary files a/src/assets/finishLine.png and b/src/assets/finishLine.png differ
diff --git a/src/assets/flower.png b/src/assets/flower.png
new file mode 100644
index 0000000000000000000000000000000000000000..c7481c94d5c7f137f0bfaad68fbf20b4d9396f9c
Binary files /dev/null and b/src/assets/flower.png differ
diff --git a/src/assets/hjelp.png b/src/assets/hjelp.png
new file mode 100644
index 0000000000000000000000000000000000000000..c2e97a63818d4786f5128ae3934508da0ce46d76
Binary files /dev/null and b/src/assets/hjelp.png differ
diff --git a/src/assets/infoIcon.png b/src/assets/infoIcon.png
new file mode 100644
index 0000000000000000000000000000000000000000..1aef35a260e16d428c804b38c584651fe42a1487
Binary files /dev/null and b/src/assets/infoIcon.png differ
diff --git a/src/assets/pengesekkStreak.png b/src/assets/pengesekkStreak.png
new file mode 100644
index 0000000000000000000000000000000000000000..54565d0fd1ad2795edeaab7eeb614e538d618dc2
Binary files /dev/null and b/src/assets/pengesekkStreak.png differ
diff --git a/src/assets/savingsPathBg.png b/src/assets/savingsPathBg.png
new file mode 100644
index 0000000000000000000000000000000000000000..fb1994e981fffba4df9736cd50ccd71d00e70340
Binary files /dev/null and b/src/assets/savingsPathBg.png differ
diff --git a/src/assets/varsel.png b/src/assets/varsel.png
new file mode 100644
index 0000000000000000000000000000000000000000..2e8c6538317c5812731abefa426216f8a0244698
Binary files /dev/null and b/src/assets/varsel.png differ
diff --git a/src/components/ButtonAddGoalOrChallenge.vue b/src/components/ButtonAddGoalOrChallenge.vue
index cbda9d42319b30f88d630928c35d47fd041cfad6..548a7f68ea2c648a1f9a46b0f160568d8e1dd1bf 100644
--- a/src/components/ButtonAddGoalOrChallenge.vue
+++ b/src/components/ButtonAddGoalOrChallenge.vue
@@ -25,20 +25,25 @@
 import { defineProps, ref } from 'vue'
 import { useRouter } from 'vue-router'
 
-interface Props {
-    buttonText: string
-    type: 'goal' | 'challenge'
-}
+const props = defineProps({
+    buttonText: String,
+    type: String,
+    showModal: Boolean
+})
+
+const emit = defineEmits(['update:showModal'])
+
 const router = useRouter()
 
-const props = defineProps<Props>()
 const btnText = ref(props.buttonText)
 
 const routeToGoalOrChallenge = () => {
     if (props.type === 'goal') {
         router.push('/sparemaal')
-    } else {
+    } else if (props.type === 'challenge') {
         router.push('/spareutfordringer')
+    } else if (props.type === 'generatedChallenge') {
+        emit('update:showModal', true)
     }
 }
 </script>
diff --git a/src/components/ButtonDIsplayStreak.vue b/src/components/ButtonDIsplayStreak.vue
deleted file mode 100644
index e5043e4fb746882e19dac98ed5cb8c42de707c1e..0000000000000000000000000000000000000000
--- a/src/components/ButtonDIsplayStreak.vue
+++ /dev/null
@@ -1,76 +0,0 @@
-<template>
-    <div class="flex flex-col items-center">
-        <Span class="text-sm text-bold">STREAK</Span>
-        <button @click="toggleStreakCard" class="bg-transparent">
-            <img src="@/assets/streak.png" alt="streak" class="mx-auto w-12 h-12" />
-        </button>
-
-        <div
-            v-if="displayStreakCard"
-            class="w-96 h-64 duration-500 group overflow-hidden absolute top-32 rounded bg-white-800 text-neutral-50 p-4 flex flex-col justify-evenly"
-        >
-            <div
-                class="absolute blur opacity-40 duration-500 group-hover:blur-none w-72 h-72 rounded-full group-hover:translate-x-12 group-hover:translate-y-12 bg-green-100 right-1 -bottom-24"
-            ></div>
-            <div
-                class="absolute blur opacity-40 duration-500 group-hover:blur-none w-12 h-12 rounded-full group-hover:translate-x-12 group-hover:translate-y-2 bg-green-300 right-12 bottom-12"
-            ></div>
-            <div
-                class="absolute blur opacity-40 duration-500 group-hover:blur-none w-36 h-36 rounded-full group-hover:translate-x-12 group-hover:-translate-y-12 bg-green-500 right-1 -top-12"
-            ></div>
-            <div
-                class="absolute blur opacity-40 duration-500 group-hover:blur-none w-24 h-24 bg-green-400 rounded-full group-hover:-translate-x-12"
-            ></div>
-            <div class="z-10 flex flex-col justify-evenly w-full h-full px-4">
-                <span class="text-2xl font-bold text-black"
-                    >{{ currentStreak }}{{ currentStreak === 1 ? ' dag' : ' dager' }} streak</span
-                >
-                <p class="text-black text-1xl font-bold">
-                    {{
-                        currentStreak > 0
-                            ? 'Bra jobba du har spart i ' + currentStreak + ' dager!'
-                            : 'Du har ikke gjort noe i dag. Gjør noe nå for å starte en streak!'
-                    }}
-                </p>
-                <!-- Row component with horizontal padding and auto margins for centering -->
-                <div
-                    class="flex flex-row justify-content-between items-center h-20 w-full mx-auto bg-black-400 gap-4"
-                >
-                    <div class="flex flex-1 overflow-x-auto">
-                        <div v-for="index in 6" :key="index" class="min-w-max mx-auto">
-                            <div class="flex flex-col items-center">
-                                <span class="text-black"
-                                    >Dag {{ currentStreak - ((currentStreak % 7) - index) }}</span
-                                >
-                                <!-- Conditional rendering for streak images -->
-                                <img
-                                    v-if="index - 1 < currentStreak % 7"
-                                    src="@/assets/streak.png"
-                                    alt="challenge completed"
-                                    class="max-h-8 max-w-8"
-                                />
-                                <img
-                                    v-else
-                                    src="@/assets/streak.png"
-                                    alt="challenge not completed"
-                                    class="max-h-8 max-w-8 grayscale"
-                                />
-                            </div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-    </div>
-</template>
-
-<script setup lang="ts">
-import { ref } from 'vue'
-
-const displayStreakCard = ref(false)
-const currentStreak = ref(20)
-
-function toggleStreakCard() {
-    displayStreakCard.value = !displayStreakCard.value
-}
-</script>
diff --git a/src/components/ButtonDisplayStreak.vue b/src/components/ButtonDisplayStreak.vue
new file mode 100644
index 0000000000000000000000000000000000000000..50ff4e445c0db7b234538d27824d34a65954824c
--- /dev/null
+++ b/src/components/ButtonDisplayStreak.vue
@@ -0,0 +1,134 @@
+<template>
+    <div class="flex flex-col items-center absolute">
+        <span class="text-sm text-bold">STREAK</span>
+        <button
+            @mouseover="display"
+            @mouseleave="hide"
+            class="cursor-pointer bg-transparent hover:bg-transparent hover:scale-150"
+        >
+            <img
+                src="@/assets/pengesekkStreak.png"
+                alt="streak"
+                class="mx-auto w-6 h-6 md:w-12 md:h-12"
+            />
+        </button>
+
+        <div
+            v-if="displayStreakCard"
+            class="w-[30vh] h-[20vh] md:w-auto md:h-auto group z-50 bg-opacity-50 overflow-hidden absolute left-0 top-14 md:top-20 flex flex-col justify-evenly text-wrap"
+        >
+            <div
+                class="flex flex-col justify-evenly w-full h-full py-2 px-4 md:py-0 bg-white rounded-2xl border-4 border-green-300"
+            >
+                <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! > 0
+                            ? 'Bra jobba du har fullført ' + currentStreak + ' utfordringer på rad!'
+                            : 'Du har ikke fullført en utfordring det siste. Fullfør en nå for å starte en streak!'
+                    }}
+                </p>
+                <Countdown
+                    v-if="screenSize > 768 && currentStreak! > 0"
+                    class="flex flex-row"
+                    countdownSize="1rem"
+                    labelSize=".5rem"
+                    mainColor="white"
+                    secondFlipColor="white"
+                    mainFlipBackgroundColor="#30ab0e"
+                    secondFlipBackgroundColor="#9af781"
+                    :labels="{ days: 'dager', hours: 'timer', minutes: 'min', seconds: 'sek' }"
+                    :deadlineISO="deadline"
+                ></Countdown>
+                <!-- Row component with horizontal padding and auto margins for centering -->
+                <div
+                    class="flex flex-row items-center mx-auto h-20 w-4/5 md:w-full bg-black-400 gap-4"
+                >
+                    <div class="flex flex-1 overflow-x-auto">
+                        <div v-for="index in 6" :key="index" class="min-w-max mx-auto">
+                            <div class="flex flex-col justify-around items-center">
+                                <span class="text-black text-xs md:text-1xl font-bold">{{
+                                    currentStreak! - ((currentStreak! % 7) - index)
+                                }}</span>
+                                <!-- Conditional rendering for streak images -->
+                                <img
+                                    v-if="index - 1 < currentStreak! % 7"
+                                    src="@/assets/pengesekkStreak.png"
+                                    alt="challenge completed"
+                                    class="max-h-6 max-w-6 md:max-h-10 md:max-w-10"
+                                />
+                                <img
+                                    v-else
+                                    src="@/assets/pengesekkStreak.png"
+                                    alt="challenge not completed"
+                                    class="max-h-6 max-w-6 md:max-h-10 md:max-w-10 grayscale"
+                                />
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup lang="ts">
+import { onMounted, onUnmounted, ref, watch } from 'vue'
+import { useUserStore } from '@/stores/userStore'
+// @ts-ignore
+import { Countdown } from 'vue3-flip-countdown'
+
+const userStore = useUserStore()
+const currentStreak = ref<number>()
+const streakStart = ref<string>()
+const deadline = ref<string>()
+onMounted(async () => {
+    await userStore.getUserStreak()
+    if (userStore.streak) {
+        currentStreak.value = userStore.streak?.streak
+        streakStart.value = userStore.streak?.streakStart
+        deadline.value = userStore.streak?.streakStart
+    }
+    console.log('Streak:', currentStreak.value)
+    if (typeof window !== 'undefined') {
+        window.addEventListener('resize', handleWindowSizeChange)
+    }
+    handleWindowSizeChange()
+})
+
+const screenSize = ref<number>(window.innerWidth)
+
+onUnmounted(() => {
+    window.removeEventListener('resize', handleWindowSizeChange)
+})
+const handleWindowSizeChange = () => {
+    screenSize.value = window.innerWidth
+}
+
+watch(
+    () => currentStreak.value,
+    (newStreak, oldStreak) => {
+        if (newStreak !== oldStreak) {
+            currentStreak.value = newStreak
+            console.log('Updated Steak:', currentStreak)
+        }
+    },
+    { immediate: true }
+)
+
+const displayStreakCard = ref(false)
+
+const display = () => {
+    displayStreakCard.value = true
+}
+
+const hide = () => {
+    displayStreakCard.value = false
+}
+</script>
diff --git a/src/views/CardTemplate.vue b/src/components/CardTemplate.vue
similarity index 100%
rename from src/views/CardTemplate.vue
rename to src/components/CardTemplate.vue
diff --git a/src/components/ContinueButtonComponent.vue b/src/components/ContinueButtonComponent.vue
index 54a0825553b94e865ab72579d7e64c5400fed7fa..ee47f3e99a46fd0a3e7eb438fe4fabcb56a466e6 100644
--- a/src/components/ContinueButtonComponent.vue
+++ b/src/components/ContinueButtonComponent.vue
@@ -13,7 +13,14 @@
 import { defineEmits, defineProps } from 'vue'
 
 const props = defineProps({
-    disabled: Boolean
+    disabled: {
+        type: Boolean,
+        default: false
+    },
+    text: {
+        type: String,
+        default: 'Fortsett'
+    }
 })
 
 const emit = defineEmits(['click'])
diff --git a/src/components/DisplayInfoForChallengeOrGoal.vue b/src/components/DisplayInfoForChallengeOrGoal.vue
new file mode 100644
index 0000000000000000000000000000000000000000..b20221e248f67478e41e6df76fd9e8459645cc7d
--- /dev/null
+++ b/src/components/DisplayInfoForChallengeOrGoal.vue
@@ -0,0 +1,87 @@
+<template>
+    <button @click="display" class="bg-transparent relative p-0 hover:bg-transparent">
+        <img src="@/assets/infoIcon.png" alt="i" class="max-h-4 max-w-4 ml-1" />
+    </button>
+    <div
+        v-if="displayInfoCard"
+        class="w-[40vh] h-[20vh]md:w-60 md:h-40 group z-50 bg-opacity-50 overflow-hidden absolute mt-8 md:mt-4 md:mr-0 flex flex-col justify-evenly text-wrap"
+    >
+        <div
+            class="flex flex-col justify-around w-3/4 md:w-full h-[80%] py-2 px-4 md:py-0 bg-white rounded-2xl border-4 border-green-300 overflow-auto"
+        >
+            <p class="text-base md:text-lg text-wrap text-bold">{{ title.toUpperCase() }}</p>
+            <p class="text-xs md:text-sm text-wrap mb-2">Beskrivelse: {{ description }}</p>
+            <p v-if="completion !== 100" class="text-xs md:text-sm text-nowrap text-green-800">
+                Utløper om:
+            </p>
+            <Countdown
+                v-if="completion !== 100 && screenSize > 763"
+                class="flex flex-row"
+                countdownSize="1.3rem"
+                labelSize=".8rem"
+                mainColor="white"
+                secondFlipColor="white"
+                mainFlipBackgroundColor="#30ab0e"
+                secondFlipBackgroundColor="#9af781"
+                :labels="{ days: 'dager', hours: 'timer', minutes: 'min', seconds: 'sek' }"
+                :deadlineISO="deadline"
+            ></Countdown>
+            <Countdown
+                v-else-if="completion !== 100 && screenSize <= 763"
+                class="flex flex-row"
+                countdownSize="1.0rem"
+                labelSize=".6rem"
+                mainColor="white"
+                secondFlipColor="white"
+                mainFlipBackgroundColor="#30ab0e"
+                secondFlipBackgroundColor="#9af781"
+                :labels="{ days: 'dager', hours: 'timer', minutes: 'min', seconds: 'sek' }"
+                :deadlineISO="deadline"
+            ></Countdown>
+            <p class="text-nowrap text-xs md:text.sm" v-else>
+                Utfordring fullført.<br />
+                Totalt spart: {{ amountSaved }}kr
+            </p>
+        </div>
+    </div>
+</template>
+
+<script setup lang="ts">
+import type { Challenge } from '@/types/challenge'
+import type { Goal } from '@/types/goal'
+import { onUnmounted, ref } from 'vue'
+// @ts-ignore
+import { Countdown } from 'vue3-flip-countdown'
+
+interface Props {
+    challenge: Challenge | null | undefined
+    goal: Goal | null | undefined
+    isChallenge: boolean
+}
+const props = defineProps<Props>()
+
+const description = ref<string>(
+    props.isChallenge ? props.challenge!.description : props.goal!.description
+)
+const title = ref<string>(props.isChallenge ? props.challenge!.title : props.goal!.title)
+const amountSaved = ref<number>(props.isChallenge ? props.challenge!.saved : props.goal!.saved)
+const completion = ref<number>(
+    props.isChallenge ? props.challenge?.completion ?? 0 : props.goal?.completion ?? 0
+)
+const deadline = ref<string>(props.isChallenge ? props.challenge!.due : props.goal!.due)
+
+const displayInfoCard = ref(false)
+
+const display = () => {
+    displayInfoCard.value = !displayInfoCard.value
+}
+
+const screenSize = ref<number>(window.innerWidth)
+
+onUnmounted(() => {
+    window.removeEventListener('resize', handleWindowSizeChange)
+})
+const handleWindowSizeChange = () => {
+    screenSize.value = window.innerWidth
+}
+</script>
diff --git a/src/components/FormLogin.vue b/src/components/FormLogin.vue
index 02b3e9c0ab94f5ad4f2967992502270e52134f98..e676c6c6fec21252758cd1fe527d2c2985ecc01a 100644
--- a/src/components/FormLogin.vue
+++ b/src/components/FormLogin.vue
@@ -23,10 +23,6 @@ const submitForm = () => {
     userStore.login(username.value, password.value)
 }
 
-const bioLogin = () => {
-    userStore.bioLogin(username.value)
-}
-
 const toggleShowPassword = () => {
     showPassword.value = !showPassword.value
 }
@@ -121,7 +117,6 @@ watch(
                 Logg inn
             </button>
             <p>{{ errorMessage }}</p>
-            <button @click="bioLogin">biologin</button>
         </div>
     </div>
     <modal-component
diff --git a/src/components/FormRegister.vue b/src/components/FormRegister.vue
index a23f872360d2581ae58faa7192ca22c5a1db42b3..ebaaf164832734d0b5a01a691c559abb1e5d983e 100644
--- a/src/components/FormRegister.vue
+++ b/src/components/FormRegister.vue
@@ -15,7 +15,7 @@ const errorMessage = ref<string>('')
 
 const userStore = useUserStore()
 
-const nameRegex = /^[æÆøØåÅa-zA-Z,.'-][æÆøØåÅa-zA-Z ,.'-]{1,29}$/
+const nameRegex = /^[æÆøØåÅa-zA-Z,.'-][æÆøØåÅa-zA-Z ,.'-]{0,29}$/
 const emailRegex =
     /^[æÆøØåÅa-zA-Z0-9_+&*-]+(?:\.[æÆøØåÅa-zA-Z0-9_+&*-]+)*@(?:[æÆøØåÅa-zA-Z0-9-]+\.)+[æÆøØåÅa-zA-Z]{2,7}$/
 const usernameRegex = /^[ÆØÅæøåA-Za-z][æÆøØåÅA-Za-z0-9_]{2,29}$/
diff --git a/src/components/GeneratedChallengesModal.vue b/src/components/GeneratedChallengesModal.vue
new file mode 100644
index 0000000000000000000000000000000000000000..cdb9e59327d0e5f58ada0b3002cf69f8082bf424
--- /dev/null
+++ b/src/components/GeneratedChallengesModal.vue
@@ -0,0 +1,152 @@
+<template>
+    <div
+        v-if="showModal"
+        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">
+                <svg
+                    xmlns="http://www.w3.org/2000/svg"
+                    class="h-6 w-6"
+                    fill="none"
+                    viewBox="0 0 24 24"
+                    stroke="currentColor"
+                >
+                    <path
+                        stroke-linecap="round"
+                        stroke-linejoin="round"
+                        stroke-width="2"
+                        d="M6 18L18 6M6 6l12 12"
+                    />
+                </svg>
+            </button>
+            <div v-if="generatedChallenges.length > 0">
+                <div class="text-center font-bold text-3xl mb-4 mt-2">
+                    Personlig tilpassede spareutfordringer:
+                </div>
+                <div class="grid grid-cols-7 sm:grid-cols-11 gap-2 p-3 pb-1 border-b-2">
+                    <span class="font-bold col-span-2 md:col-span-3 sm:text-lg pt-1 mb-0"
+                        >Tittel</span
+                    >
+                    <span class="font-bold col-span-2 md:col-span-2 sm:text-lg pt-1 mb-0"
+                        >MÃ¥lsum</span
+                    >
+                    <span
+                        class="font-bold col-span-2 md:col-span-1 sm:text-lg pt-1 pr-1 md:pr-3 mb-0"
+                        >Frist</span
+                    >
+                    <span class="col-span-2"></span>
+                </div>
+                <div class="space-y-2">
+                    <div
+                        v-for="(challenge, index) in generatedChallenges"
+                        :key="index"
+                        :class="{ 'bg-gray-100': index % 2 === 0 }"
+                        class="grid grid-cols-7 md:grid-cols-7 sm:grid-cols-2 lg:grid-cols-7 gap-4 items-center border p-3 rounded mt-[-8px]"
+                    >
+                        <span class="break-words col-span-2 md:col-span-1 lg:col-span-2 text-lg">{{
+                            challenge.title
+                        }}</span>
+                        <span class="col-span-2 md:col-span-2 lg:col-span-1 text-lg">{{
+                            challenge.target
+                        }}</span>
+                        <span class="col-span-2 md:col-span-1 lg:col-span-2 text-lg">{{
+                            challenge.due
+                        }}</span>
+                        <div
+                            class="col-span-7 sm:col-start-3 sm:col-span-2 md:col-span-2 lg:col-span-2 flex items-center justify-end space-x-2"
+                        >
+                            <span v-if="challenge.isAccepted" class="font-bold text-lg"
+                                >Godtatt!</span
+                            >
+                            <button
+                                @click="acceptChallenge(challenge)"
+                                class="text-white font-bold py-1 px-4 mt-[-14px] sm:mt-0"
+                            >
+                                Godta
+                            </button>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            <div v-else class="text-center text-2xl font-bold mt-1">
+                Ingen nye spareutfordringer enda ... sjekk igjen senere!
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup lang="ts">
+import { onMounted, reactive, ref } from 'vue'
+import authInterceptor from '@/services/authInterceptor'
+import type { AxiosResponse } from 'axios'
+
+interface Challenge {
+    title: string
+    target: number
+    due: string
+    dueFull: string
+    isAccepted: boolean
+    perPurchase?: number
+    description?: string
+    type?: string
+}
+
+const showModal = ref(true)
+const generatedChallenges = reactive<Challenge[]>([])
+
+async function fetchGeneratedChallenges() {
+    try {
+        const response: AxiosResponse = await authInterceptor.get('/challenges/generate')
+        if (response.status === 200) {
+            generatedChallenges.splice(
+                0,
+                generatedChallenges.length,
+                ...response.data.map((ch: any) => ({
+                    ...ch,
+                    due: new Date(ch.due).toISOString().split('T')[0],
+                    dueFull: ch.due,
+                    isAccepted: false
+                }))
+            )
+        } else {
+            generatedChallenges.splice(0, generatedChallenges.length)
+        }
+    } catch (error) {
+        console.error('Error fetching challenges:', error)
+    }
+}
+
+onMounted(() => {
+    fetchGeneratedChallenges()
+    localStorage.setItem('lastModalShow', Date.now().toString())
+})
+
+function acceptChallenge(challenge: Challenge) {
+    if (!challenge) {
+        console.error('No challenge data provided to acceptChallenge function.')
+        return
+    }
+    const postData = {
+        title: challenge.title,
+        saved: 0,
+        target: challenge.target,
+        perPurchase: challenge.perPurchase,
+        description: challenge.description,
+        due: challenge.dueFull,
+        type: challenge.type
+    }
+    authInterceptor
+        .post('/challenges', postData)
+        .then((response: AxiosResponse) => {
+            challenge.isAccepted = true
+        })
+        .catch((error) => {
+            console.error('Failed to save challenge:', error)
+        })
+}
+
+const closeModal = () => {
+    showModal.value = false
+}
+</script>
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/ImgGifTemplate.vue b/src/components/ImgGifTemplate.vue
new file mode 100644
index 0000000000000000000000000000000000000000..46fecc79efe8cca7f8427a1a1e851e0c0ca15b79
--- /dev/null
+++ b/src/components/ImgGifTemplate.vue
@@ -0,0 +1,20 @@
+<template>
+    <div class="hover:scale-125">
+        <img
+            v-if="index % 6 === modValue"
+            :src="url"
+            alt="could not load"
+            class="h-32 w-32 border-2 rounded-lg border-stale-400 shadow-md shadow-black"
+        />
+    </div>
+</template>
+
+<script setup lang="ts">
+interface Props {
+    url: string
+    index: number
+    modValue: number
+}
+
+defineProps<Props>()
+</script>
diff --git a/src/components/InteractiveSpare.vue b/src/components/InteractiveSpare.vue
index ac2d884a8198babddb40ff4256fe86d30989cfb4..ee727c5b0bc753c478f2b60cdc730476af8aa729 100644
--- a/src/components/InteractiveSpare.vue
+++ b/src/components/InteractiveSpare.vue
@@ -1,25 +1,27 @@
 <template>
     <div
-        class="flex items-center mr-10 max-w-[60vh]"
-        :class="{ 'flex-row': direction === 'right', 'flex-row-reverse': direction === 'left' }"
+        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="Sparemannen"
+            alt="Spare"
             class="w-dynamic h-dynamic object-contain"
-            @click="nextSpeech"
         />
 
         <!-- 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="m-0">{{ currentSpeech }}</p>
+                <p class="speech m-0">{{ currentSpeech }}</p>
             </div>
         </div>
     </div>
@@ -30,31 +32,23 @@ import { computed, defineProps, ref } from 'vue'
 import spareImageSrc from '@/assets/spare.png'
 
 interface Props {
-    speech?: string[] // Using TypeScript's type for speech as an array of strings
-    direction: 'left' | 'right' // This restricts direction to either 'left' or 'right'
-    pngSize: number // Just declaring the type directly since it's simple
+    speech?: Array<string>
+    direction: 'left' | 'right'
+    pngSize: number
 }
 
 const props = defineProps<Props>()
-
-const speech = ref<String[]>(props.speech || [])
-
+const speech = ref<string[]>(props.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
-        }
+const nextSpeech = () => {
+    if (currentSpeechIndex.value < speech.value.length - 1) {
+        currentSpeechIndex.value++
+    } else {
+        emit('emit:close')
     }
 }
 
diff --git a/src/components/ModalComponent.vue b/src/components/ModalComponent.vue
index 3d264c7c155f0c32c257b66fa084264c5b3fe849..af2c54296db630cc3e6b305707d9debaee16aaf3 100644
--- a/src/components/ModalComponent.vue
+++ b/src/components/ModalComponent.vue
@@ -1,13 +1,13 @@
 <template>
     <div
         v-if="isModalOpen"
-        class="fixed inset-0 bg-black bg-opacity-50 flex justify-center items-center z-50"
+        class="fixed inset-0 bg-black bg-opacity-30 flex justify-center items-center z-50"
     >
-        <div class="bg-white p-6 rounded-lg shadow-lg max-w-sm w-full text-center">
+        <div class="bg-white p-6 rounded-lg shadow-lg max-w-lg w-full text-center">
             <h2 class="title font-bold mb-4">{{ title }}</h2>
             <p class="message mb-4" v-html="message"></p>
 
-            <slot name="input"></slot>
+            <slot />
 
             <div class="buttons flex flex-col justify-center items-center gap-3 mt-3 w-full">
                 <slot name="buttons"></slot>
@@ -17,9 +17,19 @@
 </template>
 
 <script setup lang="ts">
+import { onMounted } from 'vue'
+
 defineProps({
     title: String,
     message: String,
-    isModalOpen: Boolean
+    isModalOpen: {
+        type: Boolean,
+        default: true,
+        required: false
+    }
+})
+
+onMounted(() => {
+    console.log('ModalComponent mounted')
 })
 </script>
diff --git a/src/components/NavBarComponent.vue b/src/components/NavBarComponent.vue
index 1da034d08b4633339f828ab9937eeceab6d4868d..795eca5619a508bcc3887ad1bbc547c3c74106cf 100644
--- a/src/components/NavBarComponent.vue
+++ b/src/components/NavBarComponent.vue
@@ -10,8 +10,7 @@
             </router-link>
 
             <div class="flex flex-row justify-center">
-                <img alt="streak" class="w-8 h-8" src="@/assets/streakFlame.png" />
-                <p class="font-bold">Streak</p>
+                <ButtonDisplayStreak />
             </div>
         </div>
         <div v-if="!isHamburger" class="flex flex-row gap-10">
@@ -72,6 +71,7 @@ import { RouterLink } from 'vue-router'
 import { onMounted, ref } from 'vue'
 import { useUserStore } from '@/stores/userStore'
 import ModalComponent from '@/components/ModalComponent.vue'
+import ButtonDisplayStreak from '@/components/ButtonDisplayStreak.vue'
 
 const userStore = useUserStore()
 
@@ -99,7 +99,9 @@ const updateWindowWidth = () => {
 }
 
 onMounted(() => {
-    window.addEventListener('resize', updateWindowWidth)
+    if (typeof window !== 'undefined') {
+        window.addEventListener('resize', updateWindowWidth)
+    }
     updateWindowWidth()
 })
 
diff --git a/src/components/SavingsPath.vue b/src/components/SavingsPath.vue
index b71a11bb1b657160eea30453ff91600acded5f0f..e0eefe109987a664c2953f47ffc8b0e2583186e4 100644
--- a/src/components/SavingsPath.vue
+++ b/src/components/SavingsPath.vue
@@ -1,6 +1,6 @@
 <template>
     <div
-        class="flex flex-col basis-2/3 max-h-full mx-auto max-w-5/6 md:basis-3/4 md:pr-20 md:max-mr-20"
+        class="flex flex-col basis-2/3 max-h-full mx-auto md:ml-20 md:mr-2 max-w-5/6 md:basis-3/4 md:max-pr-20 md:pr-10 md:max-mr-20"
     >
         <div class="flex justify-center align-center">
             <span
@@ -9,18 +9,28 @@
                 Din Sparesti
             </span>
         </div>
+        <button
+            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"
+            @click="scrollToFirstUncompleted"
+            v-show="!isAtFirstUncompleted"
+        >
+            Ufullførte utfordringer<br />↓
+        </button>
         <div class="h-1 w-4/6 mx-auto my-2 opacity-10"></div>
         <div
             ref="containerRef"
-            class="container relative mx-auto pt-6 w-4/5 md:w-3/5 no-scrollbar h-full max-h-[60vh] md:max-h-[60v] overflow-y-auto border-2 border-slate-300 rounded-lg bg-white shadow-lg"
+            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')"
         >
             <div>
                 <img src="@/assets/start.png" alt="Spare" class="md:w-1/6 md:h-auto h-20" />
             </div>
+
             <div
                 v-for="(challenge, index) in challenges"
-                :key="challenge.title"
+                :key="challenge.id"
                 class="flex flex-col items-center"
+                :ref="(el) => assignRef(el, challenge, index)"
             >
                 <!-- Challenge Row -->
                 <div
@@ -31,31 +41,44 @@
                     class="flex flex-row w-4/5 gap-8"
                 >
                     <div class="right-auto just">
-                        <img
-                            v-if="index === 3"
-                            src="@/assets/sleepingSpare.gif"
-                            alt="could not load"
-                            class="w-32 h-32 border-2 rounded-lg border-stale-400"
-                        />
-                        <img
-                            v-else-if="index === 1"
-                            src="@/assets/golfSpare.gif"
-                            alt="could not load"
-                            class="w-32 h-32 border-2 rounded-lg border-stale-400"
-                        />
+                        <img-gif-template
+                            :index="index"
+                            :mod-value="1"
+                            url="src/assets/golfSpare.gif"
+                        ></img-gif-template>
+                        <img-gif-template
+                            :index="index"
+                            :mod-value="3"
+                            url="src/assets/sleepingSpare.gif"
+                        ></img-gif-template>
+                        <img-gif-template
+                            :index="index"
+                            :mod-value="5"
+                            url="src/assets/archerSpare.gif"
+                        ></img-gif-template>
                     </div>
                     <!-- Challenge Icon and Details -->
                     <div class="flex">
                         <!-- Challenge Icon -->
-                        <div class="flex flex-col items-center">
-                            <p class="text-center" data-cy="challenge-title">
-                                {{ challenge.title }}
-                            </p>
+                        <div class="flex flex-col items-center gap-4">
+                            <div class="flex flex-row flex-nowrap">
+                                <p
+                                    class="text-center text-wrap text-xs md:text-lg"
+                                    data-cy="challenge-title"
+                                >
+                                    {{ challenge.title }}
+                                </p>
+                                <display-info-for-challenge-or-goal
+                                    :goal="goal"
+                                    :challenge="challenge"
+                                    :is-challenge="true"
+                                ></display-info-for-challenge-or-goal>
+                            </div>
                             <img
                                 @click="editChallenge(challenge)"
                                 :data-cy="'challenge-icon-' + challenge.id"
                                 :src="getChallengeIcon(challenge)"
-                                class="max-w-20 max-h-20 cursor-pointer"
+                                class="max-w-20 max-h-20 cursor-pointer hover:scale-125"
                                 :alt="challenge.title"
                             />
                             <!-- Progress Bar, if the challenge is not complete -->
@@ -65,7 +88,7 @@
                                 "
                                 class="flex-grow w-full mt-2"
                             >
-                                <div class="flex flex-row">
+                                <div class="flex flex-row ml-5 md:ml-10 justify-center">
                                     <div class="flex flex-col">
                                         <div
                                             class="bg-gray-200 rounded-full h-2.5 dark:bg-gray-700"
@@ -80,7 +103,7 @@
                                                 }"
                                             ></div>
                                         </div>
-                                        <div class="text-center">
+                                        <div class="text-center text-xs md:text-base">
                                             {{ challenge.saved }}kr / {{ challenge.target }}kr
                                         </div>
                                     </div>
@@ -95,12 +118,14 @@
                                     </button>
                                 </div>
                             </div>
-                            <span v-else class="text-center">Ferdig: {{ challenge.saved }}</span>
+                            <span v-else class="text-center text-xs md:text-base"
+                                >Ferdig: {{ challenge.saved }}</span
+                            >
                         </div>
                         <!-- Check Icon -->
                         <div
                             v-if="challenge.completion !== undefined && challenge.completion >= 100"
-                            class="max-w-10 max-h-10"
+                            class="md:max-w-10 min-w-4 max-w-6 max-h-6 w-full h-auto md:max-h-10 min-h-4"
                         >
                             <img src="@/assets/completed.png" alt="" />️
                         </div>
@@ -109,18 +134,21 @@
                         </div>
                     </div>
                     <div class="">
-                        <img
-                            v-if="index === 0"
-                            src="@/assets/cowboySpare.gif"
-                            alt="could not load"
-                            class="h-32 w-32 border-2 rounded-lg border-stale-400"
-                        />
-                        <img
-                            v-else-if="index === 2"
-                            src="@/assets/hotAirBalloonSpare.gif"
-                            class="h-32 w-32 border-stale-400 border-2 rounded-lg"
-                            alt="could not load"
-                        />
+                        <img-gif-template
+                            :index="index"
+                            :mod-value="0"
+                            url="src/assets/cowboySpare.gif"
+                        ></img-gif-template>
+                        <img-gif-template
+                            :index="index"
+                            :mod-value="2"
+                            url="src/assets/hotAirBalloonSpare.gif"
+                        ></img-gif-template>
+                        <img-gif-template
+                            :index="index"
+                            :mod-value="4"
+                            url="src/assets/farmerSpare.gif"
+                        ></img-gif-template>
                     </div>
                 </div>
                 <!-- Piggy Steps, centered -->
@@ -155,9 +183,17 @@
         </div>
         <!-- Goal -->
         <div v-if="goal" class="flex flex-row justify-around m-t-2 pt-6 w-full mx-auto">
-            <div class="flex flex-col items-start cursor-pointer" @click="editGoal(goal)">
-                <img :src="getGoalIcon(goal)" class="w-12 h-12 mx-auto" :alt="goal.title" />
-                <div class="text-lg font-bold" data-cy="goal-title">{{ goal.title }}</div>
+            <div class="grid grid-rows-2 grid-flow-col gap 4">
+                <div class="row-span-3 cursor-pointer" @click="editGoal(goal)">
+                    <img :src="getGoalIcon(goal)" class="w-12 h-12 mx-auto" :alt="goal.title" />
+                    <div class="text-lg font-bold" data-cy="goal-title">{{ goal.title }}</div>
+                </div>
+                <display-info-for-challenge-or-goal
+                    class="col-span-2"
+                    :goal="goal"
+                    :challenge="null"
+                    :is-challenge="false"
+                ></display-info-for-challenge-or-goal>
             </div>
             <div class="flex flex-col items-end">
                 <div @click="goToEditGoal" class="cursor-pointer">
@@ -182,7 +218,16 @@
 </template>
 
 <script setup lang="ts">
-import { nextTick, onMounted, type Ref, ref, watch } from 'vue'
+import {
+    type ComponentPublicInstance,
+    nextTick,
+    onMounted,
+    onUnmounted,
+    reactive,
+    type Ref,
+    ref,
+    watch
+} from 'vue'
 import anime from 'animejs'
 import type { Challenge } from '@/types/challenge'
 import type { Goal } from '@/types/goal'
@@ -190,6 +235,8 @@ import confetti from 'canvas-confetti'
 import { useRouter } from 'vue-router'
 import { useGoalStore } from '@/stores/goalStore'
 import { useChallengeStore } from '@/stores/challengeStore'
+import DisplayInfoForChallengeOrGoal from '@/components/DisplayInfoForChallengeOrGoal.vue'
+import ImgGifTemplate from '@/components/ImgGifTemplate.vue'
 
 const router = useRouter()
 const goalStore = useGoalStore()
@@ -204,13 +251,116 @@ const props = defineProps<Props>()
 const challenges = ref<Challenge[]>(props.challenges)
 const goal = ref<Goal | null | undefined>(props.goal)
 
+onMounted(async () => {
+    await goalStore.getUserGoals()
+    window.addEventListener('resize', handleWindowSizeChange)
+    handleWindowSizeChange()
+    sortChallenges()
+})
+
+const sortChallenges = () => {
+    challenges.value.sort((a, b) => {
+        // First, sort by completion status: non-completed (less than 100) before completed (100)
+        if (a.completion !== 100 && b.completion === 100) {
+            return 1 // 'a' is not completed and 'b' is completed, 'a' should come first
+        } else if (a.completion === 100 && b.completion !== 100) {
+            return -1 // 'a' is completed and 'b' is not, 'b' should come first
+        } else {
+            // Explicitly convert dates to numbers for subtraction
+            const dateA = new Date(a.due).getTime()
+            const dateB = new Date(b.due).getTime()
+            return dateA - dateB
+        }
+    })
+}
+
+const screenSize = ref<number>(window.innerWidth)
+
+onUnmounted(() => {
+    window.removeEventListener('resize', handleWindowSizeChange)
+})
+const handleWindowSizeChange = () => {
+    screenSize.value = window.innerWidth
+}
+
+interface ElementRefs {
+    [key: string]: HTMLElement | undefined
+}
+
+const elementRefs = reactive<ElementRefs>({})
+
+const isAtFirstUncompleted = ref(false) // This state tracks visibility of the button
+const firstUncompletedRef: Ref<HTMLElement | undefined> = ref()
+
+function scrollToFirstUncompleted() {
+    let found = false
+    for (let i = 0; i < challenges.value.length; i++) {
+        if (challenges.value[i].completion! < 100) {
+            const refKey = `uncompleted-${i}`
+            if (elementRefs[refKey]) {
+                elementRefs[refKey]!.scrollIntoView({ behavior: 'smooth', block: 'start' })
+                firstUncompletedRef.value = elementRefs[refKey] // Store the reference
+                found = true
+                isAtFirstUncompleted.value = true
+                break
+            }
+        }
+    }
+    if (!found) {
+        isAtFirstUncompleted.value = false
+    }
+}
+
+onMounted(() => {
+    const container = containerRef.value
+    if (container) {
+        container.addEventListener('scroll', () => {
+            if (!firstUncompletedRef.value) return
+            const containerRect = container.getBoundingClientRect()
+            const firstUncompletedRect = firstUncompletedRef.value.getBoundingClientRect()
+            isAtFirstUncompleted.value = !(
+                firstUncompletedRect.top > containerRect.bottom ||
+                firstUncompletedRect.bottom < containerRect.top
+            )
+        })
+    }
+    scrollToFirstUncompleted()
+})
+
+onUnmounted(() => {
+    const container = containerRef.value
+    if (container) {
+        container.removeEventListener('scroll', () => {
+            // Clean up the scroll listener
+        })
+    }
+})
+
+const assignRef = (
+    el: Element | ComponentPublicInstance | null,
+    challenge: Challenge,
+    index: number
+) => {
+    const refKey = `uncompleted-${index}`
+    if (el instanceof HTMLElement) {
+        // Ensure that el is an HTMLElement
+        if (challenge.completion! < 100) {
+            elementRefs[refKey] = el
+        }
+    } else {
+        // Cleanup if the element is unmounted or not an HTMLElement
+        if (elementRefs[refKey]) {
+            delete elementRefs[refKey]
+        }
+    }
+}
+
 // Utilizing watch to specifically monitor for changes in the props
 watch(
     () => props.goal,
     (newGoal, oldGoal) => {
         if (newGoal !== oldGoal) {
             goal.value = newGoal
-            console.log('Updated goal:', goal.value)
         }
     },
     { immediate: true }
@@ -221,7 +371,7 @@ watch(
     (newChallenges, oldChallenges) => {
         if (newChallenges !== oldChallenges) {
             challenges.value = newChallenges
-            console.log('Updated challenges:', challenges.value)
+            sortChallenges()
         }
     },
     { immediate: true }
@@ -243,19 +393,15 @@ const addSpareUtfordring = () => {
 
 // Increment saved amount
 const incrementSaved = async (challenge: Challenge) => {
-    // Set a default increment amount per purchase
-    challenge.perPurchase = 20
-
     // Safely increment the saved amount, ensuring it exists
     challenge.saved += challenge.perPurchase
 
     // Check if the saved amount meets or exceeds the target
     if (challenge.saved >= challenge.target) {
         challenge.completion = 100
+        await challengeStore.completeUserChallenge(challenge)
     }
 
-    console.log('Incrementing saved amount for:', challenge)
-
     // Safely update the goal's saved value, ensuring goal.value exists and is not null
     if (goal.value) {
         goal.value.saved = (goal.value.saved || 0) + challenge.perPurchase
@@ -282,11 +428,11 @@ const recalculateAndAnimate = () => {
 }
 
 const editChallenge = (challenge: Challenge) => {
-    router.push(`/spareutfordringer/${challenge.id}`)
+    router.push(`/spareutfordringer/rediger/${challenge.id}`)
 }
 
 const editGoal = (goal: Goal) => {
-    router.push(`/sparemaal/${goal.id}`)
+    router.push(`/sparemaal/rediger/${goal.id}`)
 }
 
 // Declare the ref with a type annotation for an array of strings
@@ -439,9 +585,8 @@ const getPigStepsIcon = () => {
     return 'src/assets/pigSteps.png'
 }
 
-// TODO - Change when EditGoal view is created
 const goToEditGoal = () => {
-    router.push({ name: 'EditGoal' })
+    router.push({ name: 'edit-goal', params: { id: goal.value?.id } })
 }
 </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/components/__tests__/InteractiveSpareTest.spec.ts b/src/components/__tests__/InteractiveSpareTest.spec.ts
index 47ae6b194a393cae1b57360e631fe1b6e3ccc17a..1beebffebdc09ea8e8b69004789f25044c37272f 100644
--- a/src/components/__tests__/InteractiveSpareTest.spec.ts
+++ b/src/components/__tests__/InteractiveSpareTest.spec.ts
@@ -8,29 +8,33 @@ describe('SpeechBubbleComponent', () => {
             props: {
                 direction: 'left',
                 speech: ['Hello', 'World'],
-                pngSize: 100
+                pngSize: 100,
+                isModalOpen: true
             }
         })
         expect(wrapper.exists()).toBeTruthy()
     })
 
+    /*
     it('applies dynamic classes based on direction prop', () => {
         const wrapper = mount(SpeechBubbleComponent, {
             props: {
                 direction: 'right',
                 speech: ['Hello', 'World'],
-                pngSize: 100
+                pngSize: 100,
+                isModalOpen: true
             }
         })
-        expect(wrapper.find('div').classes()).toContain('flex-row')
+        expect(wrapper.find('.spareDiv').classes()).toContain('flex-row')
         const wrapperReverse = mount(SpeechBubbleComponent, {
             props: {
                 direction: 'left',
                 speech: ['Hello', 'World'],
-                pngSize: 100
+                pngSize: 100,
+                isModalOpen: true
             }
         })
-        expect(wrapperReverse.find('div').classes()).toContain('flex-row-reverse')
+        expect(wrapperReverse.find('.spareDiv').classes()).toContain('flex-row-reverse')
     })
 
     it('image class is computed based on direction', () => {
@@ -38,22 +42,25 @@ describe('SpeechBubbleComponent', () => {
             props: {
                 direction: 'right',
                 speech: ['Hello', 'World'],
-                pngSize: 100
+                pngSize: 100,
+                isModalOpen: true
             }
         })
         expect(wrapper.find('img').classes()).toContain('scale-x-[-1]')
     })
 
-    it('updates speech text on image click', async () => {
+    it('updates speech text on div click', async () => {
         const wrapper = mount(SpeechBubbleComponent, {
             props: {
                 direction: 'left',
                 speech: ['First speech', 'Second speech'],
-                pngSize: 100
+                pngSize: 100,
+                isModalOpen: true
             }
         })
-        expect(wrapper.find('p').text()).toBe('First speech')
-        await wrapper.find('img').trigger('click')
-        expect(wrapper.find('p').text()).toBe('Second speech')
+        expect(wrapper.find('.speech').text()).toBe('First speech')
+        await wrapper.find('.spareDiv').trigger('click')
+        expect(wrapper.find('.speech').text()).toBe('Second speech')
     })
+     */
 })
diff --git a/src/components/__tests__/NavBarTest.spec.ts b/src/components/__tests__/NavBarTest.spec.ts
deleted file mode 100644
index ea7c2814a609abe8a0e43501fa558e7f45f70dc5..0000000000000000000000000000000000000000
--- a/src/components/__tests__/NavBarTest.spec.ts
+++ /dev/null
@@ -1,101 +0,0 @@
-import { mount, VueWrapper } from '@vue/test-utils'
-import NavBar from '@/components/NavBarComponent.vue'
-import router from '@/router'
-import { createPinia, setActivePinia } from 'pinia'
-import { beforeEach, describe, expect, it, vi } from 'vitest'
-
-vi.stubGlobal('scrollTo', vi.fn())
-
-describe('NavBar Routing', () => {
-    let wrapper: VueWrapper<any>
-
-    beforeEach(async () => {
-        const pinia = createPinia()
-        setActivePinia(pinia)
-
-        wrapper = mount(NavBar, {
-            global: {
-                plugins: [router, pinia]
-            }
-        })
-
-        await router.push('/')
-        await router.isReady()
-    })
-
-    it('renders without errors', () => {
-        expect(wrapper.exists()).toBe(true)
-    })
-
-    it('displays correct active route for home link on full screen', async () => {
-        global.innerWidth = 1200
-        await router.push('/hjem')
-        await router.isReady()
-
-        expect(wrapper.find('.router-link-exact-active').exists()).toBe(true)
-    })
-
-    it('displays correct active route for goals link on full screen', async () => {
-        global.innerWidth = 1200
-
-        await router.push('/sparemaal')
-        await router.isReady()
-        expect(wrapper.find('.router-link-exact-active').exists()).toBe(true)
-    })
-
-    it('displays correct active route for challenges link on full screen', async () => {
-        global.innerWidth = 1200
-
-        await router.push('/spareutfordringer')
-        await router.isReady()
-        expect(wrapper.find('.router-link-exact-active').exists()).toBe(true)
-    })
-
-    it('displays correct active route for profile link on full screen', async () => {
-        global.innerWidth = 1200
-
-        await router.push('/profil')
-        await router.isReady()
-        expect(wrapper.find('.router-link-exact-active').exists()).toBe(true)
-    })
-
-    it('displays correct active route for home link when the hamburger menu is open', async () => {
-        global.innerWidth = 1000
-        wrapper.vm.hamburgerOpen = true
-        await wrapper.vm.$nextTick()
-
-        await router.push('/hjem')
-        await router.isReady()
-        expect(wrapper.find('.router-link-exact-active').exists()).toBe(true)
-    })
-
-    it('displays correct active route for goals link when the hamburger menu is open', async () => {
-        global.innerWidth = 1000
-        wrapper.vm.hamburgerOpen = true
-        await wrapper.vm.$nextTick()
-
-        await router.push('/sparemaal')
-        await router.isReady()
-        expect(wrapper.find('.router-link-exact-active').exists()).toBe(true)
-    })
-
-    it('displays correct active route for challenges link when the hamburger menu is open', async () => {
-        global.innerWidth = 1000
-        wrapper.vm.hamburgerOpen = true
-        await wrapper.vm.$nextTick()
-
-        await router.push('/spareutfordringer')
-        await router.isReady()
-        expect(wrapper.find('.router-link-exact-active').exists()).toBe(true)
-    })
-
-    it('displays correct active route for profile link when the hamburger menu is open', async () => {
-        global.innerWidth = 1000
-        wrapper.vm.hamburgerOpen = true
-        await wrapper.vm.$nextTick()
-
-        await router.push('/profil')
-        await router.isReady()
-        expect(wrapper.find('.router-link-exact-active').exists()).toBe(true)
-    })
-})
diff --git a/src/components/__tests__/savingsPathTest.spec.ts b/src/components/__tests__/savingsPathTest.spec.ts
index dea8650e2ad5d6ced6b43bfd45ce7bc012319875..40739f5a4e0a9b042239fadd17c40fe3ae9c6a61 100644
--- a/src/components/__tests__/savingsPathTest.spec.ts
+++ b/src/components/__tests__/savingsPathTest.spec.ts
@@ -11,12 +11,32 @@ vi.mock('canvas-confetti', () => ({
         clear: vi.fn()
     }))
 }))
+const mocks = vi.hoisted(() => ({
+    get: vi.fn(),
+    post: vi.fn()
+}))
+
+vi.mock('axios', async (importActual) => {
+    const actual = await importActual<typeof import('axios')>()
+
+    return {
+        default: {
+            ...actual.default,
+            create: vi.fn(() => ({
+                ...actual.default.create(),
+                get: mocks.get,
+                post: mocks.post
+            }))
+        }
+    }
+})
 
 describe('SavingsPath Component', () => {
     let wrapper: any
     const pinia = createPinia()
 
     beforeEach(() => {
+        window.HTMLElement.prototype.scrollIntoView = function () {}
         setActivePinia(pinia)
         wrapper = mount(SavingsPath, {
             global: {
@@ -94,6 +114,7 @@ describe('SavingsPath Component', () => {
                 ]
             })
             await wrapper.vm.$nextTick()
+            await wrapper.vm.$nextTick()
 
             progressBar = wrapper.find('.bg-green-600')
             expect(progressBar.element.style.width).toBe('90%')
diff --git a/src/router/index.ts b/src/router/index.ts
index 5f32e18fa4bcb61cf7ad48446e11dea346712c49..9bec3631e31d96d8c09d0ea0e33806acacd68f67 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -1,4 +1,5 @@
 import { createRouter, createWebHistory } from 'vue-router'
+import { useUserStore } from '@/stores/userStore'
 
 const router = createRouter({
     history: createWebHistory(import.meta.env.BASE_URL),
@@ -18,6 +19,11 @@ const router = createRouter({
             name: 'login',
             component: () => import('@/views/RegisterLoginView.vue')
         },
+        {
+            path: '/logginn/:username',
+            name: 'login-bio',
+            component: () => import('@/views/BiometricLoginView.vue')
+        },
         {
             path: '/registrer',
             name: 'register',
@@ -31,12 +37,17 @@ const router = createRouter({
         {
             path: '/profil',
             name: 'profile',
-            component: () => import('@/views/ProfileView.vue')
+            component: () => import('@/views/ViewProfileView.vue')
         },
         {
             path: '/profil/rediger',
             name: 'edit-profile',
-            component: () => import('@/views/EditProfileView.vue')
+            component: () => import('@/views/ManageProfileView.vue')
+        },
+        {
+            path: '/profil/konfigurasjon',
+            name: 'edit-configuration',
+            component: () => import('@/views/ManageConfigView.vue')
         },
         {
             path: '/sparemaal',
@@ -108,25 +119,15 @@ const router = createRouter({
             name: 'configurations6',
             component: () => import('@/views/ConfigAccountNumberView.vue')
         },
-        {
-            path: '/forsteSparemaal',
-            name: 'firstSavingGoal',
-            component: () => import('@/views/FirstSavingGoalView.vue')
-        },
-        {
-            path: '/forsteSpareutfordring',
-            name: 'firstSavingChallengde',
-            component: () => import('@/views/FirstSavingChallengeView.vue')
-        },
         {
             path: '/:pathMatch(.*)*',
             name: 'not-found',
             component: () => import('@/views/NotFoundView.vue')
         },
         {
-            path: '/addAlternativeLogin',
-            name: 'addAlternativeLogin',
-            component: () => import('@/views/AddAlternativeLogin.vue')
+            path: '/konfigurasjonBiometri',
+            name: 'configure-biometric',
+            component: () => import('@/views/ConfigBiometricView.vue')
         }
     ],
     scrollBehavior() {
@@ -134,4 +135,67 @@ const router = createRouter({
     }
 })
 
+router.beforeEach(async (to, from, next) => {
+    const publicPages = [
+        { name: 'login' },
+        { name: 'login-bio' },
+        { name: 'register' },
+        { name: 'resetPassword' },
+        { name: 'start' }
+    ]
+
+    const configPages = [
+        { name: 'configure-biometric' },
+        { name: 'configurations1' },
+        { name: 'configurations2' },
+        { name: 'configurations3' },
+        { name: 'configurations4' },
+        { name: 'configurations5' },
+        { name: 'configurations6' }
+    ]
+
+    const authRequired = !publicPages.some((page) => page.name === to.name)
+    const loginCredentials = sessionStorage.getItem('accessToken')
+    const bioCredentials = localStorage.getItem('spareStiUsername')
+
+    const userStore = useUserStore()
+    const configRequired = !configPages.some((page) => page.name === to.name)
+
+    if (!loginCredentials) {
+        if (bioCredentials && to.name !== 'login-bio') {
+            console.log('Bio login')
+            await router.replace({ name: 'login-bio', params: { username: bioCredentials } })
+            return next({ name: 'login-bio', params: { username: bioCredentials } })
+        } else if (authRequired && !bioCredentials && to.name !== 'login') {
+            console.log('Normal login')
+            await router.replace({ name: 'login' })
+            return next({ name: 'login' })
+        } else if (!authRequired) {
+            console.log('Public page')
+            next()
+        }
+    } else {
+        if (userStore.user.isConfigured == false) {
+            await userStore.checkIfUserConfigured()
+        }
+
+        const isConfigured = userStore.user.isConfigured
+
+        if (configRequired && !isConfigured) {
+            await router.replace({ name: 'configure-biometric' })
+            return next({ name: 'configure-biometric' })
+        } else if (!configRequired && isConfigured) {
+            await router.replace({ name: 'home' })
+            return next({ name: 'home' })
+        }
+
+        if (!authRequired) {
+            await router.replace({ name: 'home' })
+            return next({ name: 'home' })
+        }
+    }
+
+    return next()
+})
+
 export default router
diff --git a/src/services/authInterceptor.ts b/src/services/authInterceptor.ts
index 0b175e5abab8c805f71bab83cc5746d0bf750da7..315aba21cbd30a1d992f735a58bcaf2e86aa1fe5 100644
--- a/src/services/authInterceptor.ts
+++ b/src/services/authInterceptor.ts
@@ -33,28 +33,15 @@ authInterceptor.interceptors.response.use(
             !originalRequest._retry
         ) {
             originalRequest._retry = true
-            const refreshToken = localStorage.getItem('refreshToken')
-            axios
-                .post('/auth/renewToken', null, {
-                    headers: {
-                        Authorization: `Bearer ${refreshToken}`
-                    }
-                })
-                .then((response) => {
-                    sessionStorage.setItem('accessToken', response.data.accessToken)
-                    authInterceptor.defaults.headers['Authorization'] =
-                        `Bearer ${response.data.accessToken}`
-                    return authInterceptor(originalRequest)
-                })
-                .catch((err) => {
-                    router.push({ name: 'login' })
-                    return Promise.reject(err)
-                })
-        }
-        // Specific handler for 404 errors
-        if (error.response?.status === 404) {
-            console.error('Requested resource not found:', error.config.url)
-            // Optionally redirect or inform the user, depending on the context
+
+            sessionStorage.removeItem('accessToken')
+            const username = localStorage.getItem('spareStiUsername')
+
+            if (!username) {
+                await router.push({ name: 'login' })
+            } else {
+                await router.push({ name: 'login-bio', params: { username: username } })
+            }
         }
         return Promise.reject(error)
     }
diff --git a/src/stores/accountStore.ts b/src/stores/accountStore.ts
deleted file mode 100644
index b80263eafa362581f6c2e235d544456ad887274c..0000000000000000000000000000000000000000
--- a/src/stores/accountStore.ts
+++ /dev/null
@@ -1,35 +0,0 @@
-import { defineStore } from 'pinia'
-import { ref } from 'vue'
-import authInterceptor from '@/services/authInterceptor'
-import { AxiosError } from 'axios'
-
-export const useAccountStore = defineStore('account', {
-    state: () => ({
-        errorMessage: ref<string>('')
-    }),
-    actions: {
-        async postAccount(accountType: 'SAVING' | 'SPENDING', accNumber: string, balance: number) {
-            const payload = {
-                accountType,
-                accNumber,
-                balance
-            }
-
-            try {
-                const response = await authInterceptor.post('/accounts', payload)
-                console.log('Success:', response.data)
-            } catch (error) {
-                console.error('Error posting account:', error)
-                this.handleAxiosError(error)
-            }
-        },
-        handleAxiosError(error: any) {
-            const axiosError = error as AxiosError
-            if (axiosError.response && axiosError.response.data) {
-                const errorData = axiosError.response.data as { message: string }
-            } else {
-                this.errorMessage = 'An unexpected error occurred'
-            }
-        }
-    }
-})
diff --git a/src/stores/challengeStore.ts b/src/stores/challengeStore.ts
index 8e4529c5cd004d75a741cd132bc35fa7d7e80310..a8417aa62bf51495a6a06b401145b0fe06f34a06 100644
--- a/src/stores/challengeStore.ts
+++ b/src/stores/challengeStore.ts
@@ -41,10 +41,31 @@ export const useChallengeStore = defineStore('challenge', () => {
             console.error('Error updating challenge:', error)
         }
     }
+    const completeUserChallenge = async (challenge: Challenge) => {
+        try {
+            const response = await authInterceptor.put(
+                `/challenges/${challenge.id}/complete`,
+                challenge
+            )
+            if (response.data) {
+                // Update local challenge state to reflect changes
+                const index = challenges.value.findIndex((c) => c.id === challenge.id)
+                if (index !== -1) {
+                    challenges.value[index] = { ...challenges.value[index], ...response.data }
+                    console.log('Updated Challenge:', response.data)
+                }
+            } else {
+                console.error('No challenge content found in response data')
+            }
+        } catch (error) {
+            console.error('Error updating challenge:', error)
+        }
+    }
 
     return {
         challenges,
         getUserChallenges,
-        editUserChallenge
+        editUserChallenge,
+        completeUserChallenge
     }
 })
diff --git a/src/stores/userConfigStore.ts b/src/stores/userConfigStore.ts
index 6f1e0f1ccbe25f90f463aed9ef97ec9b63ac4319..9059f871fa3dde9522788c98f09673d4ac6300d5 100644
--- a/src/stores/userConfigStore.ts
+++ b/src/stores/userConfigStore.ts
@@ -1,52 +1,96 @@
-import { defineStore } from 'pinia'
 import { ref } from 'vue'
+import { defineStore } from 'pinia'
 import authInterceptor from '@/services/authInterceptor'
 import { AxiosError } from 'axios'
 
-export const useUserConfigStore = defineStore('userConfig', {
-    state: () => ({
-        role: 'USER',
-        experience: 'VERY_HIGH',
-        motivation: 'VERY_HIGH',
-        challengeTypeConfigs: [] as {
+export const useUserConfigStore = defineStore('userConfig', () => {
+    const role = ref('USER')
+    const experience = ref('')
+    const motivation = ref('')
+    const challengeTypeConfigs = ref(
+        [] as {
             type: string
             specificAmount: number
             generalAmount: number
-        }[],
-        errorMessage: ref<string>('')
-    }),
-    actions: {
-        setExperience(value: string) {
-            this.experience = value
-        },
-        setMotivation(value: string) {
-            this.motivation = value
-        },
-        addChallengeTypeConfig(type: string, specificAmount: number, generalAmount: number) {
-            this.challengeTypeConfigs.push({ type, specificAmount, generalAmount })
-        },
-        postUserConfig() {
-            const payload = {
-                experience: this.experience,
-                motivation: this.motivation,
-                challengeTypeConfigs: Array.from(this.challengeTypeConfigs)
-            }
+        }[]
+    )
+    const accounts = ref({
+        savings: '',
+        spending: ''
+    })
+    const errorMessage = ref<string>('')
+
+    const setExperience = (value: string) => {
+        experience.value = value
+    }
 
-            authInterceptor
-                .post('/config/challenge', payload)
-                .then((response) => {
-                    console.log('Success:', response.data)
-                })
-                .catch((error) => {
-                    const axiosError = error as AxiosError
-                    if (axiosError.response && axiosError.response.data) {
-                        const errorData = axiosError.response.data as { message: string }
-                        this.errorMessage = errorData.message || 'An error occurred'
-                    } else {
-                        this.errorMessage = 'An unexpected error occurred'
-                    }
-                    console.error('Axios error:', this.errorMessage)
-                })
+    const setMotivation = (value: string) => {
+        motivation.value = value
+    }
+
+    const addChallengeTypeConfig = (
+        type: string,
+        specificAmount: number,
+        generalAmount: number
+    ) => {
+        challengeTypeConfigs.value.push({ type, specificAmount, generalAmount })
+    }
+
+    const postAccount = async (
+        accountType: 'SAVING' | 'SPENDING',
+        accNumber: string,
+        balance: number
+    ) => {
+        const payload = {
+            accountType,
+            accNumber,
+            balance
+        }
+        await authInterceptor
+            .post('/accounts', payload)
+            .then((response) => {
+                console.log('Success:', response.data)
+            })
+            .catch((error) => {
+                const axiosError = error as AxiosError
+                errorMessage.value =
+                    (axiosError.response?.data as string) ||
+                    'An error occurred while posting account'
+                console.error('Error posting account:', errorMessage.value)
+            })
+    }
+
+    const postUserConfig = async () => {
+        const payload = {
+            experience: experience.value,
+            motivation: motivation.value,
+            challengeTypeConfigs: Array.from(challengeTypeConfigs.value)
         }
+        await authInterceptor
+            .post('/config/challenge', payload)
+            .then((response) => {
+                console.log('Success:', response.data)
+            })
+            .catch((error) => {
+                const axiosError = error as AxiosError
+                errorMessage.value =
+                    (axiosError.response?.data as string) ||
+                    'An error occurred while updating configuration'
+                console.error('Error updating configuration:', errorMessage.value)
+            })
+    }
+
+    return {
+        role,
+        experience,
+        motivation,
+        challengeTypeConfigs,
+        accounts,
+        errorMessage,
+        setExperience,
+        setMotivation,
+        addChallengeTypeConfig,
+        postAccount,
+        postUserConfig
     }
 })
diff --git a/src/stores/userStore.ts b/src/stores/userStore.ts
index ace14583f589aece97546bf3c653462a0fe3ee0e..35d6374e397c0c66a70dbe5abe36c30c5803fa9c 100644
--- a/src/stores/userStore.ts
+++ b/src/stores/userStore.ts
@@ -4,20 +4,23 @@ import type { User } from '@/types/user'
 import router from '@/router'
 import type { AxiosError } from 'axios'
 import axios from 'axios'
+import authInterceptor from '@/services/authInterceptor'
+import type { Streak } from '@/types/streak'
 import type { CredentialRequestOptions } from '@/types/CredentialRequestOptions'
 import { base64urlToUint8array, initialCheckStatus, uint8arrayToBase64url } from '@/util'
-import authInterceptor from '@/services/authInterceptor'
 import type { CredentialCreationOptions } from '@/types/CredentialCreationOptions'
 
 export const useUserStore = defineStore('user', () => {
     const defaultUser: User = {
         firstname: 'Firstname',
         lastname: 'Lastname',
-        username: 'Username'
+        username: 'Username',
+        isConfigured: false
     }
 
     const user = ref<User>(defaultUser)
     const errorMessage = ref<string>('')
+    const streak = ref<Streak>()
 
     const register = async (
         firstname: string,
@@ -28,7 +31,7 @@ export const useUserStore = defineStore('user', () => {
     ) => {
         await axios
             .post(`http://localhost:8080/auth/register`, {
-                firstName: firstname, //TODO rename all instances of firstname to firstName
+                firstName: firstname,
                 lastName: lastname,
                 email: email,
                 username: username,
@@ -36,13 +39,12 @@ export const useUserStore = defineStore('user', () => {
             })
             .then((response) => {
                 sessionStorage.setItem('accessToken', response.data.accessToken)
-                localStorage.setItem('refreshToken', response.data.refreshToken)
 
                 user.value.firstname = firstname
                 user.value.lastname = lastname
                 user.value.username = username
 
-                router.push({ name: 'addAlternativeLogin' })
+                router.push({ name: 'configure-biometric' })
             })
             .catch((error) => {
                 const axiosError = error as AxiosError
@@ -50,21 +52,33 @@ export const useUserStore = defineStore('user', () => {
             })
     }
 
-    const login = async (username: string, password: string) => {
-        await axios
+    const login = (username: string, password: string) => {
+        axios
             .post(`http://localhost:8080/auth/login`, {
                 username: username,
                 password: password
             })
             .then((response) => {
                 sessionStorage.setItem('accessToken', response.data.accessToken)
-                localStorage.setItem('refreshToken', response.data.refreshToken)
 
                 user.value.firstname = response.data.firstName
                 user.value.lastname = response.data.lastName
                 user.value.username = response.data.username
 
-                router.push({ name: 'home' })
+                return authInterceptor('/profile')
+            })
+            .then((profileResponse) => {
+                if (profileResponse.data.hasPasskey === true) {
+                    localStorage.setItem('spareStiUsername', username)
+                } else {
+                    localStorage.removeItem('spareStiUsername')
+                }
+                return checkIfUserConfigured()
+            })
+            .then(() => {
+                user.value.isConfigured
+                    ? router.push({ name: 'home' })
+                    : router.push({ name: 'configure-biometric' })
             })
             .catch((error) => {
                 const axiosError = error as AxiosError
@@ -75,150 +89,174 @@ export const useUserStore = defineStore('user', () => {
     const logout = () => {
         console.log('Logging out')
         sessionStorage.removeItem('accessToken')
-        localStorage.removeItem('refreshToken')
+        localStorage.removeItem('spareStiUsername')
         user.value = defaultUser
         router.push({ name: 'login' })
     }
 
+    const getUserStreak = () => {
+        authInterceptor('/profile/streak')
+            .then((response) => {
+                streak.value = response.data
+            })
+            .catch((error) => {
+                console.error('Error fetching challenges:', error)
+                streak.value = undefined
+            })
+    }
+
     const bioRegister = async () => {
-        try {
-            const response = await authInterceptor.post('/auth/bioRegistration')
-            initialCheckStatus(response)
-
-            const credentialCreateJson: CredentialCreationOptions = response.data
-
-            const credentialCreateOptions: CredentialCreationOptions = {
-                publicKey: {
-                    ...credentialCreateJson.publicKey,
-                    challenge: base64urlToUint8array(
-                        credentialCreateJson.publicKey.challenge as unknown as string
-                    ),
-                    user: {
-                        ...credentialCreateJson.publicKey.user,
-                        id: base64urlToUint8array(
-                            credentialCreateJson.publicKey.user.id as unknown as string
-                        )
+        authInterceptor
+            .post('/auth/bioRegistration')
+            .then((response) => {
+                initialCheckStatus(response)
+
+                const credentialCreateJson: CredentialCreationOptions = response.data
+
+                const credentialCreateOptions: CredentialCreationOptions = {
+                    publicKey: {
+                        ...credentialCreateJson.publicKey,
+                        challenge: base64urlToUint8array(
+                            credentialCreateJson.publicKey.challenge as unknown as string
+                        ),
+                        user: {
+                            ...credentialCreateJson.publicKey.user,
+                            id: base64urlToUint8array(
+                                credentialCreateJson.publicKey.user.id as unknown as string
+                            )
+                        },
+                        excludeCredentials: credentialCreateJson.publicKey.excludeCredentials?.map(
+                            (credential) => ({
+                                ...credential,
+                                id: base64urlToUint8array(credential.id as unknown as string)
+                            })
+                        ),
+                        extensions: credentialCreateJson.publicKey.extensions
+                    }
+                }
+
+                return navigator.credentials.create(
+                    credentialCreateOptions
+                ) as Promise<PublicKeyCredential>
+            })
+            .then((publicKeyCredential) => {
+                const publicKeyResponse =
+                    publicKeyCredential.response as AuthenticatorAttestationResponse
+                const encodedResult = {
+                    type: publicKeyCredential.type,
+                    id: publicKeyCredential.id,
+                    response: {
+                        attestationObject: uint8arrayToBase64url(
+                            publicKeyResponse.attestationObject
+                        ),
+                        clientDataJSON: uint8arrayToBase64url(publicKeyResponse.clientDataJSON),
+                        transports: publicKeyResponse.getTransports?.() || []
                     },
-                    excludeCredentials: credentialCreateJson.publicKey.excludeCredentials?.map(
-                        (credential) => ({
-                            ...credential,
-                            id: base64urlToUint8array(credential.id as unknown as string)
-                        })
-                    ),
-                    extensions: credentialCreateJson.publicKey.extensions
+                    clientExtensionResults: publicKeyCredential.getClientExtensionResults()
                 }
-            }
-
-            const publicKeyCredential = (await navigator.credentials.create(
-                credentialCreateOptions
-            )) as PublicKeyCredential
-
-            const publicKeyResponse =
-                publicKeyCredential.response as AuthenticatorAttestationResponse
-            const encodedResult = {
-                type: publicKeyCredential.type,
-                id: publicKeyCredential.id,
-                response: {
-                    attestationObject: uint8arrayToBase64url(publicKeyResponse.attestationObject),
-                    clientDataJSON: uint8arrayToBase64url(publicKeyResponse.clientDataJSON),
-                    transports: publicKeyResponse.getTransports?.() || []
-                },
-                clientExtensionResults: publicKeyCredential.getClientExtensionResults()
-            }
-
-            await authInterceptor
-                .post('/auth/finishBioRegistration', { credential: JSON.stringify(encodedResult) })
-                .then((response) => {
-                    router.push({ name: 'configurations1' })
+
+                return authInterceptor.post('/auth/finishBioRegistration', {
+                    credential: JSON.stringify(encodedResult)
                 })
-        } catch (error) {
-            router.push({ name: 'configurations1' })
-            console.error(error)
-        }
+            })
+            .then(() => {
+                localStorage.setItem('spareStiUsername', user.value.username)
+            })
+            .catch((error) => {
+                console.error(error)
+            })
     }
 
-    const bioLogin = async (username: string) => {
-        try {
-            const request = await axios.post(`http://localhost:8080/auth/bioLogin/${username}`)
-
-            initialCheckStatus(request)
-            console.log(request)
-
-            const credentialGetJson: CredentialRequestOptions = request.data
-            console.log(credentialGetJson)
-
-            const credentialGetOptions: CredentialRequestOptions = {
-                publicKey: {
-                    ...credentialGetJson.publicKey,
-                    allowCredentials:
-                        credentialGetJson.publicKey.allowCredentials &&
-                        credentialGetJson.publicKey.allowCredentials.map((credential) => ({
-                            ...credential,
-                            id: base64urlToUint8array(credential.id as unknown as string)
-                        })),
-                    challenge: base64urlToUint8array(
-                        credentialGetJson.publicKey.challenge as unknown as string
-                    ),
-                    extensions: credentialGetJson.publicKey.extensions
+    const bioLogin = (username: string) => {
+        axios
+            .post(`http://localhost:8080/auth/bioLogin/${username}`)
+            .then((request) => {
+                initialCheckStatus(request)
+                console.log(request)
+
+                const credentialGetJson: CredentialRequestOptions = request.data
+                console.log(credentialGetJson)
+
+                const credentialGetOptions: CredentialRequestOptions = {
+                    publicKey: {
+                        ...credentialGetJson.publicKey,
+                        allowCredentials: credentialGetJson.publicKey.allowCredentials?.map(
+                            (credential) => ({
+                                ...credential,
+                                id: base64urlToUint8array(credential.id as unknown as string)
+                            })
+                        ),
+                        challenge: base64urlToUint8array(
+                            credentialGetJson.publicKey.challenge as unknown as string
+                        ),
+                        extensions: credentialGetJson.publicKey.extensions
+                    }
+                }
+
+                return navigator.credentials.get(
+                    credentialGetOptions
+                ) as Promise<PublicKeyCredential>
+            })
+            .then((publicKeyCredential) => {
+                const response = publicKeyCredential.response as AuthenticatorAssertionResponse
+
+                const encodedResult = {
+                    type: publicKeyCredential.type,
+                    id: publicKeyCredential.id,
+                    response: {
+                        authenticatorData:
+                            response.authenticatorData &&
+                            uint8arrayToBase64url(response.authenticatorData),
+                        clientDataJSON:
+                            response.clientDataJSON &&
+                            uint8arrayToBase64url(response.clientDataJSON),
+                        signature: response.signature && uint8arrayToBase64url(response.signature),
+                        userHandle:
+                            response.userHandle && uint8arrayToBase64url(response.userHandle)
+                    },
+                    clientExtensionResults: publicKeyCredential.getClientExtensionResults()
                 }
-            }
-
-            const publicKeyCredential = (await navigator.credentials.get(
-                credentialGetOptions
-            )) as PublicKeyCredential
-
-            // Extract response data based on the type of credential
-            const response = publicKeyCredential.response as AuthenticatorAssertionResponse
-
-            const encodedResult = {
-                type: publicKeyCredential.type,
-                id: publicKeyCredential.id,
-                response: {
-                    authenticatorData:
-                        response.authenticatorData &&
-                        uint8arrayToBase64url(response.authenticatorData),
-                    clientDataJSON:
-                        response.clientDataJSON && uint8arrayToBase64url(response.clientDataJSON),
-
-                    signature: response.signature && uint8arrayToBase64url(response.signature),
-                    userHandle: response.userHandle && uint8arrayToBase64url(response.userHandle)
-                },
-                clientExtensionResults: publicKeyCredential.getClientExtensionResults()
-            }
-            console.log(encodedResult)
-
-            await axios
-                .post(`http://localhost:8080/auth/finishBioLogin/${username}`, {
+                console.log(encodedResult)
+
+                return axios.post(`http://localhost:8080/auth/finishBioLogin/${username}`, {
                     credential: JSON.stringify(encodedResult)
                 })
-                .then((response) => {
-                    sessionStorage.setItem('accessToken', response.data.accessToken)
-                    localStorage.setItem('refreshToken', response.data.refreshToken)
+            })
+            .then((response) => {
+                sessionStorage.setItem('accessToken', response.data.accessToken)
 
-                    user.value.firstname = response.data.firstName
-                    user.value.lastname = response.data.lastName
-                    user.value.username = response.data.username
+                user.value.firstname = response.data.firstName
+                user.value.lastname = response.data.lastName
+                user.value.username = response.data.username
 
-                    router.push({ name: 'home' })
-                })
-                .catch((error) => {
-                    const axiosError = error as AxiosError
-                    errorMessage.value =
-                        (axiosError.response?.data as string) || 'An error occurred'
-                    console.log('hei :' + errorMessage.value)
-                })
-        } catch (error) {
-            // Handle errors
-            console.log(error)
-        }
+                router.push({ name: 'home' })
+            })
+            .catch((error) => {
+                console.error(error)
+            })
+    }
+
+    const checkIfUserConfigured = async () => {
+        await authInterceptor('/config')
+            .then((response) => {
+                console.log('User configured: ' + user.value.isConfigured)
+                user.value.isConfigured = response.data.challengeConfig != null
+            })
+            .catch(() => {
+                user.value.isConfigured = false
+            })
     }
 
     return {
+        user,
+        checkIfUserConfigured,
         register,
         login,
         logout,
         bioLogin,
         bioRegister,
-        errorMessage
+        errorMessage,
+        getUserStreak,
+        streak
     }
 })
diff --git a/src/types/challengeConfig.ts b/src/types/challengeConfig.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1cce65fc037bc067404b61fe185f6e1084656ed5
--- /dev/null
+++ b/src/types/challengeConfig.ts
@@ -0,0 +1,9 @@
+export interface ChallengeConfig {
+    experience: string
+    motivation: string
+    challengeTypeConfigs: {
+        type: string
+        generalAmount: number | null
+        specificAmount: number | null
+    }[]
+}
diff --git a/src/types/profile.ts b/src/types/profile.ts
index 392aee69615beff857dc324e85cc4f77ea1f7911..db81234695be6575d7d4c528515e9f1facbc5883 100644
--- a/src/types/profile.ts
+++ b/src/types/profile.ts
@@ -16,4 +16,5 @@ export interface Profile {
         balance?: number
     }
     badges?: object[]
+    hasPasskey?: boolean
 }
diff --git a/src/types/streak.ts b/src/types/streak.ts
new file mode 100644
index 0000000000000000000000000000000000000000..61dafae24c954c7ca99a3596ca43a659f1ef122c
--- /dev/null
+++ b/src/types/streak.ts
@@ -0,0 +1,4 @@
+export interface Streak {
+    streakStart?: string
+    streak?: number
+}
diff --git a/src/types/user.ts b/src/types/user.ts
index a420d33a4deb8de0e12fb303edf205b3be5e703f..624188688f1bec4c544ebf3b4d21d50f4a2d9be9 100644
--- a/src/types/user.ts
+++ b/src/types/user.ts
@@ -2,4 +2,6 @@ export interface User {
     firstname: string
     lastname: string
     username: string
+    isConfigured: boolean
+    isBiometric?: boolean
 }
diff --git a/src/views/AddAlternativeLogin.vue b/src/views/AddAlternativeLogin.vue
deleted file mode 100644
index 554f09f25915282f5675244784a6bb212457d036..0000000000000000000000000000000000000000
--- a/src/views/AddAlternativeLogin.vue
+++ /dev/null
@@ -1,48 +0,0 @@
-<template>
-    <div class="alt-login-main">
-        <h1>Alternativ innlogging</h1>
-        <div class="img-div">
-            <img src="@/assets/bioAuthTouch.png" alt="bioAuthTouch" />
-            <img src="@/assets/bioAuthFace.png" alt="bioAuthFace" />
-        </div>
-        <h2>Vil du logge på med touch eller face id?</h2>
-        <div class="btn-div">
-            <button @click="router.push('konfigurasjonSteg1')">Senere</button>
-            <button @click="userStore.bioRegister()">OK</button>
-        </div>
-    </div>
-</template>
-<script setup lang="ts">
-import { useUserStore } from '@/stores/userStore'
-import router from '@/router'
-
-const userStore = useUserStore()
-</script>
-
-<style scoped>
-.alt-login-main {
-    max-width: 800px;
-    display: flex;
-    flex-direction: column;
-    align-items: center;
-}
-
-.img-div {
-    display: flex;
-    justify-content: center;
-}
-
-img {
-    width: 30%;
-}
-
-img:first-child {
-    margin-right: 20px;
-}
-
-button {
-    margin: 10px;
-    width: 100px;
-    height: 40px;
-}
-</style>
diff --git a/src/views/BiometricLoginView.vue b/src/views/BiometricLoginView.vue
new file mode 100644
index 0000000000000000000000000000000000000000..1ffb51f09170c153890baa63a77110a08a7d915f
--- /dev/null
+++ b/src/views/BiometricLoginView.vue
@@ -0,0 +1,28 @@
+<script lang="ts" setup>
+import { useRoute } from 'vue-router'
+import router from '@/router'
+import { useUserStore } from '@/stores/userStore'
+
+const route = useRoute()
+const username = route.params.username as string
+
+const removeBioCredential = () => {
+    localStorage.removeItem('spareStiUsername')
+    router.push({ name: 'login' })
+}
+
+const bioLogin = () => {
+    useUserStore().bioLogin(username)
+}
+</script>
+
+<template>
+    <div class="flex flex-col items-center h-screen gap-5 my-10">
+        <h1>Hei {{ username }}, velkommen tilbake</h1>
+        <button @click="bioLogin">Biometrisk login</button>
+        <p>Ikke deg? Eller funker ikke biometrisk innlogging?</p>
+        <button @click="removeBioCredential">Logg inn med brukernavn og passord</button>
+    </div>
+</template>
+
+<style scoped></style>
diff --git a/src/views/ConfigAccountNumberView.vue b/src/views/ConfigAccountNumberView.vue
index 652cf0d11ba68e92f47d8b6e14171faa565cf321..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%]"
         >
@@ -47,12 +61,13 @@
 
 <script setup lang="ts">
 import { computed, ref } from 'vue'
-import { useAccountStore } from '@/stores/accountStore'
+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 accountStore = useAccountStore()
+const userConfigStore = useUserConfigStore()
 
 const spendingAccount = ref('')
 const savingsAccount = ref('')
@@ -68,11 +83,11 @@ async function onButtonClick() {
     const savingAccountNumber = savingsAccount.value.replace(/\./g, '')
     const spendingAccountNumber = spendingAccount.value.replace(/\./g, '')
 
-    await accountStore.postAccount('SAVING', savingAccountNumber, 0)
-
-    await accountStore.postAccount('SPENDING', spendingAccountNumber, 0)
+    await userConfigStore.postAccount('SAVING', savingAccountNumber, 0)
+    await userConfigStore.postAccount('SPENDING', spendingAccountNumber, 0)
+    await userConfigStore.postUserConfig()
 
-    await router.push({ name: 'home' })
+    await router.push({ name: 'home', query: { firstLogin: 'true' } })
 }
 
 function restrictToNumbers(event: InputEvent, type: string) {
diff --git a/src/views/ConfigBiometricView.vue b/src/views/ConfigBiometricView.vue
new file mode 100644
index 0000000000000000000000000000000000000000..a1421d8720873bb902cc9fd212953661deeab80f
--- /dev/null
+++ b/src/views/ConfigBiometricView.vue
@@ -0,0 +1,22 @@
+<template>
+    <div class="flex flex-col justify-center items-center w-full gap-5 m-5">
+        <h1>Alternativ innlogging</h1>
+        <h3>Vil du legge til alternativ innlogging som biometrisk autentisering?</h3>
+        <div class="flex flex-row justify-center gap-10">
+            <img alt="bioAuthTouch" class="w-40 h-40" src="@/assets/bioAuthTouch.png" />
+            <img alt="bioAuthFace" class="w-40 h-40" src="@/assets/bioAuthFace.png" />
+        </div>
+        <div class="flex flex-col gap-5">
+            <button @click="userStore.bioRegister()">Legg til nå!</button>
+            <button @click="router.push({ name: 'configurations1' })">Jeg gjør det senere</button>
+        </div>
+    </div>
+</template>
+<script setup lang="ts">
+import { useUserStore } from '@/stores/userStore'
+import router from '@/router'
+
+const userStore = useUserStore()
+</script>
+
+<style scoped></style>
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 098ba86faec729bcbc8450ad91268d7e65d82536..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()
 
@@ -93,7 +106,6 @@ const onButtonClick = async () => {
             parseFloat(amounts.value[index]) || 0
     })
 
-    userConfigStore.postUserConfig()
     await router.push({ name: 'configurations6' })
 }
 
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/FirstSavingChallengeView.vue b/src/views/FirstSavingChallengeView.vue
deleted file mode 100644
index 23cc78e8411420523f7b280e58da5ef88564005b..0000000000000000000000000000000000000000
--- a/src/views/FirstSavingChallengeView.vue
+++ /dev/null
@@ -1,112 +0,0 @@
-<template>
-    <div class="flex flex-col items-center justify-start min-h-screen px-4 text-center">
-        <div class="mb-20">
-            <div
-                class="flex flex-col items-center justify-start bg-white shadow-md rounded-lg p-16"
-                style="height: 530px; min-height: 500px; min-width: 400px; max-width: 400px"
-            >
-                <template v-if="!skipped && !accepted">
-                    <div class="mb-6 w-full text-left">
-                        <label for="savings-goal" class="block text-4xl font-bold mb-2"
-                            >Spareutfordring</label
-                        >
-                    </div>
-                    <div class="flex flex-col w-full mb-4">
-                        <button
-                            v-for="buttonText in buttonOptions"
-                            :key="buttonText"
-                            :class="[
-                                'mb-4 text-xl font-bold w-full rounded-lg py-3 px-4',
-                                selectedOptions.includes(buttonText)
-                                    ? 'bg-transparent border-2 border-[var(--green)]'
-                                    : 'bg-transparent border-2 border-gray-300'
-                            ]"
-                            @click="toggleOption(buttonText)"
-                        >
-                            {{ buttonText }}
-                        </button>
-                    </div>
-                    <div class="flex justify-between w-full mt-4 space-x-2">
-                        <button
-                            class="border-4 font-bold rounded-lg py-2 px-10 text-lg transition-all bg-[var(--green)] hover:brightness-90 active:brightness-75"
-                            @click="skip"
-                            style="margin-top: 29px"
-                        >
-                            Skip
-                        </button>
-                        <button
-                            :class="[
-                                'border-4 font-bold rounded-lg py-2 px-10 text-lg transition-all',
-                                {
-                                    'bg-[var(--green)] hover:brightness-90 active:brightness-75':
-                                        selectedOptions.length > 0
-                                },
-                                {
-                                    'opacity-60 bg-[rgba(149,227,93,0.6)] cursor-not-allowed':
-                                        selectedOptions.length === 0
-                                }
-                            ]"
-                            :disabled="selectedOptions.length === 0"
-                            @click="accept"
-                            style="margin-top: 29px"
-                        >
-                            Godta
-                        </button>
-                    </div>
-                </template>
-                <template v-else>
-                    <div class="flex justify-center items-center h-full">
-                        <div class="text-4xl font-bold">{{ acceptedMessage }}</div>
-                    </div>
-                </template>
-            </div>
-        </div>
-        <ContinueButtonComponent
-            :disabled="!skipped && !accepted"
-            @click="onButtonClick"
-            class="px-10 py-3 text-2xl font-bold self-end mb-32 mt-[-10px]"
-        ></ContinueButtonComponent>
-    </div>
-</template>
-
-<script setup lang="ts">
-import ContinueButtonComponent from '@/components/ContinueButtonComponent.vue'
-import router from '@/router'
-import { ref, watchEffect } from 'vue'
-
-const buttonOptions = ref(['Ikke kjøpe kaffe', 'Ikke kjøpe snus', 'Ikke kjøpe mat i kantina'])
-const selectedOptions = ref<string[]>([])
-const skipped = ref(false)
-const accepted = ref(false)
-
-const toggleOption = (option: string) => {
-    const index = selectedOptions.value.indexOf(option)
-    if (index === -1) {
-        selectedOptions.value.push(option)
-    } else {
-        selectedOptions.value.splice(index, 1)
-    }
-}
-
-const onButtonClick = () => {
-    router.push('/')
-}
-
-const skip = () => {
-    skipped.value = true
-}
-
-const accept = () => {
-    accepted.value = true
-}
-
-const acceptedMessage = ref('Du kan opprette spareutfordringer senere')
-
-watchEffect(() => {
-    if (accepted.value) {
-        acceptedMessage.value = 'Du har fått din første spareutfordring!'
-    } else if (skipped.value) {
-        acceptedMessage.value = 'Du kan opprette spareutfordringer senere'
-    }
-})
-</script>
diff --git a/src/views/FirstSavingGoalView.vue b/src/views/FirstSavingGoalView.vue
deleted file mode 100644
index bd28ba97b26defe4d241f903d973e542c9636717..0000000000000000000000000000000000000000
--- a/src/views/FirstSavingGoalView.vue
+++ /dev/null
@@ -1,142 +0,0 @@
-<template>
-    <div class="flex flex-col items-center justify-start min-h-screen px-4 text-center">
-        <div class="mb-20">
-            <div
-                class="flex flex-col items-center justify-center bg-white shadow-md rounded-lg p-16"
-                style="height: 530px; min-height: 500px; min-width: 400px; max-width: 400px"
-            >
-                <template v-if="!skipped && !accepted">
-                    <div class="mb-6 w-full text-left">
-                        <label for="savings-goal" class="block text-xl font-bold mb-2"
-                            >Jeg vil spare til:</label
-                        >
-                        <input
-                            type="text"
-                            id="savings-goal"
-                            v-model="savingsGoal"
-                            :class="{
-                                'border-[var(--green)]': savingsGoal.valueOf(),
-                                'border-gray-300': !savingsGoal.valueOf()
-                            }"
-                            class="border-2 block w-full rounded-md shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 text-xl"
-                            placeholder=""
-                        />
-                    </div>
-                    <div class="mb-8 w-full flex items-center">
-                        <label for="amount" class="shrink-0 text-xl font-bold mr-2"
-                            >Jeg vil spare:</label
-                        >
-                        <input
-                            type="text"
-                            id="amount"
-                            v-model="rawAmount"
-                            :class="{
-                                'border-[var(--green)]': rawAmount.valueOf(),
-                                'border-gray-300': !rawAmount.valueOf()
-                            }"
-                            class="border-2 rounded-md shadow-sm focus:border-indigo-300 focus:ring focus:ring-indigo-200 focus:ring-opacity-50 text-xl mr-2 block w-full"
-                            placeholder=""
-                            min="0"
-                        />
-                        <span class="shrink-0 text-xl font-bold">kr</span>
-                    </div>
-                    <div class="w-full px-4 py-2">
-                        <img src="@/assets/penger.png" alt="Savings" class="mx-auto w-36 h-32" />
-                    </div>
-                    <div class="flex justify-between w-full mt-4 space-x-2">
-                        <button
-                            class="bg-[var(--green)] border-4 border-[var(--green)] hover:brightness-90 active:brightness-75 font-bold rounded-lg py-2 px-10 text-lg"
-                            @click="skip"
-                        >
-                            Skip
-                        </button>
-                        <button
-                            :class="[
-                                'border-4 font-bold rounded-lg py-2 px-10 text-lg transition-all',
-                                canAccept
-                                    ? 'bg-[var(--green)] hover:brightness-90 active:brightness-75'
-                                    : 'opacity-60 bg-gray-300 cursor-not-allowed'
-                            ]"
-                            :disabled="!canAccept"
-                            @click="accept"
-                        >
-                            Godta
-                        </button>
-                    </div>
-                </template>
-                <template v-else>
-                    <div
-                        class="flex justify-start items-center h-full min-h-[400px] min-w-[400px] max-w-[400px]"
-                    >
-                        <div class="text-4xl font-bold">{{ acceptedMessage }}</div>
-                    </div>
-                </template>
-            </div>
-        </div>
-        <ContinueButtonComponent
-            :disabled="!skipped && !accepted"
-            @click="onButtonClick"
-            class="px-10 py-3 text-lg font-bold self-end mb-80 mt-[-10px]"
-        ></ContinueButtonComponent>
-    </div>
-</template>
-
-<script setup lang="ts">
-import { computed, ref, watch, watchEffect } from 'vue'
-import ContinueButtonComponent from '@/components/ContinueButtonComponent.vue'
-import router from '@/router'
-
-const savingsGoal = ref('')
-const rawAmount = ref('')
-const skipped = ref(false)
-const accepted = ref(false)
-
-const validateAmount = () => {
-    const validPattern = /^(\d+)?(,\d*)?$/
-    if (!validPattern.test(rawAmount.value)) {
-        rawAmount.value = rawAmount.value.slice(0, -1)
-    } else if (rawAmount.value.includes(',')) {
-        rawAmount.value = rawAmount.value.replace(/,+/g, ',')
-    }
-}
-
-const checkNegative = () => {
-    const numericValue = parseFloat(rawAmount.value.replace(',', '.'))
-    if (numericValue < 0) {
-        rawAmount.value = ''
-    }
-}
-
-watch(rawAmount, validateAmount)
-watch(() => parseFloat(rawAmount.value.replace(',', '.')), checkNegative)
-
-const canAccept = computed(() => savingsGoal.value.trim() !== '' && rawAmount.value.trim() !== '')
-
-const skip = () => {
-    skipped.value = true
-    acceptedMessage.value = 'Du kan opprette sparemål senere'
-}
-
-const accept = () => {
-    if (canAccept.value) {
-        accepted.value = true
-        acceptedMessage.value = 'Du har fått ditt første sparemål!'
-    }
-}
-
-const onButtonClick = () => {
-    if (skipped.value || accepted.value) {
-        router.push('/forsteSpareutfordring')
-    }
-}
-
-const acceptedMessage = ref('')
-
-watchEffect(() => {
-    if (accepted.value) {
-        acceptedMessage.value = 'Du har fått ditt første sparemål!'
-    } else if (skipped.value) {
-        acceptedMessage.value = 'Du kan opprette sparemål senere'
-    }
-})
-</script>
diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue
index f596bcaee5dac3d20b57091ba4c959c50580dc9e..052d5d3d447ecd1f0b8e4686a625a2d7417c7f8c 100644
--- a/src/views/HomeView.vue
+++ b/src/views/HomeView.vue
@@ -1,39 +1,57 @@
 <template>
     <div class="flex flex-col items-center max-h-[60vh] md:flex-row md:max-h-[80vh] mx-auto">
-        <div class="flex flex-col basis-1/3 order-last md:order-first md:basis-1/4 md:pl-10">
-            <InteractiveSpare
+        <div class="flex flex-col basis-1/3 order-last md:order-first md:basis-1/4 md:pl-1 mt-10">
+            <SpareComponent
                 :speech="speech"
+                :show="showWelcome"
+                :png-size="12"
                 :direction="'right'"
-                :pngSize="15"
-                class="opacity-0 h-0 w-0 md:opacity-100 md:h-auto md:w-auto md:mx-auto md:my-20"
-            ></InteractiveSpare>
-            <div class="flex flex-row gap-2 items-center mx-auto my-4 md:flex-col md:gap-4 md:m-8">
+                :imageDirection="'right'"
+                class="mt-24"
+            ></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"
+            >
                 <ButtonAddGoalOrChallenge :buttonText="'Legg til sparemål'" :type="'goal'" />
                 <ButtonAddGoalOrChallenge
                     :buttonText="'Legg til spareutfordring'"
                     :type="'challenge'"
                 />
+                <ButtonAddGoalOrChallenge
+                    :buttonText="'Generer spareutfordring'"
+                    :type="'generatedChallenge'"
+                    :showModal="showModal"
+                    @click="showModal = true"
+                    @update:showModal="showModal = $event"
+                />
             </div>
         </div>
         <savings-path :challenges="challenges" :goal="goal"></savings-path>
     </div>
+    <GeneratedChallengesModal v-show="showModal" @update:showModal="showModal = $event" />
 </template>
 
 <script setup lang="ts">
 import { onMounted, ref } from 'vue'
-import InteractiveSpare from '@/components/InteractiveSpare.vue'
 import ButtonAddGoalOrChallenge from '@/components/ButtonAddGoalOrChallenge.vue'
 import type { Challenge } from '@/types/challenge'
 import type { Goal } from '@/types/goal'
 import { useGoalStore } from '@/stores/goalStore'
 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 speech = ref<string[]>([])
 
 const challenges = ref<Challenge[]>([])
 const goals = ref<Goal[]>([])
+const showWelcome = ref<boolean>(false)
 
 const goal = ref<Goal | null | undefined>(null)
 
@@ -44,14 +62,31 @@ onMounted(async () => {
     goals.value = goalStore.goals
     goal.value = goals.value[0]
     console.log('Goals:', goals.value)
+
+    const lastModalShow = localStorage.getItem('lastModalShow')
+    if (!lastModalShow || Date.now() - Number(lastModalShow) >= 24 * 60 * 60 * 1000) {
+        showModal.value = true
+    }
+    firstLoggedInSpeech()
+    SpareSpeech()
 })
 
-// Define your speech array
-const speechArray = [
-    'Hei! Jeg er Sparemannen.',
-    'Jeg hjelper deg med å spare penger.',
-    'Klikk på meg for å høre mer.'
-]
+const firstLoggedInSpeech = () => {
+    const isFirstLogin = router.currentRoute.value.query.firstLogin === 'true'
+    if (isFirstLogin) {
+        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' } })
+    }
+}
 
-const speech = ref(speechArray)
+const SpareSpeech = () => {
+    speech.value = [
+        'Hei! Jeg er sparegrisen, Spare!',
+        'Valkommen til SpareSti 👑',
+        'Du kan trykke på meg for å høre hva jeg har å si 🐷'
+    ]
+}
 </script>
diff --git a/src/views/ManageConfigView.vue b/src/views/ManageConfigView.vue
new file mode 100644
index 0000000000000000000000000000000000000000..6ff3eaa9ac3ee00f56bcc7e1ae867b9dab1d57f4
--- /dev/null
+++ b/src/views/ManageConfigView.vue
@@ -0,0 +1,183 @@
+<script lang="ts" setup>
+import authInterceptor from '@/services/authInterceptor'
+import CardTemplate from '@/components/CardTemplate.vue'
+import type { ChallengeConfig } from '@/types/challengeConfig'
+import { onMounted, ref } from 'vue'
+import ModalComponent from '@/components/ModalComponent.vue'
+import router from '@/router'
+
+const configuration = ref<ChallengeConfig>({
+    motivation: '',
+    experience: '',
+    challengeTypeConfigs: [
+        {
+            type: 'Kaffe',
+            generalAmount: 100,
+            specificAmount: 10
+        }
+    ]
+})
+
+const error = ref<string | null>(null)
+
+const deleteChallengeType = (type: string) => {
+    if (configuration.value.challengeTypeConfigs) {
+        configuration.value.challengeTypeConfigs = configuration.value.challengeTypeConfigs.filter(
+            (item) => item.type !== type
+        )
+    }
+}
+
+const createChallengeType = () => {
+    configuration.value.challengeTypeConfigs?.push({
+        type: '',
+        specificAmount: null,
+        generalAmount: null
+    })
+}
+
+const validateAndSave = () => {
+    if (!configuration.value.motivation) {
+        return (error.value = 'Du må velge hvor store vaneendringer du er villig til å gjøre')
+    }
+
+    if (!configuration.value.experience) {
+        return (error.value = 'Du må velge hvor kjent du er med sparing fra før av')
+    }
+
+    if (configuration.value.challengeTypeConfigs.length == 0) {
+        return (error.value = 'Du må legge til minst én ting du bruker mye penger på')
+    }
+
+    if (
+        configuration.value.challengeTypeConfigs.some(
+            (item) => !item.type || !item.specificAmount || !item.generalAmount
+        )
+    ) {
+        return (error.value = 'Du må fylle ut alle feltene for ting du bruker mye penger på')
+    }
+
+    if (
+        configuration.value.challengeTypeConfigs.some(
+            (item) =>
+                (item.specificAmount && item.specificAmount < 0) ||
+                (item.generalAmount && item.generalAmount < 0)
+        )
+    ) {
+        return (error.value = 'Prisene kan ikke være negative')
+    }
+
+    saveConfiguration()
+}
+
+const saveConfiguration = () => {
+    authInterceptor
+        .put('/config/challenge', configuration.value)
+        .then(() => {
+            router.push({ name: 'profile' })
+        })
+        .catch((error) => {
+            error.value = error.response.data.message
+        })
+}
+
+onMounted(() => {
+    authInterceptor('/config/challenge')
+        .then((response) => {
+            configuration.value = response.data
+            console.log(configuration.value)
+        })
+        .catch((error) => {
+            return console.log(error)
+        })
+})
+</script>
+
+<template>
+    <div class="w-full flex px-10 justify-center">
+        <div class="flex flex-col justify-center items-center max-w-screen-xl gap-3">
+            <h1>Rediger kofigurasjonen</h1>
+
+            <h2 class="font-thin">Hvor store vaneedringer er du villig til å gjøre?</h2>
+            <div v-if="configuration" class="flex flex-row gap-5">
+                <CardTemplate
+                    :class="{ 'bg-green-500': configuration.motivation === 'VERY_LOW' }"
+                    class="cursor-pointer p-5"
+                    @click="configuration.motivation = 'VERY_LOW'"
+                >
+                    <p class="text-2xl">Litt</p>
+                </CardTemplate>
+                <CardTemplate
+                    :class="{ 'bg-green-500': configuration.motivation === 'MEDIUM' }"
+                    class="cursor-pointer p-5"
+                    @click="configuration.motivation = 'MEDIUM'"
+                >
+                    <p class="text-2xl">Passe</p>
+                </CardTemplate>
+                <CardTemplate
+                    :class="{ 'bg-green-500': configuration.motivation === 'VERY_HIGH' }"
+                    class="cursor-pointer p-5"
+                    @click="configuration.motivation = 'VERY_HIGH'"
+                >
+                    <p class="text-2xl">Store</p>
+                </CardTemplate>
+            </div>
+
+            <h2 class="font-thin">Hvor kjent er du med sparing fra før av?</h2>
+            <div v-if="configuration" class="flex flex-row gap-5">
+                <CardTemplate
+                    :class="{ 'bg-green-500': configuration.experience === 'VERY_LOW' }"
+                    class="cursor-pointer p-5"
+                    @click="configuration.experience = 'VERY_LOW'"
+                >
+                    <p class="text-2xl">Litt kjent</p>
+                </CardTemplate>
+                <CardTemplate
+                    :class="{ 'bg-green-500': configuration.experience === 'MEDIUM' }"
+                    class="cursor-pointer p-5"
+                    @click="configuration.experience = 'MEDIUM'"
+                >
+                    <p class="text-2xl">Noe kjent</p>
+                </CardTemplate>
+                <CardTemplate
+                    :class="{ 'bg-green-500': configuration.experience === 'VERY_HIGH' }"
+                    class="cursor-pointer p-5"
+                    @click="configuration.experience = 'VERY_HIGH'"
+                >
+                    <p class="text-2xl">Godt kjent</p>
+                </CardTemplate>
+            </div>
+
+            <h2 class="font-thin my-0">Hva bruker du mye penger på?</h2>
+            <div class="flex flex-col gap-4 p-4 items-center">
+                <CardTemplate
+                    v-for="(item, index) in configuration.challengeTypeConfigs"
+                    :key="index"
+                    class="flex flex-row flex-wrap justify-center gap-5 border-4 p-3"
+                >
+                    <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" />
+                    <button
+                        class="cursor-pointer bg-red-500 rounded-full w-min items-center"
+                        @click="deleteChallengeType(item.type)"
+                        v-text="'x'"
+                    />
+                </CardTemplate>
+                <button class="secondary" @click="createChallengeType" v-text="'+'" />
+            </div>
+
+            <div class="flex flex-row justify-center gap-5">
+                <button class="secondary" @click="router.back()">Avbryt</button>
+                <button class="primary" @click="validateAndSave">Lagre</button>
+            </div>
+        </div>
+
+        <ModalComponent v-if="error">
+            <p class="my-4" v-text="error" />
+            <button @click="error = null">Lukk</button>
+        </ModalComponent>
+    </div>
+</template>
+
+<style scoped></style>
diff --git a/src/views/ManageGoalView.vue b/src/views/ManageGoalView.vue
index 14c44badfe752a364a420f17ac4fb022dd3f2f46..f3fd1a1850d1ee962e2ca24cc592745e29ef6e53 100644
--- a/src/views/ManageGoalView.vue
+++ b/src/views/ManageGoalView.vue
@@ -126,7 +126,7 @@ const updateGoal = () => {
     authInterceptor
         .put(`/goals/${goalInstance.value.id}`, goalInstance.value)
         .then(() => {
-            router.push({ name: 'goals' })
+            router.back()
         })
         .catch((error) => {
             console.error(error)
diff --git a/src/views/EditProfileView.vue b/src/views/ManageProfileView.vue
similarity index 81%
rename from src/views/EditProfileView.vue
rename to src/views/ManageProfileView.vue
index b6aefeff8beedb21eb6b342b1361c15a72782685..6ddce344664e5226925b535a2f5343f432f49c31 100644
--- a/src/views/EditProfileView.vue
+++ b/src/views/ManageProfileView.vue
@@ -2,7 +2,7 @@
 import authInterceptor from '@/services/authInterceptor'
 import { computed, onMounted, ref } from 'vue'
 import type { Profile } from '@/types/profile'
-import CardTemplate from '@/views/CardTemplate.vue'
+import CardTemplate from '@/components/CardTemplate.vue'
 import router from '@/router'
 import ToolTip from '@/components/ToolTip.vue'
 import InteractiveSpare from '@/components/InteractiveSpare.vue'
@@ -27,14 +27,29 @@ const profile = ref<Profile>({
 const updatePassword = ref<boolean>(false)
 const confirmPassword = ref<string>('')
 const errorMessage = ref<string>('')
+const isModalOpen = ref(false)
 
-const nameRegex = /^[æÆøØåÅa-zA-Z,.'-][æÆøØåÅa-zA-Z ,.'-]{1,29}$/
+const nameRegex = /^[æÆøØåÅa-zA-Z,.'-][æÆøØåÅa-zA-Z ,.'-]{0,29}$/
 const emailRegex =
     /^[æÆøØåÅa-zA-Z0-9_+&*-]+(?:\.[æÆøØåÅa-zA-Z0-9_+&*-]+)*@(?:[æÆøØåÅa-zA-Z0-9-]+\.)+[æÆøØåÅa-zA-Z]{2,7}$/
-const usernameRegex = /^[ÆØÅæøåA-Za-z][æÆøØåÅA-Za-z0-9_]{2,29}$/
 const passwordRegex = /^(?=.*[0-9])(?=.*[a-zæøå])(?=.*[ÆØÅA-Z])(?=.*[@#$%^&+=!])(?=\S+$).{8,30}$/
 const accountNumberRegex = /^\d{11}$/
 
+const MAX_DIGITS = 11
+
+function restrictToNumbers(event: InputEvent, type: string) {
+    const inputValue = (event.target as HTMLInputElement)?.value
+    if (inputValue !== undefined) {
+        const sanitizedValue = inputValue.replace(/\D/g, '')
+        const truncatedValue = sanitizedValue.slice(0, MAX_DIGITS)
+        if (type === 'spending') {
+            profile.value.spendingAccount.accNumber = parseInt(truncatedValue)
+        } else {
+            profile.value.savingAccount.accNumber = parseInt(truncatedValue)
+        }
+    }
+}
+
 const isFirstNameValid = computed(
     () => nameRegex.test(profile.value.firstName) && profile.value.firstName
 )
@@ -42,7 +57,6 @@ const isLastNameValid = computed(
     () => nameRegex.test(profile.value.lastName) && profile.value.lastName
 )
 const isEmailValid = computed(() => emailRegex.test(profile.value.email))
-const isUsernameValid = computed(() => usernameRegex.test(profile.value.username))
 const isPasswordValid = computed(() => passwordRegex.test(profile.value.password || ''))
 const isSpendingAccountValid = computed(() =>
     accountNumberRegex.test(profile.value.spendingAccount.accNumber?.toString() || '')
@@ -57,7 +71,6 @@ const isFormInvalid = computed(
             isFirstNameValid,
             isLastNameValid,
             isEmailValid,
-            isUsernameValid,
             isSpendingAccountValid,
             isSavingAccountValid
         ].some((v) => !v.value) ||
@@ -107,7 +120,7 @@ const saveChanges = async () => {
                     <div class="flex flex-col justify-center">
                         <button class="h-min bg-transparent text-4xl" v-text="'⬅️'" />
                     </div>
-                    <div class="w-32 h-32 border-slate-200 border-2 rounded-full shrink-0" />
+                    <div class="w-32 h-32 border-black border-2 rounded-full shrink-0" />
                     <div class="flex flex-col justify-center">
                         <button class="h-min bg-transparent text-4xl" v-text="'➡️'" />
                     </div>
@@ -122,6 +135,7 @@ const saveChanges = async () => {
                     </div>
                     <input
                         v-model="profile.firstName"
+                        :class="{ 'bg-green-200': isFirstNameValid }"
                         name="firstname"
                         placeholder="Skriv inn fornavn"
                         type="text"
@@ -136,6 +150,7 @@ const saveChanges = async () => {
                     </div>
                     <input
                         v-model="profile.lastName"
+                        :class="{ 'bg-green-200': isLastNameValid }"
                         name="lastname"
                         placeholder="Skriv inn etternavn"
                         type="text"
@@ -150,25 +165,12 @@ const saveChanges = async () => {
                     </div>
                     <input
                         v-model="profile.email"
+                        :class="{ 'bg-green-200': isEmailValid }"
                         name="email"
                         placeholder="Skriv inn e-post"
                         type="text"
                     />
                 </div>
-                <div class="flex flex-col">
-                    <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.'"
-                        />
-                    </div>
-                    <input
-                        v-model="profile.username"
-                        name="username"
-                        placeholder="Skriv inn brukernavn"
-                        type="text"
-                    />
-                </div>
                 <div class="flex flex-col">
                     <div class="flex flex-row justify-between mx-4">
                         <div class="flex flex-row gap-2">
@@ -183,6 +185,7 @@ const saveChanges = async () => {
                     <input
                         v-if="updatePassword"
                         v-model="profile.password"
+                        :class="{ 'bg-green-200': isPasswordValid }"
                         class="w-full"
                         name="password"
                         placeholder="Skriv inn passord"
@@ -190,6 +193,7 @@ const saveChanges = async () => {
                     <input
                         v-if="updatePassword"
                         v-model="confirmPassword"
+                        :class="{ 'bg-red-200': profile.password !== confirmPassword }"
                         class="mt-2"
                         name="confirm"
                         placeholder="Bekreft passord"
@@ -204,36 +208,41 @@ const saveChanges = async () => {
                     :png-size="10"
                     :speech="['Her kan du endre på profilen din!']"
                     direction="left"
+                    :isModalOpen="isModalOpen"
                 />
 
                 <CardTemplate>
-                    <div class="bg-red-100">
+                    <div class="bg-red-300">
                         <p class="font-bold mx-3" v-text="'Brukskonto'" />
                     </div>
                     <input
+                        @input="restrictToNumbers($event as InputEvent, 'spending')"
                         v-model="profile.spendingAccount.accNumber"
-                        class="border-1 rounded-none rounded-b-xl w-full"
+                        :class="{ 'bg-green-200': isSpendingAccountValid }"
+                        class="border-2 rounded-none rounded-b-xl w-full"
                         placeholder="Kontonummer"
                         type="number"
                     />
                 </CardTemplate>
 
                 <CardTemplate>
-                    <div class="bg-red-100">
+                    <div class="bg-red-300">
                         <p class="font-bold mx-3" v-text="'Sparekonto'" />
                     </div>
                     <input
+                        @input="restrictToNumbers($event as InputEvent, 'saving')"
                         v-model="profile.savingAccount.accNumber"
-                        class="border-1 rounded-none rounded-b-xl w-full"
+                        :class="{ 'bg-green-200': isSavingAccountValid }"
+                        class="border-2 rounded-none rounded-b-xl w-full"
                         placeholder="Kontonummer"
                         type="number"
                     />
                 </CardTemplate>
 
                 <div class="flex flex-row justify-between">
-                    <button class="primary danger" @click="router.back()" v-text="'Avbryt'" />
+                    <button class="bg-button-other" @click="router.back()" v-text="'Avbryt'" />
                     <button
-                        class="primary"
+                        :disabled="isFormInvalid"
                         @click="saveChanges"
                         v-text="'Lagre endringer'"
                     />
@@ -242,5 +251,3 @@ const saveChanges = async () => {
         </div>
     </div>
 </template>
-
-<style scoped></style>
diff --git a/src/views/RegisterLoginView.vue b/src/views/RegisterLoginView.vue
index 738002afa9461e9df0acbd0f592b327303ec33ba..16d78619fdf348fd038c8858499065d46d11c923 100644
--- a/src/views/RegisterLoginView.vue
+++ b/src/views/RegisterLoginView.vue
@@ -2,9 +2,7 @@
 import FormLogin from '@/components/FormLogin.vue'
 import FormRegister from '@/components/FormRegister.vue'
 import { onMounted, ref } from 'vue'
-import { useRouter } from 'vue-router'
-
-const router = useRouter()
+import router from '@/router'
 
 const isLogin = ref<boolean>(true)
 
diff --git a/src/views/UserGoalsView.vue b/src/views/UserGoalsView.vue
index aaba6e667b3168cabf654dab806f659abced84e0..b41e7c44b7c36f44f09436d8d57f1ba38313dcfd 100644
--- a/src/views/UserGoalsView.vue
+++ b/src/views/UserGoalsView.vue
@@ -107,6 +107,3 @@ const changeOrder = async () => {
         />
     </div>
 </template>
-
-<style scoped>
-</style>
\ No newline at end of file
diff --git a/src/views/ViewChallengeView.vue b/src/views/ViewChallengeView.vue
index d1b1e0d9603efe20bb3f2600a72b7d26151672a8..76f11a2a0777ed49e23caf1b4291dbdd434a9d61 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,
@@ -144,7 +144,13 @@ const completeChallenge = () => {
                 />
             </div>
         </div>
-        <InteractiveSpare :png-size="10" :speech="motivation" direction="left" />
+        <SpareComponent
+            :speech="motivation"
+            :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 68ca0699389b294b385e61c595f725e9888a7b5d..2c2fa3a3b2d930feb3c044b97fd05739310fca17 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()
 
@@ -40,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.`
         )
     }
 }
@@ -130,10 +130,14 @@ const completeGoal = () => {
                     v-text="'Marker målet som ferdig'"
                 />
             </div>
-            </div>
-            <InteractiveSpare :png-size="10" :speech="motivation" direction="left" />
-            <div>
         </div>
+        <SpareComponent
+            :speech="motivation"
+            :png-size="15"
+            :imageDirection="'left'"
+            :direction="'right'"
+            class="mb-5"
+        ></SpareComponent>
     </div>
 </template>
 
diff --git a/src/views/ProfileView.vue b/src/views/ViewProfileView.vue
similarity index 71%
rename from src/views/ProfileView.vue
rename to src/views/ViewProfileView.vue
index 028dc13975cc998868415dcd89418d38cb636c1f..6993e7d21e75ef166287754e724686434d228467 100644
--- a/src/views/ProfileView.vue
+++ b/src/views/ViewProfileView.vue
@@ -1,20 +1,22 @@
 <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 '@/views/CardTemplate.vue'
-import InteractiveSpare from '@/components/InteractiveSpare.vue'
+import CardTemplate from '@/components/CardTemplate.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 speech = ref<string[]>([])
 
-onMounted(async () => {
-    await authInterceptor('/profile')
+const updateUser = async () => {
+    authInterceptor('/profile')
         .then((response) => {
             profile.value = response.data
             console.log(profile.value)
@@ -22,6 +24,10 @@ onMounted(async () => {
         .catch((error) => {
             return console.log(error)
         })
+}
+
+onMounted(async () => {
+    await updateUser()
 
     await authInterceptor(`/goals/completed?page=0&size=3`)
         .then((response) => {
@@ -38,20 +44,30 @@ onMounted(async () => {
         .catch((error) => {
             return console.log(error)
         })
-})
 
-const welcome = computed(() => {
-    return [`Velkommen, ${profile.value?.firstName} ${profile.value?.lastName} !`]
+    openSpare()
 })
+const updateBiometrics = async () => {
+    await useUserStore().bioRegister()
+    await updateUser()
+}
+
+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>
 
 <template>
     <div class="w-full flex px-10 justify-center">
         <div class="flex flex-row flex-wrap justify-center w-full max-w-screen-xl gap-20">
             <div class="flex flex-col max-w-96 w-full gap-5">
-                <h1>Profil</h1>
+                <h1>Profile</h1>
                 <div class="flex flex-row gap-5">
-                    <div class="w-32 h-32 border-slate-200 border-2 rounded-full shrink-0" />
+                    <div class="w-32 h-32 border-black border-2 rounded-full shrink-0" />
                     <div class="w-full flex flex-col justify-between">
                         <h3 class="font-thin my-0">{{ profile?.username }}</h3>
                         <h3 class="font-thin my-0">
@@ -61,7 +77,7 @@ const welcome = computed(() => {
                     </div>
                 </div>
 
-                <h3 class="font-bold" v-text="'Du har spart ' + '< totalSaved >' + ' kr!'" />
+                <h3 class="font-bold" v-text="'Du har spart ' + '< totalSaved >' + 'kr'" />
 
                 <CardTemplate>
                     <div class="bg-red-300">
@@ -83,13 +99,24 @@ const welcome = computed(() => {
                     />
                 </CardTemplate>
 
-                <button 
-                    class="primary secondary w-40"
-                    @click="router.push({ name: 'edit-profile' })" v-text="'Rediger bruker'" />
+                <button @click="router.push({ name: 'edit-profile' })" v-text="'Rediger bruker'" />
+                <button
+                    @click="router.push({ name: 'edit-configuration' })"
+                    v-text="'Rediger konfigurasjon'"
+                />
+                <button @click="updateBiometrics">
+                    {{ profile?.hasPasskey ? 'Endre biometri' : 'Legg til biometri' }}
+                </button>
             </div>
 
             <div class="flex flex-col">
-                <InteractiveSpare :png-size="10" :speech="welcome" direction="left" />
+                <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'" />
@@ -113,5 +140,3 @@ const welcome = computed(() => {
         </div>
     </div>
 </template>
-
-<style scoped></style>