diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000000000000000000000000000000000000..a988455b91ce00b0a2286f7a897daa382fc73639
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,8 @@
+version: '3'
+
+services:
+  boco-frontend:
+    build: .
+    container_name: boco-frontend
+    ports:
+      - 8080:8080
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 31f3a6f043da624d9d3c6de7b4f9106a47b92f80..1ebfe65823ba1a2c3c0b6aef4ec85fc3fdf6b845 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,8 +9,11 @@
       "version": "0.1.0",
       "dependencies": {
         "@mdi/font": "5.9.55",
+<<<<<<< HEAD
+=======
         "@vuelidate/core": "^2.0.0-alpha.40",
         "@vuelidate/validators": "^2.0.0-alpha.28",
+>>>>>>> main
         "axios": "^0.26.1",
         "core-js": "^3.8.3",
         "cssom": "^0.5.0",
diff --git a/package.json b/package.json
index 5ee7221e441487e60c51111e7f8105fb7f22f33e..a57e59f54735dbff9626df843f050b4aedb54fe2 100644
--- a/package.json
+++ b/package.json
@@ -10,8 +10,11 @@
   },
   "dependencies": {
     "@mdi/font": "5.9.55",
+<<<<<<< HEAD
+=======
     "@vuelidate/core": "^2.0.0-alpha.40",
     "@vuelidate/validators": "^2.0.0-alpha.28",
+>>>>>>> main
     "axios": "^0.26.1",
     "core-js": "^3.8.3",
     "cssom": "^0.5.0",
diff --git a/src/components/RegisterFormComponent.vue b/src/components/RegisterFormComponent.vue
new file mode 100644
index 0000000000000000000000000000000000000000..b69d38827a90245b00a8c961b4ef816511074bd6
--- /dev/null
+++ b/src/components/RegisterFormComponent.vue
@@ -0,0 +1,155 @@
+<template>
+  <v-form ref="form" v-model="valid" lazy-validation>
+    <v-text-field
+      v-model="email"
+      :rules="emailRules"
+      label="E-mail"
+      required
+    ></v-text-field>
+
+    <v-text-field
+      v-model="password"
+      :counter="32"
+      :rules="passwordRules"
+      label="Passord"
+      :append-icon="passwordHidden ? 'mdi-eye' : 'mdi-eye-off'"
+      :type="passwordHidden ? 'text' : 'password'"
+      @click:append="passwordHidden = !passwordHidden"
+      required
+    ></v-text-field>
+
+    <v-container class="grey lighten-5">
+      <v-row>
+        <v-text-field
+          class="pr-2"
+          v-model="firstName"
+          :counter="32"
+          :rules="firstNameRules"
+          label="Fornavn"
+          required
+        ></v-text-field>
+
+        <v-text-field
+          class="pl-2"
+          v-model="lastName"
+          :counter="32"
+          :rules="lastNameRules"
+          label="Etternavn"
+          required
+        ></v-text-field>
+      </v-row>
+    </v-container>
+
+    <v-text-field
+      v-model="address"
+      :counter="32"
+      :rules="addressRules"
+      label="Addresse"
+      required
+    ></v-text-field>
+
+    <!-- <v-text-field
+      v-model="confirmPassword"
+      :rules="confirmPasswordRules"
+      label="Bekreft passord"
+      :append-icon="confirmPasswordHidden ? 'mdi-eye' : 'mdi-eye-off'"
+      :type="confirmPasswordHidden ? 'text' : 'password'"
+      @click:append="confirmPasswordHidden = !confirmPasswordHidden"
+      required
+    ></v-text-field> -->
+
+    <!-- <v-select
+      v-model="select"
+      :items="items"
+      :rules="[(v) => !!v || 'Item is required']"
+      label="Item"
+      required
+    ></v-select> -->
+
+    <!-- <v-checkbox
+      v-model="checkbox"
+      :rules="[(v) => !!v || 'You must agree to continue!']"
+      label="Do you agree?"
+      required
+    ></v-checkbox> -->
+
+    <v-btn :disabled="!valid" color="success" class="mr-4" @click="submit()"
+      >Registrer</v-btn
+    >
+
+    <v-btn color="error" class="mr-4" @click="reset()">Tøm felter</v-btn>
+  </v-form>
+</template>
+<script>
+import axios from "axios";
+
+export default {
+  data: () => ({
+    passwordHidden: false,
+    // confirmPasswordHidden: false,
+    valid: true,
+    firstName: "",
+    firstNameRules: [
+      (v) => !!v || "Fornavn er påkrevd",
+      (v) => (v && v.length <= 32) || "Fornavn må være mindre enn 32 bokstaver",
+    ],
+    lastName: "",
+    lastNameRules: [
+      (v) => !!v || "Etternavn er påkrevd",
+      (v) =>
+        (v && v.length <= 32) || "Etternavn må være mindre enn 32 bokstaver",
+    ],
+    address: "",
+    addressRules: [
+      (v) => !!v || "Addresse er påkrevd",
+      (v) =>
+        (v && v.length <= 32) || "Addresse må være mindre enn 32 bokstaver",
+    ],
+    password: "",
+    passwordRules: [
+      (v) => !!v || "Passord er påkrevd",
+      (v) => (v && v.length <= 32) || "Passord må være mindre enn 32 tegn",
+      (v) => (v && v.length >= 8) || "Passord må være større enn 8 tegn",
+    ],
+    // confirmPassword: "",
+    // confirmPasswordRules: [
+    //   (v) => !!v || "Passord er påkrevd",
+    //   (v) => (v && v.length <= 32) || "Passord må være mindre enn 32 bokstaver",
+    //   // (v) => v === this.password || "Passordene må være like",
+    // ],
+    email: "",
+    emailRules: [
+      (v) => !!v || "E-mail is required",
+      (v) => /.+@.+\..+/.test(v) || "E-mail must be valid",
+    ],
+    // select: null,
+    // items: ["Item 1", "Item 2", "Item 3", "Item 4"],
+    // checkbox: false,
+  }),
+
+  methods: {
+    submit() {
+      console.log("Attempting to register user");
+      this.valid = this.$refs.form.validate();
+      if (!this.valid) return;
+      this.valid = false;
+      console.log("User is validated");
+      axios
+        .post("http://localhost:3000/api/register", {
+          email: this.email,
+          firstName: this.firstName,
+          lastname: this.lastName,
+          password: this.password,
+          address: this.address,
+        })
+        .then(console.log("Sent"))
+        .catch((e) => console.log(e));
+    },
+    reset() {
+      this.$refs.form.reset();
+      this.$refs.form.resetValidation();
+      this.valid = true;
+    },
+  },
+};
+</script>
diff --git a/src/router/index.js b/src/router/index.js
index 499849a932f5d5db6a9389fa270ee7bda4b03771..cf3844a9c1fffdda6bd0fe3375a0057fc7bc7abf 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -18,6 +18,15 @@ const routes = [
     component: () =>
       import(/* webpackChunkName: "about" */ "../views/AboutView.vue"),
   },
+  {
+    path: "/register",
+    name: "register",
+    // route level code-splitting
+    // this generates a separate chunk (register.[hash].js) for this route
+    // which is lazy-loaded when the route is visited.
+    component: () =>
+      import(/* webpackChunkName: "register" */ "../views/RegisterView.vue"),
+  },
   {
     path: "/",
     name: "login",
diff --git a/src/utils/apiutil.js b/src/utils/apiutil.js
index 15809ca5993e2d95edf6e771e1eaef3892b35cbb..773bd8d67e484a1f42d371339b5a46ce757a9347 100644
--- a/src/utils/apiutil.js
+++ b/src/utils/apiutil.js
@@ -2,7 +2,7 @@ import axios from "axios";
 
 export function doLogin(loginRequest) {
   return axios
-    .post(`http://localhost:8080/api/login/authentication`, loginRequest)
+    .post(`http://65.108.62.223:3000/api/login/authentication`, loginRequest)
     .then((response) => {
       return response.data;
     });
diff --git a/src/views/RegisterView.vue b/src/views/RegisterView.vue
new file mode 100644
index 0000000000000000000000000000000000000000..9d2ee691f97a923ea3fde5a7d1881792a252b801
--- /dev/null
+++ b/src/views/RegisterView.vue
@@ -0,0 +1,20 @@
+<template>
+  <register-form-component id="form" class="pa-8" />
+</template>
+
+<script>
+import RegisterFormComponent from "../components/RegisterFormComponent.vue";
+
+export default {
+  components: {
+    RegisterFormComponent,
+  },
+};
+</script>
+
+<style scoped>
+#form {
+  max-width: 600px;
+  margin: auto;
+}
+</style>
diff --git a/tests/unit/LoginFormComponentTest.spec.js b/tests/unit/LoginFormComponentTest.spec.js
deleted file mode 100644
index 1f892f5e720420f3aae91f6f3716955cd3b7daf2..0000000000000000000000000000000000000000
--- a/tests/unit/LoginFormComponentTest.spec.js
+++ /dev/null
@@ -1,16 +0,0 @@
-import { shallowMount } from "@vue/test-utils";
-import LoginForm from "@/components/LoginForm";
-
-describe("Tests labels in LoginForm component", () => {
-    it("checks the E-post label", () => {
-        const wrapper = shallowMount(LoginForm);
-
-        expect(wrapper.find('#emailLabelId').text()).toMatch("E-post");
-    });
-
-    it("checks the password label", () => {
-        const wrapper = shallowMount(LoginForm);
-
-        expect(wrapper.find('#passwordLabelId').text()).toMatch("Passord");
-    });
-});
diff --git a/tests/unit/apiutil-login-mock.spec.js b/tests/unit/apiutil-login-mock.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..4d0764ecff86922419d816522cff259cb9b838cd
--- /dev/null
+++ b/tests/unit/apiutil-login-mock.spec.js
@@ -0,0 +1,37 @@
+import { doLogin } from '@/utils/apiutil'
+import axios from 'axios';
+
+jest.mock('axios')
+
+describe('testing mocking of apiutil.js', () => {
+  it('check that login fails with wrong credentials - against mock', async () => {
+
+    // mock api response on POST call (once)
+    const expectedLoginResponse = {response: 'Login failed'};
+    axios.post.mockImplementation(() => Promise.resolve({data: expectedLoginResponse}));
+
+    // do the call
+    const loginRequest = {email: "wrong@email.com", password: "thisiswrong123"};
+    const loginResponse = await doLogin(loginRequest);
+
+    //  check response
+    //  note that even if wrong username and password are used, mock is configured to return Success
+    expect(loginResponse).toEqual(expectedLoginResponse);
+  });
+  it('check that login succeeds when correct credentials - against mock', async () => {
+
+    // mock api response on POST call (once)
+    const apiResponse = {response: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c'};
+    const expectedLoginResponse = {response: 'Login failed'};
+    axios.post.mockImplementation(() => Promise.resolve({data: apiResponse}));
+
+    // do the call
+    const loginRequest = {email: "correct@email.com", password: "thisiscorrect123"};
+    const loginResponse = await doLogin(loginRequest);
+
+    //  check response
+    //  note that even if wrong username and password are used, mock is configured to return Success
+    expect(loginResponse).not.toEqual(expectedLoginResponse);
+  })})
+
+