@goweekdays/layer-common 1.3.1 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/components/InvitationMain.vue +83 -53
- package/components/Layout/Header.vue +1 -1
- package/components/ListGroupSelection.vue +8 -6
- package/components/MemberForm.vue +227 -0
- package/components/MemberInvite.vue +58 -7
- package/components/MemberMain.vue +161 -13
- package/components/RoleForm.vue +1 -1
- package/components/RolePermissionMain.vue +11 -16
- package/composables/useLocalAuth.ts +5 -0
- package/composables/useMember.ts +28 -18
- package/composables/useRole.ts +4 -2
- package/composables/useVerification.ts +7 -0
- package/nuxt.config.ts +30 -0
- package/package.json +1 -1
- package/pages/forgot-password.vue +76 -0
- package/pages/login.vue +156 -0
- package/pages/logout.vue +18 -0
- package/pages/member-suspended.vue +44 -0
- package/pages/sign-up/[id].vue +214 -0
- package/pages/sign-up/index.vue +135 -0
- package/plugins/member.client.ts +12 -8
- package/types/member.d.ts +2 -0
- package/types/role.d.ts +1 -1
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
:items="items"
|
|
60
60
|
item-value="_id"
|
|
61
61
|
items-per-page="20"
|
|
62
|
-
|
|
62
|
+
hide-default-header
|
|
63
63
|
hide-default-footer
|
|
64
64
|
style="max-height: calc(100vh - (126px))"
|
|
65
65
|
:loading="loading"
|
|
@@ -80,6 +80,66 @@
|
|
|
80
80
|
v-model:message="message"
|
|
81
81
|
/>
|
|
82
82
|
</v-dialog>
|
|
83
|
+
|
|
84
|
+
<v-dialog v-model="dialogView" width="450" persistent>
|
|
85
|
+
<MemberForm
|
|
86
|
+
title="View member details"
|
|
87
|
+
v-model="member"
|
|
88
|
+
mode="view"
|
|
89
|
+
@close="dialogView = false"
|
|
90
|
+
@assign="handleOpenAssignRole()"
|
|
91
|
+
@suspend="handleOpenSuspension()"
|
|
92
|
+
@activate="handleOpenActivation()"
|
|
93
|
+
@delete="handleOpenDelete()"
|
|
94
|
+
/>
|
|
95
|
+
</v-dialog>
|
|
96
|
+
|
|
97
|
+
<v-dialog v-model="dialogAssignRole" width="450" persistent>
|
|
98
|
+
<MemberForm
|
|
99
|
+
title="Assign Role"
|
|
100
|
+
v-model="member"
|
|
101
|
+
mode="assign-role"
|
|
102
|
+
@cancel="dialogAssignRole = false"
|
|
103
|
+
@submit="submitAssignRole()"
|
|
104
|
+
:disabled="disabledAssignRole"
|
|
105
|
+
/>
|
|
106
|
+
</v-dialog>
|
|
107
|
+
|
|
108
|
+
<v-dialog v-model="dialogSuspend" width="450" persistent>
|
|
109
|
+
<ConfirmationPrompt
|
|
110
|
+
title="Suspend Member"
|
|
111
|
+
action="Suspend Member"
|
|
112
|
+
content="Are you sure you want to suspend this member?"
|
|
113
|
+
@cancel="handleCancelSuspension()"
|
|
114
|
+
@confirm="submitStatus('suspended')"
|
|
115
|
+
v-model:message="message"
|
|
116
|
+
:disabled="disabledStatusChange"
|
|
117
|
+
/>
|
|
118
|
+
</v-dialog>
|
|
119
|
+
|
|
120
|
+
<v-dialog v-model="dialogActive" width="450" persistent>
|
|
121
|
+
<ConfirmationPrompt
|
|
122
|
+
title="Unsuspend Member"
|
|
123
|
+
action="Unsuspend Member"
|
|
124
|
+
content="Are you sure you want to unsuspend this member?"
|
|
125
|
+
@cancel="handleCancelSuspension()"
|
|
126
|
+
@confirm="submitStatus('active')"
|
|
127
|
+
v-model:message="message"
|
|
128
|
+
:disabled="disabledStatusChange"
|
|
129
|
+
/>
|
|
130
|
+
</v-dialog>
|
|
131
|
+
|
|
132
|
+
<v-dialog v-model="dialogDelete" width="450" persistent>
|
|
133
|
+
<ConfirmationPrompt
|
|
134
|
+
title="Remove Member"
|
|
135
|
+
action="Remove Member"
|
|
136
|
+
content="Are you sure you want to remove this member?"
|
|
137
|
+
@cancel="handleCancelDelete()"
|
|
138
|
+
@confirm="submitDelete()"
|
|
139
|
+
v-model:message="message"
|
|
140
|
+
:disabled="disabledDelete"
|
|
141
|
+
/>
|
|
142
|
+
</v-dialog>
|
|
83
143
|
</v-row>
|
|
84
144
|
</template>
|
|
85
145
|
|
|
@@ -146,15 +206,6 @@ const props = defineProps({
|
|
|
146
206
|
|
|
147
207
|
value: "roleName",
|
|
148
208
|
},
|
|
149
|
-
{
|
|
150
|
-
title: "Organization",
|
|
151
|
-
|
|
152
|
-
value: "orgName",
|
|
153
|
-
},
|
|
154
|
-
{
|
|
155
|
-
title: "Action",
|
|
156
|
-
value: "action-table",
|
|
157
|
-
},
|
|
158
209
|
],
|
|
159
210
|
},
|
|
160
211
|
});
|
|
@@ -168,8 +219,9 @@ const {
|
|
|
168
219
|
invitation,
|
|
169
220
|
member,
|
|
170
221
|
getAll: _getAll,
|
|
171
|
-
|
|
172
|
-
|
|
222
|
+
updateStatusById: _updateStatusById,
|
|
223
|
+
updateRoleById: _updateRoleById,
|
|
224
|
+
deleteById: _deleteById,
|
|
173
225
|
} = useMember();
|
|
174
226
|
|
|
175
227
|
const { headerSearch } = useLocal();
|
|
@@ -187,7 +239,7 @@ const {
|
|
|
187
239
|
org: props.orgId,
|
|
188
240
|
search: headerSearch.value,
|
|
189
241
|
page: page.value,
|
|
190
|
-
|
|
242
|
+
app: props.type,
|
|
191
243
|
}),
|
|
192
244
|
{
|
|
193
245
|
watch: [headerSearch, page],
|
|
@@ -255,4 +307,100 @@ async function submitInvite() {
|
|
|
255
307
|
function handleRowClick(_: any, data: any) {
|
|
256
308
|
setMember({ data: data.item, mode: "view" });
|
|
257
309
|
}
|
|
310
|
+
|
|
311
|
+
const dialogAssignRole = ref(false);
|
|
312
|
+
|
|
313
|
+
const disabledAssignRole = ref(false);
|
|
314
|
+
|
|
315
|
+
function handleOpenAssignRole() {
|
|
316
|
+
dialogView.value = false;
|
|
317
|
+
dialogAssignRole.value = true;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
async function submitAssignRole() {
|
|
321
|
+
disabledAssignRole.value = true;
|
|
322
|
+
try {
|
|
323
|
+
await _updateRoleById(member.value._id ?? "", member.value.role);
|
|
324
|
+
await getAll();
|
|
325
|
+
dialogAssignRole.value = false;
|
|
326
|
+
setMember({ dialog: false });
|
|
327
|
+
} catch (error: any) {
|
|
328
|
+
message.value = error.response._data.message || "An error occurred.";
|
|
329
|
+
} finally {
|
|
330
|
+
disabledAssignRole.value = false;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
const dialogSuspend = ref(false);
|
|
335
|
+
|
|
336
|
+
function handleOpenSuspension() {
|
|
337
|
+
dialogView.value = false;
|
|
338
|
+
dialogSuspend.value = true;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
function handleCancelSuspension() {
|
|
342
|
+
dialogSuspend.value = false;
|
|
343
|
+
setMember({ dialog: false });
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
const dialogActive = ref(false);
|
|
347
|
+
|
|
348
|
+
function handleOpenActivation() {
|
|
349
|
+
dialogView.value = false;
|
|
350
|
+
dialogActive.value = true;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
function handleCancelActivation() {
|
|
354
|
+
dialogActive.value = false;
|
|
355
|
+
setMember({ dialog: false });
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
const disabledStatusChange = ref(false);
|
|
359
|
+
|
|
360
|
+
async function submitStatus(status = "") {
|
|
361
|
+
disabledStatusChange.value = true;
|
|
362
|
+
try {
|
|
363
|
+
await _updateStatusById(member.value._id ?? "", status);
|
|
364
|
+
await getAll();
|
|
365
|
+
if (status === "suspended") {
|
|
366
|
+
dialogSuspend.value = false;
|
|
367
|
+
}
|
|
368
|
+
if (status === "active") {
|
|
369
|
+
dialogActive.value = false;
|
|
370
|
+
}
|
|
371
|
+
setMember({ dialog: false });
|
|
372
|
+
} catch (error: any) {
|
|
373
|
+
message.value = error.response._data.message || "An error occurred.";
|
|
374
|
+
} finally {
|
|
375
|
+
disabledStatusChange.value = false;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
const dialogDelete = ref(false);
|
|
380
|
+
|
|
381
|
+
function handleOpenDelete() {
|
|
382
|
+
dialogView.value = false;
|
|
383
|
+
dialogDelete.value = true;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
function handleCancelDelete() {
|
|
387
|
+
dialogDelete.value = false;
|
|
388
|
+
setMember({ dialog: false });
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
const disabledDelete = ref(false);
|
|
392
|
+
|
|
393
|
+
async function submitDelete() {
|
|
394
|
+
disabledDelete.value = true;
|
|
395
|
+
try {
|
|
396
|
+
await _deleteById(member.value._id ?? "");
|
|
397
|
+
await getAll();
|
|
398
|
+
dialogDelete.value = false;
|
|
399
|
+
setMember({ dialog: false });
|
|
400
|
+
} catch (error: any) {
|
|
401
|
+
message.value = error.response._data.message || "An error occurred.";
|
|
402
|
+
} finally {
|
|
403
|
+
disabledDelete.value = false;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
258
406
|
</script>
|
package/components/RoleForm.vue
CHANGED
|
@@ -68,6 +68,7 @@
|
|
|
68
68
|
<v-dialog v-model="dialogAdd" width="500" persistent>
|
|
69
69
|
<RoleForm
|
|
70
70
|
v-model="role"
|
|
71
|
+
v-model:message="message"
|
|
71
72
|
:app="props.app"
|
|
72
73
|
@cancel="setRole({ mode: 'add' })"
|
|
73
74
|
@submit="submitAdd()"
|
|
@@ -77,6 +78,7 @@
|
|
|
77
78
|
<v-dialog v-model="dialogPreview" width="500" persistent>
|
|
78
79
|
<RoleForm
|
|
79
80
|
title="Role Details"
|
|
81
|
+
:app="props.app"
|
|
80
82
|
v-model="role"
|
|
81
83
|
@close="setRole({ mode: 'view' })"
|
|
82
84
|
@edit="handOpenEdit()"
|
|
@@ -115,15 +117,10 @@ const props = defineProps({
|
|
|
115
117
|
type: String,
|
|
116
118
|
default: "",
|
|
117
119
|
},
|
|
118
|
-
|
|
120
|
+
org: {
|
|
119
121
|
type: String,
|
|
120
122
|
default: "",
|
|
121
123
|
},
|
|
122
|
-
permissions: {
|
|
123
|
-
type: Object,
|
|
124
|
-
required: true,
|
|
125
|
-
default: () => ({}),
|
|
126
|
-
},
|
|
127
124
|
types: {
|
|
128
125
|
type: Array as PropType<Array<{ title: string; value: string }>>,
|
|
129
126
|
default: () => [],
|
|
@@ -165,11 +162,6 @@ const props = defineProps({
|
|
|
165
162
|
},
|
|
166
163
|
});
|
|
167
164
|
|
|
168
|
-
const type = defineModel<string>("type", {
|
|
169
|
-
type: String,
|
|
170
|
-
default: "",
|
|
171
|
-
});
|
|
172
|
-
|
|
173
165
|
const { headerSearch } = useLocal();
|
|
174
166
|
|
|
175
167
|
const {
|
|
@@ -197,7 +189,7 @@ function setRole({
|
|
|
197
189
|
JSON.parse(
|
|
198
190
|
JSON.stringify({
|
|
199
191
|
...data,
|
|
200
|
-
|
|
192
|
+
app: props.app,
|
|
201
193
|
})
|
|
202
194
|
)
|
|
203
195
|
);
|
|
@@ -233,8 +225,8 @@ const {
|
|
|
233
225
|
_getRoles({
|
|
234
226
|
page: page.value,
|
|
235
227
|
search: headerSearch.value,
|
|
236
|
-
|
|
237
|
-
org: props.
|
|
228
|
+
app: props.app,
|
|
229
|
+
org: props.org,
|
|
238
230
|
}),
|
|
239
231
|
{
|
|
240
232
|
watch: [page, headerSearch],
|
|
@@ -259,13 +251,16 @@ const dialogAdd = ref(false);
|
|
|
259
251
|
|
|
260
252
|
const dialogPreview = ref(false);
|
|
261
253
|
|
|
254
|
+
const { loggedInUser } = useLocalAuth();
|
|
255
|
+
|
|
262
256
|
async function submitAdd() {
|
|
263
257
|
try {
|
|
264
258
|
await addRole({
|
|
265
259
|
name: role.value.name,
|
|
266
260
|
permissions: role.value.permissions,
|
|
267
|
-
|
|
268
|
-
org: props.
|
|
261
|
+
app: role.value.app,
|
|
262
|
+
org: props.org,
|
|
263
|
+
createdBy: loggedInUser(),
|
|
269
264
|
});
|
|
270
265
|
setRole({ mode: "add" });
|
|
271
266
|
getRoles();
|
|
@@ -81,6 +81,10 @@ export default function useLocalAuth() {
|
|
|
81
81
|
});
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
+
function loggedInUser() {
|
|
85
|
+
return useCookie("user", cookieConfig).value ?? "";
|
|
86
|
+
}
|
|
87
|
+
|
|
84
88
|
return {
|
|
85
89
|
currentUser,
|
|
86
90
|
membership,
|
|
@@ -92,5 +96,6 @@ export default function useLocalAuth() {
|
|
|
92
96
|
forgotPassword,
|
|
93
97
|
resetPassword,
|
|
94
98
|
verify,
|
|
99
|
+
loggedInUser,
|
|
95
100
|
};
|
|
96
101
|
}
|
package/composables/useMember.ts
CHANGED
|
@@ -8,6 +8,7 @@ export default function useMember() {
|
|
|
8
8
|
});
|
|
9
9
|
|
|
10
10
|
const invitation = ref<TMemberInvitation>({
|
|
11
|
+
_id: "",
|
|
11
12
|
email: "",
|
|
12
13
|
app: "",
|
|
13
14
|
org: "",
|
|
@@ -26,9 +27,9 @@ export default function useMember() {
|
|
|
26
27
|
}
|
|
27
28
|
|
|
28
29
|
function getByApp({ app = "", user = "", org = "" } = {}) {
|
|
29
|
-
return $fetch<TMember>(`/api/members/app/${app}`, {
|
|
30
|
+
return $fetch<TMember>(`/api/members/app/${app}/user/${user}`, {
|
|
30
31
|
method: "GET",
|
|
31
|
-
query: {
|
|
32
|
+
query: { org },
|
|
32
33
|
});
|
|
33
34
|
}
|
|
34
35
|
|
|
@@ -38,12 +39,12 @@ export default function useMember() {
|
|
|
38
39
|
limit = 10,
|
|
39
40
|
user = "",
|
|
40
41
|
org = "",
|
|
41
|
-
|
|
42
|
+
app = "",
|
|
42
43
|
status = "active",
|
|
43
44
|
} = {}) {
|
|
44
|
-
return $fetch<Record<string, any>>(
|
|
45
|
+
return $fetch<Record<string, any>>(`/api/members/app/${app}`, {
|
|
45
46
|
method: "GET",
|
|
46
|
-
query: { page, limit, search, user, org,
|
|
47
|
+
query: { page, limit, search, user, org, status },
|
|
47
48
|
});
|
|
48
49
|
}
|
|
49
50
|
function createUserByVerification(
|
|
@@ -70,19 +71,26 @@ export default function useMember() {
|
|
|
70
71
|
);
|
|
71
72
|
}
|
|
72
73
|
|
|
73
|
-
function
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
) {
|
|
79
|
-
return $fetch<Record<string, any>>(
|
|
80
|
-
`/api/members/id/${id}/role/${role}/type/${type}/org/${org}`,
|
|
81
|
-
{
|
|
82
|
-
method: "PUT",
|
|
83
|
-
}
|
|
84
|
-
);
|
|
74
|
+
function updateRoleById(id: string, role: string) {
|
|
75
|
+
return $fetch<Record<string, any>>(`/api/members/role/id/${id}`, {
|
|
76
|
+
method: "PATCH",
|
|
77
|
+
body: { role },
|
|
78
|
+
});
|
|
85
79
|
}
|
|
80
|
+
|
|
81
|
+
function updateStatusById(id: string, status: string) {
|
|
82
|
+
return $fetch<Record<string, any>>(`/api/members/status/id/${id}`, {
|
|
83
|
+
method: "PATCH",
|
|
84
|
+
body: { status },
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function deleteById(id: string) {
|
|
89
|
+
return $fetch<Record<string, any>>(`/api/members/id/${id}`, {
|
|
90
|
+
method: "DELETE",
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
86
94
|
return {
|
|
87
95
|
member,
|
|
88
96
|
invitation,
|
|
@@ -93,6 +101,8 @@ export default function useMember() {
|
|
|
93
101
|
getByUserType,
|
|
94
102
|
getByApp,
|
|
95
103
|
updateMemberStatus,
|
|
96
|
-
|
|
104
|
+
updateRoleById,
|
|
105
|
+
updateStatusById,
|
|
106
|
+
deleteById,
|
|
97
107
|
};
|
|
98
108
|
}
|
package/composables/useRole.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export default function useRole() {
|
|
2
|
-
function add(
|
|
2
|
+
function add(
|
|
3
|
+
value: Pick<TRole, "name" | "permissions" | "app" | "org" | "createdBy">
|
|
4
|
+
) {
|
|
3
5
|
return $fetch("/api/roles", {
|
|
4
6
|
method: "POST",
|
|
5
7
|
body: value,
|
|
@@ -56,7 +58,7 @@ export default function useRole() {
|
|
|
56
58
|
name: "",
|
|
57
59
|
org: "",
|
|
58
60
|
permissions: [],
|
|
59
|
-
|
|
61
|
+
app: "",
|
|
60
62
|
description: "",
|
|
61
63
|
});
|
|
62
64
|
|
|
@@ -32,9 +32,16 @@ export default function useUser() {
|
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
function cancelInvite(id: string) {
|
|
36
|
+
return $fetch<Record<string, any>>(`/api/verifications/invite/id/${id}`, {
|
|
37
|
+
method: "DELETE",
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
|
|
35
41
|
return {
|
|
36
42
|
getVerifications,
|
|
37
43
|
inviteMember,
|
|
38
44
|
signUp,
|
|
45
|
+
cancelInvite,
|
|
39
46
|
};
|
|
40
47
|
}
|
package/nuxt.config.ts
CHANGED
|
@@ -45,6 +45,36 @@ export default defineNuxtConfig({
|
|
|
45
45
|
},
|
|
46
46
|
],
|
|
47
47
|
|
|
48
|
+
routeRules: {
|
|
49
|
+
"/api/apps/**": { proxy: `${process.env.API_CORE}/api/apps/**` },
|
|
50
|
+
"/api/auth/**": { proxy: `${process.env.API_CORE}/api/auth/**` },
|
|
51
|
+
"/api/users/**": { proxy: `${process.env.API_CORE}/api/users/**` },
|
|
52
|
+
"/api/apps/**": { proxy: `${process.env.API_CORE}/api/apps/**` },
|
|
53
|
+
"/api/permissions/**": {
|
|
54
|
+
proxy: `${process.env.API_CORE}/api/permissions/**`,
|
|
55
|
+
},
|
|
56
|
+
"/api/organizations/**": {
|
|
57
|
+
proxy: `${process.env.API_CORE}/api/organizations/**`,
|
|
58
|
+
},
|
|
59
|
+
"/api/members/**": { proxy: `${process.env.API_CORE}/api/members/**` },
|
|
60
|
+
"/api/teams/**": { proxy: `${process.env.API_CORE}/api/teams/**` },
|
|
61
|
+
"/api/entities/**": { proxy: `${process.env.API_CORE}/api/entities/**` },
|
|
62
|
+
"/api/workflows/**": { proxy: `${process.env.API_CORE}/api/workflows/**` },
|
|
63
|
+
"/api/roles/**": { proxy: `${process.env.API_CORE}/api/roles/**` },
|
|
64
|
+
"/api/promo-codes/**": {
|
|
65
|
+
proxy: `${process.env.API_CORE}/api/promo-codes/**`,
|
|
66
|
+
},
|
|
67
|
+
"/api/verifications/**": {
|
|
68
|
+
proxy: `${process.env.API_CORE}/api/verifications/**`,
|
|
69
|
+
},
|
|
70
|
+
"/api/files/**": {
|
|
71
|
+
proxy: `${process.env.API_CORE}/api/files/**`,
|
|
72
|
+
},
|
|
73
|
+
"/api/public/**": {
|
|
74
|
+
proxy: `${process.env.S3_BUCKET_ENDPOINT}/**`,
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
|
|
48
78
|
vite: {
|
|
49
79
|
vue: {
|
|
50
80
|
template: {
|
package/package.json
CHANGED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-row no-gutters class="fill-height" justify="center" align-content="center">
|
|
3
|
+
<v-col cols="12" class="mb-6">
|
|
4
|
+
<v-row no-gutters justify="center">
|
|
5
|
+
<nuxt-link
|
|
6
|
+
class="text-h2 font-weight-bold text-decoration-none"
|
|
7
|
+
style="color: unset"
|
|
8
|
+
:to="{ name: 'index' }"
|
|
9
|
+
>
|
|
10
|
+
GoWeekdays
|
|
11
|
+
</nuxt-link>
|
|
12
|
+
</v-row>
|
|
13
|
+
</v-col>
|
|
14
|
+
|
|
15
|
+
<v-col cols="12" lg="3" md="4" sm="6">
|
|
16
|
+
<v-form v-model="isValid" @submit.prevent="submit(email)">
|
|
17
|
+
<v-row no-gutters>
|
|
18
|
+
<v-col cols="12">
|
|
19
|
+
<v-row no-gutters>
|
|
20
|
+
<v-col cols="12" class="text-h6 font-weight-bold"> Email </v-col>
|
|
21
|
+
<v-col cols="12">
|
|
22
|
+
<v-text-field
|
|
23
|
+
v-model="email"
|
|
24
|
+
:rules="[requiredRule, emailRule]"
|
|
25
|
+
></v-text-field>
|
|
26
|
+
</v-col>
|
|
27
|
+
</v-row>
|
|
28
|
+
</v-col>
|
|
29
|
+
|
|
30
|
+
<v-col v-if="message" cols="12" class="my-2 text-center font-italic">
|
|
31
|
+
{{ message }}
|
|
32
|
+
</v-col>
|
|
33
|
+
|
|
34
|
+
<v-col cols="12">
|
|
35
|
+
<v-row no-gutters justify="center">
|
|
36
|
+
<v-btn
|
|
37
|
+
type="submit"
|
|
38
|
+
variant="tonal"
|
|
39
|
+
:disabled="!isValid"
|
|
40
|
+
rounded="xl"
|
|
41
|
+
size="large"
|
|
42
|
+
>
|
|
43
|
+
submit
|
|
44
|
+
</v-btn>
|
|
45
|
+
</v-row>
|
|
46
|
+
</v-col>
|
|
47
|
+
|
|
48
|
+
<v-col cols="12" class="mt-2 text-center">
|
|
49
|
+
All good? <nuxt-link :to="{ name: 'login' }">Login</nuxt-link>
|
|
50
|
+
</v-col>
|
|
51
|
+
</v-row>
|
|
52
|
+
</v-form>
|
|
53
|
+
</v-col>
|
|
54
|
+
</v-row>
|
|
55
|
+
</template>
|
|
56
|
+
|
|
57
|
+
<script setup lang="ts">
|
|
58
|
+
definePageMeta({
|
|
59
|
+
layout: "plain",
|
|
60
|
+
});
|
|
61
|
+
const { requiredRule, emailRule } = useUtils();
|
|
62
|
+
const email = ref("");
|
|
63
|
+
const isValid = ref(false);
|
|
64
|
+
|
|
65
|
+
const { forgotPassword } = useLocalAuth();
|
|
66
|
+
const message = ref("");
|
|
67
|
+
|
|
68
|
+
async function submit(email = "") {
|
|
69
|
+
try {
|
|
70
|
+
const result: any = await forgotPassword(email);
|
|
71
|
+
message.value = result.message;
|
|
72
|
+
} catch (error: any) {
|
|
73
|
+
message.value = error.message;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
</script>
|