diff --git a/index.html b/index.html
index a888544898a5059056e4c148c28b2eabf4b2d67a..48d04d242838a0af8891ee79b127695b46798079 100644
--- a/index.html
+++ b/index.html
@@ -2,9 +2,9 @@
 <html lang="en">
   <head>
     <meta charset="UTF-8">
-    <link rel="icon" href="/favicon.ico">
+    <link rel="icon" href="/src/assets/Sparesti-logo.png">
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
-    <title>Vite App</title>
+    <title>Sparesti</title>
   </head>
   <body>
     <div id="app"></div>
diff --git a/package-lock.json b/package-lock.json
index 05f3e7c65d110dbcb2eaa13715d7dac5e3c88dc5..a9b42c3119552e9ab948df2ed7ba8cafe9b5fe9e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,6 +11,7 @@
         "@popperjs/core": "^2.11.8",
         "axios": "^1.6.8",
         "bootstrap": "^5.3.3",
+        "install": "^0.13.0",
         "js-cookie": "^3.0.5",
         "oh-vue-icons": "^1.0.0-rc3",
         "pinia": "^2.1.7",
@@ -26,6 +27,7 @@
         "@types/node": "^20.12.5",
         "@vitejs/plugin-vue": "^5.0.4",
         "@vitejs/plugin-vue-jsx": "^3.1.0",
+        "@vitest/coverage-v8": "^1.5.0",
         "@vue/eslint-config-prettier": "^9.0.0",
         "@vue/eslint-config-typescript": "^13.0.0",
         "@vue/test-utils": "^2.4.5",
@@ -568,6 +570,12 @@
         "node": ">=6.9.0"
       }
     },
+    "node_modules/@bcoe/v8-coverage": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
+      "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
+      "dev": true
+    },
     "node_modules/@colors/colors": {
       "version": "1.5.0",
       "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
@@ -1236,6 +1244,15 @@
         "url": "https://github.com/chalk/strip-ansi?sponsor=1"
       }
     },
+    "node_modules/@istanbuljs/schema": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz",
+      "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/@jest/schemas": {
       "version": "29.6.3",
       "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
@@ -2034,6 +2051,33 @@
         "vue": "^3.0.0"
       }
     },
+    "node_modules/@vitest/coverage-v8": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-1.5.0.tgz",
+      "integrity": "sha512-1igVwlcqw1QUMdfcMlzzY4coikSIBN944pkueGi0pawrX5I5Z+9hxdTR+w3Sg6Q3eZhvdMAs8ZaF9JuTG1uYOQ==",
+      "dev": true,
+      "dependencies": {
+        "@ampproject/remapping": "^2.2.1",
+        "@bcoe/v8-coverage": "^0.2.3",
+        "debug": "^4.3.4",
+        "istanbul-lib-coverage": "^3.2.2",
+        "istanbul-lib-report": "^3.0.1",
+        "istanbul-lib-source-maps": "^5.0.4",
+        "istanbul-reports": "^3.1.6",
+        "magic-string": "^0.30.5",
+        "magicast": "^0.3.3",
+        "picocolors": "^1.0.0",
+        "std-env": "^3.5.0",
+        "strip-literal": "^2.0.0",
+        "test-exclude": "^6.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/vitest"
+      },
+      "peerDependencies": {
+        "vitest": "1.5.0"
+      }
+    },
     "node_modules/@vitest/expect": {
       "version": "1.5.0",
       "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-1.5.0.tgz",
@@ -4857,6 +4901,12 @@
         "node": ">=18"
       }
     },
+    "node_modules/html-escaper": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+      "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+      "dev": true
+    },
     "node_modules/html-tags": {
       "version": "3.3.1",
       "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz",
@@ -5018,6 +5068,14 @@
         "node": ">=10"
       }
     },
+    "node_modules/install": {
+      "version": "0.13.0",
+      "resolved": "https://registry.npmjs.org/install/-/install-0.13.0.tgz",
+      "integrity": "sha512-zDml/jzr2PKU9I8J/xyZBQn8rPCAY//UOYNmR01XwNwyfhEWObo2SWfSl1+0tm1u6PhxLwDnfsT/6jB7OUxqFA==",
+      "engines": {
+        "node": ">= 0.10"
+      }
+    },
     "node_modules/is-ci": {
       "version": "3.0.1",
       "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz",
@@ -5190,6 +5248,77 @@
       "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==",
       "dev": true
     },
+    "node_modules/istanbul-lib-coverage": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
+      "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/istanbul-lib-report": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
+      "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
+      "dev": true,
+      "dependencies": {
+        "istanbul-lib-coverage": "^3.0.0",
+        "make-dir": "^4.0.0",
+        "supports-color": "^7.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/istanbul-lib-report/node_modules/has-flag": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/istanbul-lib-report/node_modules/supports-color": {
+      "version": "7.2.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+      "dev": true,
+      "dependencies": {
+        "has-flag": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/istanbul-lib-source-maps": {
+      "version": "5.0.4",
+      "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.4.tgz",
+      "integrity": "sha512-wHOoEsNJTVltaJp8eVkm8w+GVkVNHT2YDYo53YdzQEL2gWm1hBX5cGFR9hQJtuGLebidVX7et3+dmDZrmclduw==",
+      "dev": true,
+      "dependencies": {
+        "@jridgewell/trace-mapping": "^0.3.23",
+        "debug": "^4.1.1",
+        "istanbul-lib-coverage": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/istanbul-reports": {
+      "version": "3.1.7",
+      "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz",
+      "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==",
+      "dev": true,
+      "dependencies": {
+        "html-escaper": "^2.0.0",
+        "istanbul-lib-report": "^3.0.0"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/jackspeak": {
       "version": "2.3.6",
       "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz",
@@ -5793,6 +5922,65 @@
         "node": ">=12"
       }
     },
+    "node_modules/magicast": {
+      "version": "0.3.4",
+      "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.4.tgz",
+      "integrity": "sha512-TyDF/Pn36bBji9rWKHlZe+PZb6Mx5V8IHCSxk7X4aljM4e/vyDvZZYwHewdVaqiA0nb3ghfHU/6AUpDxWoER2Q==",
+      "dev": true,
+      "dependencies": {
+        "@babel/parser": "^7.24.4",
+        "@babel/types": "^7.24.0",
+        "source-map-js": "^1.2.0"
+      }
+    },
+    "node_modules/make-dir": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
+      "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
+      "dev": true,
+      "dependencies": {
+        "semver": "^7.5.3"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/make-dir/node_modules/lru-cache": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+      "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+      "dev": true,
+      "dependencies": {
+        "yallist": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/make-dir/node_modules/semver": {
+      "version": "7.6.0",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz",
+      "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==",
+      "dev": true,
+      "dependencies": {
+        "lru-cache": "^6.0.0"
+      },
+      "bin": {
+        "semver": "bin/semver.js"
+      },
+      "engines": {
+        "node": ">=10"
+      }
+    },
+    "node_modules/make-dir/node_modules/yallist": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+      "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+      "dev": true
+    },
     "node_modules/map-stream": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz",
@@ -7397,6 +7585,62 @@
         "url": "https://opencollective.com/unts"
       }
     },
+    "node_modules/test-exclude": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz",
+      "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==",
+      "dev": true,
+      "dependencies": {
+        "@istanbuljs/schema": "^0.1.2",
+        "glob": "^7.1.4",
+        "minimatch": "^3.0.4"
+      },
+      "engines": {
+        "node": ">=8"
+      }
+    },
+    "node_modules/test-exclude/node_modules/brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "dev": true,
+      "dependencies": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "node_modules/test-exclude/node_modules/glob": {
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+      "dev": true,
+      "dependencies": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.1.1",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      },
+      "engines": {
+        "node": "*"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/isaacs"
+      }
+    },
+    "node_modules/test-exclude/node_modules/minimatch": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+      "dev": true,
+      "dependencies": {
+        "brace-expansion": "^1.1.7"
+      },
+      "engines": {
+        "node": "*"
+      }
+    },
     "node_modules/text-table": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
diff --git a/package.json b/package.json
index fe648fd2342c222ce21ce8de1351ed04156581de..88bf81d13c99ce997982fd7b8147f70b8cade92e 100644
--- a/package.json
+++ b/package.json
@@ -19,6 +19,7 @@
     "@popperjs/core": "^2.11.8",
     "axios": "^1.6.8",
     "bootstrap": "^5.3.3",
+    "install": "^0.13.0",
     "js-cookie": "^3.0.5",
     "oh-vue-icons": "^1.0.0-rc3",
     "pinia": "^2.1.7",
@@ -34,6 +35,7 @@
     "@types/node": "^20.12.5",
     "@vitejs/plugin-vue": "^5.0.4",
     "@vitejs/plugin-vue-jsx": "^3.1.0",
+    "@vitest/coverage-v8": "^1.5.0",
     "@vue/eslint-config-prettier": "^9.0.0",
     "@vue/eslint-config-typescript": "^13.0.0",
     "@vue/test-utils": "^2.4.5",
