diff --git a/src/App.vue b/src/App.vue
index be78194d361500e3ee20a20eb0d46747b92c4a2a..6cd1e8f97ea32c80831eb29c2ff51bc86c2722ac 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -10,7 +10,8 @@ const showNavBar = computed(() => {
         route.path == '/' ||
         route.path == '/registrer' ||
         route.path == '/logginn' ||
-        route.path == '/forgotPassword'
+        route.path == '/forgotPassword' ||
+        route.path.startsWith('/konfigurasjon')
     )
 })
 </script>
diff --git a/src/assets/bioAuthFace.png b/src/assets/bioAuthFace.png
new file mode 100644
index 0000000000000000000000000000000000000000..b03bb5d400029bcbc6d7bea9f5657da31e3e63a0
Binary files /dev/null and b/src/assets/bioAuthFace.png differ
diff --git a/src/assets/bioAuthTouch.png b/src/assets/bioAuthTouch.png
new file mode 100644
index 0000000000000000000000000000000000000000..363627b9c744b2a8dcabc9d2a69485d055045f43
Binary files /dev/null and b/src/assets/bioAuthTouch.png differ
diff --git a/src/components/FormLogin.vue b/src/components/FormLogin.vue
index 731e224e722324e37fb36ffd35f3bfe4ee2344f7..363580072249635f9a74c6a5e1e9ec0eac6cbdc3 100644
--- a/src/components/FormLogin.vue
+++ b/src/components/FormLogin.vue
@@ -15,11 +15,18 @@ const emailRegex = /^[a-zA-Z0-9_+&*-]+(?:\.[a-zA-Z0-9_+&*-]+)*@(?:[a-zA-Z0-9-]+\
 const userStore = useUserStore()
 
 const isEmailValid = computed(() => emailRegex.test(resetEmail.value))
+const isSendingEmail = ref(false)
+const successMessage = ref<string>('')
+const modalErrorMessage = ref<string>('')
 
 const submitForm = () => {
     userStore.login(username.value, password.value)
 }
 
+const bioLogin = () => {
+    userStore.bioLogin(username.value)
+}
+
 const toggleShowPassword = () => {
     showPassword.value = !showPassword.value
 }
@@ -30,17 +37,36 @@ const openForgotPasswordModal = (event: MouseEvent) => {
 }
 
 const submitReset = async () => {
-    await axios.post('http://localhost:8080/forgotPassword/changePasswordRequest', {
-        email: resetEmail.value
-    })
-
-    resetEmail.value = ''
-    isModalOpen.value = false
+    isSendingEmail.value = true
+    modalErrorMessage.value = ''
+    successMessage.value = ''
+    try {
+        const response = await axios.post(
+            'http://localhost:8080/forgotPassword/changePasswordRequest',
+            {
+                email: resetEmail.value
+            }
+        )
+        successMessage.value =
+            'E-posten er sendt. Vennligst sjekk innboksen din for instrukser. OBS: E-posten kan havne i spam-mappen'
+        isSendingEmail.value = false
+        setTimeout(() => {
+            isModalOpen.value = false
+            successMessage.value = ''
+        }, 5000)
+    } catch (error) {
+        console.error(error)
+        modalErrorMessage.value = 'Noe gikk galt. Vennligst prøv igjen.'
+        isSendingEmail.value = false
+    }
 }
 
 const closeModal = () => {
-    resetEmail.value = ''
     isModalOpen.value = false
+    isSendingEmail.value = false
+    modalErrorMessage.value = ''
+    resetEmail.value = ''
+    successMessage.value = ''
 }
 
 watch(
@@ -95,36 +121,58 @@ watch(
                 Logg inn
             </button>
             <p>{{ errorMessage }}</p>
+            <button @click="bioLogin">biologin</button>
         </div>
     </div>
     <modal-component
         :title="'Glemt passord'"
         :message="'Vennligst skriv inn e-posten din for å endre passordet.'"
         :is-modal-open="isModalOpen"
-        @close="isModalOpen = false"
+        @close="closeModal"
     >
         <template v-slot:input>
-            <input
-                type="email"
-                v-model="resetEmail"
-                class="border border-gray-300 p-2 w-full mb-7"
-                placeholder="Skriv e-postadressen din her"
-            />
-        </template>
-        <template v-slot:buttons>
-            <button
-                :disabled="!isEmailValid"
-                @click="submitReset"
-                class="active-button font-bold py-2 px-4 w-1/2 border-2 disabled:border-transparent"
-            >
-                Send mail
-            </button>
-            <button
-                @click="closeModal"
-                class="active-button font-bold py-2 px-4 w-1/2 border-2 disabled:border-transparent"
-            >
-                Lukk
-            </button>
+            <div v-if="isSendingEmail" class="flex justify-center items-center">
+                <div
+                    class="p-3 animate-spin drop-shadow-2xl bg-gradient-to-r from-lime-500 from-30% to-green-600 to-90% md:w-18 md:h-20 h-20 w-20 aspect-square rounded-full"
+                >
+                    <div class="rounded-full h-full w-full bg-slate-100 background-blur-md"></div>
+                </div>
+            </div>
+            <div v-else-if="successMessage">
+                <p class="text-green-500 text-center">{{ successMessage }}</p>
+            </div>
+            <div v-else-if="modalErrorMessage">
+                <p class="text-red-500 text-center">{{ modalErrorMessage }}</p>
+                <button
+                    @click="closeModal"
+                    class="active-button font-bold py-2 px-4 w-1/2 mt-4 border-2 disabled:border-transparent"
+                >
+                    Lukk
+                </button>
+            </div>
+            <div v-else>
+                <input
+                    type="email"
+                    v-model="resetEmail"
+                    class="border border-gray-300 p-2 w-full mb-7"
+                    placeholder="Skriv e-postadressen din her"
+                />
+                <div class="flex gap-5 mt-4">
+                    <button
+                        :disabled="!isEmailValid"
+                        @click="submitReset"
+                        class="active-button font-bold py-2 px-4 w-1/2 border-2 disabled:border-transparent"
+                    >
+                        Send mail
+                    </button>
+                    <button
+                        @click="closeModal"
+                        class="active-button font-bold py-2 px-4 w-1/2 border-2 disabled:border-transparent"
+                    >
+                        Lukk
+                    </button>
+                </div>
+            </div>
         </template>
     </modal-component>
 </template>
diff --git a/src/components/ImgGifTemplate.vue b/src/components/ImgGifTemplate.vue
new file mode 100644
index 0000000000000000000000000000000000000000..c4d06b434a0f6a87f09a6d84a6b63287a0ef5840
--- /dev/null
+++ b/src/components/ImgGifTemplate.vue
@@ -0,0 +1,18 @@
+<template>
+      <img
+          v-if="index%6===modValue"
+          :src="url"
+          alt="could not load"
+          class="h-32 w-32 border-2 rounded-lg border-stale-400"
+      />
+</template>
+
+<script setup lang="ts">
+interface Props {
+  url: string
+  index: number
+  modValue: number
+}
+
+const props = defineProps<Props>()
+</script>
diff --git a/src/components/SavingsPath.vue b/src/components/SavingsPath.vue
index 5fc549f0745352ab19a091228d6b5c8b5703c2a9..f23676f1827c6d148efcd76194c30b0598e6c091 100644
--- a/src/components/SavingsPath.vue
+++ b/src/components/SavingsPath.vue
@@ -31,111 +31,84 @@
                     class="flex flex-row w-4/5 gap-8"
                 >
                     <div class="right-auto just">
-                        <img
-                            v-if="index%6 ===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%6 === 1"
-                            src="@/assets/golfSpare.gif"
-                            alt="could not load"
-                            class="w-32 h-32 border-2 rounded-lg border-stale-400"
-                        />
-                        <img
-                            v-else-if="index%6===5"
-                            src="@/assets/archerSpare.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">
-                            <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"
-                                :alt="challenge.title"
-                            />
-                            <!-- Progress Bar, if the challenge is not complete -->
-                            <div
-                                v-if="
-                                    challenge.completion != undefined && challenge.completion < 100
-                                "
-                                class="flex-grow w-full mt-2"
-                            >
-                                <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"
-                                        >
-                                            <div
-                                                class="bg-green-600 h-2.5 rounded-full"
-                                                data-cy="challenge-progress"
-                                                :style="{
-                                                    width:
-                                                        (challenge.saved / challenge.target) * 100 +
-                                                        '%'
-                                                }"
-                                            ></div>
-                                        </div>
-                                        <div class="text-center text-xs md:text-base">
-                                            {{ challenge.saved }}kr / {{ challenge.target }}kr
-                                        </div>
-                                    </div>
-
-                                    <button
-                                        @click="incrementSaved(challenge)"
-                                        :data-cy="'increment-challenge' + challenge.id"
-                                        type="button"
-                                        class="inline-block mb-2 ml-2 h-7 w-8 rounded-full p-1 uppercase leading-normal transition duration-150 ease-in-out focus:bg-green-accent-300 focus:shadow-green-2 focus:outline-none focus:ring-0 active:bg-green-600 active:shadow-green-200 motion-reduce:transition-none dark:shadow-black/30 dark:hover:shadow-dark-strong dark:focus:shadow-dark-strong dark:active:shadow-dark-strong"
-                                    >
-                                        +
-                                    </button>
-                                </div>
-                            </div>
-                            <span v-else class="text-center text-xs md:text-base">Ferdig: {{ challenge.saved }}</span>
-                        </div>
-                        <!-- Check Icon -->
-                        <div
-                            v-if="challenge.completion !== undefined && challenge.completion >= 100"
-                            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>
-                        <div v-else class="max-w-6 max-h-6">
-                            <img src="@/assets/pending.png" alt="" />️
-                        </div>
-                    </div>
+                    <card-template>
+                      <div class="flex">
+                          <!-- Challenge Icon -->
+                          <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"
+                                  :alt="challenge.title"
+                              />
+                              <!-- Progress Bar, if the challenge is not complete -->
+                              <div
+                                  v-if="
+                                      challenge.completion != undefined && challenge.completion < 100
+                                  "
+                                  class="flex-grow w-full mt-2"
+                              >
+                                  <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"
+                                          >
+                                              <div
+                                                  class="bg-green-600 h-2.5 rounded-full"
+                                                  data-cy="challenge-progress"
+                                                  :style="{
+                                                      width:
+                                                          (challenge.saved / challenge.target) * 100 +
+                                                          '%'
+                                                  }"
+                                              ></div>
+                                          </div>
+                                          <div class="text-center text-xs md:text-base">
+                                              {{ challenge.saved }}kr / {{ challenge.target }}kr
+                                          </div>
+                                      </div>
+
+                                      <button
+                                          @click="incrementSaved(challenge)"
+                                          :data-cy="'increment-challenge' + challenge.id"
+                                          type="button"
+                                          class="inline-block mb-2 ml-2 h-7 w-8 rounded-full p-1 uppercase leading-normal transition duration-150 ease-in-out focus:bg-green-accent-300 focus:shadow-green-2 focus:outline-none focus:ring-0 active:bg-green-600 active:shadow-green-200 motion-reduce:transition-none dark:shadow-black/30 dark:hover:shadow-dark-strong dark:focus:shadow-dark-strong dark:active:shadow-dark-strong"
+                                      >
+                                          +
+                                      </button>
+                                  </div>
+                              </div>
+                              <span v-else class="text-center text-xs md:text-base">Ferdig: {{ challenge.saved }}</span>
+                          </div>
+                          <!-- Check Icon -->
+                          <div
+                              v-if="challenge.completion !== undefined && challenge.completion >= 100"
+                              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>
+                          <div v-else class="max-w-6 max-h-6">
+                              <img src="@/assets/pending.png" alt="" />️
+                          </div>
+                      </div>
+                    </card-template>
                     <div class="">
-                        <img
-                            v-if="index%6===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%6 === 2"
-                            src="@/assets/hotAirBalloonSpare.gif"
-                            class="h-32 w-32 border-stale-400 border-2 rounded-lg"
-                            alt="could not load"
-                        />
-                        <img
-                            v-else-if="index %6===4"
-                            src="@/assets/farmerSpare.gif"
-                            alt="could not load"
-                            class="h-32 w-32 border-stale-400 border-2 rounded-lg"
-                        />
+                        <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 -->
@@ -209,6 +182,8 @@ import { useRouter } from 'vue-router'
 import { useGoalStore } from '@/stores/goalStore'
 import { useChallengeStore } from '@/stores/challengeStore'
 import DisplayInfoForChallengeOrGoal from "@/components/DisplayInfoForChallengeOrGoal.vue";
+import CardTemplate from "@/views/CardTemplate.vue";
+import ImgGifTemplate from "@/components/ImgGifTemplate.vue";
 
 const router = useRouter()
 const goalStore = useGoalStore()
diff --git a/src/components/__tests__/NavBarTest.spec.ts b/src/components/__tests__/NavBarTest.spec.ts
index b31870d5340b4f2fe9642c8b74116ced1360c96f..ea7c2814a609abe8a0e43501fa558e7f45f70dc5 100644
--- a/src/components/__tests__/NavBarTest.spec.ts
+++ b/src/components/__tests__/NavBarTest.spec.ts
@@ -2,7 +2,7 @@ import { mount, VueWrapper } from '@vue/test-utils'
 import NavBar from '@/components/NavBarComponent.vue'
 import router from '@/router'
 import { createPinia, setActivePinia } from 'pinia'
-import { describe, it, expect, beforeEach, vi } from 'vitest'
+import { beforeEach, describe, expect, it, vi } from 'vitest'
 
 vi.stubGlobal('scrollTo', vi.fn())
 
diff --git a/src/components/__tests__/savingsPathTest.spec.ts b/src/components/__tests__/savingsPathTest.spec.ts
index af21d03c1b80df3ae2e90e8b92bd8e1782df544f..dea8650e2ad5d6ced6b43bfd45ce7bc012319875 100644
--- a/src/components/__tests__/savingsPathTest.spec.ts
+++ b/src/components/__tests__/savingsPathTest.spec.ts
@@ -1,4 +1,4 @@
-import { describe, expect, it, beforeEach, vi } from 'vitest'
+import { beforeEach, describe, expect, it, vi } from 'vitest'
 import { mount } from '@vue/test-utils'
 import { createPinia, setActivePinia } from 'pinia'
 import SavingsPath from '@/components/SavingsPath.vue'
diff --git a/src/router/index.ts b/src/router/index.ts
index 4ae0e9a4990bd24573cd01d10768f46825ef4c14..5f32e18fa4bcb61cf7ad48446e11dea346712c49 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -33,6 +33,11 @@ const router = createRouter({
             name: 'profile',
             component: () => import('@/views/ProfileView.vue')
         },
+        {
+            path: '/profil/rediger',
+            name: 'edit-profile',
+            component: () => import('@/views/EditProfileView.vue')
+        },
         {
             path: '/sparemaal',
             name: 'goals',
@@ -98,6 +103,11 @@ const router = createRouter({
             name: 'configurations5',
             component: () => import('@/views/ConfigSpendingItemsTotalAmountView.vue')
         },
+        {
+            path: '/konfigurasjonSteg6',
+            name: 'configurations6',
+            component: () => import('@/views/ConfigAccountNumberView.vue')
+        },
         {
             path: '/forsteSparemaal',
             name: 'firstSavingGoal',
@@ -112,6 +122,11 @@ const router = createRouter({
             path: '/:pathMatch(.*)*',
             name: 'not-found',
             component: () => import('@/views/NotFoundView.vue')
+        },
+        {
+            path: '/addAlternativeLogin',
+            name: 'addAlternativeLogin',
+            component: () => import('@/views/AddAlternativeLogin.vue')
         }
     ],
     scrollBehavior() {
diff --git a/src/stores/accountStore.ts b/src/stores/accountStore.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b80263eafa362581f6c2e235d544456ad887274c
--- /dev/null
+++ b/src/stores/accountStore.ts
@@ -0,0 +1,35 @@
+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/userConfigStore.ts b/src/stores/userConfigStore.ts
index c2fa6032c4fdfaf6f3e130d465d9cb33dde3c256..6f1e0f1ccbe25f90f463aed9ef97ec9b63ac4319 100644
--- a/src/stores/userConfigStore.ts
+++ b/src/stores/userConfigStore.ts
@@ -1,6 +1,7 @@
 import { defineStore } from 'pinia'
+import { ref } from 'vue'
 import authInterceptor from '@/services/authInterceptor'
-import axios from 'axios'
+import { AxiosError } from 'axios'
 
 export const useUserConfigStore = defineStore('userConfig', {
     state: () => ({
@@ -11,7 +12,8 @@ export const useUserConfigStore = defineStore('userConfig', {
             type: string
             specificAmount: number
             generalAmount: number
-        }[]
+        }[],
+        errorMessage: ref<string>('')
     }),
     actions: {
         setExperience(value: string) {
@@ -23,23 +25,28 @@ export const useUserConfigStore = defineStore('userConfig', {
         addChallengeTypeConfig(type: string, specificAmount: number, generalAmount: number) {
             this.challengeTypeConfigs.push({ type, specificAmount, generalAmount })
         },
-        async postUserConfig() {
+        postUserConfig() {
             const payload = {
                 experience: this.experience,
                 motivation: this.motivation,
                 challengeTypeConfigs: Array.from(this.challengeTypeConfigs)
             }
 
-            try {
-                const response = await authInterceptor.post('/config/challenge', payload)
-                console.log('Success:', response.data)
-            } catch (error: unknown) {
-                if (axios.isAxiosError(error)) {
-                    console.error('Axios error:', error.response?.data || error.message)
-                } else {
-                    console.error('An unexpected error occurred:', error)
-                }
-            }
+            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)
+                })
         }
     }
 })
diff --git a/src/stores/userStore.ts b/src/stores/userStore.ts
index 39c91976750e0651ed3e61980fefc86e3a8d10aa..e441008fea5b04d234fca42a9c253a21ce2b1590 100644
--- a/src/stores/userStore.ts
+++ b/src/stores/userStore.ts
@@ -6,6 +6,9 @@ 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 type { CredentialCreationOptions } from '@/types/CredentialCreationOptions'
 
 export const useUserStore = defineStore('user', () => {
     const defaultUser: User = {
@@ -41,7 +44,7 @@ export const useUserStore = defineStore('user', () => {
                 user.value.lastname = lastname
                 user.value.username = username
 
-                router.push({ name: 'configurations1' })
+                router.push({ name: 'addAlternativeLogin' })
             })
             .catch((error) => {
                 const axiosError = error as AxiosError
@@ -94,10 +97,145 @@ export const useUserStore = defineStore('user', () => {
         }
     }
 
+    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
+                        )
+                    },
+                    excludeCredentials: credentialCreateJson.publicKey.excludeCredentials?.map(
+                        (credential) => ({
+                            ...credential,
+                            id: base64urlToUint8array(credential.id as unknown as string)
+                        })
+                    ),
+                    extensions: credentialCreateJson.publicKey.extensions
+                }
+            }
+
+            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' })
+                })
+        } catch (error) {
+            router.push({ name: 'configurations1' })
+            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 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/katanta1', {
+                    credential: JSON.stringify(encodedResult)
+                })
+                .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' })
+                })
+                .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)
+        }
+    }
+
     return {
         register,
         login,
         logout,
+        bioLogin,
+        bioRegister,
         errorMessage,
         getUserStreak,
         streak,
diff --git a/src/types/CredentialCreationOptions.ts b/src/types/CredentialCreationOptions.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b6fdd7a76510ca4033a1c763a2ca9545797ab1b5
--- /dev/null
+++ b/src/types/CredentialCreationOptions.ts
@@ -0,0 +1,3 @@
+export interface CredentialCreationOptions {
+    publicKey: PublicKeyCredentialCreationOptions
+}
diff --git a/src/types/CredentialRequestOptions.ts b/src/types/CredentialRequestOptions.ts
new file mode 100644
index 0000000000000000000000000000000000000000..4349a83cdfde9e60fe294adeef87dd4f1792087c
--- /dev/null
+++ b/src/types/CredentialRequestOptions.ts
@@ -0,0 +1,3 @@
+export interface CredentialRequestOptions {
+    publicKey: PublicKeyCredentialRequestOptions
+}
diff --git a/src/types/profile.ts b/src/types/profile.ts
new file mode 100644
index 0000000000000000000000000000000000000000..392aee69615beff857dc324e85cc4f77ea1f7911
--- /dev/null
+++ b/src/types/profile.ts
@@ -0,0 +1,19 @@
+export interface Profile {
+    id: number
+    firstName: string
+    lastName: string
+    email: string
+    username: string
+    password?: string
+    spendingAccount: {
+        accNumber?: number
+        accountType?: string
+        balance?: number
+    }
+    savingAccount: {
+        accNumber?: number
+        accountType?: string
+        balance?: number
+    }
+    badges?: object[]
+}
diff --git a/src/util.ts b/src/util.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7f6cbfc818ab356135d6acf232024019ea4fafe0
--- /dev/null
+++ b/src/util.ts
@@ -0,0 +1,33 @@
+import base64js from 'base64-js'
+import { type AxiosResponse } from 'axios'
+
+export function base64urlToUint8array(base64Bytes: string): Uint8Array {
+    const padding = '===='.substring(0, (4 - (base64Bytes.length % 4)) % 4)
+    return base64js.toByteArray((base64Bytes + padding).replace(/\//g, '_').replace(/\+/g, '-'))
+}
+
+export function uint8arrayToBase64url(bytes: Uint8Array | ArrayBuffer | number[]): string {
+    if (bytes instanceof Uint8Array) {
+        return base64js
+            .fromByteArray(bytes)
+            .replace(/\+/g, '-')
+            .replace(/\//g, '_')
+            .replace(/=/g, '')
+    } else {
+        return uint8arrayToBase64url(new Uint8Array(bytes))
+    }
+}
+
+export function checkStatus(response: AxiosResponse<any>): AxiosResponse<any> | undefined {
+    if (response.status !== 200) {
+        console.log('an error occurred: ', response.statusText)
+        return undefined
+    } else {
+        return response
+    }
+}
+
+export function initialCheckStatus(response: AxiosResponse<any>): any {
+    checkStatus(response)
+    return response.data
+}
diff --git a/src/utilo.js b/src/utilo.js
new file mode 100644
index 0000000000000000000000000000000000000000..4125c85af520a7d429032a90f80c9a4611f07740
--- /dev/null
+++ b/src/utilo.js
@@ -0,0 +1,28 @@
+import base64js from 'base64-js'
+
+export function base64urlToUint8array(base64Bytes) {
+    const padding = '===='.substring(0, (4 - (base64Bytes.length % 4)) % 4)
+    return base64js.toByteArray((base64Bytes + padding).replace(/\//g, '_').replace(/\+/g, '-'))
+}
+export function uint8arrayToBase64url(bytes) {
+    if (bytes instanceof Uint8Array) {
+        return base64js
+            .fromByteArray(bytes)
+            .replace(/\+/g, '-')
+            .replace(/\//g, '_')
+            .replace(/=/g, '')
+    } else {
+        return uint8arrayToBase64url(new Uint8Array(bytes))
+    }
+}
+export function checkStatus(response) {
+    if (response.status !== 200) {
+        console.log('an error occurred: ', response.body)
+    } else {
+        return response
+    }
+}
+export function initialCheckStatus(response) {
+    checkStatus(response)
+    return response.data
+}
diff --git a/src/views/AddAlternativeLogin.vue b/src/views/AddAlternativeLogin.vue
new file mode 100644
index 0000000000000000000000000000000000000000..554f09f25915282f5675244784a6bb212457d036
--- /dev/null
+++ b/src/views/AddAlternativeLogin.vue
@@ -0,0 +1,48 @@
+<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/CardTemplate.vue b/src/views/CardTemplate.vue
new file mode 100644
index 0000000000000000000000000000000000000000..6fa731e67776d9e923ea99427b9a23893f3de385
--- /dev/null
+++ b/src/views/CardTemplate.vue
@@ -0,0 +1,9 @@
+<script lang="ts" setup></script>
+
+<template>
+    <div class="border rounded-xl shadow-lg overflow-hidden">
+        <slot></slot>
+    </div>
+</template>
+
+<style scoped></style>
diff --git a/src/views/ConfigAccountNumberView.vue b/src/views/ConfigAccountNumberView.vue
new file mode 100644
index 0000000000000000000000000000000000000000..652cf0d11ba68e92f47d8b6e14171faa565cf321
--- /dev/null
+++ b/src/views/ConfigAccountNumberView.vue
@@ -0,0 +1,114 @@
+<template>
+    <div
+        class="flex flex-col items-center justify-center min-h-screen md:pt-10 pt-4 pb-24 text-center"
+    >
+        <h1 class="mb-8 lg:mb-12 text-4xl font-bold">
+            Legg til kontonummer for sparekonto og brukskonto
+        </h1>
+        <div
+            class="flex flex-col items-center justify-center bg-white rounded-lg p-8 shadow-lg w-full md:w-[45%]"
+        >
+            <div class="w-full mb-4">
+                <label for="savingsAccount" class="block text-lg font-bold mb-2">Sparekonto</label>
+                <input
+                    id="savingsAccount"
+                    v-model="savingsAccount"
+                    @input="restrictToNumbers($event as InputEvent, 'savings')"
+                    @focus="removeFormatting('savings')"
+                    @blur="applyFormatting('savings')"
+                    class="w-full h-11 px-3 rounded-md text-xl focus:outline-none transition-colors border-2 border-gray-300"
+                    type="text"
+                    placeholder="Skriv inn ditt kontonummer..."
+                />
+            </div>
+            <div class="w-full mb-4">
+                <label for="spendingAccount" class="block text-lg font-bold mb-2">Brukskonto</label>
+                <input
+                    id="spendingAccount"
+                    v-model="spendingAccount"
+                    @input="restrictToNumbers($event as InputEvent, 'spending')"
+                    @focus="removeFormatting('spending')"
+                    @blur="applyFormatting('spending')"
+                    class="w-full h-11 px-3 rounded-md text-xl focus:outline-none transition-colors border-2 border-gray-300"
+                    type="text"
+                    placeholder="Skriv inn ditt kontonummer..."
+                />
+            </div>
+        </div>
+        <div class="absolute bottom-36 right-2">
+            <ContinueButtonComponent
+                @click="onButtonClick"
+                :disabled="!isFormValid"
+                class="px-10 py-3 text-2xl font-bold mb-4 mr-2"
+            ></ContinueButtonComponent>
+        </div>
+    </div>
+</template>
+
+<script setup lang="ts">
+import { computed, ref } from 'vue'
+import { useAccountStore } from '@/stores/accountStore'
+import ContinueButtonComponent from '@/components/ContinueButtonComponent.vue'
+import router from '@/router'
+
+const MAX_DIGITS = 11
+const accountStore = useAccountStore()
+
+const spendingAccount = ref('')
+const savingsAccount = ref('')
+
+const isFormValid = computed(() => {
+    return (
+        spendingAccount.value.replace(/\./g, '').length === MAX_DIGITS &&
+        savingsAccount.value.replace(/\./g, '').length === MAX_DIGITS
+    )
+})
+
+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 router.push({ name: 'home' })
+}
+
+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') {
+            spendingAccount.value = truncatedValue
+        } else {
+            savingsAccount.value = truncatedValue
+        }
+    }
+}
+
+function applyFormatting(type: string) {
+    if (type === 'spending') {
+        spendingAccount.value = formatAccount(spendingAccount.value)
+    } else {
+        savingsAccount.value = formatAccount(savingsAccount.value)
+    }
+}
+
+function removeFormatting(type: string) {
+    if (type === 'spending') {
+        spendingAccount.value = removeFormat(spendingAccount.value)
+    } else {
+        savingsAccount.value = removeFormat(savingsAccount.value)
+    }
+}
+
+function formatAccount(value: string): string {
+    return value.replace(/\D/g, '').replace(/^(.{4})(.{2})(.*)$/, '$1.$2.$3')
+}
+
+function removeFormat(value: string): string {
+    return value.replace(/\./g, '')
+}
+</script>
diff --git a/src/views/ConfigFamiliarWithSavingsView.vue b/src/views/ConfigFamiliarWithSavingsView.vue
index 3b3c8a4d1c6b6143ce1100e1e850a97a82e27988..ecbd66aa41acbc1aa29f2fd9405ec17cb0c00213 100644
--- a/src/views/ConfigFamiliarWithSavingsView.vue
+++ b/src/views/ConfigFamiliarWithSavingsView.vue
@@ -1,7 +1,9 @@
 <template>
     <div class="flex flex-col items-center justify-center min-h-screen px-4 text-center">
-        <h1 class="mb-16 text-4xl font-bold lg:mb-20">Hvor kjent er du med sparing fra før?</h1>
-        <div class="grid grid-cols-1 gap-14 mb-20 md:grid-cols-3">
+        <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="grid grid-cols-1 gap-8 mb-16 sm:gap-14 sm:mb-20 md:grid-cols-3">
             <div
                 :class="{
                     'border-[var(--green)] border-4': selectedOption === 'litt',
@@ -39,7 +41,7 @@
         <ContinueButtonComponent
             :disabled="selectedOption === null"
             @click="onButtonClick"
-            class="px-10 py-3 text-2xl self-end mb-4 mt-0"
+            class="px-10 py-3 text-2xl self-end"
         ></ContinueButtonComponent>
     </div>
 </template>
@@ -67,8 +69,6 @@ const selectOption = (option: string) => {
         case 'godt':
             experienceValue = 'VERY_HIGH'
             break
-        default:
-            experienceValue = 'VERY_LOW'
     }
 
     userConfigStore.setExperience(experienceValue)
@@ -76,7 +76,7 @@ const selectOption = (option: string) => {
 
 const onButtonClick = () => {
     if (selectedOption.value) {
-        router.push('/konfigurasjonSteg3')
+        router.push({ name: 'configurations3' })
     } else {
         console.error('No option selected')
     }
diff --git a/src/views/ConfigHabitChangeView.vue b/src/views/ConfigHabitChangeView.vue
index c686e26112e56a2d298e5e80d5cb59f0b8736f83..a1e8b37350d385d2c3f31db77f2b8c81b56b6e41 100644
--- a/src/views/ConfigHabitChangeView.vue
+++ b/src/views/ConfigHabitChangeView.vue
@@ -69,8 +69,6 @@ const selectOption = (option: string) => {
         case 'store':
             motivationValue = 'VERY_HIGH'
             break
-        default:
-            motivationValue = 'VERY_LOW'
     }
 
     userConfigStore.setMotivation(motivationValue)
@@ -78,7 +76,7 @@ const selectOption = (option: string) => {
 
 const onButtonClick = () => {
     if (selectedOption.value) {
-        router.push('/konfigurasjonSteg2')
+        router.push({ name: 'configurations2' })
     } else {
         console.error('No option selected')
     }
diff --git a/src/views/ConfigSpendingItemsAmountView.vue b/src/views/ConfigSpendingItemsAmountView.vue
index 625bf5335a0e50a61c1db4cb2a388d954430a73e..aa77feb1371de00b5a70dfe7815dd86e77f939c5 100644
--- a/src/views/ConfigSpendingItemsAmountView.vue
+++ b/src/views/ConfigSpendingItemsAmountView.vue
@@ -1,59 +1,74 @@
 <template>
     <div class="flex flex-col items-center justify-center min-h-screen px-4 text-center relative">
-        <h1 class="mb-8 lg:mb-12 text-4xl font-bold">Hvor mye bruker du per kjøp på ...</h1>
-        <div class="grid grid-cols-1 md:grid-cols-2 gap-8 mb-6">
-            <div class="flex flex-col items-center bg-white rounded-lg p-8 shadow-lg w-full">
+        <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="w-full flex justify-center">
+            <div :class="[showSecondBox ? 'md:grid md:grid-cols-2 md:gap-4 sm:gap-8 mb-6' : '']">
                 <div
-                    v-for="(option, index) in options.slice(0, 6)"
-                    :key="`option-${index}`"
-                    class="w-full my-4"
+                    v-if="showFirstBox"
+                    class="flex flex-col items-center bg-white rounded-lg p-4 sm:p-8 shadow-lg"
+                    :class="showSecondBox ? 'w-full' : 'w-full md:w-1/2 mx-auto'"
+                    :style="{ minWidth: '400px', maxWidth: '400px' }"
                 >
-                    <div class="flex justify-between items-center">
-                        <p class="text-xl font-bold mr-4">{{ option.type }}</p>
-                        <div class="flex items-center w-2/3">
-                            <input
-                                v-model="amounts[index]"
-                                @input="filterAmount(index, $event)"
-                                class="h-11 px-3 rounded-md text-lg focus:outline-none border-2 w-full"
-                                :class="{
-                                    'border-gray-300': !amounts[index],
-                                    'border-[var(--green)]': amounts[index]
-                                }"
-                            />
-                            <p class="text-xl font-bold ml-2">kr</p>
+                    <div
+                        v-for="(option, index) in firstBoxOptions"
+                        :key="`first-option-${index}`"
+                        class="w-full my-4"
+                    >
+                        <div class="flex justify-between items-center">
+                            <p class="text-xl font-bold mr-4">{{ option.type }}</p>
+                            <div class="flex items-center w-2/3">
+                                <input
+                                    v-model="amounts[index]"
+                                    @input="filterAmount(index, $event)"
+                                    class="h-11 px-3 rounded-md text-lg focus:outline-none border-2 w-full"
+                                    :class="{
+                                        'border-gray-300': !amounts[index],
+                                        'border-[var(--green)]': amounts[index]
+                                    }"
+                                />
+                                <p class="text-xl font-bold ml-2">kr</p>
+                            </div>
                         </div>
                     </div>
                 </div>
-            </div>
-            <div class="flex flex-col items-center bg-white rounded-lg p-8 shadow-lg w-full">
                 <div
-                    v-for="(option, index) in options.slice(6, 12)"
-                    :key="`option-${index}`"
-                    class="w-full my-4"
+                    v-if="showSecondBox"
+                    class="flex flex-col items-center bg-white rounded-lg p-4 sm:p-8 shadow-lg"
+                    :class="showSecondBox ? 'w-full' : 'w-full md:w-1/2 mx-auto'"
+                    :style="{ minWidth: '400px', maxWidth: '400px' }"
                 >
-                    <div class="flex justify-between items-center">
-                        <p class="text-xl font-bold mr-4">{{ option.type }}</p>
-                        <div class="flex items-center w-2/3">
-                            <input
-                                v-model="amounts[index + 6]"
-                                @input="filterAmount(index + 6, $event)"
-                                class="h-11 px-3 rounded-md text-lg focus:outline-none border-2 w-full"
-                                :class="{
-                                    'border-gray-300': !amounts[index + 6],
-                                    'border-[var(--green)]': amounts[index + 6]
-                                }"
-                            />
-                            <p class="text-xl font-bold ml-2">kr</p>
+                    <div
+                        v-for="(option, index) in secondBoxOptions"
+                        :key="`second-option-${index}`"
+                        class="w-full my-4"
+                    >
+                        <div class="flex justify-between items-center">
+                            <p class="text-xl font-bold mr-4">{{ option.type }}</p>
+                            <div class="flex items-center w-2/3">
+                                <input
+                                    v-model="amounts[index + firstBoxOptions.length]"
+                                    @input="filterAmount(index + firstBoxOptions.length, $event)"
+                                    class="h-11 px-3 rounded-md text-lg focus:outline-none border-2 w-full"
+                                    :class="{
+                                        'border-gray-300': !amounts[index + firstBoxOptions.length],
+                                        'border-[var(--green)]':
+                                            amounts[index + firstBoxOptions.length]
+                                    }"
+                                />
+                                <p class="text-xl font-bold ml-2">kr</p>
+                            </div>
                         </div>
                     </div>
                 </div>
             </div>
         </div>
-        <div class="absolute bottom-36 right-4">
+        <div class="w-full text-right">
             <ContinueButtonComponent
                 @click="onButtonClick"
                 :disabled="!isAllAmountsFilled"
-                class="px-10 py-3 text-2xl font-bold mb-4"
+                class="px-10 py-3 text-2xl font-bold mb-20 mt-10 sm:mb-12 sm:mt-10"
             ></ContinueButtonComponent>
         </div>
     </div>
@@ -77,7 +92,7 @@ const onButtonClick = () => {
         userConfigStore.challengeTypeConfigs[index].specificAmount =
             parseFloat(amounts.value[index]) || 0
     })
-    router.push('/konfigurasjonSteg5')
+    router.push({ name: 'configurations5' })
 }
 
 const filterAmount = (index: number, event: Event) => {
@@ -86,4 +101,10 @@ const filterAmount = (index: number, event: Event) => {
     filteredValue = filteredValue.replace(/(,.*?),/g, '$1').replace(/,+/g, ',')
     amounts.value[index] = filteredValue
 }
+
+const firstBoxOptions = computed(() => options.value.slice(0, 6))
+const secondBoxOptions = computed(() => (options.value.length > 6 ? options.value.slice(6) : []))
+
+const showFirstBox = computed(() => options.value.length > 0)
+const showSecondBox = computed(() => options.value.length > 6)
 </script>
diff --git a/src/views/ConfigSpendingItemsTotalAmountView.vue b/src/views/ConfigSpendingItemsTotalAmountView.vue
index d24cb4f6c652780a935a810a34c0ef3b489a2588..098ba86faec729bcbc8450ad91268d7e65d82536 100644
--- a/src/views/ConfigSpendingItemsTotalAmountView.vue
+++ b/src/views/ConfigSpendingItemsTotalAmountView.vue
@@ -1,61 +1,74 @@
 <template>
-    <div class="flex flex-col items-center justify-center min-h-screen px-4 text-center">
-        <h1 class="mb-8 lg:mb-12 text-4xl font-bold">Hvor mye bruker du totalt per uke på ...</h1>
-        <div class="grid grid-cols-1 md:grid-cols-2 gap-8 mb-6">
-            <div class="flex flex-col items-center bg-white rounded-lg p-8 shadow-lg w-full">
+    <div class="flex flex-col items-center justify-center min-h-screen px-4 text-center relative">
+        <h1 class="mb-8 text-2xl font-bold sm:mb-16 sm:text-4xl">
+            Hvor mye bruker du per uke på ...
+        </h1>
+        <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
-                    v-for="(option, index) in options.slice(0, 6)"
-                    :key="`option-${index}`"
-                    class="w-full my-4"
+                    v-if="showFirstBox"
+                    class="flex flex-col items-center bg-white rounded-lg p-4 sm:p-8 shadow-lg"
+                    :class="showSecondBox ? 'w-full' : 'w-full md:w-1/2 mx-auto'"
+                    :style="{ minWidth: '400px', maxWidth: '400px' }"
                 >
-                    <div class="flex justify-between items-center">
-                        <p class="text-xl font-bold mr-4">{{ option.type }}</p>
-                        <div class="flex items-center w-2/3">
-                            <input
-                                type="text"
-                                v-model="amounts[index]"
-                                @input="($event) => filterAmount(index, $event)"
-                                class="h-11 px-3 rounded-md text-lg focus:outline-none border-2 w-full"
-                                :class="{
-                                    'border-gray-300': !amounts[index],
-                                    'border-[var(--green)]': amounts[index]
-                                }"
-                            />
-                            <p class="text-xl font-bold ml-2">kr</p>
+                    <div
+                        v-for="(option, index) in firstBoxOptions"
+                        :key="`first-option-${index}`"
+                        class="w-full my-4"
+                    >
+                        <div class="flex justify-between items-center">
+                            <p class="text-xl font-bold mr-4">{{ option.type }}</p>
+                            <div class="flex items-center w-2/3">
+                                <input
+                                    v-model="amounts[index]"
+                                    @input="filterAmount(index, $event)"
+                                    class="h-11 px-3 rounded-md text-lg focus:outline-none border-2 w-full"
+                                    :class="{
+                                        'border-gray-300': !amounts[index],
+                                        'border-[var(--green)]': amounts[index]
+                                    }"
+                                />
+                                <p class="text-xl font-bold ml-2">kr</p>
+                            </div>
                         </div>
                     </div>
                 </div>
