|
2 | 2 | <div> |
3 | 3 | <flash-message variant="danger" /> |
4 | 4 | <flash-message variant="success" /> |
5 | | - <flash-message variant="warning" /> |
6 | | - <flash-message variant="info" /> |
7 | | - <div class="py-4" v-if="errors && errors.length === 1"> |
| 5 | + <div class="pb-4" v-if="errors && errors.length === 1"> |
8 | 6 | <div class="p-2 bg-red-dark border-red-darker border items-center text-red-lightest leading-normal rounded flex lg:inline-flex w-full text-sm" |
9 | 7 | role="alert"> |
10 | 8 | <span class="flex rounded-full bg-red uppercase px-2 py-1 text-xs font-bold mr-3 leading-none">Error</span> |
11 | 9 | <span class="mr-2 text-left flex-auto">{{ errors[0] }}</span> |
12 | 10 | </div> |
13 | 11 | </div> |
14 | 12 | <form class="bg-white shadow-lg rounded-lg pt-10 px-8 pb-6 mb-4 animate fadein" method="post" |
15 | | - v-on:submit.prevent="handleLogin" |
| 13 | + v-on:submit.prevent="submitForm" |
16 | 14 | > |
17 | 15 | <div class="flex flex-wrap -mx-3 mb-6"> |
18 | 16 | <div class="input-open"> |
19 | | - <input class="input" id="grid-username" type="text" name="user" aria-labelledby="grid-username" |
| 17 | + <input class="input" id="grid-username" type="text" name="user" aria-labelledby="grid-username" required |
20 | 18 | ref="email" |
21 | | - required |
22 | 19 | v-bind:value="user.email" |
23 | 20 | v-on:input="updateEmail($event)" |
24 | 21 | /> |
|
28 | 25 | <div class="flex flex-wrap -mx-3 mb-6"> |
29 | 26 | <div class="input-open"> |
30 | 27 | <input class="input" id="grid-password" type="password" name="password" |
| 28 | + ref="password" |
31 | 29 | aria-labelledby="grid-password" required |
32 | 30 | v-model="user.password" |
33 | 31 | /> |
34 | 32 | <label for="grid-password">{{ $t('strings.password') }}</label> |
35 | 33 | </div> |
36 | 34 | </div> |
37 | 35 | <div> |
38 | | - <button class="btn btn-blue btn-jumbo" type="submit"> |
39 | | - {{ $t('auth.sign_in') }} |
| 36 | + <button class="btn btn-blue btn-jumbo" type="submit" v-bind:disabled="showSpinner"> |
| 37 | + <span class="spinner white" v-bind:class="{ hidden: ! showSpinner }"> </span> |
| 38 | + <span v-bind:class="{ hidden: showSpinner }"> |
| 39 | + {{ $t('auth.sign_in') }} |
| 40 | + </span> |
40 | 41 | </button> |
41 | 42 | </div> |
42 | 43 | <div class="pt-6 text-center"> |
|
67 | 68 | data: function () { |
68 | 69 | return { |
69 | 70 | errors: [], |
| 71 | + showSpinner: false, |
70 | 72 | } |
71 | 73 | }, |
72 | 74 | mounted: function () { |
|
75 | 77 | methods: { |
76 | 78 | // Handle a login request eminating from the form. If 2FA is required the |
77 | 79 | // user will be presented with the 2FA modal window. |
78 | | - handleLogin: function () { |
| 80 | + submitForm: function () { |
79 | 81 | const self = this; |
| 82 | + this.$data.showSpinner = true; |
80 | 83 |
|
81 | 84 | axios.post(this.route('auth.login'), { |
82 | 85 | user: this.$props.user.email, |
|
88 | 91 | } |
89 | 92 |
|
90 | 93 | self.$props.user.password = ''; |
| 94 | + self.$data.showSpinner = false; |
91 | 95 | self.$router.push({name: 'checkpoint', query: {token: response.data.token}}); |
92 | 96 | }) |
93 | 97 | .catch(function (err) { |
94 | 98 | self.$props.user.password = ''; |
| 99 | + self.$data.showSpinner = false; |
95 | 100 | if (!err.response) { |
96 | 101 | return console.error(err); |
97 | 102 | } |
98 | 103 |
|
99 | 104 | const response = err.response; |
100 | 105 | if (response.data && _.isObject(response.data.errors)) { |
101 | | - self.$data.errors.push(response.data.errors[0].detail); |
| 106 | + self.$data.errors = [response.data.errors[0].detail]; |
| 107 | + self.$refs.password.focus(); |
102 | 108 | } |
103 | 109 | }); |
104 | 110 | }, |
|
0 commit comments