@goweekdays/layer-common 1.3.3 → 1.3.4

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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # @goweekdays/layer-common
2
2
 
3
+ ## 1.3.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 8e83e63: Fix role, member, and user management
8
+
3
9
  ## 1.3.3
4
10
 
5
11
  ### Patch Changes
@@ -145,14 +145,16 @@ const {
145
145
  data: getInviteReq,
146
146
  refresh: getInvitations,
147
147
  status: getInviteReqStatus,
148
- } = await useLazyAsyncData("get-invitations", () =>
149
- getVerifications({
150
- page: page.value,
151
- search: headerSearch.value,
152
- status: props.status,
153
- type: "user-invite,member-invite",
154
- app: props.app,
155
- })
148
+ } = await useLazyAsyncData(
149
+ `get-all-invitations-${props.status}-${page.value}`,
150
+ () =>
151
+ getVerifications({
152
+ page: page.value,
153
+ search: headerSearch.value,
154
+ status: props.status,
155
+ type: "user-invite,member-invite",
156
+ org: props.org,
157
+ })
156
158
  );
157
159
 
158
160
  const loading = computed(() => getInviteReqStatus.value === "pending");
@@ -11,19 +11,22 @@
11
11
  <v-card-text style="max-height: 100vh; overflow-y: auto">
12
12
  <v-form v-model="valid" :disabled="localProps.disabled">
13
13
  <v-row no-gutters>
14
- <v-col cols="12" class="mb-1">
14
+ <v-col v-if="!isAdmin" cols="12" class="mb-1">
15
15
  <v-row no-gutters>
16
16
  <InputLabel
17
17
  class="text-capitalize"
18
- title="Email"
18
+ title="App"
19
19
  :required="isMutable"
20
20
  />
21
21
  <v-col cols="12">
22
- <v-text-field
23
- v-model="invite.email"
24
- :rules="isMutable ? [requiredRule, emailRule] : []"
25
- :readonly="!isMutable"
26
- ></v-text-field>
22
+ <v-select
23
+ v-model="invite.app"
24
+ :items="apps"
25
+ item-title="name"
26
+ item-value="code"
27
+ :rules="isMutable ? [requiredRule] : []"
28
+ :loading="loadingApps"
29
+ ></v-select>
27
30
  </v-col>
28
31
  </v-row>
29
32
  </v-col>
@@ -49,14 +52,19 @@
49
52
  </v-row>
50
53
  </v-col>
51
54
 
52
- <v-col v-if="!localProps.app" cols="12" class="mb-1">
55
+ <v-col cols="12" class="mb-1">
53
56
  <v-row no-gutters>
54
- <InputLabel class="text-capitalize" title="App" required />
57
+ <InputLabel
58
+ class="text-capitalize"
59
+ title="Email"
60
+ :required="isMutable"
61
+ />
55
62
  <v-col cols="12">
56
- <v-select
57
- v-model="invite.app"
58
- :rules="[requiredRule]"
59
- ></v-select>
63
+ <v-text-field
64
+ v-model="invite.email"
65
+ :rules="isMutable ? [requiredRule, emailRule] : []"
66
+ :readonly="!isMutable"
67
+ ></v-text-field>
60
68
  </v-col>
61
69
  </v-row>
62
70
  </v-col>
@@ -181,6 +189,8 @@ const invite = defineModel<TMemberInvitation>({
181
189
  default: () => useMember().invitation.value,
182
190
  });
183
191
 
192
+ invite.value.app = localProps.app;
193
+
184
194
  const message = defineModel("message", { default: "" });
185
195
 
186
196
  const valid = ref(false);
@@ -193,7 +203,10 @@ const roles = ref<Array<Record<string, any>>>([]);
193
203
 
194
204
  const { data: roleData, status: roleReqStatus } = await useLazyAsyncData(
195
205
  `get-all-role-app-${localProps.app}-${localProps.org ?? "org"}`,
196
- () => getAllRoles({ org: localProps.org, app: localProps.app, limit: 50 })
206
+ () => getAllRoles({ org: localProps.org, app: invite.value.app, limit: 50 }),
207
+ {
208
+ watch: [() => invite.value.app],
209
+ }
197
210
  );