-            </div>
-            <div class="flex flex-col items-center bg-white rounded-lg p-8 shadow-lg w-full">
                 <div
-                    v-for="(option, index) in options.slice(6, 12)"
-                    :key="`option-${index}`"
-                    class="w-full my-4"
+                    v-if="showSecondBox"
+                    class="flex flex-col items-center bg-white rounded-lg p-4 sm:p-8 shadow-lg"
+                    :class="showSecondBox ? 'w-full' : 'w-full md:w-1/2 mx-auto'"
+                    :style="{ minWidth: '400px', maxWidth: '400px' }"
                 >
-                    <div class="flex justify-between items-center">
-                        <p class="text-xl font-bold mr-4">{{ option.type }}</p>
-                        <div class="flex items-center w-2/3">
-                            <input
-                                type="text"
-                                v-model="amounts[index + 6]"
-                                @input="($event) => filterAmount(index + 6, $event)"
-                                class="h-11 px-3 rounded-md text-lg focus:outline-none border-2 w-full"
-                                :class="{
-                                    'border-gray-300': !amounts[index + 6],
-                                    'border-[var(--green)]': amounts[index + 6]
-                                }"
-                            />
-                            <p class="text-xl font-bold ml-2">kr</p>
+                    <div
+                        v-for="(option, index) in secondBoxOptions"
+                        :key="`second-option-${index}`"
+                        class="w-full my-4"
+                    >
+                        <div class="flex justify-between items-center">
+                            <p class="text-xl font-bold mr-4">{{ option.type }}</p>
+                            <div class="flex items-center w-2/3">
+                                <input
+                                    v-model="amounts[index + firstBoxOptions.length]"
+                                    @input="filterAmount(index + firstBoxOptions.length, $event)"
+                                    class="h-11 px-3 rounded-md text-lg focus:outline-none border-2 w-full"
+                                    :class="{
+                                        'border-gray-300': !amounts[index + firstBoxOptions.length],
+                                        'border-[var(--green)]':
+                                            amounts[index + firstBoxOptions.length]
+                                    }"
+                                />
+                                <p class="text-xl font-bold ml-2">kr</p>
+                            </div>
                         </div>
                     </div>
                 </div>
             </div>
         </div>
