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