diff --git a/spec.json b/spec.json
index 26570a49b0bae494c990a7ffb525e6bedf4c6a7f..39d296813341dac9fecbc619df7eb63d3a4287e9 100644
--- a/spec.json
+++ b/spec.json
@@ -1,535 +1 @@
-{
-  "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
+{"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":{"409":{"description":"Email already exists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExceptionResponse"}}}},"201":{"description":"Successfully signed up","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuthenticationResponse"}}}}},"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"},"rank":{"type":"integer","format":"int64"}}}},"securitySchemes":{"Bearer Authentication":{"type":"http","scheme":"bearer","bearerFormat":"JWT"}}}}
\ No newline at end of file
diff --git a/src/api/index.ts b/src/api/index.ts
index 22e1808268ec1c7b349141ce999d2e4b668cb45c..952a64c78269b8003d0635a30820fdd15932e689 100644
--- a/src/api/index.ts
+++ b/src/api/index.ts
@@ -12,6 +12,7 @@ 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 { PasswordResetDTO } from './models/PasswordResetDTO';
 export type { ProfileDTO } from './models/ProfileDTO';
 export type { SignUpRequest } from './models/SignUpRequest';
 export type { UserDTO } from './models/UserDTO';
@@ -19,4 +20,4 @@ export type { UserUpdateDTO } from './models/UserUpdateDTO';
 
 export { AuthenticationService } from './services/AuthenticationService';
 export { LeaderboardService } from './services/LeaderboardService';
-export { UserControllerService } from './services/UserControllerService';
+export { UserService } from './services/UserService';
diff --git a/src/api/models/LeaderboardEntryDTO.ts b/src/api/models/LeaderboardEntryDTO.ts
index 9a93b2ff579409b4fa78077ba9f9cb47befc465d..6a7dc1d7c916baae5ea0b496ac69ef08792f4e98 100644
--- a/src/api/models/LeaderboardEntryDTO.ts
+++ b/src/api/models/LeaderboardEntryDTO.ts
@@ -6,5 +6,6 @@ import type { UserDTO } from './UserDTO';
 export type LeaderboardEntryDTO = {
     user?: UserDTO;
     score?: number;
+    rank?: number;
 };
 
diff --git a/src/api/services/UserControllerService.ts b/src/api/services/UserService.ts
similarity index 53%
rename from src/api/services/UserControllerService.ts
rename to src/api/services/UserService.ts
index 5a1ea3560cb016455a4d2c77c2e34e9b0754a684..d4bec02c95c05faf669d7d0663da47d34ff67771 100644
--- a/src/api/services/UserControllerService.ts
+++ b/src/api/services/UserService.ts
@@ -2,15 +2,55 @@
 /* istanbul ignore file */
 /* tslint:disable */
 /* eslint-disable */
+import type { PasswordResetDTO } from '../models/PasswordResetDTO';
 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 {
+export class UserService {
     /**
-     * Update profile
+     * Initiate a password reset
+     * Send a password reset mail to the user with the specified email
+     * @returns any Successfully initiated a password reset
+     * @throws ApiError
+     */
+    public static resetPassword({
+        requestBody,
+    }: {
+        requestBody: string,
+    }): CancelablePromise<any> {
+        return __request(OpenAPI, {
+            method: 'POST',
+            url: '/api/users/reset-password',
+            body: requestBody,
+            mediaType: 'text/plain',
+        });
+    }
+    /**
+     * Confirm a password reset
+     * Confirms a password reset using a token and a new password
+     * @returns void
+     * @throws ApiError
+     */
+    public static confirmPasswordReset({
+        requestBody,
+    }: {
+        requestBody: PasswordResetDTO,
+    }): CancelablePromise<void> {
+        return __request(OpenAPI, {
+            method: 'POST',
+            url: '/api/users/confirm-password',
+            body: requestBody,
+            mediaType: 'application/json',
+            errors: {
+                403: `Invalid token`,
+            },
+        });
+    }
+    /**
+     * Update a profile
      * Update the profile of the authenticated user
      * @returns UserDTO Successfully updated profile
      * @throws ApiError
@@ -28,8 +68,8 @@ export class UserControllerService {
         });
     }
     /**
-     * Get profile
-     * Get user profile
+     * Get a profile
+     * Get the profile of a user
      * @returns ProfileDTO Successfully got profile
      * @throws ApiError
      */
@@ -47,8 +87,8 @@ export class UserControllerService {
         });
     }
     /**
-     * Get user
-     * Get user information
+     * Get the authenticated user
+     * Get all user information for the authenticated user
      * @returns UserDTO Successfully got user
      * @throws ApiError
      */
diff --git a/src/assets/icons/black_paintBrush.svg b/src/assets/icons/black_paintBrush.svg
new file mode 100644
index 0000000000000000000000000000000000000000..004dc5c256ebe65d2de56f6d8c4e9bd3e94fe9e8
--- /dev/null
+++ b/src/assets/icons/black_paintBrush.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M440-80q-33 0-56.5-23.5T360-160v-160H240q-33 0-56.5-23.5T160-400v-280q0-66 47-113t113-47h480v440q0 33-23.5 56.5T720-320H600v160q0 33-23.5 56.5T520-80h-80ZM240-560h480v-200h-40v160h-80v-160h-40v80h-80v-80H320q-33 0-56.5 23.5T240-680v120Zm0 160h480v-80H240v80Zm0 0v-80 80Z"/></svg>
\ No newline at end of file
diff --git a/src/assets/icons/black_person.svg b/src/assets/icons/black_person.svg
new file mode 100644
index 0000000000000000000000000000000000000000..787c1a2c5f8ba200d2254734be28326996a3f678
--- /dev/null
+++ b/src/assets/icons/black_person.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="32" viewBox="0 -960 960 960" width="32"><path d="M480-481q-66 0-108-42t-42-108q0-66 42-108t108-42q66 0 108 42t42 108q0 66-42 108t-108 42ZM160-160v-94q0-38 19-65t49-41q67-30 128.5-45T480-420q62 0 123 15.5t127.921 44.694q31.301 14.126 50.19 40.966Q800-292 800-254v94H160Zm60-60h520v-34q0-16-9.5-30.5T707-306q-64-31-117-42.5T480-360q-57 0-111 11.5T252-306q-14 7-23 21.5t-9 30.5v34Zm260-321q39 0 64.5-25.5T570-631q0-39-25.5-64.5T480-721q-39 0-64.5 25.5T390-631q0 39 25.5 64.5T480-541Zm0-90Zm0 411Z" fill="#000"/></svg>
\ No newline at end of file
diff --git a/src/assets/icons/download.svg b/src/assets/icons/download.svg
new file mode 100644
index 0000000000000000000000000000000000000000..00ee08bbec0c0421ce472cf666530061a2f3501f
--- /dev/null
+++ b/src/assets/icons/download.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M480-320 280-520l56-58 104 104v-326h80v326l104-104 56 58-200 200ZM240-160q-33 0-56.5-23.5T160-240v-120h80v120h480v-120h80v120q0 33-23.5 56.5T720-160H240Z" fill="#ffffff"/></svg>
\ No newline at end of file
diff --git a/src/assets/icons/paintBrush.svg b/src/assets/icons/paintBrush.svg
new file mode 100644
index 0000000000000000000000000000000000000000..9bc0b0da47075b208009c939b52b2b595576dfc0
--- /dev/null
+++ b/src/assets/icons/paintBrush.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 -960 960 960" width="24"><path d="M440-80q-33 0-56.5-23.5T360-160v-160H240q-33 0-56.5-23.5T160-400v-280q0-66 47-113t113-47h480v440q0 33-23.5 56.5T720-320H600v160q0 33-23.5 56.5T520-80h-80ZM240-560h480v-200h-40v160h-80v-160h-40v80h-80v-80H320q-33 0-56.5 23.5T240-680v120Zm0 160h480v-80H240v80Zm0 0v-80 80Z" fill="#ffffff"/></svg>
\ No newline at end of file
diff --git a/src/assets/items/pigcoin.png b/src/assets/items/pigcoin.png
new file mode 100644
index 0000000000000000000000000000000000000000..302e7e190ca30d4868094fb733fc1b8f2a438a55
Binary files /dev/null and b/src/assets/items/pigcoin.png differ
diff --git a/src/components/Buttons/ShopButton.vue b/src/components/Buttons/ShopButton.vue
index 4e28fcdb6e68eb87602d970bd0d612a46270668d..4ed5e02632d891b47f6752b8e870987b3e178edc 100644
--- a/src/components/Buttons/ShopButton.vue
+++ b/src/components/Buttons/ShopButton.vue
@@ -1,5 +1,5 @@
 <template>
-    <button type="button" class="btn btn-primary" id="buttonStyle"><img src="@/assets/items/v-buck.png" style="width: 2rem"> +{{ buttonText }}</button>
+    <button type="button" class="btn btn-primary" id="buttonStyle"><img src="@/assets/items/pigcoin.png" style="width: 2rem"> +{{ buttonText }}</button>
 </template>
 
 <script>
