From e7e355560fe4a7e818f0cc760fc03cadc1221b86 Mon Sep 17 00:00:00 2001
From: Zara Mudassar <zara.1310@hotmail.com>
Date: Tue, 26 Apr 2022 14:03:36 +0200
Subject: [PATCH] login form and utils added

---
 src/components/LoginForm.vue | 179 +++++++++++++++++++++++++++++++++++
 src/router/index.js          |  67 +++++++++++++
 src/utils/apiutil.js         |  73 ++++++++++++++
 3 files changed, 319 insertions(+)
 create mode 100644 src/components/LoginForm.vue
 create mode 100644 src/router/index.js
 create mode 100644 src/utils/apiutil.js

diff --git a/src/components/LoginForm.vue b/src/components/LoginForm.vue
new file mode 100644
index 0000000..9d8afb4
--- /dev/null
+++ b/src/components/LoginForm.vue
@@ -0,0 +1,179 @@
+<template>
+  <div class="App">
+    <div id="logoField" class="flex justify-center m-6">
+      <img src="../assets/logo3.svg" alt="BoCo logo" />
+    </div>
+
+    <div
+      id="emailField"
+      class="m-6"
+      :class="{ error: v$.user.email.$errors.length }"
+    >
+      <div class="mb-6">
+        <label
+          for="email"
+          class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300"
+          >E-post</label
+        >
+        <input
+          type="email"
+          id="email"
+          class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
+          placeholder="eksempel@eksempel.no"
+          v-model="v$.user.email.$model"
+          required
+        />
+        <!-- error message -->
+        <div v-for="(error, index) of v$.user.email.$errors" :key="index">
+          <div
+            class="text-red-600 text-sm"
+            v-show="showError"
+            id="emailErrorId"
+          >
+            {{ error.$message }}
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <div
+      id="passwordField"
+      class="m-6"
+      :class="{ error: v$.user.password.$errors.length }"
+    >
+      <label
+        for="password"
+        class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300"
+        >Passord</label
+      >
+      <input
+        type="password"
+        id="password"
+        class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500"
+        v-model="v$.user.password.$model"
+        required
+        @keyup.enter="loginClicked"
+      />
+      <!-- error message -->
+      <div
+        class="text-red"
+        v-for="(error, index) of v$.user.password.$errors"
+        :key="index"
+      >
+        <div
+          class="text-red-600 text-sm"
+          v-show="showError"
+          id="passwordErrorId"
+        >
+          {{ error.$message }}
+        </div>
+      </div>
+    </div>
+
+    <div id="buttonsField" class="m-6">
+      <div class="align-items: flex-end; mb-6">
+        <div class="ml-3 text-sm">
+          <router-link to="about" class="text-blue-600"
+            >Glemt passord</router-link
+          >
+        </div>
+      </div>
+      <button
+        @click="loginClicked"
+        class="flex justify-center align-items: flex-end; text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm w-full sm:w-auto px-5 py-2.5 text-center dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800"
+      >
+        Logg inn
+      </button>
+      <div class="align-items: flex-end; mb-6 mt-6">
+        <div class="ml-3 text-sm">
+          <router-link to="register" class="text-blue-600"
+            >Ny bruker</router-link
+          >
+        </div>
+      </div>
+      <div class="flex justify-center">
+        <label>{{ message }}</label>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+import useVuelidate from "@vuelidate/core";
+import { required, email, helpers } from "@vuelidate/validators";
+import { doLogin } from "@/utils/apiutil";
+import { parseUserFromToken } from "@/utils/token-utils";
+
+export default {
+  name: "LoginForm.vue",
+
+  setup() {
+    return { v$: useVuelidate() };
+  },
+
+  validations() {
+    return {
+      user: {
+        email: {
+          required,
+          email: helpers.withMessage(`E-posten er ugyldig`, email),
+        },
+        password: {
+          required,
+        },
+      },
+    };
+  },
+
+  data() {
+    return {
+      message: "",
+      user: {
+        email: "",
+        password: "",
+      },
+
+      showError: false,
+    };
+  },
+
+  methods: {
+    async loginClicked() {
+      this.showError = true;
+
+      this.v$.user.email.$touch();
+
+      if (this.v$.user.email.$invalid) {
+        console.log("Ugyldig, avslutter...");
+        return;
+      }
+
+      const loginRequest = {
+        email: this.user.email,
+        password: this.user.password,
+      };
+
+      const loginResponse = await doLogin(loginRequest);
+
+      if (loginResponse.isLoggedIn === false) {
+        this.message = "Feil e-post/passord";
+        this.$store.commit("logout");
+      } else if (loginResponse.isLoggedIn === true) {
+        this.$store.commit("saveToken", loginResponse.token);
+
+        let user = parseUserFromToken(loginResponse.token);
+        console.log(user);
+        let id = user.accountId;
+        console.log(id);
+        this.$router.push("/profile/" + id);
+      } else {
+        console.log("Something went wrong");
+      }
+    },
+
+    validate() {
+      this.$refs.form.validate();
+    },
+  },
+};
+</script>
diff --git a/src/router/index.js b/src/router/index.js
new file mode 100644
index 0000000..44952f1
--- /dev/null
+++ b/src/router/index.js
@@ -0,0 +1,67 @@
+import store from "@/store";
+import { createRouter, createWebHistory } from "vue-router";
+import HomeView from "../views/HomeView.vue";
+import LoginView from "../views/LoginView.vue";
+import NewPasswordView from "../views/NewPasswordView";
+
+const routes = [
+  {
+    path: "/", //Endre før push
+    name: "home",
+    component: HomeView,
+  },
+  {
+    path: "/about",
+    name: "about",
+    component: () => import("../views/AboutView.vue"),
+  },
+  {
+    path: "/profile/:id",
+    name: "profile",
+    component: () => import("../views/ProfileView.vue"),
+    beforeEnter: () => {
+      if (store.state.user.token == null) router.push("login");
+    },
+  },
+  {
+    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: "/login",
+    name: "login",
+    component: LoginView,
+  },
+  {
+    path: "/newPassword",
+    name: "newPassword",
+    component: NewPasswordView,
+  },
+  {
+    path: "/searchItemList",
+    name: "searchItemList",
+    component: () => import("../views/SearchItemListView.vue"),
+  },
+  {
+    path: "/createNewGroup",
+    name: "createNewGroup",
+    component: () => import("../views/CreateNewGroupView.vue"),
+  },
+  {
+    path: "/addNewItem",
+    name: "addNewItem",
+    component: () => import("../views/AddNewItemView.vue"),
+  },
+];
+
+const router = createRouter({
+  history: createWebHistory(process.env.BASE_URL),
+  routes,
+});
+
+export default router;
diff --git a/src/utils/apiutil.js b/src/utils/apiutil.js
new file mode 100644
index 0000000..94dee18
--- /dev/null
+++ b/src/utils/apiutil.js
@@ -0,0 +1,73 @@
+import axios from "axios";
+import { tokenHeader } from "./token-utils";
+
+const API_URL = process.env.VUE_APP_BASEURL;
+
+export function doLogin(loginRequest) {
+  const auth = { isLoggedIn: false, token: "" };
+  return axios
+    .post(API_URL + "login/authentication", loginRequest)
+    .then((response) => {
+      auth.isLoggedIn = true;
+      auth.token = response.data;
+      return auth;
+    })
+    .catch((error) => {
+      console.log(error.response);
+      return auth;
+    });
+}
+
+export function registerUser(registerInfo) {
+  return axios
+    .post(API_URL + "register", {
+      email: registerInfo.email,
+      firstName: registerInfo.firstName,
+      lastname: registerInfo.lastname,
+      password: registerInfo.password,
+      address: registerInfo.address,
+    })
+    .then((response) => {
+      return response;
+    })
+    .catch((err) => console.log(err));
+}
+
+export async function getUser(userid) {
+  return axios
+    .get(API_URL + "users/" + userid + "/profile", {
+      headers: tokenHeader(),
+    })
+    .then((response) => {
+      return response.data;
+    })
+    .catch((error) => {
+      console.error(error);
+    });
+}
+
+export function getRenterRating(userid) {
+  return axios
+    .get(API_URL + "rating/" + userid + "/as_owner", {
+      headers: tokenHeader(),
+    })
+    .then((response) => {
+      return response.data;
+    })
+    .catch((error) => {
+      console.error(error);
+    });
+}
+
+export function getOwnerRating(userid) {
+  return axios
+    .get(API_URL + "rating/" + userid + "/as_renter", {
+      headers: tokenHeader(),
+    })
+    .then((response) => {
+      return response.data;
+    })
+    .catch((error) => {
+      console.error(error);
+    });
+}
-- 
GitLab