@goweekdays/layer-common 1.3.1 → 1.3.3
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 +12 -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 +162 -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
package/pages/login.vue
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-row
|
|
3
|
+
no-gutters
|
|
4
|
+
class="fill-height pa-8"
|
|
5
|
+
justify="center"
|
|
6
|
+
align-content="center"
|
|
7
|
+
>
|
|
8
|
+
<v-col cols="12" lg="3" md="4" sm="6">
|
|
9
|
+
<v-form
|
|
10
|
+
v-model="isValid"
|
|
11
|
+
@submit.prevent="submit({ email, password })"
|
|
12
|
+
:disabled="loading"
|
|
13
|
+
>
|
|
14
|
+
<v-row no-gutters>
|
|
15
|
+
<v-col cols="12">
|
|
16
|
+
<v-row no-gutters justify="center">
|
|
17
|
+
<nuxt-link
|
|
18
|
+
class="text-h3 text-sm-h2 text-md-h2 text-lg-h2 text-xl-h2 font-weight-bold text-decoration-none"
|
|
19
|
+
style="color: unset"
|
|
20
|
+
:to="{ name: 'index' }"
|
|
21
|
+
>
|
|
22
|
+
GoWeekdays
|
|
23
|
+
</nuxt-link>
|
|
24
|
+
</v-row>
|
|
25
|
+
</v-col>
|
|
26
|
+
|
|
27
|
+
<v-col cols="12" class="mt-6">
|
|
28
|
+
<v-row no-gutters>
|
|
29
|
+
<v-col cols="12" class="text-h6 font-weight-bold"> Email </v-col>
|
|
30
|
+
<v-col cols="12">
|
|
31
|
+
<v-text-field
|
|
32
|
+
v-model="email"
|
|
33
|
+
:rules="[requiredRule, emailRule]"
|
|
34
|
+
></v-text-field>
|
|
35
|
+
</v-col>
|
|
36
|
+
</v-row>
|
|
37
|
+
</v-col>
|
|
38
|
+
|
|
39
|
+
<v-col cols="12">
|
|
40
|
+
<v-row no-gutters>
|
|
41
|
+
<v-col cols="12" class="text-h6 font-weight-bold">
|
|
42
|
+
Password
|
|
43
|
+
</v-col>
|
|
44
|
+
<v-col cols="12">
|
|
45
|
+
<InputPassword v-model="password" :rules="[requiredRule]" />
|
|
46
|
+
</v-col>
|
|
47
|
+
</v-row>
|
|
48
|
+
</v-col>
|
|
49
|
+
|
|
50
|
+
<v-col v-if="message" cols="12" class="my-2 text-center font-italic">
|
|
51
|
+
{{ message }}
|
|
52
|
+
</v-col>
|
|
53
|
+
|
|
54
|
+
<v-col cols="12" class="mt-4">
|
|
55
|
+
<v-row no-gutters justify="center">
|
|
56
|
+
<v-btn
|
|
57
|
+
block
|
|
58
|
+
type="submit"
|
|
59
|
+
variant="tonal"
|
|
60
|
+
:disabled="!isValid"
|
|
61
|
+
rounded="xl"
|
|
62
|
+
size="large"
|
|
63
|
+
class="text-none"
|
|
64
|
+
:loading="loading"
|
|
65
|
+
>
|
|
66
|
+
Login
|
|
67
|
+
</v-btn>
|
|
68
|
+
</v-row>
|
|
69
|
+
</v-col>
|
|
70
|
+
|
|
71
|
+
<v-col cols="12" class="text-center font-weight-bold mt-4">
|
|
72
|
+
<nuxt-link
|
|
73
|
+
:to="{ name: 'forgot-password' }"
|
|
74
|
+
class="text-decoration-none text-primary"
|
|
75
|
+
>
|
|
76
|
+
Forgot password?
|
|
77
|
+
</nuxt-link>
|
|
78
|
+
</v-col>
|
|
79
|
+
|
|
80
|
+
<v-col cols="12" class="my-4">
|
|
81
|
+
<v-divider></v-divider>
|
|
82
|
+
</v-col>
|
|
83
|
+
|
|
84
|
+
<v-col cols="12">
|
|
85
|
+
<v-row no-gutters justify="center">
|
|
86
|
+
<v-btn
|
|
87
|
+
block
|
|
88
|
+
variant="flat"
|
|
89
|
+
color="black"
|
|
90
|
+
rounded="xl"
|
|
91
|
+
size="large"
|
|
92
|
+
class="text-none"
|
|
93
|
+
:to="{ name: 'sign-up' }"
|
|
94
|
+
>
|
|
95
|
+
Create new account
|
|
96
|
+
</v-btn>
|
|
97
|
+
</v-row>
|
|
98
|
+
</v-col>
|
|
99
|
+
</v-row>
|
|
100
|
+
</v-form>
|
|
101
|
+
</v-col>
|
|
102
|
+
</v-row>
|
|
103
|
+
</template>
|
|
104
|
+
|
|
105
|
+
<script setup lang="ts">
|
|
106
|
+
definePageMeta({
|
|
107
|
+
layout: "plain",
|
|
108
|
+
});
|
|
109
|
+
const { requiredRule, emailRule } = useUtils();
|
|
110
|
+
const email = ref("");
|
|
111
|
+
const password = ref("");
|
|
112
|
+
const isValid = ref(false);
|
|
113
|
+
|
|
114
|
+
const { login } = useLocalAuth();
|
|
115
|
+
|
|
116
|
+
const message = ref("");
|
|
117
|
+
|
|
118
|
+
const loading = ref(false);
|
|
119
|
+
|
|
120
|
+
const { APP, cookieConfig } = useRuntimeConfig().public;
|
|
121
|
+
|
|
122
|
+
const { getByApp } = useMember();
|
|
123
|
+
|
|
124
|
+
async function submit({ email = "", password = "" } = {}) {
|
|
125
|
+
loading.value = true;
|
|
126
|
+
try {
|
|
127
|
+
await login({ email, password });
|
|
128
|
+
|
|
129
|
+
if (APP === "main") {
|
|
130
|
+
await navigateTo({ name: "feed" });
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (APP === "admin") {
|
|
135
|
+
await navigateTo({ name: "home" });
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const userId = (useCookie("user", cookieConfig).value as string) ?? "";
|
|
140
|
+
|
|
141
|
+
const memberData = await getByApp({ app: APP, user: userId });
|
|
142
|
+
|
|
143
|
+
if (memberData && memberData.org) {
|
|
144
|
+
navigateTo({
|
|
145
|
+
name: "org-dashboard",
|
|
146
|
+
params: { org: memberData.org },
|
|
147
|
+
});
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
} catch (error: any) {
|
|
151
|
+
message.value = error.response._data.message;
|
|
152
|
+
} finally {
|
|
153
|
+
loading.value = false;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
</script>
|
package/pages/logout.vue
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-row no-gutters class="fill-height" justify="center" align-content="center">
|
|
3
|
+
<v-col cols="12" class="mt-2 text-center font-weight-bold">
|
|
4
|
+
You have been logged out.
|
|
5
|
+
<nuxt-link :to="{ name: 'login' }">Login</nuxt-link>
|
|
6
|
+
</v-col>
|
|
7
|
+
</v-row>
|
|
8
|
+
</template>
|
|
9
|
+
|
|
10
|
+
<script setup lang="ts">
|
|
11
|
+
definePageMeta({
|
|
12
|
+
layout: "plain",
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const { logout } = useLocalAuth();
|
|
16
|
+
|
|
17
|
+
logout();
|
|
18
|
+
</script>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-row no-gutters class="fill-height" justify="center" align-content="center">
|
|
3
|
+
<v-col cols="12" class="mb-4">
|
|
4
|
+
<v-row justify="center" class="pa-4">
|
|
5
|
+
<span class="text-h5 font-weight-medium"> Member Suspended </span>
|
|
6
|
+
</v-row>
|
|
7
|
+
</v-col>
|
|
8
|
+
|
|
9
|
+
<span class="text-subtitle-2">
|
|
10
|
+
Your membership has been suspended. Please contact your organization
|
|
11
|
+
administrator for more information.
|
|
12
|
+
</span>
|
|
13
|
+
|
|
14
|
+
<v-col cols="12" class="mt-6">
|
|
15
|
+
<v-row no-gutters justify="center">
|
|
16
|
+
<v-btn
|
|
17
|
+
size="large"
|
|
18
|
+
class="text-none"
|
|
19
|
+
variant="flat"
|
|
20
|
+
color="black"
|
|
21
|
+
rounded
|
|
22
|
+
@click="navigateTo({ name: 'index' })"
|
|
23
|
+
>
|
|
24
|
+
Return to Landing Page
|
|
25
|
+
</v-btn>
|
|
26
|
+
</v-row>
|
|
27
|
+
</v-col>
|
|
28
|
+
</v-row>
|
|
29
|
+
</template>
|
|
30
|
+
|
|
31
|
+
<script setup lang="ts">
|
|
32
|
+
definePageMeta({
|
|
33
|
+
layout: "plain",
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
function createOrg() {
|
|
37
|
+
const { APP, APP_ORG } = useRuntimeConfig().public;
|
|
38
|
+
if (APP === "organization") {
|
|
39
|
+
navigateTo({ name: "organizations-create" });
|
|
40
|
+
} else {
|
|
41
|
+
navigateTo(`${APP_ORG}/organizations/create`, { external: true });
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
</script>
|
|
@@ -0,0 +1,214 @@
|
|
|
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
|
|
16
|
+
v-if="validating"
|
|
17
|
+
cols="12"
|
|
18
|
+
class="text-subtitle-1 font-weight-medium text-center font-italic"
|
|
19
|
+
>
|
|
20
|
+
{{ message }}
|
|
21
|
+
</v-col>
|
|
22
|
+
<v-col v-else cols="12" lg="3" md="4" sm="6">
|
|
23
|
+
<v-row no-gutters>
|
|
24
|
+
<v-col v-if="validInvitation" cols="12">
|
|
25
|
+
<v-form
|
|
26
|
+
v-model="isValid"
|
|
27
|
+
@submit.prevent="
|
|
28
|
+
submit({ firstName, lastName, password, id, referralCode, type })
|
|
29
|
+
"
|
|
30
|
+
id="form1"
|
|
31
|
+
autocomplete="off"
|
|
32
|
+
:disabled="isFormDisabled"
|
|
33
|
+
>
|
|
34
|
+
<v-row no-gutters>
|
|
35
|
+
<v-col cols="12">
|
|
36
|
+
<v-row no-gutters>
|
|
37
|
+
<InputLabel
|
|
38
|
+
class="text-capitalize"
|
|
39
|
+
title="First Name"
|
|
40
|
+
required
|
|
41
|
+
/>
|
|
42
|
+
<v-col cols="12">
|
|
43
|
+
<v-text-field
|
|
44
|
+
v-model="firstName"
|
|
45
|
+
density="comfortable"
|
|
46
|
+
:rules="[requiredRule]"
|
|
47
|
+
></v-text-field>
|
|
48
|
+
</v-col>
|
|
49
|
+
</v-row>
|
|
50
|
+
</v-col>
|
|
51
|
+
|
|
52
|
+
<v-col cols="12" class="mt-2">
|
|
53
|
+
<v-row no-gutters>
|
|
54
|
+
<InputLabel
|
|
55
|
+
class="text-capitalize"
|
|
56
|
+
title="Last Name"
|
|
57
|
+
required
|
|
58
|
+
/>
|
|
59
|
+
<v-col cols="12">
|
|
60
|
+
<v-text-field
|
|
61
|
+
v-model="lastName"
|
|
62
|
+
density="comfortable"
|
|
63
|
+
:rules="[requiredRule]"
|
|
64
|
+
></v-text-field>
|
|
65
|
+
</v-col>
|
|
66
|
+
</v-row>
|
|
67
|
+
</v-col>
|
|
68
|
+
|
|
69
|
+
<v-col cols="12">
|
|
70
|
+
<v-row no-gutters>
|
|
71
|
+
<InputLabel
|
|
72
|
+
class="text-capitalize"
|
|
73
|
+
title="Password"
|
|
74
|
+
required
|
|
75
|
+
/>
|
|
76
|
+
<v-col cols="12">
|
|
77
|
+
<InputPassword v-model="password" :rules="[requiredRule]" />
|
|
78
|
+
</v-col>
|
|
79
|
+
</v-row>
|
|
80
|
+
</v-col>
|
|
81
|
+
|
|
82
|
+
<v-col
|
|
83
|
+
v-if="message"
|
|
84
|
+
cols="12"
|
|
85
|
+
:class="'my-2 text-center font-italic' + msgColor"
|
|
86
|
+
>
|
|
87
|
+
{{ message }}
|
|
88
|
+
</v-col>
|
|
89
|
+
|
|
90
|
+
<v-col cols="12" v-if="!isFormDisabled">
|
|
91
|
+
<v-btn
|
|
92
|
+
block
|
|
93
|
+
type="submit"
|
|
94
|
+
variant="text"
|
|
95
|
+
:disabled="!isValid"
|
|
96
|
+
rounded="xl"
|
|
97
|
+
size="large"
|
|
98
|
+
:loading="loading"
|
|
99
|
+
>
|
|
100
|
+
submit
|
|
101
|
+
</v-btn>
|
|
102
|
+
</v-col>
|
|
103
|
+
</v-row>
|
|
104
|
+
</v-form>
|
|
105
|
+
</v-col>
|
|
106
|
+
|
|
107
|
+
<v-col
|
|
108
|
+
v-else
|
|
109
|
+
cols="12"
|
|
110
|
+
class="text-subtitle-1 font-weight-medium text-center font-italic"
|
|
111
|
+
>
|
|
112
|
+
<span>{{ message }}</span>
|
|
113
|
+
<v-row no-gutters justify="center">
|
|
114
|
+
<nuxt-link :to="{ name: 'index' }">Go to homepage</nuxt-link>
|
|
115
|
+
</v-row>
|
|
116
|
+
</v-col>
|
|
117
|
+
</v-row>
|
|
118
|
+
</v-col>
|
|
119
|
+
</v-row>
|
|
120
|
+
</template>
|
|
121
|
+
|
|
122
|
+
<script setup lang="ts">
|
|
123
|
+
definePageMeta({
|
|
124
|
+
layout: "plain",
|
|
125
|
+
});
|
|
126
|
+
const { verify } = useLocalAuth();
|
|
127
|
+
|
|
128
|
+
const id = (useRoute().params.id as string) ?? "";
|
|
129
|
+
|
|
130
|
+
const validating = ref(true);
|
|
131
|
+
const validInvitation = ref(false);
|
|
132
|
+
|
|
133
|
+
const message = ref("Validating invitation...");
|
|
134
|
+
const msgColor = ref("text-error");
|
|
135
|
+
|
|
136
|
+
const type = ref("");
|
|
137
|
+
const referralCode = ref("");
|
|
138
|
+
const loading = ref(false);
|
|
139
|
+
|
|
140
|
+
async function validate() {
|
|
141
|
+
try {
|
|
142
|
+
const result = await verify(id);
|
|
143
|
+
|
|
144
|
+
if (result.type) {
|
|
145
|
+
type.value = result.type;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (result.referralCode) {
|
|
149
|
+
referralCode.value = result.referralCode;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
validInvitation.value = true;
|
|
153
|
+
message.value = "";
|
|
154
|
+
} catch (error: any) {
|
|
155
|
+
message.value = error.data.message;
|
|
156
|
+
}
|
|
157
|
+
validating.value = false;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
await validate();
|
|
161
|
+
|
|
162
|
+
const { requiredRule } = useUtils();
|
|
163
|
+
const firstName = ref("");
|
|
164
|
+
const lastName = ref("");
|
|
165
|
+
const password = ref("");
|
|
166
|
+
|
|
167
|
+
const isValid = ref(false);
|
|
168
|
+
|
|
169
|
+
const { createUserByVerification } = useUser();
|
|
170
|
+
|
|
171
|
+
const countdown = ref(5); // Countdown from 5 seconds
|
|
172
|
+
const isFormDisabled = ref(false);
|
|
173
|
+
|
|
174
|
+
async function submit({
|
|
175
|
+
firstName = "",
|
|
176
|
+
lastName = "",
|
|
177
|
+
password = "",
|
|
178
|
+
id = "",
|
|
179
|
+
type = "",
|
|
180
|
+
referralCode = "",
|
|
181
|
+
} = {}) {
|
|
182
|
+
message.value = "";
|
|
183
|
+
loading.value = true;
|
|
184
|
+
try {
|
|
185
|
+
const res = await createUserByVerification({
|
|
186
|
+
firstName,
|
|
187
|
+
lastName,
|
|
188
|
+
password,
|
|
189
|
+
id,
|
|
190
|
+
type,
|
|
191
|
+
referralCode,
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
isFormDisabled.value = true;
|
|
195
|
+
|
|
196
|
+
msgColor.value = " text-none";
|
|
197
|
+
|
|
198
|
+
message.value = `${res.message} Redirecting in ${countdown.value} seconds...`;
|
|
199
|
+
|
|
200
|
+
// Start countdown
|
|
201
|
+
const interval = setInterval(() => {
|
|
202
|
+
countdown.value--;
|
|
203
|
+
message.value = `${res.message} Redirecting in ${countdown.value} seconds...`;
|
|
204
|
+
if (countdown.value <= 0) {
|
|
205
|
+
clearInterval(interval);
|
|
206
|
+
navigateTo({ name: "index" });
|
|
207
|
+
}
|
|
208
|
+
}, 1000);
|
|
209
|
+
} catch (error: any) {
|
|
210
|
+
message.value = error.data.message;
|
|
211
|
+
}
|
|
212
|
+
loading.value = false;
|
|
213
|
+
}
|
|
214
|
+
</script>
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-row no-gutters class="fill-height" justify="center" align-content="center">
|
|
3
|
+
<v-col cols="12" lg="3" md="4" sm="6">
|
|
4
|
+
<v-form
|
|
5
|
+
v-model="valid"
|
|
6
|
+
@submit.prevent="submit(email)"
|
|
7
|
+
:disabled="loading"
|
|
8
|
+
>
|
|
9
|
+
<v-row no-gutters>
|
|
10
|
+
<v-col cols="12">
|
|
11
|
+
<v-row no-gutters justify="center">
|
|
12
|
+
<nuxt-link
|
|
13
|
+
class="text-h2 font-weight-bold text-decoration-none"
|
|
14
|
+
style="color: unset"
|
|
15
|
+
:to="{ name: 'index' }"
|
|
16
|
+
>
|
|
17
|
+
GoWeekdays
|
|
18
|
+
</nuxt-link>
|
|
19
|
+
</v-row>
|
|
20
|
+
</v-col>
|
|
21
|
+
|
|
22
|
+
<v-col cols="12" class="mt-6">
|
|
23
|
+
<v-row no-gutters>
|
|
24
|
+
<v-col cols="12" class="text-h6 font-weight-bold"> Email </v-col>
|
|
25
|
+
<v-col cols="12">
|
|
26
|
+
<v-text-field
|
|
27
|
+
v-model="email"
|
|
28
|
+
:rules="[requiredRule, emailRule]"
|
|
29
|
+
></v-text-field>
|
|
30
|
+
</v-col>
|
|
31
|
+
</v-row>
|
|
32
|
+
</v-col>
|
|
33
|
+
|
|
34
|
+
<!-- Honeypot Field (Hidden) -->
|
|
35
|
+
<v-text-field
|
|
36
|
+
v-model="goWeekdaysHoneypot"
|
|
37
|
+
label="Leave this field empty"
|
|
38
|
+
class="goWeekdaysHoneypot"
|
|
39
|
+
autocomplete="off"
|
|
40
|
+
></v-text-field>
|
|
41
|
+
|
|
42
|
+
<v-col cols="12">
|
|
43
|
+
<v-row no-gutters justify="center">
|
|
44
|
+
<v-col
|
|
45
|
+
cols="12"
|
|
46
|
+
class="text-subtitle-1 font-weight-medium text-center font-italic"
|
|
47
|
+
>
|
|
48
|
+
{{ message }}
|
|
49
|
+
</v-col>
|
|
50
|
+
</v-row>
|
|
51
|
+
</v-col>
|
|
52
|
+
|
|
53
|
+
<v-col cols="12" class="mt-4">
|
|
54
|
+
<v-btn
|
|
55
|
+
block
|
|
56
|
+
type="submit"
|
|
57
|
+
variant="tonal"
|
|
58
|
+
:disabled="!valid"
|
|
59
|
+
rounded="xl"
|
|
60
|
+
size="large"
|
|
61
|
+
class="text-none"
|
|
62
|
+
:loading="loading"
|
|
63
|
+
>
|
|
64
|
+
Sign up
|
|
65
|
+
</v-btn>
|
|
66
|
+
</v-col>
|
|
67
|
+
|
|
68
|
+
<v-col cols="12" class="my-4">
|
|
69
|
+
<v-divider></v-divider>
|
|
70
|
+
</v-col>
|
|
71
|
+
|
|
72
|
+
<v-col cols="12" class="text-center font-weight-bold">
|
|
73
|
+
<v-btn
|
|
74
|
+
block
|
|
75
|
+
variant="flat"
|
|
76
|
+
color="black"
|
|
77
|
+
rounded="xl"
|
|
78
|
+
size="large"
|
|
79
|
+
class="text-none"
|
|
80
|
+
:to="{ name: 'login' }"
|
|
81
|
+
>
|
|
82
|
+
Login
|
|
83
|
+
</v-btn>
|
|
84
|
+
</v-col>
|
|
85
|
+
</v-row>
|
|
86
|
+
</v-form>
|
|
87
|
+
</v-col>
|
|
88
|
+
</v-row>
|
|
89
|
+
</template>
|
|
90
|
+
|
|
91
|
+
<script setup lang="ts">
|
|
92
|
+
definePageMeta({
|
|
93
|
+
layout: "plain",
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
const { requiredRule, emailRule } = useUtils();
|
|
97
|
+
const email = ref("");
|
|
98
|
+
const valid = ref(false);
|
|
99
|
+
|
|
100
|
+
const goWeekdaysHoneypot = ref("");
|
|
101
|
+
|
|
102
|
+
const { signUp } = useVerification();
|
|
103
|
+
|
|
104
|
+
const message = ref("");
|
|
105
|
+
|
|
106
|
+
const loading = ref(false);
|
|
107
|
+
|
|
108
|
+
async function submit(email = "") {
|
|
109
|
+
loading.value = true;
|
|
110
|
+
if (goWeekdaysHoneypot.value) {
|
|
111
|
+
console.warn("Bot detected! Form rejected.");
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
try {
|
|
116
|
+
await signUp(email);
|
|
117
|
+
message.value = "Verification email sent! Please check your inbox.";
|
|
118
|
+
} catch (error: any) {
|
|
119
|
+
message.value = error.response._data.message;
|
|
120
|
+
} finally {
|
|
121
|
+
loading.value = false;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
</script>
|
|
125
|
+
|
|
126
|
+
<style scoped>
|
|
127
|
+
.goWeekdaysHoneypot {
|
|
128
|
+
position: absolute;
|
|
129
|
+
left: -9999px;
|
|
130
|
+
opacity: 0;
|
|
131
|
+
height: 0;
|
|
132
|
+
width: 0;
|
|
133
|
+
pointer-events: none;
|
|
134
|
+
}
|
|
135
|
+
</style>
|
package/plugins/member.client.ts
CHANGED
|
@@ -13,18 +13,22 @@ export default defineNuxtPlugin(() => {
|
|
|
13
13
|
|
|
14
14
|
const userId = useCookie("user").value ?? "";
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
membership.value = member;
|
|
16
|
+
try {
|
|
17
|
+
const member = await getByApp({ app: APP, user: userId, org });
|
|
18
|
+
membership.value = member;
|
|
20
19
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
20
|
+
const role = await getRoleById(member.role);
|
|
21
|
+
permissions.value = role.permissions ?? [];
|
|
22
|
+
|
|
23
|
+
if (member.status === "suspended") {
|
|
24
24
|
navigateTo({
|
|
25
|
-
name: "
|
|
25
|
+
name: "member-suspended",
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
|
+
} catch (error) {
|
|
29
|
+
navigateTo({
|
|
30
|
+
name: "index",
|
|
31
|
+
});
|
|
28
32
|
}
|
|
29
33
|
});
|
|
30
34
|
});
|
package/types/member.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ declare type TMember = {
|
|
|
5
5
|
name: string;
|
|
6
6
|
user: string;
|
|
7
7
|
role: string;
|
|
8
|
+
roleName?: string;
|
|
8
9
|
status?: string;
|
|
9
10
|
createdAt?: string;
|
|
10
11
|
updatedAt?: string;
|
|
@@ -12,6 +13,7 @@ declare type TMember = {
|
|
|
12
13
|
};
|
|
13
14
|
|
|
14
15
|
declare type TMemberInvitation = {
|
|
16
|
+
_id?: string;
|
|
15
17
|
email: string;
|
|
16
18
|
app: string;
|
|
17
19
|
org: string;
|