198
211
 
199
212
  const loadingRoles = computed(() => roleReqStatus.value === "pending");
@@ -203,4 +216,26 @@ watchEffect(() => {
203
216
  roles.value = roleData.value.items;
204
217
  }
205
218
  });
219
+
220
+ const isAdmin = computed(() => localProps.app === "admin");
221
+
222
+ const apps = ref<TApp[]>([]);
223
+
224
+ const { getAll: getAllApps } = useApps();
225
+
226
+ const { data: appsData, status: appsReqStatus } = useLazyAsyncData(
227
+ "get-all-apps-invite-member-form",
228
+ () => getAllApps({ limit: 100 }),
229
+ {
230
+ immediate: !isAdmin.value,
231
+ }
232
+ );
233
+
234
+ const loadingApps = computed(() => appsReqStatus.value === "pending");
235
+
236
+ watchEffect(() => {
237
+ if (appsData.value && appsData.value.items) {
238
+ apps.value = appsData.value.items;
239
+ }
240
+ });
206
241
  </script>
@@ -292,7 +292,7 @@ async function submitInvite() {
292
292
  disabledInvite.value = true;
293
293
  try {
294
294
  await inviteMember({
295
- app: props.type,
295
+ app: invitation.value.app,
296
296
  org: props.orgId,
297
297
  email: invitation.value.email,
298
298
  role: invitation.value.role,
@@ -11,6 +11,26 @@
11
11
  <v-card-text style="max-height: 100vh; overflow-y: auto">
12
12
  <v-form v-model="valid">
13
13
  <v-row no-gutters>
14
+ <v-col v-if="isOrg" cols="12" class="mb-1">
15
+ <v-row no-gutters>
16
+ <InputLabel
17
+ class="text-capitalize"
18
+ title="App"
19
+ :required="isMutable"
20
+ />
21
+ <v-col cols="12">
22
+ <v-select
23
+ v-model="role.app"
24
+ :items="apps"
25
+ item-title="name"
26
+ item-value="code"
27
+ :readonly="!isMutable"
28
+ :loading="loadingApps"
29
+ ></v-select>
30
+ </v-col>
31
+ </v-row>
32
+ </v-col>
33
+
14
34
  <v-col cols="12" class="mb-1">
15
35
  <v-row no-gutters>
16
36
  <InputLabel
@@ -65,26 +85,6 @@
65
85
  </v-col>
66
86
  </v-row>
67
87
  </v-col>
68
-
69
- <v-col v-if="!localProps.app && isMutable" cols="12" class="mb-1">
70
- <v-row no-gutters>
71
- <InputLabel
72
- class="text-capitalize"
73
- title="App"
74
- :required="isMutable"
75
- />
76
- <v-col cols="12">
77
- <v-select
78
- v-model="role.app"
79
- :items="apps"
80
- item-title="name"
81
- item-value="code"
82
- :readonly="!isMutable"
83
- :loading="loadingApps"
84
- ></v-select>
85
- </v-col>
86
- </v-row>
87
- </v-col>
88
88
  </v-row>
89
89
  </v-form>
90
90
 
@@ -222,6 +222,8 @@ const apps = ref<TApp[]>([]);
222
222
 
223
223
  const { getAll: getAllApps } = useApps();
224
224
 
225
+ const isOrg = computed(() => localProps.app === "org");
226
+
225
227
  const {
226
228
  data: appsData,
227
229
  status: appsReqStatus,
@@ -233,14 +235,10 @@ const {
233
235
  limit: 20,
234
236
  }),
235
237
  {
236
- immediate: false,
238
+ immediate: isOrg.value,
237
239
  }
238
240
  );
239
241
 
240
- if (!localProps.app) {
241
- refreshApps();
242
- }
243
-
244
242
  const loadingApps = computed(() => appsReqStatus.value === "pending");
245
243
 
246
244
  watchEffect(() => {
@@ -105,7 +105,7 @@
105
105
  content="Are you sure you want to delete this role? This action cannot be undone."
106
106
  @cancel="setRole({ mode: 'delete' })"
107
107
  @confirm="submitDelete()"
108
- :message="message"
108
+ v-model:message="message"
109
109
  />
110
110
  </v-dialog>
111
111
  </v-row>
@@ -136,8 +136,7 @@ const props = defineProps({
136
136
  title: "permissions",
137
137
  value: "permissions",
138
138
  },
139
- { title: "App", value: "type" },
140
- { title: "Action", value: "action-table" },
139
+ { title: "App", value: "app" },
141
140
  ],
142
141
  },
143
142
  canCreateRole: {
@@ -189,7 +188,7 @@ function setRole({
189
188
  JSON.parse(
190
189
  JSON.stringify({
191
190
  ...data,
192
- app: props.app,
191
+ app: mode === "admin" ? props.app : data.app,
193
192
  })
194
193
  )
195
194
  );
@@ -215,6 +214,8 @@ function setRole({
215
214
 
216
215
  const items = ref<Array<Record<string, any>>>([]);
217
216
 
217
+ const isOrg = computed(() => props.app === "org");
218
+
218
219
  const {
219
220
  data: getRoleReq,
220
221
  refresh: getRoles,
@@ -225,8 +226,8 @@ const {
225
226
  _getRoles({
226
227
  page: page.value,
227
228
  search: headerSearch.value,
228
- app: props.app,
229
229
  org: props.org,
230
+ app: isOrg.value ? "" : props.app,
230
231
  }),
231
232
  {
232
233
  watch: [page, headerSearch],
@@ -41,38 +41,10 @@ export default function useLocalAuth() {
41
41
  }
42
42
 
43
43
  async function forgotPassword(email: string) {
44
- if (!email) {
45
- throw new Error("Email is required for password reset request.");
46
- }
47
-
48
- try {
49
- const response = await $fetch("/api/auth/forget-password", {
50
- method: "POST",
51
- body: JSON.stringify({ email }),
52
- headers: { "Content-Type": "application/json" },
53
- });
54
- return response;
55
- } catch (error) {
56
- console.error("Error in password reset request:", error);
57
- throw error;
58
- }
59
- }
60
-
61
- async function resetPassword(
62
- otp: string,
63
- newPassword: string,
64
- passwordConfirmation: string
65
- ) {
66
- try {
67
- return await $fetch("/api/auth/reset-password", {
68
- method: "POST",
69
- body: JSON.stringify({ otp, newPassword, passwordConfirmation }),
70
- headers: { "Content-Type": "application/json" },
71
- });
72
- } catch (error) {
73
- console.error("Error resetting password:", error);
74
- throw error;
75
- }
44
+ return $fetch<Record<string, any>>("/api/verifications/forget-password", {
45
+ method: "POST",
46
+ body: JSON.stringify({ email }),
47
+ });
76
48
  }
77
49
 
78
50
  function verify(id: string) {
@@ -94,7 +66,6 @@ export default function useLocalAuth() {
94
66
  logout,
95
67
  getCurrentUser,
96
68
  forgotPassword,
97
- resetPassword,
98
69
  verify,
99
70
  loggedInUser,
100
71
  };
@@ -87,6 +87,17 @@ export default function useUser() {
87
87
  });
88
88
  }
89
89
 
90
+ async function resetPassword(value: {
91
+ id: string;
92
+ newPassword: string;
93
+ confirmPassword: string;
94
+ }) {
95
+ return $fetch("/api/users/password", {
96
+ method: "PATCH",
97
+ body: value,
98
+ });
99
+ }
100
+
90
101
  return {
91
102
  inviteUser,
92
103
  updateName,
@@ -98,5 +109,6 @@ export default function useUser() {
98
109
  getUsers,
99
110
  createUserByVerification,
100
111
  getById,
112
+ resetPassword,
101
113
  };
102
114
  }
@@ -6,10 +6,11 @@ export default function useUser() {
6
6
  page = 1,
7
7
  email = "",
8
8
  app = "",
9
+ org = "",
9
10
  } = {}) {
10
11
  return $fetch<Record<string, any>>("/api/verifications", {
11
12
  method: "GET",
12
- query: { status, search, page, type, email, app },
13
+ query: { status, search, page, type, email, app, org },
13
14
  });
14
15
  }
15
16
 
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@goweekdays/layer-common",
3
3
  "license": "MIT",
4
4
  "type": "module",
5
- "version": "1.3.3",
5
+ "version": "1.3.4",
6
6
  "main": "./nuxt.config.ts",
7
7
  "publishConfig": {
8
8
  "access": "public"
@@ -66,11 +66,12 @@ const { forgotPassword } = useLocalAuth();
66
66
  const message = ref("");
67
67
 
68
68
  async function submit(email = "") {
69
+ message.value = "";
69
70
  try {
70
- const result: any = await forgotPassword(email);
71
- message.value = result.message;
71
+ const result = await forgotPassword(email);
72
+ message.value = result.message;
72
73
  } catch (error: any) {
73
- message.value = error.message;
74
+ message.value = error.response?._data?.message || "An error occurred.";
74
75
  }
75
76
  }
76
77
  </script>
package/pages/index.vue CHANGED
@@ -1,3 +1,94 @@
1
1
  <template>
2
- <h1>index</h1>
2
+ <v-row no-gutters class="fill-height" justify="center" align-content="center">
3
+ <v-col cols="12" class="text-center">
4
+ <span class="text-h1 font-weight-bold">{{ APP_NAME }}</span>
5
+ </v-col>
6
+
7
+ <v-col cols="12" class="text-center mt-6" v-if="currentUser">
8
+ <v-row no-gutters justify="center">
9
+ <v-btn
10
+ class="text-lowercase"
11
+ rounded="xl"
12
+ variant="tonal"
13
+ size="large"
14
+ @click="handleSignin()"
15
+ >
16
+ <span class="d-inline-block text-truncate" style="width: 300px">
17
+ Sign-in as {{ currentUser?.email }}
18
+ </span>
19
+ </v-btn>
20
+ </v-row>
21
+ </v-col>
22
+
23
+ <v-col cols="12" class="text-center mt-6" v-else>
24
+ <v-row justify="center">
25
+ <v-col cols="12" lg="2" md="3" sm="3">
26
+ <v-btn
27
+ block
28
+ class="text-lowercase"
29
+ rounded="xl"
30
+ variant="tonal"
31
+ size="large"
32
+ :to="{ name: 'login' }"
33
+ >
34
+ Sign In
35
+ </v-btn>
36
+ </v-col>
37
+
38
+ <v-col cols="12">
39
+ Don't have an account?
40
+ <nuxt-link :href="`${APP_MAIN}/sign-up`">Sign up</nuxt-link>
41
+ </v-col>
42
+ </v-row>
43
+ </v-col>
44
+ </v-row>
3
45
  </template>
46
+
47
+ <script setup lang="ts">
48
+ definePageMeta({
49
+ layout: "plain",
50
+ });
51
+
52
+ const { APP_NAME, APP_MAIN, APP } = useRuntimeConfig().public;
53
+
54
+ const { getCurrentUser, currentUser, loggedInUser } = useLocalAuth();
55
+ try {
56
+ await getCurrentUser();
57
+ } catch (error) {
58
+ console.log(error);
59
+ }
60
+
61
+ const { getByApp } = useMember();
62
+
63
+ const isPartnerApp = computed(() =>
64
+ [
65
+ "org",
66
+ "marketplace",
67
+ "services",
68
+ "stay",
69
+ "ride",
70
+ "eat",
71
+ "experience",
72
+ "job",
73
+ ].includes(APP)
74
+ );
75
+
76
+ const { data: member } = await useLazyAsyncData(
77
+ "get-member-by-app",
78
+ () => getByApp({ app: APP, user: loggedInUser() }),
79
+ { immediate: isPartnerApp.value }
80
+ );
81
+
82
+ function handleSignin() {
83
+ if (APP === "main") {
84
+ navigateTo({ name: "feeds" });
85
+ } else if (APP === "admin") {
86
+ navigateTo({ name: "home" });
87
+ } else {
88
+ navigateTo({
89
+ name: "org-dashboard",
90
+ params: { org: member.value?.org ?? "org" },
91
+ });
92
+ }
93
+ }
94
+ </script>
package/pages/login.vue CHANGED
@@ -127,7 +127,7 @@ async function submit({ email = "", password = "" } = {}) {
127
127
  await login({ email, password });
128
128
 
129
129
  if (APP === "main") {
130
- await navigateTo({ name: "feed" });
130
+ await navigateTo({ name: "feeds" });
131
131
  return;
132
132
  }
133
133
 
@@ -148,7 +148,16 @@ async function submit({ email = "", password = "" } = {}) {
148
148
  return;
149
149
  }
150
150
  } catch (error: any) {
151
- message.value = error.response._data.message;
151
+ if (
152
+ error.response &&
153
+ error.response._data &&
154
+ error.response._data.message
155
+ ) {
156
+ message.value = error.response._data.message;
157
+ } else {
158
+ message.value = "An unexpected error occurred. Please try again.";
159
+ }
160
+ console.log(error);
152
161
  } finally {
153
162
  loading.value = false;
154
163
  }
@@ -0,0 +1,110 @@
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="isValid"
6
+ @submit.prevent="submit(otp, newPassword, confirmPassword)"
7
+ >
8
+ <v-row no-gutters>
9
+ <v-col cols="12">
10
+ <v-row no-gutters justify="center">
11
+ <nuxt-link
12
+ class="text-h2 font-weight-bold text-decoration-none"
13
+ style="color: unset"
14
+ :to="{ name: 'index' }"
15
+ >
16
+ GoWeekdays
17
+ </nuxt-link>
18
+ </v-row>
19
+ </v-col>
20
+
21
+ <v-col cols="12" class="mt-6">
22
+ <v-row no-gutters>
23
+ <v-col cols="12" class="text-h6 font-weight-bold">
24
+ New Password
25
+ </v-col>
26
+ <v-col cols="12">
27
+ <InputPassword
28
+ id="newPassword"
29
+ v-model="newPassword"
30
+ :rules="[requiredRule, passwordRule]"
31
+ />
32
+ </v-col>
33
+ </v-row>
34
+ </v-col>
35
+
36
+ <v-col cols="12">
37
+ <v-row no-gutters>
38
+ <v-col cols="12" class="text-h6 font-weight-bold">
39
+ Confirm New Password
40
+ </v-col>
41
+ <v-col cols="12">
42
+ <InputPassword
43
+ id="confirmPassword"
44
+ v-model="confirmPassword"
45
+ :rules="[requiredRule, passwordRule]"
46
+ :errorMessages="
47
+ confirmPassword && newPassword !== confirmPassword
48
+ ? 'Password mismatch!'
49
+ : ''
50
+ "
51
+ />
52
+ </v-col>
53
+ </v-row>
54
+ </v-col>
55
+
56
+ <v-col v-if="message" cols="12" class="my-2 font-italic text-center">
57
+ {{ message }}
58
+ </v-col>
59
+
60
+ <v-col cols="12">
61
+ <v-row no-gutters justify="center">
62
+ <v-btn
63
+ type="submit"
64
+ variant="tonal"
65
+ :disabled="!isValid"
66
+ rounded="xl"
67
+ size="large"
68
+ >
69
+ submit
70
+ </v-btn>
71
+ </v-row>
72
+ </v-col>
73
+
74
+ <v-col cols="12" class="mt-6 text-center">
75
+ All good?
76
+ <nuxt-link :to="{ name: 'index' }">Sign in</nuxt-link>
77
+ </v-col>
78
+ </v-row>
79
+ </v-form>
80
+ </v-col>
81
+ </v-row>
82
+ </template>
83
+
84
+ <script setup lang="ts">
85
+ definePageMeta({
86
+ layout: "plain",
87
+ });
88
+ const { requiredRule, passwordRule } = useUtils();
89
+ const newPassword = ref("");
90
+ const confirmPassword = ref("");
91
+ const isValid = ref(false);
92
+ const otp = (useRoute().params.otp as string) ?? "";
93
+
94
+ const { resetPassword } = useUser();
95
+
96
+ const message = ref("");
97
+
98
+ async function submit(id = "", newPassword = "", confirmPassword = "") {
99
+ try {
100
+ const result: any = await resetPassword({
101
+ id,
102
+ newPassword,
103
+ confirmPassword,
104
+ });
105
+ message.value = result.message;
106
+ } catch (error: any) {
107
+ message.value = error.response._data.message;
108
+ }
109
+ }
110
+ </script>
@@ -139,15 +139,7 @@ const loading = ref(false);
139
139
 
140
140
  async function validate() {
141
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
- }
142
+ await verify(id);
151
143
 
152
144
  validInvitation.value = true;
153
145
  message.value = "";
@@ -0,0 +1,163 @@
1
+ <template>
2
+ <v-row no-gutters class="fill-height" justify="center" align-content="center">
3
+ <v-col
4
+ v-if="validating"
5
+ cols="12"
6
+ class="text-subtitle-1 font-weight-medium text-center"
7
+ >
8
+ {{ message }}
9
+ </v-col>
10
+ <v-col v-else cols="12" lg="3" md="4" sm="6">
11
+ <v-row no-gutters>
12
+ <v-col v-if="validInvitation" cols="12">
13
+ <v-form
14
+ v-model="isValid"
15
+ @submit.prevent="submit({ firstName, lastName, password, id })"
16
+ id="form1"
17
+ autocomplete="off"
18
+ >
19
+ <v-row no-gutters>
20
+ <v-col cols="12">
21
+ <v-row no-gutters>
22
+ <InputLabel
23
+ class="text-capitalize"
24
+ title="First Name"
25
+ required
26
+ />
27
+ <v-col cols="12">
28
+ <v-text-field
29
+ v-model="firstName"
30
+ density="comfortable"
31
+ :rules="[requiredRule]"
32
+ ></v-text-field>
33
+ </v-col>
34
+ </v-row>
35
+ </v-col>
36
+
37
+ <v-col cols="12" class="mt-2">
38
+ <v-row no-gutters>
39
+ <InputLabel
40
+ class="text-capitalize"
41
+ title="Last Name"
42
+ required
43
+ />
44
+ <v-col cols="12">
45
+ <v-text-field
46
+ v-model="lastName"
47
+ density="comfortable"
48
+ :rules="[requiredRule]"
49
+ ></v-text-field>
50
+ </v-col>
51
+ </v-row>
52
+ </v-col>
53
+
54
+ <v-col cols="12">
55
+ <v-row no-gutters>
56
+ <InputLabel
57
+ class="text-capitalize"
58
+ title="Password"
59
+ required
60
+ />
61
+ <v-col cols="12">
62
+ <InputPassword v-model="password" :rules="[requiredRule]" />
63
+ </v-col>
64
+ </v-row>
65
+ </v-col>
66
+
67
+ <v-col
68
+ v-if="errorOnSubmit"
69
+ cols="12"
70
+ class="my-2 text-error text-center"
71
+ >
72
+ {{ message }}
73
+ </v-col>
74
+
75
+ <v-col cols="12">
76
+ <v-btn
77
+ block
78
+ type="submit"
79
+ variant="text"
80
+ :disabled="!isValid"
81
+ rounded="xl"
82
+ size="large"
83
+ >
84
+ submit
85
+ </v-btn>
86
+ </v-col>
87
+ </v-row>
88
+ </v-form>
89
+ </v-col>
90
+
91
+ <v-col
92
+ v-else
93
+ cols="12"
94
+ class="text-subtitle-1 font-weight-medium text-center"
95
+ >
96
+ <span>{{ message }}</span>
97
+ <v-row no-gutters justify="center">
98
+ <nuxt-link :to="{ name: 'index' }">Go to homepage</nuxt-link>
99
+ </v-row>
100
+ </v-col>
101
+ </v-row>
102
+ </v-col>
103
+ </v-row>
104
+ </template>
105
+
106
+ <script setup lang="ts">
107
+ definePageMeta({
108
+ layout: "plain",
109
+ });
110
+ const { verify } = useLocalAuth();
111
+
112
+ const id = (useRoute().params.id as string) ?? "";
113
+
114
+ const validating = ref(true);
115
+ const validInvitation = ref(false);
116
+
117
+ const message = ref("Validating invitation...");
118
+ const invite = ref<Record<string, any> | null>(null);
119
+
120
+ async function validate() {
121
+ try {
122
+ invite.value = await verify(id);
123
+ validInvitation.value = true;
124
+ } catch (error: any) {
125
+ message.value = error.data.message;
126
+ }
127
+ validating.value = false;
128
+ }
129
+
130
+ await validate();
131
+
132
+ const { requiredRule } = useUtils();
133
+ const firstName = ref("");
134
+ const lastName = ref("");
135
+ const password = ref("");
136
+ const isValid = ref(false);
137
+
138
+ const { createUserByVerification } = useUser();
139
+
140
+ const errorOnSubmit = ref(false);
141
+
142
+ async function submit({
143
+ firstName = "",
144
+ lastName = "",
145
+ password = "",
146
+ id = "",
147
+ } = {}) {
148
+ errorOnSubmit.value = false;
149
+ try {
150
+ await createUserByVerification({
151
+ firstName,
152
+ lastName,
153
+ password,
154
+ id,
155
+ type: invite.value?.type,
156
+ });
157
+ await navigateTo({ name: "index" });
158
+ } catch (error: any) {
159
+ message.value = error.response._data.message;
160
+ errorOnSubmit.value = true;
161
+ }
162
+ }
163
+ </script>
@@ -0,0 +1,67 @@
1
+ <template>
2
+ <v-row no-gutters class="fill-height" justify="center" align-content="center">
3
+ <v-col cols="12" class="text-subtitle-1 font-weight-medium text-center">
4
+ {{ message }}
5
+ </v-col>
6
+ </v-row>
7
+ </template>
8
+
9
+ <script setup lang="ts">
10
+ definePageMeta({
11
+ layout: "plain",
12
+ });
13
+ const { verify } = useLocalAuth();
14
+
15
+ const id = (useRoute().params.id as string) ?? "";
16
+
17
+ const validating = ref(true);
18
+ const validInvitation = ref(false);
19
+
20
+ const message = ref("Validating invitation...");
21
+ const invite = ref<Record<string, any> | null>(null);
22
+
23
+ async function validate() {
24
+ try {
25
+ invite.value = await verify(id);
26
+ validInvitation.value = true;
27
+ message.value =
28
+ invite.value.message || "Successfully accepted the invitation!";
29
+ } catch (error: any) {
30
+ message.value = error.data.message;
31
+ }
32
+ validating.value = false;
33
+ }
34
+
35
+ await validate();
36
+
37
+ const { requiredRule } = useUtils();
38
+ const firstName = ref("");
39
+ const lastName = ref("");
40
+ const password = ref("");
41
+ const isValid = ref(false);
42
+
43
+ const { createUserByVerification } = useUser();
44
+
45
+ const errorOnSubmit = ref(false);
46
+
47
+ async function submit({
48
+ firstName = "",
49
+ lastName = "",
50
+ password = "",
51
+ id = "",
52
+ } = {}) {
53
+ errorOnSubmit.value = false;
54
+ try {
55
+ await createUserByVerification({
56
+ firstName,
57
+ lastName,
58
+ password,
59
+ id,
60
+ type: invite.value?.type,
61
+ });
62
+ } catch (error: any) {
63
+ message.value = error.response._data.message;
64
+ errorOnSubmit.value = true;
65
+ }
66
+ }
67
+ </script>