Skip to content

Commit ef6c9e6

Browse files
reset password
1 parent 04224df commit ef6c9e6

File tree

12 files changed

+406
-139
lines changed

12 files changed

+406
-139
lines changed

src/App.vue

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import LayoutDefault from '@/layouts/LayoutDefault.vue'
1313
import { mapGetters } from 'vuex'
1414
import { User } from './interfaces/user'
1515
import { unexpectedExc } from './utils'
16+
import { assertErrCode, status } from './utils/status-codes'
1617
1718
@Component({
1819
components: {
@@ -29,14 +30,33 @@ export default class App extends Vue {
2930
loading = false
3031
initDone = false
3132
33+
noAuthenRoutes = [
34+
'Login',
35+
'Register',
36+
'ResetPassword',
37+
'NewPassword'
38+
]
39+
3240
created (): void {
3341
this.setUserInfo()
3442
}
3543
3644
setUserInfo (): void {
45+
const routeName = this.$route.name
46+
if (this.noAuthenRoutes.includes(routeName as string)) {
47+
this.initDone = true
48+
return
49+
}
50+
3751
this.loading = true
3852
this.$store.dispatch('account/getInfo')
39-
.catch(unexpectedExc)
53+
.catch(err => {
54+
if (assertErrCode(err, status.HTTP_401_UNAUTHORIZED)) {
55+
this.$router.push({ name: 'Login' })
56+
} else {
57+
unexpectedExc(err)
58+
}
59+
})
4060
.finally(() => {
4161
this.loading = false
4262
this.initDone = true
@@ -79,4 +99,8 @@ export default class App extends Vue {
7999
.container-sm {
80100
width: 1140px;
81101
}
102+
103+
.container-xs {
104+
width: 720px;
105+
}
82106
</style>

src/api/account.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ import Vue from 'vue'
22
import { endpoints, replacePk } from './endpoints'
33
import {
44
ChangePasswordReq,
5+
EmailResetPasswordLinkReq,
56
LoginReq, LoginRes,
67
MyInfoRes,
7-
RegisterTeacherReq, RegisterTeacherRes, TokenRefreshReq, TokenRefreshRes, UpdateProfileReq, UpdateProfileRes, UserDetailRes
8+
RegisterTeacherReq, RegisterTeacherRes, ResetPasswordReq, TokenRefreshReq, TokenRefreshRes, UpdateProfileReq, UpdateProfileRes, UserDetailRes
89
} from '@/interfaces/api/account'
910
import { User } from '@/interfaces/user'
1011

@@ -60,5 +61,13 @@ export const account = {
6061

6162
async changePassword (payload: ChangePasswordReq): Promise<void> {
6263
await Vue.axios.post(endpoints.account.users.changePassword, payload)
64+
},
65+
66+
async emailResetPasswordLink (payload: EmailResetPasswordLinkReq): Promise<void> {
67+
await Vue.axios.post(endpoints.account.users.emailResetPasswordLink, payload)
68+
},
69+
70+
async resetPassword (payload: ResetPasswordReq): Promise<void> {
71+
await Vue.axios.post(endpoints.account.users.resetPassword, payload)
6372
}
6473
}

src/api/endpoints.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ export const endpoints = {
55
tokenRefresh: '/account/users/token-refresh/',
66
registerTeacher: '/account/users/register-teacher/',
77
detail: '/account/users/<pk>/',
8-
changePassword: '/account/users/change-password/'
8+
changePassword: '/account/users/change-password/',
9+
emailResetPasswordLink: '/account/users/email-reset-password-link/',
10+
resetPassword: '/account/users/reset-password/'
911
},
1012
me: {
1113
myInfo: '/account/me/',

src/interfaces/api/account.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,3 +48,13 @@ export declare interface ChangePasswordReq {
4848
current_password: string;
4949
new_password: string;
5050
}
51+
52+
export declare interface EmailResetPasswordLinkReq {
53+
email: string;
54+
}
55+
56+
export declare interface ResetPasswordReq {
57+
uid: string;
58+
token: string;
59+
password: string;
60+
}

src/plugins/axios.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ function handleResponseError (error) {
129129

130130
function isLoginRoute () {
131131
if (router.options !== undefined && router.options.routes !== undefined) {
132-
const loginRoute = router.options.routes.find(route => route.name === 'Auth')
132+
const loginRoute = router.options.routes.find(route => route.name === 'Login')
133133
return (
134134
loginRoute !== undefined &&
135135
location.pathname === loginRoute.path
@@ -147,7 +147,7 @@ function goToLogin () {
147147
// If user is at some other page, redirect them to signin page
148148
const next = `${window.location.pathname}${window.location.search}`
149149
router.push({
150-
name: 'Auth',
150+
name: 'Login',
151151
query: {
152152
next
153153
}

src/router/index.ts

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ import LayoutClassroomTeacher from '../layouts/LayoutClassroomTeacher.vue'
66
import LayoutClassroomStudent from '../layouts/LayoutClassroomStudent.vue'
77

88
import Home from '../views/Home.vue'
9-
import Auth from '../views/auth/Auth.vue'
9+
import Login from '../views/auth/Login.vue'
10+
import Register from '../views/auth/Register.vue'
11+
import ResetPassword from '../views/auth/ResetPassword.vue'
12+
import NewPassword from '../views/auth/NewPassword.vue'
1013
import Http404 from '../views/http/Http404.vue'
1114

1215
import MyInfo from '../views/account/MyInfo.vue'
@@ -41,9 +44,33 @@ const routes: Array<RouteConfig> = [
4144
component: Home
4245
},
4346
{
44-
path: '/auth',
45-
name: 'Auth',
46-
component: Auth,
47+
path: '/login',
48+
name: 'Login',
49+
component: Login,
50+
meta: {
51+
layout: LayoutNoAppbar
52+
}
53+
},
54+
{
55+
path: '/register',
56+
name: 'Register',
57+
component: Register,
58+
meta: {
59+
layout: LayoutNoAppbar
60+
}
61+
},
62+
{
63+
path: '/reset-password',
64+
name: 'ResetPassword',
65+
component: ResetPassword,
66+
meta: {
67+
layout: LayoutNoAppbar
68+
}
69+
},
70+
{
71+
path: '/new-password',
72+
name: 'NewPassword',
73+
component: NewPassword,
4774
meta: {
4875
layout: LayoutNoAppbar
4976
}

src/views/account/MyInfo.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ export default class MyInfo extends Vue {
106106
107107
goodBye (): void {
108108
logout()
109-
this.$router.push({ name: 'Auth' })
109+
this.$router.push({ name: 'Login' })
110110
}
111111
}
112112
</script>

src/views/auth/Auth.vue

Lines changed: 0 additions & 32 deletions
This file was deleted.

src/views/auth/Login.vue

Lines changed: 71 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,74 @@
11
<template>
2-
<v-card outlined>
3-
<v-card-title>
4-
Keep learning
5-
</v-card-title>
2+
<v-container class="container-xs">
3+
<h1>Welcome to Tango</h1>
4+
<v-divider></v-divider>
65

7-
<v-card-subtitle>
8-
Login
9-
</v-card-subtitle>
10-
11-
<v-card-text>
12-
<v-form v-on:keyup.enter.native="login">
13-
<v-text-field
14-
v-model="email"
15-
label="Email"
16-
></v-text-field>
17-
<v-text-field
18-
v-model="password"
19-
label="Password"
20-
:type="showPassword ? 'text' : 'password'"
21-
:append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
22-
@click:append="showPassword = !showPassword"
23-
></v-text-field>
24-
</v-form>
6+
<v-card class="mt-5">
7+
<v-card-title>
8+
Login
9+
</v-card-title>
2510

26-
<div
27-
v-if="errorMsg !== ''"
28-
class="error--text mb-3"
29-
>
30-
{{ errorMsg }}
31-
</div>
11+
<v-card-text>
12+
<v-form v-on:keydown.enter.native="login">
13+
<v-text-field
14+
v-model="email"
15+
label="Email"
16+
autofocus
17+
:error-messages="emailErrs"
18+
:error-count="emailErrs.length"
19+
></v-text-field>
20+
<v-text-field
21+
v-model="password"
22+
label="Password"
23+
:type="showPassword ? 'text' : 'password'"
24+
:append-icon="showPassword ? 'mdi-eye' : 'mdi-eye-off'"
25+
@click:append="showPassword = !showPassword"
26+
:error-messages="passwordErrs"
27+
:error-count="passwordErrs.length"
28+
></v-text-field>
29+
</v-form>
3230

33-
<div>
34-
<span>Want to register as a teacher?</span>
35-
<a
36-
href="#"
37-
@click="changePage"
31+
<div
32+
v-if="errorMsg !== ''"
33+
class="error--text mb-3"
3834
>
39-
Register
40-
</a>
41-
</div>
42-
</v-card-text>
35+
{{ errorMsg }}
36+
</div>
4337

44-
<v-card-actions>
45-
<v-spacer></v-spacer>
46-
<v-btn
47-
@click="login"
48-
color="primary"
49-
depressed
50-
:loading="loading"
51-
>
52-
Login
53-
</v-btn>
54-
</v-card-actions>
55-
</v-card>
38+
<div>
39+
Want to register teacher account?
40+
<router-link :to="{ name: 'Register' }">
41+
Register
42+
</router-link>
43+
</div>
44+
45+
<div class="mt-3">
46+
Forgot password?
47+
<router-link :to="{ name: 'ResetPassword' }">
48+
Reset
49+
</router-link>
50+
</div>
51+
</v-card-text>
52+
53+
<v-card-actions>
54+
<v-spacer></v-spacer>
55+
<v-btn
56+
@click="login"
57+
color="primary"
58+
min-width="110"
59+
:loading="loading"
60+
>
61+
Login
62+
</v-btn>
63+
</v-card-actions>
64+
</v-card>
65+
</v-container>
5666
</template>
5767

5868
<script lang="ts">
5969
import { Vue, Component, Emit } from 'vue-property-decorator'
6070
import { LoginReq } from '@/interfaces/api/account'
61-
import { unexpectedExc } from '@/utils'
71+
import { snakeCaseToCamelCase, unexpectedExc } from '@/utils'
6272
import { assertErrCode, status } from '@/utils/status-codes'
6373
import { mapState } from 'vuex'
6474
@@ -70,8 +80,13 @@ import { mapState } from 'vuex'
7080
}
7181
})
7282
export default class Login extends Vue {
83+
// eslint-disable-next-line no-undef
84+
[index: string]: unknown
85+
7386
email = ''
7487
password = ''
88+
emailErrs: string[] = []
89+
passwordErrs: string[] = []
7590
showPassword = false
7691
loading = false
7792
errorMsg = ''
@@ -99,6 +114,12 @@ export default class Login extends Vue {
99114
} catch (error) {
100115
if (assertErrCode(error, status.HTTP_401_UNAUTHORIZED)) {
101116
this.errorMsg = error.response.data.detail
117+
} else if (assertErrCode(error, status.HTTP_400_BAD_REQUEST)) {
118+
const data = error.response.data
119+
Object.entries(data).forEach(([field, errMsgs]) => {
120+
const attr = `${snakeCaseToCamelCase(field)}Errs`
121+
this[attr] = errMsgs
122+
})
102123
} else {
103124
unexpectedExc(error)
104125
}

0 commit comments

Comments
 (0)