diff --git a/spec.json b/spec.json
new file mode 100644
index 0000000000000000000000000000000000000000..26570a49b0bae494c990a7ffb525e6bedf4c6a7f
--- /dev/null
+++ b/spec.json
@@ -0,0 +1,535 @@
+{
+  "openapi": "3.0.1",
+  "info": {
+    "title": "Sparesti API",
+    "description": "The Sparesti API",
+    "version": "3.0"
+  },
+  "servers": [
+    {
+      "url": "http://localhost:8080",
+      "description": "Generated server url"
+    }
+  ],
+  "security": [
+    {
+      "Bearer Authentication": []
+    }
+  ],
+  "tags": [
+    {
+      "name": "Authentication",
+      "description": "User authentication"
+    },
+    {
+      "name": "Leaderboard",
+      "description": "Retrieving leaderboard data"
+    }
+  ],
+  "paths": {
+    "/api/auth/valid-email/{email}": {
+      "post": {
+        "tags": [
+          "Authentication"
+        ],
+        "summary": "Validate email",
+        "description": "Check that the given email is valid",
+        "operationId": "validateEmail",
+        "parameters": [
+          {
+            "name": "email",
+            "in": "path",
+            "required": true,
+            "schema": {
+              "type": "string"
+            }
+          }
+        ],
+        "responses": {
+          "409": {
+            "description": "Email already exists",
+            "content": {
+              "*/*": {
+                "schema": {
+                  "$ref": "#/components/schemas/ExceptionResponse"
+                }
+              }
+            }
+          },
+          "200": {
+            "description": "Email is valid",
+            "content": {
+              "*/*": {
+                "schema": {
+                  "type": "object"
+                }
+              }
+            }
+          }
+        },
+        "security": []
+      }
+    },
+    "/api/auth/signup": {
+      "post": {
+        "tags": [
+          "Authentication"
+        ],
+        "summary": "User Signup",
+        "description": "Sign up a new user",
+        "operationId": "signup",
+        "requestBody": {
+          "content": {
+            "application/json": {
+              "schema": {
+                "$ref": "#/components/schemas/SignUpRequest"
+              }
+            }
+          },
+          "required": true
+        },
+        "responses": {
+          "201": {
+            "description": "Successfully signed up",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/AuthenticationResponse"
+                }
+              }
+            }
+          },
+          "409": {
+            "description": "Email already exists",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/ExceptionResponse"
+                }
+              }
+            }
+          }
+        },
+        "security": []
+      }
+    },
+    "/api/auth/login": {
+      "post": {
+        "tags": [
+          "Authentication"
+        ],
+        "summary": "User Login",
+        "description": "Log in with an existing user",
+        "operationId": "login",
+        "requestBody": {
+          "content": {
+            "application/json": {
+              "schema": {
+                "$ref": "#/components/schemas/LoginRequest"
+              }
+            }
+          },
+          "required": true
+        },
+        "responses": {
+          "200": {
+            "description": "Successfully logged in",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/AuthenticationResponse"
+                }
+              }
+            }
+          },
+          "401": {
+            "description": "Invalid credentials",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/ExceptionResponse"
+                }
+              }
+            }
+          },
+          "404": {
+            "description": "User not found",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/ExceptionResponse"
+                }
+              }
+            }
+          }
+        },
+        "security": []
+      }
+    },
+    "/api/users": {
+      "patch": {
+        "tags": [
+          "user-controller"
+        ],
+        "summary": "Update profile",
+        "description": "Update the profile of the authenticated user",
+        "operationId": "update",
+        "requestBody": {
+          "content": {
+            "application/json": {
+              "schema": {
+                "$ref": "#/components/schemas/UserUpdateDTO"
+              }
+            }
+          },
+          "required": true
+        },
+        "responses": {
+          "200": {
+            "description": "Successfully updated profile",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/UserDTO"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/api/users/{userId}/profile": {
+      "get": {
+        "tags": [
+          "user-controller"
+        ],
+        "summary": "Get profile",
+        "description": "Get user profile",
+        "operationId": "getProfile",
+        "parameters": [
+          {
+            "name": "userId",
+            "in": "path",
+            "required": true,
+            "schema": {
+              "type": "integer",
+              "format": "int64"
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "Successfully got profile",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/ProfileDTO"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/api/users/me": {
+      "get": {
+        "tags": [
+          "user-controller"
+        ],
+        "summary": "Get user",
+        "description": "Get user information",
+        "operationId": "getUser",
+        "responses": {
+          "200": {
+            "description": "Successfully got user",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/UserDTO"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/api/leaderboard": {
+      "get": {
+        "tags": [
+          "Leaderboard"
+        ],
+        "operationId": "getLeaderboard",
+        "parameters": [
+          {
+            "name": "type",
+            "in": "query",
+            "required": true,
+            "schema": {
+              "type": "string"
+            }
+          },
+          {
+            "name": "filter",
+            "in": "query",
+            "required": true,
+            "schema": {
+              "type": "string"
+            }
+          },
+          {
+            "name": "entryCount",
+            "in": "query",
+            "required": false,
+            "schema": {
+              "type": "integer",
+              "format": "int32",
+              "default": 10
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/LeaderboardDTO"
+                }
+              }
+            }
+          }
+        }
+      }
+    },
+    "/api/leaderboard/surrounding": {
+      "get": {
+        "tags": [
+          "Leaderboard"
+        ],
+        "operationId": "getSurrounding",
+        "parameters": [
+          {
+            "name": "type",
+            "in": "query",
+            "required": true,
+            "schema": {
+              "type": "string"
+            }
+          },
+          {
+            "name": "filter",
+            "in": "query",
+            "required": true,
+            "schema": {
+              "type": "string"
+            }
+          },
+          {
+            "name": "entryCount",
+            "in": "query",
+            "required": false,
+            "schema": {
+              "type": "integer",
+              "format": "int32",
+              "default": 10
+            }
+          }
+        ],
+        "responses": {
+          "200": {
+            "description": "OK",
+            "content": {
+              "application/json": {
+                "schema": {
+                  "$ref": "#/components/schemas/LeaderboardDTO"
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  },
+  "components": {
+    "schemas": {
+      "ExceptionResponse": {
+        "type": "object",
+        "properties": {
+          "status": {
+            "type": "integer",
+            "format": "int32"
+          },
+          "message": {
+            "type": "string"
+          }
+        }
+      },
+      "SignUpRequest": {
+        "type": "object",
+        "properties": {
+          "firstName": {
+            "type": "string"
+          },
+          "lastName": {
+            "type": "string"
+          },
+          "email": {
+            "type": "string"
+          },
+          "password": {
+            "type": "string"
+          },
+          "commitment": {
+            "type": "string"
+          },
+          "experience": {
+            "type": "string"
+          },
+          "challengeTypes": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            }
+          }
+        }
+      },
+      "AuthenticationResponse": {
+        "type": "object",
+        "properties": {
+          "firstName": {
+            "type": "string"
+          },
+          "lastName": {
+            "type": "string"
+          },
+          "role": {
+            "type": "string"
+          },
+          "token": {
+            "type": "string"
+          }
+        }
+      },
+      "LoginRequest": {
+        "type": "object",
+        "properties": {
+          "email": {
+            "type": "string"
+          },
+          "password": {
+            "type": "string"
+          }
+        }
+      },
+      "UserUpdateDTO": {
+        "type": "object",
+        "properties": {
+          "firstName": {
+            "type": "string"
+          },
+          "lastName": {
+            "type": "string"
+          },
+          "email": {
+            "type": "string"
+          },
+          "password": {
+            "type": "string"
+          },
+          "commitment": {
+            "type": "string"
+          },
+          "experience": {
+            "type": "string"
+          },
+          "challengeTypes": {
+            "type": "array",
+            "items": {
+              "type": "string"
+            }
+          }
+        }
+      },
+      "UserDTO": {
+        "type": "object",
+        "properties": {
+          "id": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "firstName": {
+            "type": "string"
+          },
+          "lastName": {
+            "type": "string"
+          },
+          "email": {
+            "type": "string"
+          },
+          "createdAt": {
+            "type": "string",
+            "format": "date-time"
+          },
+          "role": {
+            "type": "string"
+          }
+        }
+      },
+      "ProfileDTO": {
+        "type": "object",
+        "properties": {
+          "id": {
+            "type": "integer",
+            "format": "int64"
+          },
+          "firstName": {
+            "type": "string"
+          },
+          "lastName": {
+            "type": "string"
+          },
+          "createdAt": {
+            "type": "string",
+            "format": "date-time"
+          }
+        }
+      },
+      "LeaderboardDTO": {
+        "type": "object",
+        "properties": {
+          "type": {
+            "type": "string"
+          },
+          "filter": {
+            "type": "string"
+          },
+          "entries": {
+            "type": "array",
+            "items": {
+              "$ref": "#/components/schemas/LeaderboardEntryDTO"
+            }
+          }
+        }
+      },
+      "LeaderboardEntryDTO": {
+        "type": "object",
+        "properties": {
+          "user": {
+            "$ref": "#/components/schemas/UserDTO"
+          },
+          "score": {
+            "type": "integer",
+            "format": "int32"
+          }
+        }
+      }
+    },
+    "securitySchemes": {
+      "Bearer Authentication": {
+        "type": "http",
+        "scheme": "bearer",
+        "bearerFormat": "JWT"
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/src/App.vue b/src/App.vue
index 12ad03a6b286a47ed6a392e7338562c82b213f64..dc693f471ad9c9828c6519d81cea07c8bd5ce5ee 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -1,6 +1,6 @@
 <script setup lang="ts">
 import { RouterView } from 'vue-router'
-import ErrorBoundaryCatcher from '@/components/Exceptions/ErrorBoundaryCatcher.vue';
+// import ErrorBoundaryCatcher from '@/components/Exceptions/ErrorBoundaryCatcher.vue';
 </script>
 
 <template>
diff --git a/src/api/index.ts b/src/api/index.ts
index 2a974f1dd456ed118f2caf5c190038eb3cfa7c3f..22e1808268ec1c7b349141ce999d2e4b668cb45c 100644
--- a/src/api/index.ts
+++ b/src/api/index.ts
@@ -9,7 +9,14 @@ export type { OpenAPIConfig } from './core/OpenAPI';
 
 export type { AuthenticationResponse } from './models/AuthenticationResponse';
 export type { ExceptionResponse } from './models/ExceptionResponse';
+export type { LeaderboardDTO } from './models/LeaderboardDTO';
+export type { LeaderboardEntryDTO } from './models/LeaderboardEntryDTO';
 export type { LoginRequest } from './models/LoginRequest';
+export type { ProfileDTO } from './models/ProfileDTO';
 export type { SignUpRequest } from './models/SignUpRequest';
+export type { UserDTO } from './models/UserDTO';
+export type { UserUpdateDTO } from './models/UserUpdateDTO';
 
 export { AuthenticationService } from './services/AuthenticationService';
+export { LeaderboardService } from './services/LeaderboardService';
+export { UserControllerService } from './services/UserControllerService';
diff --git a/src/api/models/LeaderboardDTO.ts b/src/api/models/LeaderboardDTO.ts
new file mode 100644
index 0000000000000000000000000000000000000000..58bddb76f2fc2a4cfbf09ec19b8915ca5f7f3976
--- /dev/null
+++ b/src/api/models/LeaderboardDTO.ts
@@ -0,0 +1,11 @@
+/* generated using openapi-typescript-codegen -- do not edit */
+/* istanbul ignore file */
+/* tslint:disable */
+/* eslint-disable */
+import type { LeaderboardEntryDTO } from './LeaderboardEntryDTO';
+export type LeaderboardDTO = {
+    type?: string;
+    filter?: string;
+    entries?: Array<LeaderboardEntryDTO>;
+};
+
diff --git a/src/api/models/LeaderboardEntryDTO.ts b/src/api/models/LeaderboardEntryDTO.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9a93b2ff579409b4fa78077ba9f9cb47befc465d
--- /dev/null
+++ b/src/api/models/LeaderboardEntryDTO.ts
@@ -0,0 +1,10 @@
+/* generated using openapi-typescript-codegen -- do not edit */
+/* istanbul ignore file */
+/* tslint:disable */
+/* eslint-disable */
+import type { UserDTO } from './UserDTO';
+export type LeaderboardEntryDTO = {
+    user?: UserDTO;
+    score?: number;
+};
+
diff --git a/src/api/models/ProfileDTO.ts b/src/api/models/ProfileDTO.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f3a7d36f290da3dfa38b6143e83b934b427ee47f
--- /dev/null
+++ b/src/api/models/ProfileDTO.ts
@@ -0,0 +1,11 @@
+/* generated using openapi-typescript-codegen -- do not edit */
+/* istanbul ignore file */
+/* tslint:disable */
+/* eslint-disable */
+export type ProfileDTO = {
+    id?: number;
+    firstName?: string;
+    lastName?: string;
+    createdAt?: string;
+};
+
diff --git a/src/api/models/SignUpRequest.ts b/src/api/models/SignUpRequest.ts
index 28a2e78a3a39e8ceb5f28567ebdf02d912017210..f9aa1f6162784c19e4012289fd61c429edf6eea7 100644
--- a/src/api/models/SignUpRequest.ts
+++ b/src/api/models/SignUpRequest.ts
@@ -7,8 +7,8 @@ export type SignUpRequest = {
     lastName?: string;
     email?: string;
     password?: string;
-    changeWilling?: string;
+    commitment?: string;
     experience?: string;
-    challenges?: Array<string>;
+    challengeTypes?: Array<string>;
 };
 
diff --git a/src/api/models/UserDTO.ts b/src/api/models/UserDTO.ts
new file mode 100644
index 0000000000000000000000000000000000000000..56f00b30d40ee5427b6dce81810255504a11b756
--- /dev/null
+++ b/src/api/models/UserDTO.ts
@@ -0,0 +1,13 @@
+/* generated using openapi-typescript-codegen -- do not edit */
+/* istanbul ignore file */
+/* tslint:disable */
+/* eslint-disable */
+export type UserDTO = {
+    id?: number;
+    firstName?: string;
+    lastName?: string;
+    email?: string;
+    createdAt?: string;
+    role?: string;
+};
+
diff --git a/src/api/models/UserUpdateDTO.ts b/src/api/models/UserUpdateDTO.ts
new file mode 100644
index 0000000000000000000000000000000000000000..54cc0f5524b3ca515f3b671e02edf92ec05a54aa
--- /dev/null
+++ b/src/api/models/UserUpdateDTO.ts
@@ -0,0 +1,14 @@
+/* generated using openapi-typescript-codegen -- do not edit */
+/* istanbul ignore file */
+/* tslint:disable */
+/* eslint-disable */
+export type UserUpdateDTO = {
+    firstName?: string;
+    lastName?: string;
+    email?: string;
+    password?: string;
+    commitment?: string;
+    experience?: string;
+    challengeTypes?: Array<string>;
+};
+
diff --git a/src/api/services/LeaderboardService.ts b/src/api/services/LeaderboardService.ts
new file mode 100644
index 0000000000000000000000000000000000000000..f77a3cc9b2e67de48357385ed47ae8c523b2c0e0
--- /dev/null
+++ b/src/api/services/LeaderboardService.ts
@@ -0,0 +1,56 @@
+/* generated using openapi-typescript-codegen -- do not edit */
+/* istanbul ignore file */
+/* tslint:disable */
+/* eslint-disable */
+import type { LeaderboardDTO } from '../models/LeaderboardDTO';
+import type { CancelablePromise } from '../core/CancelablePromise';
+import { OpenAPI } from '../core/OpenAPI';
+import { request as __request } from '../core/request';
+export class LeaderboardService {
+    /**
+     * @returns LeaderboardDTO OK
+     * @throws ApiError
+     */
+    public static getLeaderboard({
+        type,
+        filter,
+        entryCount = 10,
+    }: {
+        type: string,
+        filter: string,
+        entryCount?: number,
+    }): CancelablePromise<LeaderboardDTO> {
+        return __request(OpenAPI, {
+            method: 'GET',
+            url: '/api/leaderboard',
+            query: {
+                'type': type,
+                'filter': filter,
+                'entryCount': entryCount,
+            },
+        });
+    }
+    /**
+     * @returns LeaderboardDTO OK
+     * @throws ApiError
+     */
+    public static getSurrounding({
+        type,
+        filter,
+        entryCount = 10,
+    }: {
+        type: string,
+        filter: string,
+        entryCount?: number,
+    }): CancelablePromise<LeaderboardDTO> {
+        return __request(OpenAPI, {
+            method: 'GET',
+            url: '/api/leaderboard/surrounding',
+            query: {
+                'type': type,
+                'filter': filter,
+                'entryCount': entryCount,
+            },
+        });
+    }
+}
diff --git a/src/api/services/UserControllerService.ts b/src/api/services/UserControllerService.ts
new file mode 100644
index 0000000000000000000000000000000000000000..5a1ea3560cb016455a4d2c77c2e34e9b0754a684
--- /dev/null
+++ b/src/api/services/UserControllerService.ts
@@ -0,0 +1,61 @@
+/* generated using openapi-typescript-codegen -- do not edit */
+/* istanbul ignore file */
+/* tslint:disable */
+/* eslint-disable */
+import type { ProfileDTO } from '../models/ProfileDTO';
+import type { UserDTO } from '../models/UserDTO';
+import type { UserUpdateDTO } from '../models/UserUpdateDTO';
+import type { CancelablePromise } from '../core/CancelablePromise';
+import { OpenAPI } from '../core/OpenAPI';
+import { request as __request } from '../core/request';
+export class UserControllerService {
+    /**
+     * Update profile
+     * Update the profile of the authenticated user
+     * @returns UserDTO Successfully updated profile
+     * @throws ApiError
+     */
+    public static update({
+        requestBody,
+    }: {
+        requestBody: UserUpdateDTO,
+    }): CancelablePromise<UserDTO> {
+        return __request(OpenAPI, {
+            method: 'PATCH',
+            url: '/api/users',
+            body: requestBody,
+            mediaType: 'application/json',
+        });
+    }
+    /**
+     * Get profile
+     * Get user profile
+     * @returns ProfileDTO Successfully got profile
+     * @throws ApiError
+     */
+    public static getProfile({
+        userId,
+    }: {
+        userId: number,
+    }): CancelablePromise<ProfileDTO> {
+        return __request(OpenAPI, {
+            method: 'GET',
+            url: '/api/users/{userId}/profile',
+            path: {
+                'userId': userId,
+            },
+        });
+    }
+    /**
+     * Get user
+     * Get user information
+     * @returns UserDTO Successfully got user
+     * @throws ApiError
+     */
+    public static getUser(): CancelablePromise<UserDTO> {
+        return __request(OpenAPI, {
+            method: 'GET',
+            url: '/api/users/me',
+        });
+    }
+}
diff --git a/src/components/Configuration/ConfigurationSteps/SuitableChallenges.vue b/src/components/Configuration/ConfigurationSteps/SuitableChallenges.vue
index 91c39045671a85816e70cab8bd81ed8131b4452a..dc849d5cdde9afd61f9e53e53b4eaefba203bf64 100644
--- a/src/components/Configuration/ConfigurationSteps/SuitableChallenges.vue
+++ b/src/components/Configuration/ConfigurationSteps/SuitableChallenges.vue
@@ -22,6 +22,7 @@ const onChangedChallengeEvent = (value) => {
     console.log('Reached')
     chosenChallenges.value = chosenChallenges.value.filter(item => item !== value[0]);
   }
+  console.log(chosenChallenges.value)
 }
 
 const onClick = () => {
diff --git a/src/components/InputFields/BaseInput.vue b/src/components/InputFields/BaseInput.vue
index 22ed03466408636bb262bb56fe77aa63f914b6ac..c773e4c203294cabd1dee9d555dd94b013961871 100644
--- a/src/components/InputFields/BaseInput.vue
+++ b/src/components/InputFields/BaseInput.vue
@@ -22,10 +22,6 @@ const props = defineProps({
     type: String,
     default: ""
   },
-  isValid: {
-    type: Boolean,
-    default: false
-  },
   min: {
     type: String,
     required: false
@@ -33,6 +29,14 @@ const props = defineProps({
   pattern: {
     type: String,
     default: null
+  },
+  validMessage: {
+    type: String,
+    default: ''
+  },
+  invalidMessage: {
+    type: String,
+    default: ''
   }
 });
 
@@ -44,17 +48,16 @@ const onInputEvent = (event: any) => {
 <template>
   <div>
     <label :for="inputId">{{ label }}</label>
-    <input :value="props.modelValue"
+    <input :value="modelValue"
            @input="onInputEvent"
-           :type="props.type"
+           :type="type"
            class="form-control"
-           :placeholder="props.placeholder"
+           :placeholder="placeholder"
            :id="inputId" required
            :min="min"
-           :pattern="pattern"
-    />
-    <div v-if="props.isValid" class="invalid-feedback">Invalid {{ label }}</div>
-    <div v-else class="valid-feedback">Valid {{ label }}</div>
+           :pattern="pattern"/>
+    <div class="valid-feedback">{{ validMessage }}</div>
+    <div class="invalid-feedback">{{ invalidMessage }}</div>
   </div>
 </template>
 
diff --git a/src/components/Login/LoginForm.vue b/src/components/Login/LoginForm.vue
index 953ecb8e13403f5efcd766222a1f936b6280a630..21d4de86686d68850b9ee49b09cb9246be596ced 100644
--- a/src/components/Login/LoginForm.vue
+++ b/src/components/Login/LoginForm.vue
@@ -8,8 +8,8 @@ import { useRouter, useRoute } from 'vue-router';
 import handleUnknownError from '@/components/Exceptions/unkownErrorHandler';
 import { useErrorStore } from '@/stores/ErrorStore';
 
-const emailRef = ref()
-const passwordRef = ref()
+const emailRef = ref('')
+const passwordRef = ref('')
 const formRef = ref()
 let errorMsg = ref('');
 
@@ -19,13 +19,18 @@ const userStore = useUserInfoStore();
 
 const handleEmailInputEvent = (newValue: any) => {
   emailRef.value = newValue
+  console.log(emailRef.value)
 }
 
 const handlePasswordInputEvent = (newValue: any) => {
   passwordRef.value = newValue
+  console.log(passwordRef.value)
 }
 
 const handleSubmit = async () => {
+  console.log(emailRef.value)
+  console.log(passwordRef.value)
+
   formRef.value.classList.add("was-validated")
   const loginUserPayload: LoginRequest = {
     email: emailRef.value,
@@ -64,11 +69,30 @@ const handleSubmit = async () => {
       <h1>Sparesti.no</h1>
     </div>
     <form ref="formRef" id="loginForm" @submit.prevent="handleSubmit" novalidate>
-      <BaseInput :model-value="emailRef" @input-change-event="handleEmailInputEvent" id="emailInput" input-id="email"
-        type="email" label="Email" placeholder="Enter your email" />
-      <BaseInput pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{4,16}" :model-value="passwordRef"
-        @input-change-event="handlePasswordInputEvent" id="passwordInput" input-id="password" type="password"
-        label="Password" placeholder="Enter password" />
+
+      <BaseInput :model-value="emailRef"
+                 @input-change-event="handleEmailInputEvent"
+                 id="emailInput"
+                 input-id="email"
+                 type="email"
+                 label="Email"
+                 placeholder="Enter your email"
+                 valid-message="Valid email"
+                 invalid-message="Invalid email"
+      />
+
+      <BaseInput :model-value="passwordRef"
+                 @input-change-event="handlePasswordInputEvent"
+                 id="passwordInput"
+                 input-id="password"
+                 type="password"
+                 pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{4,16}"
+                 label="Password"
+                 placeholder="Enter password"
+                 valid-message="Valid password"
+                 invalid-message="Password must be between 4 and 16 characters and contain one capital letter, small letter and a number"
+      />
+
       <p class="text-danger">{{ errorMsg }}</p>
       <button1 id="confirmButton" type="submit" @click="handleSubmit" button-text="Login"></button1>
     </form>
diff --git a/src/components/SavingGoalComponents/SavingGoal.vue b/src/components/SavingGoalComponents/SavingGoal.vue
index 89cae3a4258a8c705e15c4146f8c2e479530d7d5..e3de05112d6f449f7d2a1f3f0ba047d8b056fcd7 100644
--- a/src/components/SavingGoalComponents/SavingGoal.vue
+++ b/src/components/SavingGoalComponents/SavingGoal.vue
@@ -36,7 +36,7 @@ export default {
 </script>
 
 <template>
-  <div class="container">
+  <div class="cont">
     <div class="row">
       <div class="col-lg-4 blue-background overflow-auto" :style="{ 'max-height': bluePanelMaxHeight }">
         <h3 style="color: white; margin-bottom: 16px">Your saving goals</h3>
@@ -53,9 +53,10 @@ export default {
 </template>
 
 <style scoped>
-.container {
+.cont {
+  padding-left: 10px;
   margin: 0;
-  width: 100%;
+  width: 98%;
   box-sizing: unset;
 }
 
diff --git a/src/components/SavingGoalComponents/SavingGoalRoadmap.vue b/src/components/SavingGoalComponents/SavingGoalRoadmap.vue
index 74e8d2d54cea2c9a2a0d34d0c7435b0a93f6994d..018c4579e1948559e1bbc2f93220fac6f97a3d0b 100644
--- a/src/components/SavingGoalComponents/SavingGoalRoadmap.vue
+++ b/src/components/SavingGoalComponents/SavingGoalRoadmap.vue
@@ -4,6 +4,7 @@ interface Step {
   showPanel: boolean;
   description: string;
   percentFinished: number;
+  unFinished: boolean;
 }
 export default {
   data() {
@@ -13,18 +14,28 @@ export default {
       title: 'Spain trip' as string,
       //This will be changed to info gathered from backend
       steps: [
-        { title: 'Challenge 1', showPanel: false, description: 'Save 50kr on coffee in 3 days', percentFinished: 22 },
-        { title: 'Challenge 2', showPanel: false, description: 'Save 500kr on food in 7 days', percentFinished: 73 },
-        { title: 'Challenge 3', showPanel: false, description: 'Save 350kr on clothes in 5 days', percentFinished: 50 },
-        { title: 'Challenge 4', showPanel: false, description: 'Save 150kr on coffee in 4 days', percentFinished: 10 },
-        { title: 'Challenge 5', showPanel: false, description: 'Save 50kr on coffee in 3 days', percentFinished: 90 }
+        { title: 'Challenge 1', showPanel: false, description: 'Save 50kr on coffee in 3 days', percentFinished: 22, unFinished: false },
+        { title: 'Challenge 2', showPanel: false, description: 'Save 500kr on food in 7 days', percentFinished: 73, unFinished: false },
+        { title: 'Challenge 3', showPanel: false, description: 'Save 350kr on clothes in 5 days', percentFinished: 50, unFinished: true },
+        { title: 'Challenge 4', showPanel: false, description: 'Save 150kr on coffee in 4 days', percentFinished: 10, unFinished: true },
+        { title: 'Challenge 5', showPanel: false, description: 'Save 50kr on coffee in 3 days', percentFinished: 90, unFinished: true }
       ]
       ,
       bluePanelMaxHeight: 'auto' as string
     };
   },
   mounted() {
-    this.togglePanel(this.steps[2]);
+    setTimeout(() => {
+      this.togglePanel(this.steps[2]);
+    }, 500);
+    
+  },
+  computed: {
+    computeImageFilter() {
+      return (step: Step) => {
+        return step.unFinished ? 'none' : 'grayscale(100%)';
+      };
+    }
   },
   methods: {
     togglePanel(step: Step) {
@@ -40,12 +51,8 @@ export default {
       if (step.showPanel) {
         this.$nextTick(() => {
           const panel = document.getElementById(`panel-${this.steps.indexOf(step)}`);
-          console.log(panel);
           if (panel) {
-            setTimeout(() => {
-              panel.scrollIntoView({ behavior: 'smooth', block: 'center' });
-              console.log('I should have scrolled');
-            }, 100); // Wait for 1 second before scrolling
+            panel.scrollIntoView({ behavior: 'smooth', block: 'center' });
           }
         });
       }
@@ -56,11 +63,24 @@ export default {
 
 <template>
   <div class="col-lg-8">
-    <div class="SavingGoalTitle text-center">{{title}}</div>
+    <div class="SavingGoalTitle text-center">
+      {{title}}
+      <br>
+      <p class="d-inline-flex gap-1">
+        <button class="btn btn-primary" type="button" data-bs-toggle="collapse" data-bs-target="#collapseExample" aria-expanded="false" aria-controls="collapseExample" style="font-size: 25px;">
+          See more info
+        </button>
+      </p>
+      <div class="collapse" id="collapseExample">
+        <div class="card card-body bg-primary mx-auto" style="width: 80%;">
+          Total saved: 20kr
+        </div>
+      </div>
+    </div>
     <ul class="timeline">
       <li v-for="(step, index) in steps" :key="index" :class="{ 'timeline-inverted': index % 2 !== 0 }">
           <div class="timeline-image z-1" @click="togglePanel(step)">
-            <img class="circular-image" :src="step.showPanel ? altImage : image" alt="">
+            <img class="circular-image" :src="step.showPanel ? altImage : image" :style="{ filter: computeImageFilter(step) }" alt="">
           </div>
         <div class="timeline-panel z-3" :id="'panel-' + index" v-show="step.showPanel">
           <div class="timeline-heading">
@@ -95,9 +115,8 @@ export default {
 
 <style scoped>
 .col-lg-8 {
-  width: 63%;
+  width: 58%;
   margin-bottom: 20px;
-  max-height: 1000px;
 }
 
 .SavingGoalTitle {
diff --git a/src/components/SignUp/SignUpForm.vue b/src/components/SignUp/SignUpForm.vue
index b085f6ee59b1b3d38c777f8b041fa9d1b76013d6..9a8dab783a1c291575375d0f8ea69fb1d3a6b525 100644
--- a/src/components/SignUp/SignUpForm.vue
+++ b/src/components/SignUp/SignUpForm.vue
@@ -5,15 +5,18 @@ import { ref } from 'vue'
 import { useRouter } from 'vue-router'
 
 const router = useRouter();
+
 const firstNameRef = ref('')
 const surnameRef = ref('')
 const emailRef = ref('')
 const passwordRef = ref('')
 const confirmPasswordRef = ref('')
 const formRef = ref()
+let samePasswords = ref(true)
 
 const handleFirstNameInputEvent = (newValue: any) => {
   firstNameRef.value = newValue
+  console.log(firstNameRef.value)
 }
 
 const handleSurnameInputEvent = (newValue: any) => {
@@ -26,21 +29,30 @@ const handleEmailInputEvent = (newValue: any) => {
 
 const handlePasswordInputEvent = (newValue: any) => {
   passwordRef.value = newValue
+  console.log(passwordRef.value)
 }
 
 const handleConfirmPasswordInputEvent = (newValue: any) => {
   confirmPasswordRef.value = newValue
+  console.log(confirmPasswordRef.value)
 }
 
-const handleSubmit = () => {
+const handleSubmit = async () => {
+  console.log(firstNameRef.value)
+
+  samePasswords.value = (passwordRef.value === confirmPasswordRef.value)
+  console.log(samePasswords.value)
   const form = formRef.value;
 
   // Check if the form is valid
   if (form.checkValidity()) {
     // Form is valid, submit the form or perform other actions
     console.log('Form is valid');
+  } else {
+    console.log('Form is not valid');
   }
 
+
   formRef.value.classList.add("was-validated")
 }
 
@@ -49,46 +61,54 @@ const handleSubmit = () => {
 <template>
   <div class="container">
     <form ref="formRef" id="signUpForm" @submit.prevent="handleSubmit">
-      <BaseInput :model-value="firstNameRef.value"
+      <BaseInput :model-value="firstNameRef"
                  @input-change-event="handleFirstNameInputEvent"
                  ref="firstNameRef"
                  id="firstNameInput"
                  input-id="first-name"
                  type="text"
                  label="First name"
-                 placeholder="Enter your first name"/>
-      <BaseInput :model-value="surnameRef.value"
+                 placeholder="Enter your first name"
+                 invalid-message="Please enter your first name"/>
+      <BaseInput :model-value="surnameRef"
                  @input-change-event="handleSurnameInputEvent"
                  ref="surnameRef"
                  id="surnameInput"
                  input-id="surname"
                  type="text"
                  label="Surname"
-                 placeholder="Enter your surname"/>
-      <BaseInput :model-value="emailRef.value"
+                 placeholder="Enter your surname"
+                 invalid-message="Please enter your surname"/>
+      <BaseInput :model-value="emailRef"
                  @input-change-event="handleEmailInputEvent"
                  ref="emailRef"
                  id="emailInput"
                  input-id="email"
                  type="email"
                  label="Email"
-                 placeholder="Enter your email"/>
-      <BaseInput :model-value="passwordRef.value"
+                 placeholder="Enter your email"
+                 invalid-message="Invalid email"/>
+      <BaseInput :model-value="passwordRef"
                  @input-change-event="handlePasswordInputEvent"
                  ref="passwordRef"
                  id="passwordInput"
                  input-id="password"
                  type="password"
+                 pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{4,16}"
                  label="Password"
-                 placeholder="Enter password"/>
-      <BaseInput :model-value="confirmPasswordRef.value"
+                 placeholder="Enter password"
+                 invalid-message="Password must be between 4 and 16 characters and contain one capital letter, small letter and a number"/>
+      <BaseInput :modelValue="confirmPasswordRef"
                  @input-change-event="handleConfirmPasswordInputEvent"
                  ref="confirmPasswordRef"
                  id="confirmPasswordInput"
                  input-id="confirmPassword"
                  type="password"
+                 pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{4,16}"
                  label="Confirm Password"
-                 placeholder="Confirm password"/>
+                 placeholder="Confirm password"
+                 invalid-message="Password must be between 4 and 16 characters and contain one capital letter, small letter and a number"/>
+      <p v-if="samePasswords" class="text-danger">The passwords are not identical</p>
       <button1 id="confirmButton" @click="handleSubmit" button-text="Sign up"></button1>
     </form>
   </div>