WIP Progress on skeleton of the Vue app.
This commit is contained in:
25
web/src/views/Login.vue
Normal file
25
web/src/views/Login.vue
Normal file
@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<div class="login">
|
||||
<h1>Personal Measure</h1>
|
||||
<form @submit.prevent=login() class=login-form v-show="!waiting">
|
||||
<input type=text
|
||||
name=email
|
||||
v-model="loginForm.email"
|
||||
placeholder="email address">
|
||||
</input>
|
||||
<input type=password
|
||||
name=password
|
||||
v-model="loginForm.password"
|
||||
placeholder="password">
|
||||
</input>
|
||||
<button class="btn-action">Login</button>
|
||||
<div class=flash>{{flashMessage}}</div>
|
||||
</form>
|
||||
<div class=loading v-show="waiting">
|
||||
<img src="/img/mickey-open-door.gif">
|
||||
<div>logging you in...</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts" src="./login.ts"></script>
|
||||
<style lang="scss" src="./login.scss"></style>
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<nav v-bind:class='collapsed ? "collapsed" : "expanded"'>
|
||||
<nav v-if='user' v-bind:class='collapsed ? "collapsed" : "expanded"'>
|
||||
<h1 class=logo>
|
||||
<span class=expanded>Personal Measure</span>
|
||||
<span class=collapsed>PM</span>
|
||||
|
@ -1,6 +1,17 @@
|
||||
import { Component, Vue } from 'vue-property-decorator';
|
||||
import { Route, RawLocation } from 'vue-router';
|
||||
import userStore from '@/store-modules/user';
|
||||
import { NavNext } from '@/types';
|
||||
|
||||
@Component({
|
||||
components: { }
|
||||
})
|
||||
export default class Home extends Vue {}
|
||||
@Component({})
|
||||
export default class Dashboard extends Vue {
|
||||
|
||||
public get user() {
|
||||
return userStore.user;
|
||||
}
|
||||
|
||||
public beforeRouteEnter<V extends Vue>( to: Route, from: Route, next: NavNext): void {
|
||||
|
||||
next();
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +0,0 @@
|
||||
import { Component, Vue } from 'vue-property-decorator';
|
||||
|
||||
@Component({})
|
||||
export default class Dashboard extends Vue {}
|
36
web/src/views/login.scss
Normal file
36
web/src/views/login.scss
Normal file
@ -0,0 +1,36 @@
|
||||
@import '~@/styles/vars';
|
||||
|
||||
.login {
|
||||
margin: 4rem auto;
|
||||
text-align: center;
|
||||
width: 36rem;
|
||||
|
||||
.login-form {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-top: 2em;
|
||||
|
||||
input {
|
||||
border: solid thin lighten($fg-primary, 25%);
|
||||
border-radius: .25em;
|
||||
font-size: 150%;
|
||||
margin-bottom: 1em;
|
||||
padding: .5em;
|
||||
}
|
||||
|
||||
.btn-action {
|
||||
font-size: 150%;
|
||||
}
|
||||
}
|
||||
|
||||
.loading {
|
||||
margin: 1em 0;
|
||||
|
||||
img {
|
||||
border-radius: 10em;
|
||||
width: 32em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
40
web/src/views/login.ts
Normal file
40
web/src/views/login.ts
Normal file
@ -0,0 +1,40 @@
|
||||
import { Route } from 'vue-router';
|
||||
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
|
||||
import { LoginSubmit } from '@/models';
|
||||
import userStore from '@/store-modules/user';
|
||||
|
||||
@Component({})
|
||||
export default class Login extends Vue {
|
||||
|
||||
private loginForm: LoginSubmit = {
|
||||
email: '',
|
||||
password: ''
|
||||
};
|
||||
|
||||
private waiting = false;
|
||||
private flashMessage = '';
|
||||
private redirect: string | undefined = undefined;
|
||||
|
||||
public async login() {
|
||||
this.waiting = true;
|
||||
this.flashMessage = '';
|
||||
try {
|
||||
await userStore.login(this.loginForm);
|
||||
this.$router.push({ path: this.redirect || '/' });
|
||||
} catch (e) {
|
||||
if (e.response.status === 401) {
|
||||
this.flashMessage = 'invlid username or password';
|
||||
}
|
||||
}
|
||||
this.waiting = false;
|
||||
}
|
||||
|
||||
/*
|
||||
@Watch('$route', { immediate: true })
|
||||
private onRouteChange(route: Route) {
|
||||
this.redirect = route.query && route.query.redirect as string;
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// TODO: styling of flash message
|
@ -2,6 +2,7 @@ import { Component, Vue } from 'vue-property-decorator';
|
||||
import { library } from '@fortawesome/fontawesome-svg-core';
|
||||
import { faAngleDoubleLeft, faAngleDoubleRight,
|
||||
faHome, faPencilRuler, faThLarge, faUser } from '@fortawesome/free-solid-svg-icons';
|
||||
import userStore from '@/store-modules/user';
|
||||
// import UiIconButton from 'keen-ui/src/UiIconButton.vue';
|
||||
|
||||
library.add(faAngleDoubleLeft, faAngleDoubleRight, faHome, faPencilRuler, faThLarge, faUser);
|
||||
@ -23,4 +24,8 @@ export default class NavBar extends Vue {
|
||||
this.collapsed = !this.collapsed;
|
||||
return this.collapsed;
|
||||
}
|
||||
|
||||
public get user() {
|
||||
return userStore.user;
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user