-        <div class="absolute bottom-24 right-4">
+        <div class="w-full text-right">
             <ContinueButtonComponent
                 @click="onButtonClick"
                 :disabled="!isAllAmountsFilled"
-                class="px-10 py-3 text-2xl font-bold mb-4"
+                class="px-10 py-3 text-2xl font-bold mb-20 mt-10 sm:mb-12 sm:mt-10"
             ></ContinueButtonComponent>
         </div>
     </div>
@@ -80,8 +93,8 @@ const onButtonClick = async () => {
             parseFloat(amounts.value[index]) || 0
     })
 
-    await userConfigStore.postUserConfig()
-    router.push('/hjem')
+    userConfigStore.postUserConfig()
+    await router.push({ name: 'configurations6' })
 }
 
 const filterAmount = (index: number, event: Event) => {
@@ -90,4 +103,10 @@ const filterAmount = (index: number, event: Event) => {
     filteredValue = filteredValue.replace(/(,.*?),/g, '$1').replace(/,+/g, ',')
     amounts.value[index] = filteredValue
 }
+
+const firstBoxOptions = computed(() => options.value.slice(0, 6))
+const secondBoxOptions = computed(() => (options.value.length > 6 ? options.value.slice(6) : []))
+
+const showFirstBox = computed(() => options.value.length > 0)
+const showSecondBox = computed(() => options.value.length > 6)
 </script>
diff --git a/src/views/ConfigSpendingItemsView.vue b/src/views/ConfigSpendingItemsView.vue
index 2226cb066b6cc1ed6a880672f6f3223bd33bbb5d..fbeda5f09011b4a3f8639d752c02eab917c32e14 100644
--- a/src/views/ConfigSpendingItemsView.vue
+++ b/src/views/ConfigSpendingItemsView.vue
@@ -1,9 +1,9 @@
 <template>
     <div class="flex flex-col items-center justify-center min-h-screen text-center">
-        <h1 class="mb-8 lg:mb-12 text-4xl font-bold">Hva bruker du mye penger på?</h1>
+        <h1 class="mb-8 text-2xl font-bold sm:mb-16 sm:text-4xl">Hva bruker du mye penger på?</h1>
         <div class="flex flex-wrap justify-center gap-8 mb-8">
             <div
-                class="flex flex-col items-center justify-center bg-white rounded-lg p-8 shadow-lg w-full md:w-[45%]"
+                class="flex flex-col items-center justify-center bg-white rounded-lg sm:p-8 shadow-lg sm:w-full md:w-[45%]"
             >
                 <div
                     v-for="buttonText in [
@@ -32,7 +32,7 @@
                 </div>
             </div>
             <div
-                class="flex flex-col items-center justify-center bg-white rounded-lg p-8 shadow-lg w-full md:w-[45%]"
+                class="flex flex-col items-center justify-center bg-white rounded-lg sm:p-8 shadow-lg sm:w-full md:w-[45%]"
             >
                 <div
                     v-for="(option, index) in customOptions"
@@ -41,18 +41,23 @@
                 >
                     <input
                         v-model="customOptions[index]"
-                        class="w-full md:w-64 h-11 px-3 rounded-md text-xl focus:outline-none transition-colors border-2 border-gray-300"
+                        :class="[
+                            'w-full md:w-64 h-11 px-3 rounded-md text-xl focus:outline-none transition-colors border-2',
+                            customOptions[index].trim() !== ''
+                                ? 'border-[var(--green)]'
+                                : 'border-gray-300'
+                        ]"
                         type="text"
                         :placeholder="'Annet ' + ' ...'"
                     />
                 </div>
             </div>
         </div>
