Mercurial > gemma
changeset 6:7c1bde663c8e vue-cli
current frontend
author | Thomas Junk <thomas.junk@intevation.de> |
---|---|
date | Thu, 14 Jun 2018 13:33:26 +0200 |
parents | 1597506a2241 |
children | e4bc7e0465b3 |
files | .env.sample package.json src/lib/http.js src/router.js src/stores/application.js src/stores/language.js src/stores/user.js src/views/Login.vue src/views/Main.vue yarn.lock |
diffstat | 10 files changed, 89 insertions(+), 26 deletions(-) [+] |
line wrap: on
line diff
--- a/.env.sample Wed Jun 13 10:57:57 2018 +0200 +++ b/.env.sample Thu Jun 14 13:33:26 2018 +0200 @@ -1,1 +1,2 @@ VUE_APP_TITLE="Waterway Monitoring system" +VUE_API_URL="/api/"
--- a/package.json Wed Jun 13 10:57:57 2018 +0200 +++ b/package.json Thu Jun 14 13:33:26 2018 +0200 @@ -9,6 +9,7 @@ "test:unit": "vue-cli-service test:unit" }, "dependencies": { + "axios": "^0.18.0", "bootstrap": "^4.1.1", "vue": "^2.5.16", "vue-router": "^3.0.1",
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lib/http.js Thu Jun 14 13:33:26 2018 +0200 @@ -0,0 +1,8 @@ +import axios from "axios"; + +export const HTTP = axios.create({ + baseURL: process.env.VUE_APP_API_URL || "/api" + /* headers: { + Authorization: 'Bearer {token}' + }*/ +});
--- a/src/router.js Wed Jun 13 10:57:57 2018 +0200 +++ b/src/router.js Thu Jun 14 13:33:26 2018 +0200 @@ -1,7 +1,7 @@ import Vue from "vue"; import Router from "vue-router"; import Login from "./views/Login.vue"; -import UserClient from "./views/UserClient.vue"; +import Main from "./views/Main.vue"; import store from "./store"; Vue.use(Router); @@ -9,14 +9,14 @@ const router = new Router({ routes: [ { - path: "/", + path: "/login", name: "login", component: Login }, { - path: "/client", - name: "userclient", - component: UserClient, + path: "/", + name: "main", + component: Main, meta: { requiresAuth: true } @@ -32,7 +32,7 @@ const requiresAuth = to.matched.some(record => record.meta.requiresAuth); const currentUser = store.getters["user/authenticated"]; if (requiresAuth && !currentUser) { - next("/"); + next("/login"); } else if (requiresAuth && currentUser) { next(); } else {
--- a/src/stores/application.js Wed Jun 13 10:57:57 2018 +0200 +++ b/src/stores/application.js Thu Jun 14 13:33:26 2018 +0200 @@ -1,14 +1,25 @@ const Application = { namespaced: true, state: { - appTitle: process.env.VUE_APP_TITLE + appTitle: process.env.VUE_APP_TITLE, + loginFailed: false }, getters: { appTitle: state => { return state.appTitle; + }, + loginFailed: state => { + return state.loginFailed; } }, - mutations: {}, + mutations: { + loginError(state) { + state.loginFailed = true; + }, + loginSuccess(state) { + state.loginFailed = false; + } + }, actions: {} };
--- a/src/stores/language.js Wed Jun 13 10:57:57 2018 +0200 +++ b/src/stores/language.js Thu Jun 14 13:33:26 2018 +0200 @@ -4,7 +4,8 @@ signinHeader: "Please sign in", emailLabel: "Email address", passwordLabel: "Password", - loginButtonLabel: "Login" + loginButtonLabel: "Login", + loginAttemptFailed: "Login Failed" }, getters: { signinHeader: state => { @@ -16,6 +17,9 @@ passwordLabel: state => { return state.passwordLabel; }, + loginAttemptFailed: state => { + return state.loginAttemptFailed; + }, loginButtonLabel: state => { return state.loginButtonLabel; }
--- a/src/stores/user.js Wed Jun 13 10:57:57 2018 +0200 +++ b/src/stores/user.js Thu Jun 14 13:33:26 2018 +0200 @@ -1,28 +1,39 @@ +import { HTTP } from "../lib/http"; + const User = { namespaced: true, state: { - authenticated: false, - authStatus: "error" + authenticated: false }, getters: { authenticated: state => { return state.authenticated; - }, - authStatus: state => { - return state.authStatus; } }, mutations: { - auth_success: state => { + auth_success: (state, token) => { state.authenticated = true; + sessionStorage.setItem("token", token); + }, + auth_failure: state => { + state.authenticated = false; + sessionStorage.removeItem("token"); } }, actions: { - auth({ commit }, user) { - const { username, password } = user; - if (username === "admin" && password === "secret") { - commit("auth_success"); - } + login({ commit }, user) { + return new Promise((resolve, reject) => { + HTTP.post("/token", user) + .then(response => { + let token = response.data; + commit("auth_success", token); + resolve(response); + }) + .catch(error => { + commit("auth_failure"); + reject(error); + }); + }); } } };
--- a/src/views/Login.vue Wed Jun 13 10:57:57 2018 +0200 +++ b/src/views/Login.vue Thu Jun 14 13:33:26 2018 +0200 @@ -9,11 +9,14 @@ <div class="login-wrapper border border-light d-flex flex-row justify-content-center"> <form class="form-signin" @submit.prevent="login"> <h2 class="form-signin-heading">{{ signinHeader }}</h2> + <div v-if="loginFailed" class="alert alert-danger" role="alert"> + {{ loginAttemptFailed }} + </div> <label for="inputEmail" class="sr-only">{{ emailLabel }}</label> <input type="text" v-model="username" id="inputEmail" class="form-control" :placeholder="emailLabel" required autofocus> <label for="inputPassword" class="sr-only">{{ passwordLabel }}</label> <input type="password" v-model="password" id="inputPassword" class="form-control" :placeholder="passwordLabel" required> - <button class="btn btn-lg btn-primary btn-block" type="submit">{{ loginButtonLabel }}</button> + <button class="btn btn-lg btn-primary btn-block" :disabled="submitted" type="submit">{{ loginButtonLabel }}</button> </form> </div> </div> @@ -33,22 +36,34 @@ data() { return { username: "", - password: "" + password: "", + submitted: false }; }, computed: { - ...mapGetters("application", ["appTitle"]), + ...mapGetters("application", ["appTitle", "loginFailed"]), ...mapGetters("i18n", [ "signinHeader", "emailLabel", "passwordLabel", - "loginButtonLabel" + "loginButtonLabel", + "loginAttemptFailed" ]) }, methods: { login() { + this.submitted = true; const { username, password } = this; - this.$store.dispatch("user/auth", { username, password }); + this.$store + .dispatch("user/login", { username, password }) + .then(() => { + this.$store.commit("application/loginSuccess"); + this.$router.push("/"); + }) + .catch(() => { + this.$store.commit("application/loginError"); + this.submitted = false; + }); } } };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/views/Main.vue Thu Jun 14 13:33:26 2018 +0200 @@ -0,0 +1,5 @@ +<template> + <div class="main"> + <h1>Guarded!</h1> + </div> +</template>
--- a/yarn.lock Wed Jun 13 10:57:57 2018 +0200 +++ b/yarn.lock Thu Jun 14 13:33:26 2018 +0200 @@ -1362,6 +1362,13 @@ version "1.7.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.7.0.tgz#d4d0e9b9dbfca77bf08eeb0a8a471550fe39e289" +axios@^0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.0.tgz#32d53e4851efdc0a11993b6cd000789d70c05102" + dependencies: + follow-redirects "^1.3.0" + is-buffer "^1.1.5" + babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" @@ -3436,7 +3443,7 @@ inherits "^2.0.1" readable-stream "^2.0.4" -follow-redirects@^1.0.0: +follow-redirects@^1.0.0, follow-redirects@^1.3.0: version "1.5.0" resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.0.tgz#234f49cf770b7f35b40e790f636ceba0c3a0ab77" dependencies: