@goweekdays/layer-common 1.3.0 → 1.3.1
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/MemberInvite.vue +155 -0
- package/components/MemberMain.vue +69 -263
- package/composables/useLocalAuth.ts +0 -35
- package/composables/useMember.ts +18 -21
- package/composables/useRole.ts +2 -2
- package/composables/useVerification.ts +21 -0
- package/package.json +1 -1
- package/plugins/member.client.ts +2 -2
- package/types/member.d.ts +7 -0
- package/types/verification.d.ts +9 -4
package/CHANGELOG.md
CHANGED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-card width="100%">
|
|
3
|
+
<v-toolbar>
|
|
4
|
+
<v-row no-gutters class="fill-height px-6" align="center">
|
|
5
|
+
<span class="font-weight-bold text-h5 text-capitalize">
|
|
6
|
+
{{ localProps.title }}
|
|
7
|
+
</span>
|
|
8
|
+
</v-row>
|
|
9
|
+
</v-toolbar>
|
|
10
|
+
|
|
11
|
+
<v-card-text style="max-height: 100vh; overflow-y: auto">
|
|
12
|
+
<v-form v-model="valid" :disabled="localProps.disabled">
|
|
13
|
+
<v-row no-gutters>
|
|
14
|
+
<v-col cols="12" class="mb-1">
|
|
15
|
+
<v-row no-gutters>
|
|
16
|
+
<InputLabel class="text-capitalize" title="Email" required />
|
|
17
|
+
<v-col cols="12">
|
|
18
|
+
<v-text-field
|
|
19
|
+
v-model="invite.email"
|
|
20
|
+
:rules="[requiredRule, emailRule]"
|
|
21
|
+
></v-text-field>
|
|
22
|
+
</v-col>
|
|
23
|
+
</v-row>
|
|
24
|
+
</v-col>
|
|
25
|
+
|
|
26
|
+
<v-col cols="12" class="mb-1">
|
|
27
|
+
<v-row no-gutters>
|
|
28
|
+
<InputLabel class="text-capitalize" title="Role" required />
|
|
29
|
+
<v-col cols="12">
|
|
30
|
+
<v-select
|
|
31
|
+
v-model="invite.role"
|
|
32
|
+
:items="roles"
|
|
33
|
+
item-title="name"
|
|
34
|
+
item-value="_id"
|
|
35
|
+
:loading="loadingRoles"
|
|
36
|
+
:rules="[requiredRule]"
|
|
37
|
+
></v-select>
|
|
38
|
+
</v-col>
|
|
39
|
+
</v-row>
|
|
40
|
+
</v-col>
|
|
41
|
+
|
|
42
|
+
<v-col v-if="!localProps.app" cols="12" class="mb-1">
|
|
43
|
+
<v-row no-gutters>
|
|
44
|
+
<InputLabel class="text-capitalize" title="App" required />
|
|
45
|
+
<v-col cols="12">
|
|
46
|
+
<v-select
|
|
47
|
+
v-model="invite.app"
|
|
48
|
+
:rules="[requiredRule]"
|
|
49
|
+
></v-select>
|
|
50
|
+
</v-col>
|
|
51
|
+
</v-row>
|
|
52
|
+
</v-col>
|
|
53
|
+
</v-row>
|
|
54
|
+
</v-form>
|
|
55
|
+
|
|
56
|
+
<v-alert
|
|
57
|
+
v-if="message"
|
|
58
|
+
type="error"
|
|
59
|
+
variant="flat"
|
|
60
|
+
closable
|
|
61
|
+
position="absolute"
|
|
62
|
+
location="bottom"
|
|
63
|
+
style="bottom: 48px"
|
|
64
|
+
@click:close="message = ''"
|
|
65
|
+
width="100%"
|
|
66
|
+
tile
|
|
67
|
+
class="text-caption"
|
|
68
|
+
>
|
|
69
|
+
{{ message }}
|
|
70
|
+
</v-alert>
|
|
71
|
+
</v-card-text>
|
|
72
|
+
|
|
73
|
+
<v-toolbar density="compact">
|
|
74
|
+
<v-row no-gutters>
|
|
75
|
+
<v-col cols="6">
|
|
76
|
+
<v-btn
|
|
77
|
+
tile
|
|
78
|
+
block
|
|
79
|
+
variant="text"
|
|
80
|
+
class="text-none"
|
|
81
|
+
size="48"
|
|
82
|
+
@click="emits('cancel')"
|
|
83
|
+
>
|
|
84
|
+
Cancel
|
|
85
|
+
</v-btn>
|
|
86
|
+
</v-col>
|
|
87
|
+
|
|
88
|
+
<v-col cols="6">
|
|
89
|
+
<v-btn
|
|
90
|
+
tile
|
|
91
|
+
block
|
|
92
|
+
variant="flat"
|
|
93
|
+
color="black"
|
|
94
|
+
class="text-none"
|
|
95
|
+
size="48"
|
|
96
|
+
@click="emits('submit')"
|
|
97
|
+
:disabled="localProps.disabled || !valid"
|
|
98
|
+
>
|
|
99
|
+
Invite
|
|
100
|
+
</v-btn>
|
|
101
|
+
</v-col>
|
|
102
|
+
</v-row>
|
|
103
|
+
</v-toolbar>
|
|
104
|
+
</v-card>
|
|
105
|
+
</template>
|
|
106
|
+
|
|
107
|
+
<script setup lang="ts">
|
|
108
|
+
const emits = defineEmits(["submit", "cancel", "edit", "delete"]);
|
|
109
|
+
|
|
110
|
+
const localProps = defineProps({
|
|
111
|
+
title: {
|
|
112
|
+
type: String,
|
|
113
|
+
default: "Invite Member",
|
|
114
|
+
},
|
|
115
|
+
app: {
|
|
116
|
+
type: String,
|
|
117
|
+
default: "",
|
|
118
|
+
},
|
|
119
|
+
org: {
|
|
120
|
+
type: String,
|
|
121
|
+
default: "",
|
|
122
|
+
},
|
|
123
|
+
disabled: {
|
|
124
|
+
type: Boolean,
|
|
125
|
+
default: false,
|
|
126
|
+
},
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
const invite = defineModel<TMemberInvitation>({
|
|
130
|
+
default: () => useMember().invitation.value,
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const message = defineModel("message", { default: "" });
|
|
134
|
+
|
|
135
|
+
const valid = ref(false);
|
|
136
|
+
|
|
137
|
+
const { requiredRule, emailRule } = useUtils();
|
|
138
|
+
|
|
139
|
+
const { getAll: getAllRoles } = useRole();
|
|
140
|
+
|
|
141
|
+
const roles = ref<Array<Record<string, any>>>([]);
|
|
142
|
+
|
|
143
|
+
const { data: roleData, status: roleReqStatus } = await useLazyAsyncData(
|
|
144
|
+
`get-all-role-app-${localProps.app}-${localProps.org ?? "org"}`,
|
|
145
|
+
() => getAllRoles({ org: localProps.org, app: localProps.app, limit: 50 })
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
const loadingRoles = computed(() => roleReqStatus.value === "pending");
|
|
149
|
+
|
|
150
|
+
watchEffect(() => {
|
|
151
|
+
if (roleData.value && roleData.value.items) {
|
|
152
|
+
roles.value = roleData.value.items;
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
</script>
|
|
@@ -1,18 +1,15 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-row no-gutters>
|
|
3
|
-
<v-col
|
|
3
|
+
<v-col cols="12" class="mb-2">
|
|
4
4
|
<v-row no-gutters>
|
|
5
5
|
<v-btn
|
|
6
|
-
class="text-none"
|
|
6
|
+
class="text-none mr-2"
|
|
7
7
|
rounded="pill"
|
|
8
8
|
variant="tonal"
|
|
9
|
-
:to="{
|
|
10
|
-
name: props.seatManagement,
|
|
11
|
-
params: { organization: props.orgId },
|
|
12
|
-
}"
|
|
13
9
|
size="large"
|
|
10
|
+
@click="setInvite()"
|
|
14
11
|
>
|
|
15
|
-
|
|
12
|
+
Invite
|
|
16
13
|
</v-btn>
|
|
17
14
|
</v-row>
|
|
18
15
|
</v-col>
|
|
@@ -31,11 +28,7 @@
|
|
|
31
28
|
<span class="mr-2 text-caption text-font gray">
|
|
32
29
|
{{ pageRange }}
|
|
33
30
|
</span>
|
|
34
|
-
<local-pagination
|
|
35
|
-
v-model="page"
|
|
36
|
-
:length="pages"
|
|
37
|
-
@update:value="getAll()"
|
|
38
|
-
/>
|
|
31
|
+
<local-pagination v-model="page" :length="pages" />
|
|
39
32
|
</v-row>
|
|
40
33
|
</template>
|
|
41
34
|
|
|
@@ -51,7 +44,7 @@
|
|
|
51
44
|
name: props.route,
|
|
52
45
|
params: setRouteParams({
|
|
53
46
|
status: tab.status,
|
|
54
|
-
|
|
47
|
+
org: props.orgId,
|
|
55
48
|
}),
|
|
56
49
|
}"
|
|
57
50
|
>
|
|
@@ -70,162 +63,22 @@
|
|
|
70
63
|
hide-default-footer
|
|
71
64
|
style="max-height: calc(100vh - (126px))"
|
|
72
65
|
:loading="loading"
|
|
66
|
+
@click:row="handleRowClick"
|
|
73
67
|
>
|
|
74
|
-
<template #item.nature="{ item }">
|
|
75
|
-
{{ replaceMatch(item.nature, "_", " ") }}
|
|
76
|
-
</template>
|
|
77
|
-
<template #item.action-table="{ item }">
|
|
78
|
-
<v-menu
|
|
79
|
-
v-if="
|
|
80
|
-
(status === 'active' &&
|
|
81
|
-
(canSuspendMembers || canDeleteMembers)) ||
|
|
82
|
-
(status === 'suspended' &&
|
|
83
|
-
(canActivateMembers || canDeleteMembers))
|
|
84
|
-
"
|
|
85
|
-
v-model="item.menuOpen"
|
|
86
|
-
offset-y
|
|
87
|
-
width="150"
|
|
88
|
-
>
|
|
89
|
-
<template v-slot:activator="{ props }">
|
|
90
|
-
<v-icon v-bind="props">mdi-dots-horizontal</v-icon>
|
|
91
|
-
</template>
|
|
92
|
-
<v-list>
|
|
93
|
-
<v-list-item
|
|
94
|
-
v-if="props.assignRole"
|
|
95
|
-
@click="
|
|
96
|
-
setMember({
|
|
97
|
-
dialog: true,
|
|
98
|
-
mode: 'assign-role',
|
|
99
|
-
role: item,
|
|
100
|
-
})
|
|
101
|
-
"
|
|
102
|
-
>
|
|
103
|
-
Assign Role
|
|
104
|
-
</v-list-item>
|
|
105
|
-
|
|
106
|
-
<v-list-item
|
|
107
|
-
v-if="status === 'active' && canSuspendMembers"
|
|
108
|
-
@click="openUpdateDialog(item.user, 'suspended')"
|
|
109
|
-
>
|
|
110
|
-
Suspend
|
|
111
|
-
</v-list-item>
|
|
112
|
-
<v-list-item
|
|
113
|
-
v-if="status === 'suspended' && canActivateMembers"
|
|
114
|
-
@click="openUpdateDialog(item.user, 'active')"
|
|
115
|
-
>
|
|
116
|
-
Activate
|
|
117
|
-
</v-list-item>
|
|
118
|
-
<v-list-item
|
|
119
|
-
v-if="canDeleteMembers"
|
|
120
|
-
@click="openUpdateDialog(item.user, 'deleted')"
|
|
121
|
-
>
|
|
122
|
-
Delete
|
|
123
|
-
</v-list-item>
|
|
124
|
-
</v-list>
|
|
125
|
-
</v-menu>
|
|
126
|
-
</template>
|
|
127
68
|
</v-data-table>
|
|
128
69
|
</v-card>
|
|
129
70
|
</v-col>
|
|
130
|
-
<ConfirmDialog
|
|
131
|
-
v-model="confirmDialog"
|
|
132
|
-
:loading="updateLoading"
|
|
133
|
-
@submit="handleUpdateMemberStatus"
|
|
134
|
-
>
|
|
135
|
-
<template #title>
|
|
136
|
-
<span class="font-weight-medium text-h5">
|
|
137
|
-
{{ updateActionText }} Member</span
|
|
138
|
-
>
|
|
139
|
-
</template>
|
|
140
|
-
|
|
141
|
-
<template #description>
|
|
142
|
-
<p class="text-subtitle-2">
|
|
143
|
-
Are you sure you want to {{ updateActionText }} this Member? This
|
|
144
|
-
action cannot be undone.
|
|
145
|
-
</p>
|
|
146
|
-
</template>
|
|
147
|
-
|
|
148
|
-
<template #footer>
|
|
149
|
-
<v-btn
|
|
150
|
-
variant="text"
|
|
151
|
-
@click="confirmDialog = false"
|
|
152
|
-
:disabled="updateLoading"
|
|
153
|
-
>
|
|
154
|
-
Close
|
|
155
|
-
</v-btn>
|
|
156
|
-
<v-btn
|
|
157
|
-
color="primary"
|
|
158
|
-
variant="flat"
|
|
159
|
-
@click="handleUpdateMemberStatus"
|
|
160
|
-
:loading="updateLoading"
|
|
161
|
-
>
|
|
162
|
-
{{ updateActionText }} Member
|
|
163
|
-
</v-btn>
|
|
164
|
-
</template>
|
|
165
|
-
</ConfirmDialog>
|
|
166
71
|
|
|
167
|
-
<
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
<InputLabel class="text-capitalize" title="Name" required />
|
|
178
|
-
<v-col cols="12">
|
|
179
|
-
<v-select
|
|
180
|
-
v-model="selectedRole"
|
|
181
|
-
:items="roles"
|
|
182
|
-
item-value="_id"
|
|
183
|
-
item-title="name"
|
|
184
|
-
density="comfortable"
|
|
185
|
-
:rules="[requiredRule]"
|
|
186
|
-
:error-messages="
|
|
187
|
-
selectedRole === selectedMemberRole
|
|
188
|
-
? 'Role already assigned'
|
|
189
|
-
: ''
|
|
190
|
-
"
|
|
191
|
-
persistent-hint
|
|
192
|
-
></v-select>
|
|
193
|
-
</v-col>
|
|
194
|
-
|
|
195
|
-
<v-col cols="12" class="text-error text-center">
|
|
196
|
-
{{ message }}
|
|
197
|
-
</v-col>
|
|
198
|
-
</v-row>
|
|
199
|
-
</v-col>
|
|
200
|
-
|
|
201
|
-
<v-col cols="12">
|
|
202
|
-
<v-row>
|
|
203
|
-
<v-col cols="6">
|
|
204
|
-
<v-btn
|
|
205
|
-
block
|
|
206
|
-
variant="text"
|
|
207
|
-
@click="setMember({ mode: 'assign-role' })"
|
|
208
|
-
>
|
|
209
|
-
Cancel
|
|
210
|
-
</v-btn>
|
|
211
|
-
</v-col>
|
|
212
|
-
<v-col cols="6">
|
|
213
|
-
<v-btn
|
|
214
|
-
block
|
|
215
|
-
variant="flat"
|
|
216
|
-
color="black"
|
|
217
|
-
:disabled="!memberRoleForm"
|
|
218
|
-
type="submit"
|
|
219
|
-
>
|
|
220
|
-
Submit
|
|
221
|
-
</v-btn>
|
|
222
|
-
</v-col>
|
|
223
|
-
</v-row>
|
|
224
|
-
</v-col>
|
|
225
|
-
</v-row>
|
|
226
|
-
</v-form>
|
|
227
|
-
</v-card-text>
|
|
228
|
-
</v-card>
|
|
72
|
+
<v-dialog v-model="dialogInvite" width="450" persistent>
|
|
73
|
+
<MemberInvite
|
|
74
|
+
v-model="invitation"
|
|
75
|
+
:app="type"
|
|
76
|
+
:org="orgId"
|
|
77
|
+
:disabled="disabledInvite"
|
|
78
|
+
@cancel="setInvite(false)"
|
|
79
|
+
@submit="submitInvite()"
|
|
80
|
+
v-model:message="message"
|
|
81
|
+
/>
|
|
229
82
|
</v-dialog>
|
|
230
83
|
</v-row>
|
|
231
84
|
</template>
|
|
@@ -250,7 +103,7 @@ const props = defineProps({
|
|
|
250
103
|
},
|
|
251
104
|
type: {
|
|
252
105
|
type: String,
|
|
253
|
-
default: "
|
|
106
|
+
default: "org",
|
|
254
107
|
},
|
|
255
108
|
seatManagement: {
|
|
256
109
|
type: String,
|
|
@@ -311,31 +164,34 @@ const page = ref(1);
|
|
|
311
164
|
const pages = ref(10);
|
|
312
165
|
const pageRange = ref("-- - -- of --");
|
|
313
166
|
|
|
314
|
-
const message = ref("");
|
|
315
|
-
const messageSnackbar = ref(false);
|
|
316
|
-
const messageColor = ref("");
|
|
317
|
-
|
|
318
167
|
const {
|
|
168
|
+
invitation,
|
|
169
|
+
member,
|
|
319
170
|
getAll: _getAll,
|
|
320
171
|
updateMemberStatus: _updateMemberStatus,
|
|
321
172
|
updateMemberRole: _updateMemberRole,
|
|
322
173
|
} = useMember();
|
|
323
174
|
|
|
324
175
|
const { headerSearch } = useLocal();
|
|
325
|
-
const {
|
|
176
|
+
const { setRouteParams } = useUtils();
|
|
326
177
|
|
|
327
178
|
const {
|
|
328
179
|
data: getAllReq,
|
|
329
180
|
refresh: getAll,
|
|
330
181
|
status: getAllReqStatus,
|
|
331
|
-
} = useLazyAsyncData(
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
182
|
+
} = await useLazyAsyncData(
|
|
183
|
+
"get-all-members-by-status" + props.status,
|
|
184
|
+
() =>
|
|
185
|
+
_getAll({
|
|
186
|
+
status: props.status,
|
|
187
|
+
org: props.orgId,
|
|
188
|
+
search: headerSearch.value,
|
|
189
|
+
page: page.value,
|
|
190
|
+
type: props.type,
|
|
191
|
+
}),
|
|
192
|
+
{
|
|
193
|
+
watch: [headerSearch, page],
|
|
194
|
+
}
|
|
339
195
|
);
|
|
340
196
|
|
|
341
197
|
const loading = computed(() => getAllReqStatus.value === "pending");
|
|
@@ -348,105 +204,55 @@ watchEffect(() => {
|
|
|
348
204
|
}
|
|
349
205
|
});
|
|
350
206
|
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
const confirmDialog = ref(false);
|
|
356
|
-
const selectedMemberId = ref<string | null>(null);
|
|
357
|
-
const updateLoading = ref(false);
|
|
358
|
-
const updateAction = ref("");
|
|
359
|
-
|
|
360
|
-
const memberRoleForm = ref(false);
|
|
361
|
-
const assignRoleDialog = ref(false);
|
|
362
|
-
const selectedRole = ref<string | null>(null);
|
|
363
|
-
const selectedMemberRole = ref("");
|
|
207
|
+
const dialogInvite = ref(false);
|
|
208
|
+
const dialogView = ref(false);
|
|
209
|
+
const modeMember = ref("");
|
|
210
|
+
const message = ref("");
|
|
364
211
|
|
|
365
212
|
function setMember({
|
|
366
|
-
|
|
213
|
+
data = useMember().member.value,
|
|
367
214
|
mode = "",
|
|
368
|
-
|
|
215
|
+
dialog = true,
|
|
369
216
|
} = {}) {
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
selectedMemberId.value = role._id;
|
|
375
|
-
selectedRole.value = role.role;
|
|
376
|
-
selectedMemberRole.value = role.role;
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
const roles = ref<Array<Record<string, any>>>([]);
|
|
380
|
-
const { getRoles } = useRole();
|
|
381
|
-
const { data: getAllRoleReq } = useLazyAsyncData("get-roles", () =>
|
|
382
|
-
getRoles({ org: props.orgId, type: props.type, limit: 20 })
|
|
383
|
-
);
|
|
384
|
-
|
|
385
|
-
watchEffect(() => {
|
|
386
|
-
if (getAllRoleReq.value) {
|
|
387
|
-
roles.value = getAllRoleReq.value.items;
|
|
388
|
-
}
|
|
389
|
-
});
|
|
390
|
-
|
|
391
|
-
watchEffect(() => {
|
|
392
|
-
if (selectedRole.value) {
|
|
393
|
-
message.value = "";
|
|
394
|
-
}
|
|
395
|
-
});
|
|
217
|
+
dialogView.value = dialog;
|
|
218
|
+
Object.assign(member.value, JSON.parse(JSON.stringify(data)));
|
|
219
|
+
modeMember.value = mode;
|
|
396
220
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
await _updateMemberRole(
|
|
400
|
-
selectedMemberId.value ?? "",
|
|
401
|
-
selectedRole.value ?? "",
|
|
402
|
-
props.type,
|
|
403
|
-
props.orgId
|
|
404
|
-
);
|
|
405
|
-
await setMember({ mode: "assign-role" });
|
|
406
|
-
await getAll();
|
|
407
|
-
} catch (error: any) {
|
|
408
|
-
message.value = error?.response?._data?.message || "Failed to update role";
|
|
221
|
+
if (mode === "view") {
|
|
222
|
+
dialogView.value = true;
|
|
409
223
|
}
|
|
410
224
|
}
|
|
411
225
|
|
|
412
|
-
function
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
226
|
+
function setInvite(dialog = true) {
|
|
227
|
+
dialogInvite.value = dialog;
|
|
228
|
+
Object.assign(
|
|
229
|
+
invitation.value,
|
|
230
|
+
JSON.parse(JSON.stringify(useMember().invitation.value))
|
|
231
|
+
);
|
|
416
232
|
}
|
|
417
233
|
|
|
418
|
-
|
|
419
|
-
message.value = msg;
|
|
420
|
-
messageColor.value = color;
|
|
421
|
-
messageSnackbar.value = true;
|
|
422
|
-
}
|
|
234
|
+
const disabledInvite = ref(false);
|
|
423
235
|
|
|
424
|
-
|
|
425
|
-
if (!selectedMemberId.value) return;
|
|
426
|
-
updateLoading.value = true;
|
|
427
|
-
try {
|
|
428
|
-
const res = await _updateMemberStatus(
|
|
429
|
-
selectedMemberId.value,
|
|
430
|
-
updateAction.value
|
|
431
|
-
);
|
|
236
|
+
const { inviteMember } = useVerification();
|
|
432
237
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
238
|
+
async function submitInvite() {
|
|
239
|
+
disabledInvite.value = true;
|
|
240
|
+
try {
|
|
241
|
+
await inviteMember({
|
|
242
|
+
app: props.type,
|
|
243
|
+
org: props.orgId,
|
|
244
|
+
email: invitation.value.email,
|
|
245
|
+
role: invitation.value.role,
|
|
246
|
+
});
|
|
247
|
+
await setInvite(false);
|
|
436
248
|
} catch (error: any) {
|
|
437
|
-
|
|
438
|
-
showMessage(errorMessage, "error");
|
|
249
|
+
message.value = error.response._data.message || "An error occurred.";
|
|
439
250
|
} finally {
|
|
440
|
-
|
|
441
|
-
selectedMemberId.value = null;
|
|
251
|
+
disabledInvite.value = false;
|
|
442
252
|
}
|
|
443
253
|
}
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
deleted: "Delete",
|
|
449
|
-
};
|
|
450
|
-
return map[updateAction.value] || updateAction.value;
|
|
451
|
-
});
|
|
254
|
+
|
|
255
|
+
function handleRowClick(_: any, data: any) {
|
|
256
|
+
setMember({ data: data.item, mode: "view" });
|
|
257
|
+
}
|
|
452
258
|
</script>
|
|
@@ -12,32 +12,6 @@ export default function useLocalAuth() {
|
|
|
12
12
|
});
|
|
13
13
|
};
|
|
14
14
|
|
|
15
|
-
function authenticate() {
|
|
16
|
-
if (currentUser.value) {
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const user = useCookie("user", cookieConfig).value;
|
|
21
|
-
|
|
22
|
-
const { data: getCurrentUserReq, error: getCurrentUserErr } =
|
|
23
|
-
useLazyAsyncData("get-current-user", () =>
|
|
24
|
-
$fetch<TUser>(`/api/users/id/${user}`)
|
|
25
|
-
);
|
|
26
|
-
|
|
27
|
-
watchEffect(() => {
|
|
28
|
-
if (getCurrentUserReq.value) {
|
|
29
|
-
currentUser.value = getCurrentUserReq.value;
|
|
30
|
-
}
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
watchEffect(() => {
|
|
34
|
-
if (getCurrentUserErr.value) {
|
|
35
|
-
// Redirect to login page if user authentication fails
|
|
36
|
-
navigateTo({ name: "index" });
|
|
37
|
-
}
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
|
|
41
15
|
async function login({ email = "", password = "", role = "" }) {
|
|
42
16
|
return $fetch<Record<string, any>>("/api/auth/login", {
|
|
43
17
|
method: "POST",
|
|
@@ -107,25 +81,16 @@ export default function useLocalAuth() {
|
|
|
107
81
|
});
|
|
108
82
|
}
|
|
109
83
|
|
|
110
|
-
function signUp(email: string, referral: string) {
|
|
111
|
-
return $fetch<TKeyValuePair>("/api/auth/sign-up", {
|
|
112
|
-
method: "POST",
|
|
113
|
-
body: { email, referral },
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
|
-
|
|
117
84
|
return {
|
|
118
85
|
currentUser,
|
|
119
86
|
membership,
|
|
120
87
|
permissions,
|
|
121
88
|
hasPermission,
|
|
122
|
-
authenticate,
|
|
123
89
|
login,
|
|
124
90
|
logout,
|
|
125
91
|
getCurrentUser,
|
|
126
92
|
forgotPassword,
|
|
127
93
|
resetPassword,
|
|
128
94
|
verify,
|
|
129
|
-
signUp,
|
|
130
95
|
};
|
|
131
96
|
}
|
package/composables/useMember.ts
CHANGED
|
@@ -1,25 +1,18 @@
|
|
|
1
1
|
export default function useMember() {
|
|
2
|
-
const
|
|
3
|
-
const page = useState("page", () => 1);
|
|
4
|
-
const pages = useState("pages", () => 0);
|
|
5
|
-
const pageRange = useState("pageRange", () => "-- - -- of --");
|
|
6
|
-
|
|
7
|
-
const member = useState<TMember>("member", () => ({
|
|
8
|
-
_id: "",
|
|
2
|
+
const member = ref<TMember>({
|
|
9
3
|
org: "",
|
|
10
4
|
orgName: "",
|
|
11
|
-
roleName: "",
|
|
12
5
|
name: "",
|
|
13
6
|
user: "",
|
|
14
7
|
role: "",
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
})
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const invitation = ref<TMemberInvitation>({
|
|
11
|
+
email: "",
|
|
12
|
+
app: "",
|
|
13
|
+
org: "",
|
|
14
|
+
role: "",
|
|
15
|
+
});
|
|
23
16
|
|
|
24
17
|
function getByUserId(user: string) {
|
|
25
18
|
return $fetch<TMember>(`/api/members/user/${user}`);
|
|
@@ -32,6 +25,13 @@ export default function useMember() {
|
|
|
32
25
|
});
|
|
33
26
|
}
|
|
34
27
|
|
|
28
|
+
function getByApp({ app = "", user = "", org = "" } = {}) {
|
|
29
|
+
return $fetch<TMember>(`/api/members/app/${app}`, {
|
|
30
|
+
method: "GET",
|
|
31
|
+
query: { user, org },
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
35
35
|
async function getAll({
|
|
36
36
|
page = 1,
|
|
37
37
|
search = "",
|
|
@@ -84,17 +84,14 @@ export default function useMember() {
|
|
|
84
84
|
);
|
|
85
85
|
}
|
|
86
86
|
return {
|
|
87
|
-
members,
|
|
88
87
|
member,
|
|
89
|
-
|
|
90
|
-
pages,
|
|
91
|
-
pageRange,
|
|
92
|
-
|
|
88
|
+
invitation,
|
|
93
89
|
getAll,
|
|
94
90
|
getByUserId,
|
|
95
91
|
createUserByVerification,
|
|
96
92
|
createMemberInvite,
|
|
97
93
|
getByUserType,
|
|
94
|
+
getByApp,
|
|
98
95
|
updateMemberStatus,
|
|
99
96
|
updateMemberRole,
|
|
100
97
|
};
|
package/composables/useRole.ts
CHANGED
|
@@ -10,12 +10,12 @@ export default function useRole() {
|
|
|
10
10
|
search = "",
|
|
11
11
|
page = 1,
|
|
12
12
|
limit = 20,
|
|
13
|
-
|
|
13
|
+
app = "",
|
|
14
14
|
org = "",
|
|
15
15
|
} = {}) {
|
|
16
16
|
return $fetch<Record<string, any>>("/api/roles", {
|
|
17
17
|
method: "GET",
|
|
18
|
-
query: { search, page, limit,
|
|
18
|
+
query: { search, page, limit, app, org },
|
|
19
19
|
});
|
|
20
20
|
}
|
|
21
21
|
|
|
@@ -13,7 +13,28 @@ export default function useUser() {
|
|
|
13
13
|
});
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
+
function inviteMember(value: {
|
|
17
|
+
email: string;
|
|
18
|
+
app: string;
|
|
19
|
+
org: string;
|
|
20
|
+
role: string;
|
|
21
|
+
}) {
|
|
22
|
+
return $fetch<Record<string, any>>("/api/verifications/member", {
|
|
23
|
+
method: "POST",
|
|
24
|
+
body: value,
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function signUp(email: string) {
|
|
29
|
+
return $fetch<Record<string, any>>("/api/verifications/sign-up", {
|
|
30
|
+
method: "POST",
|
|
31
|
+
body: { email },
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
|
16
35
|
return {
|
|
17
36
|
getVerifications,
|
|
37
|
+
inviteMember,
|
|
38
|
+
signUp,
|
|
18
39
|
};
|
|
19
40
|
}
|
package/package.json
CHANGED
package/plugins/member.client.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export default defineNuxtPlugin(() => {
|
|
2
2
|
const router = useRouter();
|
|
3
|
-
const {
|
|
3
|
+
const { getByApp } = useMember();
|
|
4
4
|
const { getById: getRoleById } = useRole();
|
|
5
5
|
const { membership, permissions } = useLocalAuth();
|
|
6
6
|
|
|
@@ -15,7 +15,7 @@ export default defineNuxtPlugin(() => {
|
|
|
15
15
|
|
|
16
16
|
if (!membership.value) {
|
|
17
17
|
try {
|
|
18
|
-
const member = await
|
|
18
|
+
const member = await getByApp({ app: APP, user: userId, org });
|
|
19
19
|
membership.value = member;
|
|
20
20
|
|
|
21
21
|
const role = await getRoleById(member.role);
|
package/types/member.d.ts
CHANGED
package/types/verification.d.ts
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
|
-
declare type
|
|
1
|
+
declare type TVerMetadata = {
|
|
2
|
+
name?: string;
|
|
2
3
|
app?: string;
|
|
3
4
|
role?: string;
|
|
5
|
+
roleName?: string;
|
|
6
|
+
referralCode?: string;
|
|
7
|
+
org?: string;
|
|
8
|
+
orgName?: string;
|
|
4
9
|
};
|
|
5
10
|
|
|
6
|
-
declare type
|
|
11
|
+
declare type TVer = {
|
|
7
12
|
_id?: string;
|
|
8
13
|
type: string;
|
|
9
14
|
email: string;
|
|
10
|
-
metadata?:
|
|
15
|
+
metadata?: TVerMetadata;
|
|
11
16
|
status?: string;
|
|
12
17
|
createdAt: string;
|
|
13
|
-
updatedAt?: string
|
|
18
|
+
updatedAt?: string;
|
|
14
19
|
expireAt: string;
|
|
15
20
|
};
|