-        <div class="w-full text-right mb-0 mt-0" style="position: relative; top: -92px; right: 8px">
+        <div class="w-full text-right">
             <ContinueButtonComponent
                 @click="onButtonClick"
                 :disabled="!isFormValid"
-                class="px-10 py-3 text-2xl font-bold mb-4 mr-2"
+                class="px-10 py-3 text-2xl font-bold mt-36 mr-4 sm:mb-12 sm:mt-10"
             ></ContinueButtonComponent>
         </div>
     </div>
@@ -68,24 +73,27 @@ const userConfigStore = useUserConfigStore()
 const selectedOptions = ref<string[]>([])
 const customOptions = ref(['', '', '', '', '', ''])
 
-const toggleOption = (option: string, isCustom: boolean = false) => {
-    if (!isCustom) {
-        const index = selectedOptions.value.indexOf(option)
-        if (index === -1) {
-            selectedOptions.value.push(option)
-        } else {
-            selectedOptions.value.splice(index, 1)
-        }
+const toggleOption = (option: string) => {
+    const index = selectedOptions.value.indexOf(option)
+    if (index === -1) {
+        selectedOptions.value.push(option)
+    } else {
+        selectedOptions.value.splice(index, 1)
     }
 }
 
 const isFormValid = computed(() => {
     const predefinedSelected = selectedOptions.value.length > 0
     const customFilled = customOptions.value.some((option) => option.trim() !== '')
-    return predefinedSelected || (customFilled && predefinedSelected)
+    return predefinedSelected || customFilled
 })
 
 const onButtonClick = () => {
+    if (!isFormValid.value) {
+        console.error('Form is not valid')
+        return
+    }
+
     const predefinedChallengeTypes = selectedOptions.value.map((option) => ({
         type: option,
         specificAmount: 0,
@@ -101,7 +109,6 @@ const onButtonClick = () => {
         }))
 
     userConfigStore.challengeTypeConfigs = [...predefinedChallengeTypes, ...customChallengeTypes]
-    console.log('Selected Challenge Types:', userConfigStore.challengeTypeConfigs)
-    router.push('/konfigurasjonSteg4')
+    router.push({ name: 'configurations4' })
 }
 </script>
diff --git a/src/views/EditProfileView.vue b/src/views/EditProfileView.vue
new file mode 100644
index 0000000000000000000000000000000000000000..82da35481c774c789baffd3264b4a36cbbe45614
--- /dev/null
+++ b/src/views/EditProfileView.vue
@@ -0,0 +1,254 @@
+<script lang="ts" setup>
+import authInterceptor from '@/services/authInterceptor'
+import { computed, onMounted, ref } from 'vue'
+import type { Profile } from '@/types/profile'
+import CardTemplate from '@/views/CardTemplate.vue'
+import router from '@/router'
+import ToolTip from '@/components/ToolTip.vue'
+import InteractiveSpare from '@/components/InteractiveSpare.vue'
+
+const profile = ref<Profile>({
+    id: 0,
+    firstName: '',
+    lastName: '',
+    email: '',
+    username: '',
+    password: '',
+    spendingAccount: {
+        accNumber: undefined,
+        balance: 0
+    },
+    savingAccount: {
+        accNumber: undefined,
+        balance: 0
+    }
+})
+
+const updatePassword = ref<boolean>(false)
+const confirmPassword = ref<string>('')
+const errorMessage = ref<string>('')
+
+const nameRegex = /^[æÆøØåÅa-zA-Z,.'-][æÆøØåÅa-zA-Z ,.'-]{1,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 isFirstNameValid = computed(
+    () => nameRegex.test(profile.value.firstName) && profile.value.firstName
+)
+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() || '')
+)
+const isSavingAccountValid = computed(() =>
+    accountNumberRegex.test(profile.value.savingAccount.accNumber?.toString() || '')
+)
+
+const isFormInvalid = computed(
+    () =>
+        [
+            isFirstNameValid,
+            isLastNameValid,
+            isEmailValid,
+            isUsernameValid,
+            isSpendingAccountValid,
+            isSavingAccountValid
+        ].some((v) => !v.value) ||
+        (updatePassword.value
+            ? profile.value.password !== confirmPassword.value || profile.value.password === ''
+            : false)
+)
+
+onMounted(async () => {
+    await authInterceptor('/profile')
+        .then((response) => {
+            profile.value = response.data
+            console.log(profile.value)
+        })
+        .catch((error) => {
+            return console.log(error)
+        })
+})
+
+const saveChanges = async () => {
+    if (isFormInvalid.value) {
+        errorMessage.value = 'Vennligst fyll ut alle feltene riktig'
+        return
+    }
+
+    if (!updatePassword.value) {
+        delete profile.value.password
+    }
+
+    await authInterceptor
+        .put('/profile', profile.value)
+        .then(() => {
+            router.back()
+        })
+        .catch((error) => {
+            errorMessage.value = error.response.data.message
+        })
+}
+</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>Rediger profil</h1>
+                <div class="w-full flex flex-row gap-5 justify-between justify-items-end">
+                    <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-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>
+                </div>
+
+                <div class="flex flex-col">
+                    <div class="flex flex-row justify-between mx-4">
+                        <p>Fornavn*</p>
+                        <ToolTip
+                            :message="'Must include only letters, spaces, commas, apostrophes, periods, and hyphens. 1-30 characters long'"
+                        />
+                    </div>
+                    <input
+                        v-model="profile.firstName"
+                        :class="{ 'bg-green-200': isFirstNameValid }"
+                        name="firstname"
+                        placeholder="Skriv inn fornavn"
+                        type="text"
+                    />
+                </div>
+                <div class="flex flex-col">
+                    <div class="flex flex-row justify-between mx-4">
+                        <p>Etternavn*</p>
+                        <ToolTip
+                            :message="'Must include only letters, spaces, commas, apostrophes, periods, and hyphens. 1-30 characters long'"
+                        />
+                    </div>
+                    <input
+                        v-model="profile.lastName"
+                        :class="{ 'bg-green-200': isLastNameValid }"
+                        name="lastname"
+                        placeholder="Skriv inn etternavn"
+                        type="text"
+                    />
+                </div>
+                <div class="flex flex-col">
+                    <div class="flex flex-row justify-between mx-4">
+                        <p>E-post*</p>
+                        <ToolTip
+                            :message="'Valid email: Starts with Norwegian letters, numbers, or special characters. Includes \@\ followed by a domain. Ends with 2-7 letters.'"
+                        />
+                    </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"
+                        :class="{ 'bg-green-200': isUsernameValid }"
+                        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">
+                            <p>Endre passord</p>
+                            <input v-model="updatePassword" type="checkbox" />
+                        </div>
+                        <ToolTip
+                            v-if="updatePassword"
+                            :message="'Must be at least 8 characters, including at least one number, one lowercase letter, one uppercase letter, one special character (@#$%^&+=!), and no spaces.'"
+                        />
+                    </div>
+                    <input
+                        v-if="updatePassword"
+                        v-model="profile.password"
+                        :class="{ 'bg-green-200': isPasswordValid }"
+                        class="w-full"
+                        name="password"
+                        placeholder="Skriv inn passord"
+                    />
+                    <input
+                        v-if="updatePassword"
+                        v-model="confirmPassword"
+                        :class="{ 'bg-red-200': profile.password !== confirmPassword }"
+                        class="mt-2"
+                        name="confirm"
+                        placeholder="Bekreft passord"
+                        type="password"
+                    />
+                </div>
+
+                <p v-if="errorMessage" class="text-red-500" v-text="errorMessage" />
+            </div>
+            <div class="flex flex-col justify-end max-w-96 w-full gap-5">
+                <InteractiveSpare
+                    :png-size="10"
+                    :speech="['Her kan du endre på profilen din!']"
+                    direction="left"
+                />
+
+                <CardTemplate>
+                    <div class="bg-red-300">
+                        <p class="font-bold mx-3" v-text="'Brukskonto'" />
+                    </div>
+                    <input
+                        v-model="profile.spendingAccount.accNumber"
+                        :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-300">
+                        <p class="font-bold mx-3" v-text="'Sparekonto'" />
+                    </div>
+                    <input
+                        v-model="profile.savingAccount.accNumber"
+                        :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="bg-button-other" @click="router.back()" v-text="'Avbryt'" />
+                    <button
+                        :disabled="isFormInvalid"
+                        @click="saveChanges"
+                        v-text="'Lagre endringer'"
+                    />
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<style scoped></style>
diff --git a/src/views/ProfileView.vue b/src/views/ProfileView.vue
index 255824275b207f62108888007491f385b3b8e1d2..436e522c7c815ad6cb5725724b76a8f76779d75d 100644
--- a/src/views/ProfileView.vue
+++ b/src/views/ProfileView.vue
@@ -1,21 +1,115 @@
 <script lang="ts" setup>
 import authInterceptor from '@/services/authInterceptor'
-import { onMounted } from 'vue'
+import { computed, onMounted, ref } from 'vue'
+import type { Profile } from '@/types/profile'
+import CardTemplate from '@/views/CardTemplate.vue'
+import InteractiveSpare from '@/components/InteractiveSpare.vue'
+import type { Challenge } from '@/types/challenge'
+import type { Goal } from '@/types/goal'
+import CardGoal from '@/components/CardGoal.vue'
+import router from '@/router'
+
+const profile = ref<Profile>()
+const completedGoals = ref<Goal[]>([])
+const completedChallenges = ref<Challenge[]>([])
 
 onMounted(async () => {
-    await authInterceptor
-        .get('/config')
+    await authInterceptor('/profile')
+        .then((response) => {
+            profile.value = response.data
+            console.log(profile.value)
+        })
+        .catch((error) => {
+            return console.log(error)
+        })
+
+    await authInterceptor(`/goals/completed?page=0&size=3`)
         .then((response) => {
-            console.log(response.data)
+            completedGoals.value = response.data.content
         })
         .catch((error) => {
-            console.log(error)
+            return console.log(error)
         })
+
+    await authInterceptor('/challenges/completed?page=0&size=3')
+        .then((response) => {
+            completedChallenges.value = response.data.content
+        })
+        .catch((error) => {
+            return console.log(error)
+        })
+})
+
+const welcome = computed(() => {
+    return [`Velkommen, ${profile.value?.firstName} ${profile.value?.lastName} !`]
 })
 </script>
 
 <template>
-    <h1>Din profil</h1>
+    <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>Profile</h1>
+                <div class="flex flex-row gap-5">
+                    <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">
+                            {{ profile?.firstName + ' ' + profile?.lastName }}
+                        </h3>
+                        <h3 class="font-thin my-0">{{ profile?.email }}</h3>
+                    </div>
+                </div>
+
+                <h3 class="font-bold" v-text="'Du har spart ' + '< totalSaved >' + 'kr'" />
+
+                <CardTemplate>
+                    <div class="bg-red-300">
+                        <p class="font-bold mx-3" v-text="'Brukskonto'" />
+                    </div>
+                    <p
+                        class="mx-3"
+                        v-text="profile?.spendingAccount.accNumber || 'Ingen brukskonto oppkoblet'"
+                    />
+                </CardTemplate>
+
+                <CardTemplate>
+                    <div class="bg-red-300">
+                        <p class="font-bold mx-3" v-text="'Sparekonto'" />
+                    </div>
+                    <p
+                        class="mx-3"
+                        v-text="profile?.savingAccount.accNumber || 'Ingen sparekonto oppkoblet'"
+                    />
+                </CardTemplate>
+
+                <button @click="router.push({ name: 'edit-profile' })" v-text="'Rediger bruker'" />
+            </div>
+
+            <div class="flex flex-col">
+                <InteractiveSpare :png-size="10" :speech="welcome" direction="left" />
+                <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'" />
+                </div>
+                <CardTemplate class="p-4 flex flex-row flex-wrap justify-center gap-2 mb-4 mt-2">
+                    <CardGoal v-for="goal in completedGoals" :key="goal.id" :goal-instance="goal" />
+                </CardTemplate>
+
+                <div class="flex flex-row justify-between mx-4">
+                    <p class="font-bold">Fullførte utfordringer</p>
+                    <a class="hover:p-0 cursor-pointer" v-text="'Se alle'" />
+                </div>
+                <CardTemplate class="p-4 flex flex-row flex-wrap justify-center gap-2 mb-4 mt-2">
+                    <CardGoal
+                        v-for="challenge in completedChallenges"
+                        :key="challenge.id"
+                        :goal-instance="challenge"
+                    />
+                </CardTemplate>
+            </div>
+        </div>
+    </div>
 </template>
 
 <style scoped></style>