Skip to content

Commit 6627db5

Browse files
change password
1 parent 2dd5caf commit 6627db5

File tree

4 files changed

+101
-2
lines changed

4 files changed

+101
-2
lines changed

src/api/account.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import Vue from 'vue'
22
import { endpoints, replacePk } from './endpoints'
33
import {
4+
ChangePasswordReq,
45
LoginReq, LoginRes,
56
MyInfoRes,
67
RegisterTeacherReq, RegisterTeacherRes, TokenRefreshReq, TokenRefreshRes, UpdateProfileReq, UpdateProfileRes, UserDetailRes
@@ -55,5 +56,9 @@ export const account = {
5556
}
5657
})
5758
return res.data
59+
},
60+
61+
async changePassword (payload: ChangePasswordReq): Promise<void> {
62+
await Vue.axios.post(endpoints.account.users.changePassword, payload)
5863
}
5964
}

src/api/endpoints.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ export const endpoints = {
44
login: '/account/users/login/',
55
tokenRefresh: '/account/users/token-refresh/',
66
registerTeacher: '/account/users/register-teacher/',
7-
detail: '/account/users/<pk>/'
7+
detail: '/account/users/<pk>/',
8+
changePassword: '/account/users/change-password/'
89
},
910
me: {
1011
myInfo: '/account/me/',

src/interfaces/api/account.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,3 +43,8 @@ export declare interface UpdateProfileReq {
4343
}
4444

4545
export declare interface UpdateProfileRes extends User {}
46+
47+
export declare interface ChangePasswordReq {
48+
current_password: string;
49+
new_password: string;
50+
}

src/views/account/ChangePassword.vue

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,103 @@
11
<template>
22
<v-container class="container-sm">
3-
ChangePassword
3+
<v-breadcrumbs :items="breadcrumbs"></v-breadcrumbs>
4+
5+
<h1>Change password</h1>
6+
<v-divider></v-divider>
7+
8+
<v-card class="mt-5">
9+
<v-card-text>
10+
<v-form v-on:keyup.enter.native="changePassword">
11+
<v-text-field
12+
v-model="currentPassword"
13+
label="Current password"
14+
:type="showCurrentPassword ? 'text' : 'password'"
15+
:append-icon="showCurrentPassword ? 'mdi-eye' : 'mdi-eye-off'"
16+
@click:append="showCurrentPassword = !showCurrentPassword"
17+
:error-messages="currentPasswordErrs"
18+
:error-count="currentPasswordErrs.length"
19+
></v-text-field>
20+
21+
<v-text-field
22+
v-model="newPassword"
23+
label="New password"
24+
:type="showNewPassword ? 'text' : 'password'"
25+
:append-icon="showNewPassword ? 'mdi-eye' : 'mdi-eye-off'"
26+
@click:append="showNewPassword = !showNewPassword"
27+
:error-messages="newPasswordErrs"
28+
:error-count="newPasswordErrs.length"
29+
></v-text-field>
30+
</v-form>
31+
</v-card-text>
32+
33+
<v-card-actions>
34+
<v-btn
35+
color="primary"
36+
:loading="loading"
37+
@click="changePassword"
38+
min-width="110"
39+
>
40+
Save
41+
</v-btn>
42+
</v-card-actions>
43+
</v-card>
444
</v-container>
545
</template>
646

747
<script lang="ts">
48+
import { Api } from '@/api'
49+
import { VForm } from '@/interfaces/vuetify'
50+
import { snakeCaseToCamelCase } from '@/utils'
51+
import { assertErrCode, status } from '@/utils/status-codes'
852
import { Vue, Component } from 'vue-property-decorator'
953
1054
@Component
1155
export default class ChangePassword extends Vue {
56+
// eslint-disable-next-line no-undef
57+
[key: string]: unknown
58+
59+
breadcrumbs = [
60+
{ text: 'Home', to: { name: 'Home' }, exact: true },
61+
{ text: 'Profile', to: { name: 'MyInfo' }, exact: true },
62+
{ text: 'Change password', to: { name: 'ChangePassword' }, exact: true }
63+
]
64+
65+
currentPassword = ''
66+
newPassword = ''
67+
68+
currentPasswordErrs: string[] = []
69+
newPasswordErrs: string[] = []
70+
71+
showCurrentPassword = false
72+
showNewPassword = false
73+
loading = false
74+
75+
changePassword (): void {
76+
if (this.loading) return
77+
this.loading = true
1278
79+
Api.account.changePassword({
80+
current_password: this.currentPassword,
81+
new_password: this.newPassword
82+
})
83+
.then(() => {
84+
this.$router.push({ name: 'MyInfo' })
85+
})
86+
.catch(err => {
87+
if (assertErrCode(err, status.HTTP_400_BAD_REQUEST)) {
88+
const data = err.response.data
89+
Object.entries(data).forEach(([field, errMsgs]) => {
90+
const attr = `${snakeCaseToCamelCase(field)}Errs`
91+
this[attr] = errMsgs
92+
})
93+
} else if (assertErrCode(err, status.HTTP_403_FORBIDDEN)) {
94+
this.currentPasswordErrs = [err.response.data.detail]
95+
}
96+
})
97+
.finally(() => {
98+
this.loading = false
99+
})
100+
}
13101
}
14102
</script>
15103

0 commit comments

Comments
 (0)