Add user settings (#108)

Add email update

Add settings link to menu

Add password update route

Add password update page

Co-authored-by: kolaente <k@knt.li>
Reviewed-on: https://kolaente.dev/vikunja/frontend/pulls/108
This commit is contained in:
konrad 2020-04-17 20:46:50 +00:00
parent 335ea49801
commit a75670e4f0
7 changed files with 175 additions and 0 deletions

View file

@ -29,6 +29,9 @@
<transition name="fade"> <transition name="fade">
<div class="dropdown-menu" v-if="userMenuActive"> <div class="dropdown-menu" v-if="userMenuActive">
<div class="dropdown-content"> <div class="dropdown-content">
<router-link :to="{name: 'userSettings'}" class="dropdown-item">
Settings
</router-link>
<a @click="logout()" class="dropdown-item"> <a @click="logout()" class="dropdown-item">
Logout Logout
</a> </a>

View file

@ -0,0 +1,128 @@
<template>
<div class="loader-container" v-bind:class="{ 'is-loading': passwordUpdateService.loading}">
<div class="card">
<header class="card-header">
<p class="card-header-title">
Update Your Password
</p>
</header>
<div class="card-content">
<div class="content">
<form @submit.prevent="updatePassword()">
<div class="field">
<label class="label" for="newPassword">New Password</label>
<div class="control">
<input class="input" type="password" id="newPassword" placeholder="The new password..."
v-model="passwordUpdate.newPassword" @keyup.enter="updatePassword"/>
</div>
</div>
<div class="field">
<label class="label" for="newPasswordConfirm">New Password Confirmation</label>
<div class="control">
<input class="input" type="password" id="newPasswordConfirm" placeholder="Confirm your new password..."
v-model="passwordConfirm" @keyup.enter="updatePassword"/>
</div>
</div>
<div class="field">
<label class="label" for="currentPassword">Current Password</label>
<div class="control">
<input class="input" type="password" id="currentPassword" placeholder="Your current password"
v-model="passwordUpdate.oldPassword" @keyup.enter="updatePassword"/>
</div>
</div>
</form>
<div class="bigbuttons">
<button @click="updatePassword()" class="button is-primary is-fullwidth"
:class="{ 'is-loading': passwordUpdateService.loading}">
Save
</button>
</div>
</div>
</div>
</div>
<div class="card">
<header class="card-header">
<p class="card-header-title">
Update Your E-Mail Address
</p>
</header>
<div class="card-content">
<div class="content">
<form @submit.prevent="updateEmail()">
<div class="field">
<label class="label" for="newEmail">New Email Address</label>
<div class="control">
<input class="input" type="email" id="newEmail" placeholder="The new email address..."
v-model="emailUpdate.newEmail" @keyup.enter="updateEmail"/>
</div>
</div>
<div class="field">
<label class="label" for="currentPassword">Current Password</label>
<div class="control">
<input class="input" type="password" id="currentPassword" placeholder="Your current password"
v-model="emailUpdate.password" @keyup.enter="updateEmail"/>
</div>
</div>
</form>
<div class="bigbuttons">
<button @click="updateEmail()" class="button is-primary is-fullwidth"
:class="{ 'is-loading': emailUpdateService.loading}">
Save
</button>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import PasswordUpdateModel from '../../models/passwordUpdate'
import PasswordUpdateService from '../../services/passwordUpdateService'
import EmailUpdateService from '../../services/emailUpdate'
import EmailUpdateModel from '../../models/emailUpdate'
export default {
name: 'Settings',
data() {
return {
passwordUpdateService: PasswordUpdateService,
passwordUpdate: PasswordUpdateModel,
passwordConfirm: '',
emailUpdateService: EmailUpdateService,
emailUpdate: EmailUpdateModel,
}
},
created() {
this.passwordUpdate = new PasswordUpdateModel()
this.passwordUpdateService = new PasswordUpdateService()
this.emailUpdate = new EmailUpdateModel()
this.emailUpdateService = new EmailUpdateService()
},
methods: {
updatePassword() {
if (this.passwordConfirm !== this.passwordUpdate.newPassword) {
this.error({message: 'The new password and its confirmation don\'t match.'}, this)
return
}
this.passwordUpdateService.update(this.passwordUpdate)
.then(() => {
this.success({message: 'The password was successfully updated.'}, this)
})
.catch(e => this.error(e, this))
},
updateEmail() {
this.emailUpdateService.update(this.emailUpdate)
.then(() => {
this.success({message: 'Your email address was successfully updated. We\'ve sent you a link to confirm it.'}, this)
})
.catch(e => this.error(e, this))
},
},
}
</script>

10
src/models/emailUpdate.js Normal file
View file

@ -0,0 +1,10 @@
import AbstractModel from './abstractModel'
export default class EmailUpdateModel extends AbstractModel {
defaults() {
return {
newEmail: '',
passwort: '',
}
}
}

View file

@ -0,0 +1,10 @@
import AbstractModel from './abstractModel'
export default class PasswordUpdateModel extends AbstractModel {
defaults() {
return {
newPassword: '',
oldPassword: '',
}
}
}

View file

@ -8,6 +8,7 @@ import LoginComponent from '@/components/user/Login'
import RegisterComponent from '@/components/user/Register' import RegisterComponent from '@/components/user/Register'
import PasswordResetComponent from '@/components/user/PasswordReset' import PasswordResetComponent from '@/components/user/PasswordReset'
import GetPasswordResetComponent from '@/components/user/RequestPasswordReset' import GetPasswordResetComponent from '@/components/user/RequestPasswordReset'
import UserSettingsComponent from '@/components/user/Settings'
// List Handling // List Handling
import ShowListComponent from '@/components/lists/ShowList' import ShowListComponent from '@/components/lists/ShowList'
import NewListComponent from '@/components/lists/NewList' import NewListComponent from '@/components/lists/NewList'
@ -154,5 +155,10 @@ export default new Router({
name: 'migrateWunderlist', name: 'migrateWunderlist',
component: WunderlistMigrationComponent, component: WunderlistMigrationComponent,
}, },
{
path: '/user/settings',
name: 'userSettings',
component: UserSettingsComponent,
},
] ]
}) })

View file

@ -0,0 +1,9 @@
import AbstractService from './abstractService'
export default class EmailUpdateService extends AbstractService {
constructor() {
super({
update: '/user/settings/email',
})
}
}

View file

@ -0,0 +1,9 @@
import AbstractService from './abstractService'
export default class PasswordUpdateService extends AbstractService {
constructor() {
super({
update: '/user/password'
})
}
}