diff --git a/src/components/LeaderboardComponents/Leaderboard.vue b/src/components/LeaderboardComponents/Leaderboard.vue
index 0a1b9a5b472971d79cac4aa62380e891caa72ec7..9003a25a4c37050a30eafc00cb1551c4885b0dc7 100644
--- a/src/components/LeaderboardComponents/Leaderboard.vue
+++ b/src/components/LeaderboardComponents/Leaderboard.vue
@@ -1,161 +1,197 @@
 <template>
-    <div id="leaderboard">
-      <div class="ribbon"></div>
-      <table>
-        <tr v-for="(entry, index) in leaderboard" :key="entry.user.id">
-          <td class="number">{{ index + 1 }}</td>
+  <div id="leaderboard">
+    <div class="ribbon"></div>
+    <table>
+      <tbody>
+        <tr v-for="(entry, index) in leaderboard" :key="entry.user.id" :class="{ 'is-user-5': entry.user.firstName === 'User' }">
+          <td class="number">{{ entry.rank }}</td>
           <td class="name" @click="navigateToUserProfile(entry.user.id)">{{ entry.user.firstName }}</td>
           <td class="points" v-if="index === 0">
             {{ entry.score }}
-            <div class = "medal">
-                <img class="gold-medal" src="https://github.com/malunaridev/Challenges-iCodeThis/blob/master/4-leaderboard/assets/gold-medal.png?raw=true" alt="gold medal" />
+            <div class="medal">
+              <img class="gold-medal"
+                src="https://github.com/malunaridev/Challenges-iCodeThis/blob/master/4-leaderboard/assets/gold-medal.png?raw=true"
+                alt="gold medal" />
             </div>
-        </td>
-        <td v-else class="points">{{ entry.score }}</td>
+          </td>
+          <td v-else class="points">{{ entry.score }}</td>
         </tr>
-      </table>
-    </div>
-  </template>
-  
-  <script setup lang="ts">
-  import { ref } from 'vue';
-  import { useRouter } from 'vue-router';
-  
-  const router = useRouter();
-  
-  const props = defineProps({
-    leaderboard: {
-      type: Array,
-      required: true
-    }
-  });
-  
-  const navigateToUserProfile = () => {
-    router.push({ name: 'news' });
-  };
-  </script>
-  
-  <style scoped>
-  #leaderboard {
-    width: 100%;
-    position: relative;
-  }
-  
-  table {
-    width: 100%;
-    border-collapse: collapse;
-    table-layout: fixed;
-    color: #141a39;
-    cursor: default;
-  }
-  
-  tr {
-    transition: all 0.2s ease-in-out;
-    border-radius: 0.2rem;
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-    height: 4rem;
-  }
-  
-  tr:not(:first-child):hover {
-    background-color: #fff;
-    transform: scale(1.1);
-    -webkit-box-shadow: 0px 5px 15px 8px #e4e7fb;
-    box-shadow: 0px 5px 15px 8px #e4e7fb;
-  }
-  
-  tr:nth-child(even) {
-    background-color: #f9f9f9;
-  }
-  
-  tr:nth-child(1) {
-    color: #fff;
+      </tbody>
+      <tbody id="line">`</tbody>
+      <tbody v-if="!userInLeaderboard">
+        <tr></tr>
+        <tr v-for="(entry, index) in leaderboardExtra" :key="entry.user.id" :class="{ 'is-user-5': entry.user.firstName === 'User' }">
+          <td class="number">{{ entry.rank }}</td>
+          <td class="name" @click="navigateToUserProfile(entry.user.id)">{{ entry.user.firstName }}</td>
+          <td class="points">{{ entry.score }}</td>
+        </tr>
+      </tbody>
+      <tbody v-else></tbody>
+    </table>
+  </div>
+</template>
+
+
+<script setup lang="ts">
+import { computed } from 'vue';
+import { useRouter } from 'vue-router';
+import { useUserInfoStore } from '@/stores/UserStore';
+
+const router = useRouter();
+const userStore = useUserInfoStore();
+
+const props = defineProps({
+  leaderboard: {
+    type: Array,
+    required: true
+  },
+  leaderboardExtra: {
+    type: Array,
+    required: true
+  }
+});
+
+console.log(props.leaderboardExtra);
+
+const userInLeaderboard = computed(() => props.leaderboard.some(entry => entry.user.email === userStore.email));
+
+const navigateToUserProfile = () => {
+  router.push({ name: 'user-profile' });
+};
+</script>
+
+<style scoped>
+#leaderboard {
+  width: 100%;
+  position: relative;
+}
+
+table {
+  width: 100%;
+  border-collapse: collapse;
+  table-layout: fixed;
+  color: #141a39;
+  cursor: default;
+}
+
+tr {
+  transition: all 0.2s ease-in-out;
+  border-radius: 0.2rem;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  height: 4rem;
+}
+
+tr:not(:first-child):hover {
+  background-color: #fff;
+  transform: scale(1.1);
+  -webkit-box-shadow: 0px 5px 15px 8px #e4e7fb;
+  box-shadow: 0px 5px 15px 8px #e4e7fb;
+}
+
+tr:nth-child(even) {
+  background-color: #f9f9f9;
+}
+
+tr:nth-child(1) {
+  color: #fff;
+}
+
+td {
+  height: 2rem;
+  font-family: "Rubik", sans-serif;
+  font-size: 1.4rem;
+  padding: 1rem 2rem;
+  position: relative;
+}
+
+.number {
+  width: 1rem;
+  font-size: 2.2rem;
+  font-weight: bold;
+  text-align: left;
+  display: flex;
+  align-items: center;
+}
+
+.name {
+  font-size: 1.3rem;
+  cursor: pointer;
+  display: flex;
+  align-items: center;
+}
+
+.points {
+  font-weight: bold;
+  font-size: 1.3rem;
+  display: flex;
+  justify-content: flex-end;
+  align-items: center;
+}
+
+@media (max-width: 1000px) {
+  .number .name .points {
+    font-size: 0.5rem;
   }
-  
+
   td {
-    height: 2rem;
-    font-family: "Rubik", sans-serif;
-    font-size: 1.4rem;
-    padding: 1rem 2rem;
-    position: relative;
-  }
-  
-  .number {
-    width: 1rem;
-    font-size: 2.2rem;
-    font-weight: bold;
-    text-align: left;
-    display: flex;
-    align-items: center;
-  }
-  
-  .name {
-    font-size: 1.3rem;
-    cursor: pointer;
-    display: flex;
-    align-items: center;
-  }
-  
-  .points {
-    font-weight: bold;
-    font-size: 1.3rem;
-    display: flex;
-    justify-content: flex-end;
-    align-items: center;
+    padding: 0.2rem 0.5rem;
   }
+}
 
-  @media (max-width: 1000px) {
-    .number .name .points {
-      font-size: 0.5rem;
-    }
 
-    td {
-      padding: 0.2rem 0.5rem;
-    }
-  }
+.points:first-child {
+  width: 10rem;
+}
 
-  
-  .points:first-child {
-    width: 10rem;
-  }
-  
-  .gold-medal {
-    height: 3rem;
-    margin-left: 1.5rem;
-  }
-  
-  .ribbon {
-    width: 106%;
-    height: 4.5rem;
-    top: -0.5rem;
-    background-color: #0A58CA;
-    position: absolute;
-    /**left: -1rem;*/
-    box-shadow: 0px 15px 11px -6px #7a7a7d;
-  }
-  
-  .ribbon::before {
-    content: "";
-    height: 1.5rem;
-    width: 1.5rem;
-    bottom: -0.8rem;
-    left: 0.35rem;
-    transform: rotate(45deg);
-    background-color: #0A58CA;
-    position: absolute;
-    z-index: -1;
-  }
-  
-  .ribbon::after {
-    content: "";
-    height: 1.5rem;
-    width: 1.5rem;
-    bottom: -0.8rem;
-    right: 0.35rem;
-    transform: rotate(45deg);
-    background-color: #0A58CA;
-    position: absolute;
-    z-index: -1;
-  }
-  </style>
\ No newline at end of file
+.gold-medal {
+  height: 3rem;
+  margin-left: 1.5rem;
+}
+
+.ribbon {
+  width: 106%;
+  height: 4.5rem;
+  top: -0.5rem;
+  background-color: #0A58CA;
+  position: absolute;
+  /**left: -1rem;*/
+  box-shadow: 0px 15px 11px -6px #7a7a7d;
+}
+
+.ribbon::before {
+  content: "";
+  height: 1.5rem;
+  width: 1.5rem;
+  bottom: -0.8rem;
+  left: 0.35rem;
+  transform: rotate(45deg);
+  background-color: #0A58CA;
+  position: absolute;
+  z-index: -1;
+}
+
+.ribbon::after {
+  content: "";
+  height: 1.5rem;
+  width: 1.5rem;
+  bottom: -0.8rem;
+  right: 0.35rem;
+  transform: rotate(45deg);
+  background-color: #0A58CA;
+  position: absolute;
+  z-index: -1;
+}
+
+#line {
+  width: 100%;
+  height: 0.01rem;
+  border-top: 8px solid #0A58CA;
+}
+
+tr.is-user-5 {
+  background-color: #419c5c !important;
+  color: #fff !important;
+}
+</style>
\ No newline at end of file
diff --git a/src/components/Login/Login.vue b/src/components/Login/Login.vue
index 25469a19d2cbd3c352545218fe480114ae8c6181..834e1b7e7e3c7c62076dbfdb0c3897abc3f1daaa 100644
--- a/src/components/Login/Login.vue
+++ b/src/components/Login/Login.vue
@@ -3,11 +3,29 @@ import LoginForm from '@/components/Login/LoginForm.vue'
 </script>
 
 <template>
-  <div class="container-fluid">
-    <LoginForm/>
+  <div class="containers">
+    <div class="box">
+      <LoginForm/>
+    </div>
   </div>
 </template>
 
-<style>
+<style scoped>
+  .containers {
+    background-color: #A2CC99;
+    height: 100vh;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+  }
 
+  .box {
+    background-color: white;
+    border-radius: 3rem;
+    max-width: 450px;
+    padding: 1rem 4rem;
+    box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 29px 0px;
+  }
+
+  
 </style>
\ No newline at end of file
diff --git a/src/components/Login/LoginForm.vue b/src/components/Login/LoginForm.vue
index 6091ab82d28b5c081b081370cd01996d78d327d2..3401af96d2977c1f508c15d2dc47e3e9748a2c6d 100644
--- a/src/components/Login/LoginForm.vue
+++ b/src/components/Login/LoginForm.vue
@@ -93,6 +93,7 @@ const handleSubmit = async () => {
                  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>Forgotten password? <RouterLink to="/forgotten-password">Reset password</RouterLink></p>
 
       <p class="text-danger">{{ errorMsg }}</p>
       <button1 id="confirmButton" type="submit" @click="handleSubmit" button-text="Login"></button1>
diff --git a/src/components/SignUp/SignUp.vue b/src/components/SignUp/SignUp.vue
index 4dff39dcd4bbe2a47e1471473d7a1632eb540827..eb272c6f1966c45c9d61045a1375fc8dcfb14981 100644
--- a/src/components/SignUp/SignUp.vue
+++ b/src/components/SignUp/SignUp.vue
@@ -4,9 +4,27 @@ import SignUpForm from '@/components/SignUp/SignUpForm.vue'
 </script>
 
 <template>
-  <SignUpForm/>
+  <div class="containers">
+    <div class="box">
+      <SignUpForm />
+    </div>
+  </div>
 </template>
 
 <style scoped>
+.containers {
+  background-color: #A2CC99;
+  height: 100vh;
+  display: flex;
+  justify-content: center;
+}
 
+.box {
+  width: 450px;
+  margin: 2rem;
+  background-color: white;
+  border-radius: 3rem;
+  padding: 1rem 4rem;
+  box-shadow: rgba(100, 100, 111, 0.2) 0px 7px 29px 0px;
+}
 </style>
\ No newline at end of file
diff --git a/src/components/SignUp/SignUpForm.vue b/src/components/SignUp/SignUpForm.vue
index dad760e62b52dab00c22e31e5c63dba26ad0c0bb..b0b04ad2309aeaa1c82d1d86e651838a98decc68 100644
--- a/src/components/SignUp/SignUpForm.vue
+++ b/src/components/SignUp/SignUpForm.vue
@@ -68,6 +68,7 @@ const handleSubmit = async () => {
 
 <template>
   <div class="container">
+    <img src="@/assets/Sparesti-logo.png" style="width: 120px">
     <form ref="formRef" id="signUpForm" @submit.prevent="handleSubmit" novalidate>
       <BaseInput :model-value=firstNameRef
                  @input-change-event="handleFirstNameInputEvent"
@@ -124,12 +125,17 @@ const handleSubmit = async () => {
 
 .container {
   max-width: 450px;
+  display: flex;
+  justify-content: center;
+  align-items: center; 
+  flex-direction: column;
 }
 
 #signUpForm {
   display: flex;
   flex-direction: column;
   justify-items: center;
+  width: 100%;
 }
 
 #firstNameInput, #surnameInput, #emailInput, #passwordInput, #confirmButton, #confirmPasswordInput {
diff --git a/src/components/UpdateUserComponents/UpdateUserLayout.vue b/src/components/UpdateUserComponents/UpdateUserLayout.vue
new file mode 100644
index 0000000000000000000000000000000000000000..511ece58743fbe4502419a4646f6247c680d2530
--- /dev/null
+++ b/src/components/UpdateUserComponents/UpdateUserLayout.vue
@@ -0,0 +1,326 @@
+<script setup lang="ts">
+import BaseInput from "@/components/InputFields/BaseInput.vue";
+import { onMounted, ref } from "vue";
+import { AuthenticationService, LeaderboardService, UserService, type UserUpdateDTO } from "@/api";
+import { useUserInfoStore } from "@/stores/UserStore";
+
+const firstNameRef = ref()
+const surnameRef = ref('')
+const emailRef = ref('')
+const passwordRef = ref('')
+const confirmPasswordRef = ref('')
+const formRef = ref()
+let samePasswords = ref(true)
+
+async function setupForm() {
+  try {
+    let response = await UserService.getUser();
+    console.log(response.firstName)
+
+    firstNameRef.value = response.firstName;
+    if (response.lastName != null) {
+      surnameRef.value = response.lastName;
+    }
+    if (response.email != null) {
+      emailRef.value = response.email
+    }
+  } catch (err) {
+    console.error(err)
+  }
+}
+
+
+
+const handleFirstNameInputEvent = (newValue: any) => {
+  firstNameRef.value = newValue
+}
+
+
+const handleSurnameInputEvent = (newValue: any) => {
+  surnameRef.value = newValue
+}
+
+const handleEmailInputEvent = (newValue: any) => {
+  emailRef.value = newValue
+}
+
+const handlePasswordInputEvent = (newValue: any) => {
+  passwordRef.value = newValue
+}
+
+const handleConfirmPasswordInputEvent = (newValue: any) => {
+  confirmPasswordRef.value = newValue
+}
+
+const handleSubmit = async () => {
+
+  samePasswords.value = (passwordRef.value === confirmPasswordRef.value)
+  console.log(samePasswords.value)
+  formRef.value.classList.add("was-validated")
+  const form = formRef.value;
+
+  const updateUserPayload: UserUpdateDTO = {
+    firstName: firstNameRef.value,
+    lastName: surnameRef.value,
+    email: emailRef.value,
+    password: passwordRef.value
+  };
+
+
+
+
+
+  if (form.checkValidity()) {
+    if (samePasswords.value) {
+      try {
+        UserService.update({ requestBody: updateUserPayload })
+        useUserInfoStore().setUserInfo({
+          email: emailRef.value,
+          firstname: firstNameRef.value,
+          lastname: surnameRef.value,
+          password: passwordRef.value
+        })
+
+      } catch (err) {
+        cosole.error(err)
+      }
+    }
+  } else {
+    console.log('Form is not valid');
+  }
+
+}
+onMounted(() => {
+  setupForm()
+})
+
+
+
+</script>
+
+<template>
+  <div class="containers">
+    <div class="row gutters">
+      <div class="col-xl-3 col-lg-3 col-md-12 col-sm-12 col-12">
+        <div class="card h-100">
+          <div class="card-body">
+            <div class="account-settings">
+              <div class="user-profile">
+                <div class="user-avatar">
+                  <img src="https://bootdey.com/img/Content/avatar/avatar7.png" alt="Maxwell Admin">
+                </div>
+                <div class="text-center">
+                  <div class="mt-2">
+                    <span class="btn btn-primary"><img src="@/assets/icons/download.svg"></span>
+                  </div>
+                </div>
+                <br>
+                <h5 class="user-name">Yuki Hayashi</h5>
+                <h6 class="user-email">yuki@Maxwell.com</h6>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <div class="col-xl-9 col-lg-9 col-md-12 col-sm-12 col-12">
+        <div class="card h-100">
+          <div class="card-body">
+            <div class="row gutters">
+              <div class="col-xl-12 col-lg-12 col-md-12 col-sm-12 col-12">
+                <h6 class="mb-2 text-primary">Personal Details <img src="@/assets/icons/black_person.svg"></h6>
+              </div>
+              <div class="col-xl-6 col-lg-6 col-md-6 col-sm-6 col-12">
+                <div class="form-group">
+                  <BaseInput :model-value="firstNameRef" @input-change-event="handleFirstNameInputEvent"
+                    id="firstNameInputChange" input-id="first-name-new" type="text" label="First name"
+                    placeholder="Enter your first name" invalid-message="Please enter your first name" />
+                </div>
+              </div>
+              <div class="col-xl-6 col-lg-6 col-md-6 col-sm-6 col-12">
+                <div class="form-group">
+                  <BaseInput :model-value="surnameRef" @input-change-event="handleSurnameInputEvent"
+                    id="surnameInput-change" input-id="surname-new" type="text" label="Surname"
+                    placeholder="Enter your surname" invalid-message="Please enter your surname" />
+
+                </div>
+              </div>
+              <div class="col-xl-6 col-lg-6 col-md-6 col-sm-6 col-12">
+                <div class="form-group">
+                  <BaseInput :model-value="emailRef" @input-change-event="handleEmailInputEvent" id="emailInput-change"
+                    input-id="email-new" type="email" label="Email" placeholder="Enter your email"
+                    invalid-message="Invalid email" />
+
+                </div>
+              </div>
+              <div class="col-xl-6 col-lg-6 col-md-6 col-sm-6 col-12">
+                <div class="form-group">
+                  <BaseInput :model-value="passwordRef" @input-change-event="handlePasswordInputEvent"
+                    id="passwordInput-change" input-id="password-new" type="password"
+                    pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{4,16}" label="Password" placeholder="Enter password"
+                    invalid-message="Password must be between 4 and 16 characters and contain one capital letter, small letter and a number" />
+
+                </div>
+              </div>
+            </div>
+
+            <div class="row gutters">
+              <div class="col-xl-12 col-lg-12 col-md-12 col-sm-12 col-12" style="margin-top: 10px;">
+                <h6 class="mb-2 text-primary">Personal Configuration <img src="@/assets/icons/black_person.svg"></h6>
+              </div>
+              <div class="accordion" id="accordionExample">
+                <div class="accordion-item">
+                  <h2 class="accordion-header">
+                    <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
+                      data-bs-target="#collapseThree" aria-expanded="true" aria-controls="collapseThree">
+                      Configuration
+                    </button>
+                  </h2>
+                  <div id="collapseThree" class="accordion-collapse collapse" data-bs-parent="#accordionExample">
+                    <div class="accordion-body">
+                      Hallo
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+            <div class="row gutters">
+              <div class="col-xl-12 col-lg-12 col-md-12 col-sm-12 col-12">
+                <h6 class="mt-3 mb-2 text-primary">Styles <img src="@/assets/icons/black_paintBrush.svg"></h6>
+              </div>
+              <div class="accordion" id="accordionExample">
+                <div class="accordion-item">
+                  <h2 class="accordion-header">
+                    <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
+                      data-bs-target="#collapseOne" aria-expanded="false" aria-controls="collapseOne">
+                      Profile pictures
+                    </button>
+                  </h2>
+                  <div id="collapseOne" class="accordion-collapse collapse" data-bs-parent="#accordionExample">
+                    <div class="accordion-body">
+                      Hallo
+                    </div>
+                  </div>
+                </div>
+                <div class="accordion-item">
+                  <h2 class="accordion-header">
+                    <button class="accordion-button collapsed" type="button" data-bs-toggle="collapse"
+                      data-bs-target="#collapseTwo" aria-expanded="false" aria-controls="collapseTwo">
+                      Road styles
+                    </button>
+                  </h2>
+                  <div id="collapseTwo" class="accordion-collapse collapse" data-bs-parent="#accordionExample">
+                    <div class="accordion-body">
+                      Hallo
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+            <div class="row gutters">
+              <div class="col-xl-12 col-lg-12 col-md-12 col-sm-12 col-12">
+                <div class="text-right">
+                  <button type="button" id="submit" name="submit" class="btn btn-secondary">Cancel</button>
+                  <button type="button" id="submit" name="submit" class="btn btn-primary">Update</button>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+
+</template>
+
+<style scoped>
+body {
+  margin: 0;
+  padding-top: 40px;
+  color: #2e323c;
+  background: #f5f6fa;
+  position: relative;
+  height: 100%;
+}
+
+.row {
+  margin: 0px;
+}
+
+.containers {
+  width: 100%;
+  justify-content: center;
+  display: flex;
+  align-items: center;
+  margin-top: 2rem;
+  margin-bottom: 4rem;
+}
+
+.account-settings .user-profile {
+  margin: 0 0 1rem 0;
+  padding-bottom: 1rem;
+  text-align: center;
+}
+
+.account-settings .user-profile .user-avatar {
+  margin: 0 0 1rem 0;
+}
+
+.account-settings .user-profile .user-avatar img {
+  width: 90px;
+  height: 90px;
+  -webkit-border-radius: 100px;
+  -moz-border-radius: 100px;
+  border-radius: 100px;
+}
+
+.account-settings .user-profile h5.user-name {
+  margin: 0 0 0.5rem 0;
+}
+
+.account-settings .user-profile h6.user-email {
+  margin: 0;
+  font-size: 0.8rem;
+  font-weight: 400;
+  color: #9fa8b9;
+}
+
+.account-settings .about {
+  margin: 2rem 0 0 0;
+  text-align: center;
+}
+
+.account-settings .about h5 {
+  margin: 0 0 15px 0;
+  color: #007ae1;
+}
+
+.account-settings .about p {
+  font-size: 0.825rem;
+}
+
+.form-control {
+  border: 1px solid #cfd1d8;
+  -webkit-border-radius: 2px;
+  -moz-border-radius: 2px;
+  border-radius: 2px;
+  font-size: .825rem;
+  background: #ffffff;
+  color: #2e323c;
+}
+
+.text-right {
+  display: flex;
+  justify-content: flex-end;
+  margin-top: 10px;
+}
+
+.card {
+  background: #efefef;
+  -webkit-border-radius: 5px;
+  -moz-border-radius: 5px;
+  border-radius: 5px;
+  border: 0;
+  margin-bottom: 1rem;
+  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.12), 0 1px 2px rgba(0, 0, 0, 0.24);
+}
+</style>
\ No newline at end of file
diff --git a/src/components/UserProfile/UserProfileLayout.vue b/src/components/UserProfile/UserProfileLayout.vue
index e36115715e64b79691d773ea44286d46558620fd..db2c4bca1ccc4af534c3a5aacd5dd162657ffaec 100644
--- a/src/components/UserProfile/UserProfileLayout.vue
+++ b/src/components/UserProfile/UserProfileLayout.vue
@@ -2,7 +2,8 @@
 
 import Menu from "@/components/BaseComponents/Menu.vue";
 import Footer from "@/components/BaseComponents/Footer.vue";
-import {useRouter} from "vue-router";
+import { useRouter } from "vue-router";
+import { useUserInfoStore } from "../../stores/UserStore";
 
 let numberOfHistory = 6;
 
@@ -12,109 +13,119 @@ let points = 0;
 let streak = 0;
 
 let route = useRouter()
-function toRoadmap(){
+function toRoadmap() {
   route.push('/roadmap')
 }
+
+function toUpdateUserSettings() {
+  route.push('/update-user')
+}
 </script>
 
 <template>
-    <div class="container text-center">
-    <div class="row">
-      <div class="col">
-        <img src="/src/assets/userprofile.png" class="img-fluid">
-        <p class="h2">Username</p>
-        <p><a class="link-dark" href="#">Edit profile</a></p>
-      </div>
-    </div>
-      <div class="row">
-        <div class="col">
-          <img src="/src/assets/icons/fire.png" class="img-fluid" style="width: 30px; height: 30px" alt="dollar">
-          <p>Streak: 10</p>
-        </div>
-      </div>
-      <div class="row">
-      <div class="col-12">
-        <img src="/src/assets/icons/dollar.png" class="img-fluid" style="width: 30px; height: 30px" alt="dollar">
-        <p class="">Points: 2000 </p>
-      </div>
-      </div>
-
-    <div class="row">
-      <div class="col">
-        total points earned
-      </div>
-      <div class="col">
-        total badges earned
-      </div>
-    </div>
-    <div class="row">
-      <div class="col">
-        <!-- Here is the badges of the user -->
-        <div class="container-fluid">
-          <h1 class="mt-5 text-start badges-text">Badges</h1>
-          <div class="scrolling-wrapper-badges row flex-row flex-nowrap mt-4 pb-4 pt-2">
-
-            <div class="col-5">
-              <div class="card badges-block card-1"></div>
+  <div class="container py-5 h-100">
+    <div class="row d-flex justify-content-center align-items-center h-100">
+      <div class="col 12">
+        <div class="card">
+          <div class="rounded-top text-white d-flex flex-row bg-primary" style="height:200px;">
+            <div class="ms-4 mt-5 d-flex flex-column" style="width: 150px;">
+              <img src="https://bootdey.com/img/Content/avatar/avatar3.png" alt="Generic placeholder image"
+                class="img-fluid img-thumbnail mt-4 mb-2" style="width: 150px; z-index: 1">
+              <button type="button" data-mdb-button-init data-mdb-ripple-init class="btn btn-outline-primary"
+                data-mdb-ripple-color="dark" style="z-index: 1;" @click="toUpdateUserSettings">
+                Edit profile
+              </button>
             </div>
-            <div class="col-5">
-              <div class="card badges-block card-2"></div>
+            <div class="ms-3" style="margin-top: 130px;">
+              <h1>Andy Horwitz</h1>
             </div>
-            <div class="col-5">
-              <div class="card badges-block card-3"></div>
-            </div>
-            <div class="col-5">
-              <div class="card badges-block card-4"></div>
-            </div>
-            <div class="col-5">
-              <div class="card badges-block card-5"></div>
-            </div>
-            <div class="col-5">
-              <div class="card badges-block card-6"></div>
-            </div>
-            <div class="col-5">
-              <div class="card badges-block card-7"></div>
-            </div>
-            <div class="col-5">
-              <div class="card badges-block card-8"></div>
-            </div>
-            <div class="col-5">
-              <div class="card badges-block card-9"></div>
-            </div>
-            <div class="col-5">
-              <div class="card badges-block card-10"></div>
+          </div>
+          <div class="p-4 text-black" style="background-color: #f8f9fa;">
+            <div class="d-flex justify-content-end text-center py-1">
+              <div>
+                <p class="mb-1 h2">253 <img src="@/assets/items/pigcoin.png" style="width: 4rem"></p>
+                <p class="small text-muted mb-0">Points</p>
+              </div>
+              <div class="px-3">
+                <p class="mb-1 h2">1026 <img src="@/assets/icons/fire.png" style="width: 4rem"></p>
+                <p class="small text-muted mb-0">Streak</p>
+              </div>
             </div>
           </div>
-        </div>
-      </div>
-    </div>
-    <div class="row">
-      <div class="col">
-        <!-- Here is the history of saving target -->
-        <div class="container-fluid mb-5">
-          <h1 class="mt-5 text-start history-text">History</h1>
-          <div class="row scrolling-wrapper-history">
-            <div v-for="index in numberOfHistory" :key="index" class="col-md-4 col-sm-4 col-lg-4 col-xs-4 col-xl-4 control-label">
-              <div class="card history-block" >
-                <div class="card mb-3" style="max-width: 540px;">
-                  <div class="row g-0">
-                    <div class="col-md-4">
-                      <img src="/src/assets/icons/piggybank.svg" class="img-fluid rounded-start h-40 mx-auto d-none d-md-block" alt="...">
+          <div class="card-body p-1 text-black">
+            <div class="row">
+              <div class="col">
+                <div class="container-fluid">
+                  <h1 class="mt-5 text-start badges-text">Badges</h1>
+                  <div class="scrolling-wrapper-badges row flex-row flex-nowrap mt-4 pb-4 pt-2">
+
+                    <div class="col-5">
+                      <div class="card badges-block card-1"></div>
+                    </div>
+                    <div class="col-5">
+                      <div class="card badges-block card-2"></div>
+                    </div>
+                    <div class="col-5">
+                      <div class="card badges-block card-3"></div>
+                    </div>
+                    <div class="col-5">
+                      <div class="card badges-block card-4"></div>
+                    </div>
+                    <div class="col-5">
+                      <div class="card badges-block card-5"></div>
                     </div>
-                    <div class="col-md-8">
-                      <div class="card-body">
-                        <h5 class="card-title">{{cardTitles[index-1]}}</h5>
-                        <p class="card-text">Money saved: 200 <br/>You are one challenge: 21</p>
-                        <p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
-                        <a href="#" class="btn  stretched-link" @click="toRoadmap"></a>
+                    <div class="col-5">
+                      <div class="card badges-block card-6"></div>
+                    </div>
+                    <div class="col-5">
+                      <div class="card badges-block card-7"></div>
+                    </div>
+                    <div class="col-5">
+                      <div class="card badges-block card-8"></div>
+                    </div>
+                    <div class="col-5">
+                      <div class="card badges-block card-9"></div>
+                    </div>
+                    <div class="col-5">
+                      <div class="card badges-block card-10"></div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </div>
+            <div class="row">
+              <div class="col">
+                <!-- Here is the history of saving target -->
+                <div class="container-fluid mb-5">
+                  <h1 class="mt-5 text-start history-text">History</h1>
+                  <div class="row scrolling-wrapper-history">
+                    <div v-for="index in numberOfHistory" :key="index"
+                      class="col-md-4 col-sm-4 col-lg-4 col-xs-4 col-xl-4 control-label">
+                      <div class="card history-block">
+                        <div class="card mb-3" style="max-width: 540px;">
+                          <div class="row g-0">
+                            <div class="col-md-4">
+                              <img src="/src/assets/icons/piggybank.svg"
+                                class="img-fluid rounded-start h-40 mx-auto d-none d-md-block" alt="...">
+                            </div>
+                            <div class="col-md-8">
+                              <div class="card-body">
+                                <h5 class="card-title">{{ cardTitles[index - 1] }}</h5>
+                                <p class="card-text">Money saved: 200 <br />You are one challenge: 21</p>
+                                <p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
+                                <a href="#" class="btn  stretched-link" @click="toRoadmap"></a>
+                              </div>
+                            </div>
+                          </div>
+                        </div>
                       </div>
                     </div>
                   </div>
+
                 </div>
               </div>
             </div>
           </div>
-
         </div>
       </div>
     </div>
@@ -122,28 +133,28 @@ function toRoadmap(){
 </template>
 
 <style scoped>
-.scrolling-wrapper-badges{
+.scrolling-wrapper-badges {
   overflow-x: auto;
 }
 
-.scrolling-wrapper-history{
+.scrolling-wrapper-history {
   max-height: 300px;
   overflow: auto;
 }
 
 
 
-.badges-text{
+.badges-text {
   font-weight: 500;
   font-size: 2.0em;
 }
 
-.history-text{
+.history-text {
   font-weight: 500;
   font-size: 2.0em;
 }
 
-.badges-block{
+.badges-block {
   height: 200px;
   background-color: #fff;
   border: none;
@@ -151,14 +162,15 @@ function toRoadmap(){
   background-size: cover;
   transition: all 0.2s ease-in-out !important;
   border-radius: 24px;
-  &:hover{
+
+  &:hover {
     transform: translateY(-5px);
     box-shadow: none;
     opacity: 0.9;
   }
 }
 
-.history-block{
+.history-block {
   height: 200px;
 
   background-color: #fff;
@@ -168,61 +180,68 @@ function toRoadmap(){
   transition: all 0.2s ease-in-out !important;
   border-radius: 24px;
   margin: 20px;
-  &:hover{
+
+  &:hover {
     transform: translateY(-5px);
     box-shadow: none;
     opacity: 0.9;
   }
 }
 
-.card-1{
+.card-1 {
   background-color: #4158D0;
   background-image: linear-gradient(43deg, #4158D0 0%, #C850C0 46%, #FFCC70 100%);
 }
 
-.card-2{
+.card-2 {
   background-color: #0093E9;
   background-image: linear-gradient(160deg, #0093E9 0%, #80D0C7 100%);
 }
 
-.card-3{
+.card-3 {
   background-color: #00DBDE;
   background-image: linear-gradient(90deg, #00DBDE 0%, #FC00FF 100%);
 }
 
-.card-4{
+.card-4 {
   background-color: #FBAB7E;
   background-image: linear-gradient(62deg, #FBAB7E 0%, #F7CE68 100%);
 }
 
-.card-5{
+.card-5 {
   background-color: #85FFBD;
   background-image: linear-gradient(45deg, #85FFBD 0%, #FFFB7D 100%);
 }
 
-.card-6{
+.card-6 {
   background-color: #FA8BFF;
   background-image: linear-gradient(45deg, #FA8BFF 0%, #2BD2FF 52%, #2BFF88 90%);
 }
 
-.card-7{
+.card-7 {
   background-color: #FA8BFF;
   background-image: linear-gradient(45deg, #FA8BFF 0%, #2BD2FF 52%, #2BFF88 90%);
 }
 
-.card-8{
+.card-8 {
   background-color: #FBDA61;
   background-image: linear-gradient(45deg, #FBDA61 0%, #FF5ACD 100%);
 }
 
-.card-9{
+.card-9 {
   background-color: #4158D0;
   background-image: linear-gradient(43deg, #4158D0 0%, #C850C0 46%, #FFCC70 100%);
 }
 
-.card-10{
+.card-10 {
   background-color: #FF3CAC;
   background-image: linear-gradient(225deg, #FF3CAC 0%, #784BA0 50%, #2B86C5 100%);
 
 }
+
+
+/*-------*/
+.rounded-top {
+  background-color: #00DBDE;
+}
 </style>
\ No newline at end of file
diff --git a/src/router/index.ts b/src/router/index.ts
index 170e39ea9491fc3e2defbab475f4ae3a74b41080..70bd7ba69d8236b5ae338cec2490cb7c47ed272e 100644
--- a/src/router/index.ts
+++ b/src/router/index.ts
@@ -4,6 +4,7 @@ import LoginView from '../views/Authentication/LoginView.vue';
 import { useUserInfoStore } from '@/stores/UserStore';
 import UserProfileView from "@/views/User/UserProfileView.vue";
 import SignUp from '@/components/SignUp/SignUp.vue'
+import UpdateUserView from "@/views/UpdateUser/UpdateUserView.vue";
 
 
 const routes = [
@@ -33,6 +34,16 @@ const routes = [
         name: 'test',
         component: () => import('@/views/TestView.vue'),
       },
+      {
+        path: '/profile',
+        name: 'profile',
+        component: UserProfileView
+      },
+      {
+        path: 'update-user',
+        name: 'update-user',
+        component: UpdateUserView
+      },
       {
         path: 'roadmap',
         name: 'roadmap',
diff --git a/src/views/Authentication/ChangePasswordView.vue b/src/views/Authentication/ChangePasswordView.vue
index ad52ab1b300380fa1c665e882c88b83f217424ac..36e2e75e365f0f9bb01d81155533be0fa48e2ec0 100644
--- a/src/views/Authentication/ChangePasswordView.vue
+++ b/src/views/Authentication/ChangePasswordView.vue
@@ -1,61 +1,86 @@
 <template>
-    <div class="container">
-      <div class="row justify-content-center">
-        <div class="col-lg-5">
-          <div class="card shadow-lg border-0 rounded-lg mt-5">
-            <div class="card-header"><h3 class="text-center font-weight-light my-4">Password Recovery</h3></div>
-            <div class="card-body">
-              <div class="small mb-3 text-muted">Enter the new password for your account</div>
-              <form @submit.prevent="submitForm">
-                <div class="form-floating mb-3">
-                  <input v-model="newPassword" class="form-control" id="newPassword" type="password" placeholder="New Password" required>
-                  <label for="newPassword">Enter your new password</label>
+    <div class="containers">
+        <div class="row justify-content-center">
+            <div class="col-lg-5">
+                <div class="card shadow-lg border-0 rounded-lg mt-5">
+                    <div class="card-header">
+                        <h3 class="text-center font-weight-light my-4">Password Recovery</h3>
+                    </div>
+                    <div class="card-body">
+                        <div class="small mb-3 text-muted">Enter the new password for your account</div>
+                        <form @submit.prevent="submitForm">
+                            <div class="form-floating mb-3">
+                                <input v-model="newPassword" class="form-control" id="newPassword" type="password"
+                                    placeholder="New Password" required>
+                                <label for="newPassword">Enter your new password</label>
+                            </div>
+                            <div class="form-floating mb-3">
+                                <input v-model="confirmPassword" class="form-control" id="confirmPassword"
+                                    type="password" placeholder="Confirm Password" required>
+                                <label for="confirmPassword">Confirm your new password</label>
+                            </div>
+                            <div class="errorMsg">{{ errormsg }}</div>
+                            <div class="d-flex align-items-center justify-content-between mt-4 mb-0">
+                                <router-link to="/login" class="small">Return to login</router-link>
+                                <button class="btn btn-primary" type="submit">Confirm Password</button>
+                            </div>
+                        </form>
+                    </div>
+                    <div class="card-footer text-center py-3">
+                        <div class="small"><router-link to="/sign-up">Need an account? Sign up!</router-link></div>
+                    </div>
                 </div>
-                <div class="form-floating mb-3">
-                  <input v-model="confirmPassword" class="form-control" id="confirmPassword" type="password" placeholder="Confirm Password" required>
-                  <label for="confirmPassword">Confirm your new password</label>
-                </div>
-                <div class="d-flex align-items-center justify-content-between mt-4 mb-0">
-                  <router-link to="/login" class="small">Return to login</router-link>
-                  <button class="btn btn-primary" type="submit">Confirm Password</button>
-                </div>
-              </form>
             </div>
-            <div class="card-footer text-center py-3">
-              <div class="small"><router-link to="/sign-up">Need an account? Sign up!</router-link></div>
-            </div>
-          </div>
         </div>
-      </div>
     </div>
-  </template>
-  
-  <script setup lang="ts">
-  import { ref } from 'vue';
-  import { useRouter } from 'vue-router';
-  import axios from 'axios';
-
-  const router = useRouter();
-  
-  const newPassword = ref('');
-  const confirmPassword = ref('');
-  
-  const submitForm = async () => {
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue';
+import { useRouter, useRoute } from 'vue-router';
+import axios from 'axios';
+import { UserService } from '@/api';
+
+const router = useRouter();
+const route = useRoute();
+
+const token = route.params.token;
+
+const newPassword = ref('');
+const confirmPassword = ref('');
+
+let errormsg = ref('');
+
+const submitForm = async () => {
     if (newPassword.value !== confirmPassword.value) {
-      alert('Passwords do not match!');
-      return;
+        errormsg.value = 'The passwords do not match';
+        return;
     }
+    errormsg.value = '';
     try {
-      const response = await axios.post('/api/reset-password', {
-        password: newPassword.value,
-        confirmPassword: confirmPassword.value
-      });
-      console.log('Success:', response.data);
+        const resetPassword = {
+            password: newPassword.value,
+            token: token
+        };
+        const response = await UserService.confirmPasswordReset({ requestBody: resetPassword });
+        console.log(response);
         router.push('/login');
     } catch (error) {
-      console.error('Error:', error);
+        console.error('Error:', error);
+    }
+};
+
+</script>
+
+<style scoped>
+    .containers {
+        width: 100%;
+        background-color: #A2CC99;
+        height: 100vh;
+    }
+
+    .row {
+        margin-right: 0px;
+        margin-left: 0px;
     }
-  };
-  
-  </script>
-  
\ No newline at end of file
+</style>
\ No newline at end of file
diff --git a/src/views/Authentication/ForgottenPasswordView.vue b/src/views/Authentication/ForgottenPasswordView.vue
index 521c2aa54b52169ae720d94d9862f8464cb10ebf..07501b6f6593a120c171fc99bc72a7bbf0bfe893 100644
--- a/src/views/Authentication/ForgottenPasswordView.vue
+++ b/src/views/Authentication/ForgottenPasswordView.vue
@@ -1,52 +1,72 @@
 <template>
-    <div class="container">
-      <div class="row justify-content-center">
-        <div class="col-lg-5">
-          <div class="card shadow-lg border-0 rounded-lg mt-5">
-            <div class="card-header"><h3 class="text-center font-weight-light my-4">Password Recovery</h3></div>
-            <div class="card-body">
-              <div class="small mb-3 text-muted">Enter your email address and we will send you a link to reset your password.</div>
-              <form @submit.prevent="submitForm">
-                <div class="form-floating mb-3">
-                  <input v-model="email" class="form-control" id="inputEmail" type="email" placeholder="name@example.com" required> 
-                  <label for="inputEmail">Enter email address</label>
+    <div class="containers">
+        <div class="row justify-content-center">
+            <div class="col-lg-5">
+                <div class="card shadow-lg border-0 rounded-lg mt-5">
+                    <div class="card-header">
+                        <h3 class="text-center font-weight-light my-4">Password Recovery</h3>
+                    </div>
+                    <div class="card-body">
+                        <div class="small mb-3 text-muted">Enter your email address and we will send you a link to reset
+                            your password.</div>
+                        <form @submit.prevent="submitForm">
+                            <div class="form-floating mb-3">
+                                <input v-model="email" class="form-control" id="inputEmail" type="email"
+                                    placeholder="name@example.com" required>
+                                <label for="inputEmail">Enter email address</label>
+                            </div>
+                            <div class="d-flex align-items-center justify-content-between mt-4 mb-0">
+                                <router-link to="/login" class="small">Return to login</router-link>
+                                <button class="btn btn-primary" type="submit">Reset Password</button>
+                            </div>
+                            <div class="text-success">
+                                {{ confirmationMessage }}
+                            </div>
+                        </form>
+                    </div>
+                    <div class="card-footer text-center py-3">
+                        <div class="small"><router-link to="/sign-up">Need an account? Sign up!</router-link></div>
+                    </div>
                 </div>
-                <div class="d-flex align-items-center justify-content-between mt-4 mb-0">
-                  <router-link to="/login" class="small">Return to login</router-link>
-                  <button class="btn btn-primary" type="submit">Reset Password</button>
-                </div>
-                <div class="text-success">
-                    {{ confirmationMessage }}
-                </div>
-              </form>
-            </div>
-            <div class="card-footer text-center py-3">
-              <div class="small"><router-link to="/sign-up">Need an account? Sign up!</router-link></div>
             </div>
-          </div>
         </div>
-      </div>
     </div>
-  </template>
-  
-  <script setup lang="ts">
-  import { ref } from 'vue';
-  import { useRouter } from 'vue-router';
-  import axios from 'axios';
-  
-  const router = useRouter();
-  const email = ref('');
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue';
+import { useRouter, useRoute } from 'vue-router';
+import axios from 'axios';
+import { UserService } from '@/api';
+
+const router = useRouter();
+
+const email = ref('');
+let confirmationMessage = ref('');
 
-    let confirmationMessage = ref('');
-  
-  const submitForm = async () => {
+const submitForm = async () => {
     try {
-      const response = await axios.post('/api/password-reset', { email: email.value });
-      console.log('Success:', response.data);
-      confirmationMessage.value = 'An email has been sent to your email address with a link to reset your password.';
+        const response = await UserService.resetPassword({
+            requestBody: email.value 
+        });
+        console.log('Success:', response.data);
+        confirmationMessage.value = 'An email has been sent to your email address with a link to reset your password.';
     } catch (error) {
-      console.error('Error:', error);
+        console.error('Error:', error);
+    }
+};
+
+</script>
+
+<style scoped>
+    .containers {
+        width: 100%;
+        background-color: #A2CC99;
+        height: 100vh;
+    }
+
+    .row {
+        margin-right: 0px;
+        margin-left: 0px;
     }
-  };
-  </script>
-  
\ No newline at end of file
+</style>
\ No newline at end of file
diff --git a/src/views/LeaderboardView.vue b/src/views/LeaderboardView.vue
index 769c67973bae2d8b15612e38a1141279d845ed3e..16b4ae404a28b1fa484d981980f072ce8fa8824d 100644
--- a/src/views/LeaderboardView.vue
+++ b/src/views/LeaderboardView.vue
@@ -17,16 +17,16 @@
     </div>
     <main>
         <div id="leaderboard">
-            <h1><img src="@/assets/items/v-buck.png" style="width: 2rem"> Total points</h1>
-            <Leaderboard :leaderboard="pointsLeaderboardData" @navigateToUserProfile="navigateToUserProfile" />
+            <h1><img src="@/assets/items/pigcoin.png" style="width: 3rem"> Total points</h1>
+            <Leaderboard :leaderboard="pointsLeaderboardData" :leaderboardExtra="pointsLeaderboardDataExtra" @navigateToUserProfile="navigateToUserProfile" />
         </div>
         <div id="leaderboard">
             <h1><img src="@/assets/icons/fire.png" style="width: 2rem"> Current streak</h1>
-            <Leaderboard :leaderboard="currentLeaderboardData" @navigateToUserProfile="navigateToUserProfile" />
+            <Leaderboard :leaderboard="currentLeaderboardData" :leaderboardExtra="currentLeaderboardDataExtra" @navigateToUserProfile="navigateToUserProfile" />
         </div>
         <div id="leaderboard">
             <h1><img src="@/assets/icons/fire.png" style="width: 2rem"> Highest streak</h1>
-            <Leaderboard :leaderboard="streakLeaderboardData" @navigateToUserProfile="navigateToUserProfile" />
+            <Leaderboard :leaderboard="streakLeaderboardData" :leaderboardExtra="streakLeaderboardDataExtra" @navigateToUserProfile="navigateToUserProfile" />
         </div>
     </main>
     </div>
@@ -41,12 +41,16 @@ import { onMounted, ref } from 'vue';
 import { useRoute, useRouter } from 'vue-router';
 import Leaderboard from '@/components/LeaderboardComponents/Leaderboard.vue';
 import { on } from 'events';
-import { LeaderboardService } from '@/api';
+import { LeaderboardService, UserControllerService } from '@/api';
 
 let streakLeaderboardData = ref([]);
 let currentLeaderboardData = ref([]);
 let pointsLeaderboardData = ref([]);
 
+let streakLeaderboardDataExtra = ref([]);
+let currentLeaderboardDataExtra = ref([]);
+let pointsLeaderboardDataExtra = ref([]);
+
 const router = useRouter();
 
 async function fetchQuizData() {
@@ -73,23 +77,26 @@ async function global() {
     let globalPointsYou = await LeaderboardService.getSurrounding({
         type: "TOTAL_POINTS",
         filter: "GLOBAL",
+        entryCount: 2,
     });
     let globalStreakYou = await LeaderboardService.getSurrounding({
         type: "TOP_STREAK",
         filter: "GLOBAL",
+        entryCount: 2,
     });
     let globalCurrentStreakYou = await LeaderboardService.getSurrounding({
         type: "CURRENT_STREAK",
         filter: "GLOBAL",
+        entryCount: 2,
     });
-
-    console.log(globalPointsYou);
-    console.log(globalStreakYou);
-    console.log(globalCurrentStreakYou);
-
+    
     pointsLeaderboardData.value = globalPoints.entries;
     currentLeaderboardData.value = globalCurrentStreak.entries;
     streakLeaderboardData.value = globalStreak.entries;
+
+    pointsLeaderboardDataExtra.value = globalPointsYou.entries;
+    currentLeaderboardDataExtra.value = globalCurrentStreakYou.entries;
+    streakLeaderboardDataExtra.value = globalStreakYou.entries;
 }
 
 async function friends() {
@@ -105,9 +112,30 @@ async function friends() {
         type: "CURRENT_STREAK",
         filter: "FRIENDS",
     });
+    let friendsPointsYou = await LeaderboardService.getSurrounding({
+        type: "TOTAL_POINTS",
+        filter: "FRIENDS",
+        entryCount: 2,
+    });
+    let friendsStreakYou = await LeaderboardService.getSurrounding({
+        type: "TOP_STREAK",
+        filter: "FRIENDS",
+        entryCount: 2,
+    });
+    let friendsCurrentStreakYou = await LeaderboardService.getSurrounding({
+        type: "CURRENT_STREAK",
+        filter: "FRIENDS",
+        entryCount: 2,
+    });
+
+
     pointsLeaderboardData.value = friendsPoints.entries;
     currentLeaderboardData.value = friendsCurrentStreak.entries;
     streakLeaderboardData.value = friendsStreak.entries;
+
+    pointsLeaderboardDataExtra.value = friendsPointsYou.entries;
+    currentLeaderboardDataExtra.value = friendsStreakYou.entries;
+    streakLeaderboardDataExtra.value = friendsCurrentStreakYou.entries;
 }
 
 const navigateToUserProfile = (userId: number) => {
@@ -121,7 +149,7 @@ main {
     width: 80%;
     display: flex;
     justify-content: space-around;
-    align-items: center;
+    align-items: start;
     flex-wrap: wrap;
     flex-direction: row;
 }
@@ -138,7 +166,6 @@ main {
 #content {
     display: flex;
     flex-direction: row;
-   
     justify-content: center;
     flex-wrap: wrap;
 }
@@ -156,7 +183,6 @@ h1 {
     display: flex;
     justify-content: center;
     margin-bottom: 2rem;
-
 }
 
 #radioContainer {
diff --git a/src/views/ShopView.vue b/src/views/ShopView.vue
index 2bf2eafe93dff64150ce1365535defa33e28fa01..86c22ee13bdac2ab935a2bb0dce6c1712aeab55d 100644
--- a/src/views/ShopView.vue
+++ b/src/views/ShopView.vue
@@ -73,14 +73,14 @@
                         <img src="@/assets/items/adfree.png" class="card-img-top" alt="...">
                         <div class="card-body">
                             <h5 class="card-title">Adfree</h5>
-                            <ShopButton button-text="35kr"></ShopButton>
+                            <button type="button" class="btn btn-primary" id="buttonStyle"> +35kr</button>
                         </div>
                     </div> 
                     <div class="card text-center" style="width: 16rem; border: none">
                         <img src="@/assets/items/piggybank.webp" class="card-img-top" alt="...">
                         <div class="card-body">
                             <h5 class="card-title">Premium</h5>
-                            <ShopButton button-text="50kr"></ShopButton>
+                            <button type="button" class="btn btn-primary" id="buttonStyle">+50kr</button>
                         </div>
                     </div> 
                 </div>
diff --git a/src/views/UpdateUser/UpdateUserView.vue b/src/views/UpdateUser/UpdateUserView.vue
new file mode 100644
index 0000000000000000000000000000000000000000..aae915c1e1225dca1b3f6ac4b34e5b987c765515
--- /dev/null
+++ b/src/views/UpdateUser/UpdateUserView.vue
@@ -0,0 +1,12 @@
+<script setup lang="ts">
+
+import UpdateUserLayout from "@/components/UpdateUserComponents/UpdateUserLayout.vue";
+</script>
+
+<template>
+<UpdateUserLayout></UpdateUserLayout>
+</template>
+
+<style scoped>
+
+</style>
\ No newline at end of file
diff --git a/vitest.config.ts b/vitest.config.ts
index 4b1c897997739635a6e14248a6448b67b2703c44..f5088576a014873999241d0a3d0fe0313984f2b3 100644
--- a/vitest.config.ts
+++ b/vitest.config.ts
@@ -8,7 +8,10 @@ export default mergeConfig(
     test: {
       environment: 'jsdom',
       exclude: [...configDefaults.exclude, 'e2e/**'],
-      root: fileURLToPath(new URL('./', import.meta.url))
+      root: fileURLToPath(new URL('./', import.meta.url)),
+      coverage: {
+          provider: 'v8'
+      }
     }
   })
 )