@iservice365/layer-common 0.1.0 → 0.2.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.
Files changed (93) hide show
  1. package/.playground/app.vue +7 -2
  2. package/.playground/pages/feedback.vue +30 -0
  3. package/CHANGELOG.md +12 -0
  4. package/components/Chat/Bubbles.vue +53 -0
  5. package/components/Chat/Information.vue +187 -0
  6. package/components/Chat/ListCard.vue +62 -0
  7. package/components/Chat/Message.vue +149 -0
  8. package/components/Chat/Navigation.vue +150 -0
  9. package/components/ConfirmDialog.vue +66 -0
  10. package/components/Container/Standard.vue +33 -0
  11. package/components/Feedback/Form.vue +136 -0
  12. package/components/FeedbackDetail.vue +465 -0
  13. package/components/FeedbackMain.vue +454 -0
  14. package/components/FormDialog.vue +65 -0
  15. package/components/Input/File.vue +203 -0
  16. package/components/Input/ListGroupSelection.vue +96 -0
  17. package/components/Input/NewDate.vue +123 -0
  18. package/components/Input/Number.vue +124 -0
  19. package/components/InvitationMain.vue +284 -0
  20. package/components/Layout/Header.vue +14 -4
  21. package/components/ListView.vue +87 -0
  22. package/components/MemberMain.vue +459 -0
  23. package/components/RolePermissionFormCreate.vue +161 -0
  24. package/components/RolePermissionFormPreviewUpdate.vue +183 -0
  25. package/components/RolePermissionMain.vue +361 -0
  26. package/components/ServiceProviderFormCreate.vue +154 -0
  27. package/components/ServiceProviderMain.vue +195 -0
  28. package/components/SignaturePad.vue +73 -0
  29. package/components/SpecificAttr.vue +53 -0
  30. package/components/SwitchContext.vue +26 -5
  31. package/components/TableList.vue +150 -0
  32. package/components/TableListSecondary.vue +164 -0
  33. package/components/WorkOrder/Create.vue +197 -0
  34. package/components/WorkOrder/ListView.vue +96 -0
  35. package/components/WorkOrder/Main.vue +308 -0
  36. package/components/Workorder.vue +1 -0
  37. package/composables/useAddress.ts +107 -0
  38. package/composables/useCommonPermission.ts +130 -0
  39. package/composables/useCustomer.ts +113 -0
  40. package/composables/useFeedback.ts +117 -0
  41. package/composables/useFile.ts +40 -0
  42. package/composables/useInvoice.ts +18 -0
  43. package/composables/useLocal.ts +24 -4
  44. package/composables/useLocalAuth.ts +62 -20
  45. package/composables/useLocalSetup.ts +13 -0
  46. package/composables/useMember.ts +111 -0
  47. package/composables/useOrg.ts +76 -92
  48. package/composables/usePaymentMethod.ts +101 -0
  49. package/composables/usePrice.ts +15 -0
  50. package/composables/usePromoCode.ts +36 -0
  51. package/composables/useRole.ts +38 -7
  52. package/composables/useServiceProvider.ts +218 -0
  53. package/composables/useSite.ts +108 -0
  54. package/composables/useSubscription.ts +149 -0
  55. package/composables/useUser.ts +38 -14
  56. package/composables/useUtils.ts +218 -6
  57. package/composables/useVerification.ts +33 -0
  58. package/composables/useWorkOrder.ts +68 -0
  59. package/middleware/01.auth.ts +11 -0
  60. package/middleware/02.org.ts +18 -0
  61. package/middleware/03.customer.ts +13 -0
  62. package/middleware/member.ts +4 -0
  63. package/nuxt.config.ts +3 -1
  64. package/package.json +7 -3
  65. package/pages/index.vue +3 -0
  66. package/pages/payment-method-linked.vue +31 -0
  67. package/pages/require-customer.vue +56 -0
  68. package/pages/require-organization-membership.vue +47 -0
  69. package/pages/unauthorized.vue +29 -0
  70. package/plugins/API.ts +2 -25
  71. package/plugins/iconify.client.ts +5 -0
  72. package/plugins/secure-member.client.ts +54 -0
  73. package/plugins/vuetify.ts +2 -0
  74. package/public/bg-camera.jpg +0 -0
  75. package/public/bg-city.jpg +0 -0
  76. package/public/bg-condo.jpg +0 -0
  77. package/public/images/icons/delete-icon.png +0 -0
  78. package/public/sprite.svg +1 -0
  79. package/types/address.d.ts +13 -0
  80. package/types/customer.d.ts +15 -0
  81. package/types/feedback.d.ts +63 -0
  82. package/types/local.d.ts +47 -38
  83. package/types/member.d.ts +21 -0
  84. package/types/org.d.ts +13 -0
  85. package/types/permission.d.ts +1 -0
  86. package/types/price.d.ts +17 -0
  87. package/types/promo-code.d.ts +19 -0
  88. package/types/service-provider.d.ts +15 -0
  89. package/types/site.d.ts +13 -0
  90. package/types/subscription.d.ts +23 -0
  91. package/types/user.d.ts +19 -0
  92. package/types/verification.d.ts +20 -0
  93. package/types/work-order.d.ts +40 -0
@@ -0,0 +1,183 @@
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">
6
+ {{ props.name }}
7
+ </span>
8
+ </v-row>
9
+ </v-toolbar>
10
+ <v-card-text style="max-height: 100vh; overflow-y: auto" class="pb-0">
11
+ <v-form v-model="validForm" :disabled="disable">
12
+ <v-row no-gutters>
13
+ <v-col cols="12" class="mt-4">
14
+ <InputListGroupSelection
15
+ v-model="definedModel"
16
+ :items="props.permissions"
17
+ variant="outlined"
18
+ border="thin"
19
+ :error-messages="errorMessages"
20
+ :readonly="!edit"
21
+ :hint="
22
+ edit ? 'Select permissions' : 'Permissions are not editable'
23
+ "
24
+ persistent-hint
25
+ />
26
+ </v-col>
27
+
28
+ <v-col v-if="edit" cols="12" class="my-2">
29
+ <v-row no-gutters>
30
+ <v-col cols="12" class="text-center">
31
+ <span
32
+ class="text-none text-subtitle-2 font-weight-medium text-error"
33
+ >
34
+ {{ message }}
35
+ </span>
36
+ </v-col>
37
+ </v-row>
38
+ </v-col>
39
+
40
+ <v-col cols="12" class="my-2">
41
+ <v-row no-gutters>
42
+ <v-col cols="12" class="text-center">
43
+ <span
44
+ class="text-none text-subtitle-2 font-weight-medium text-error"
45
+ >
46
+ {{ message }}
47
+ </span>
48
+ </v-col>
49
+ </v-row>
50
+ </v-col>
51
+ </v-row>
52
+ </v-form>
53
+ </v-card-text>
54
+
55
+ <v-toolbar>
56
+ <v-row class="px-6">
57
+ <v-col v-if="!edit" cols="6">
58
+ <v-btn
59
+ block
60
+ variant="text"
61
+ class="text-none"
62
+ size="large"
63
+ @click="emit('cancel')"
64
+ >
65
+ Close
66
+ </v-btn>
67
+ </v-col>
68
+
69
+ <v-col v-else cols="6">
70
+ <v-btn
71
+ block
72
+ variant="text"
73
+ class="text-none"
74
+ size="large"
75
+ @click="edit = false"
76
+ >
77
+ Cancel
78
+ </v-btn>
79
+ </v-col>
80
+
81
+ <v-col v-if="!edit" cols="6">
82
+ <v-btn
83
+ block
84
+ variant="flat"
85
+ color="black"
86
+ class="text-none"
87
+ size="large"
88
+ :disabled="!validForm"
89
+ @click="edit = true"
90
+ >
91
+ Edit
92
+ </v-btn>
93
+ </v-col>
94
+
95
+ <v-col v-else cols="6">
96
+ <v-btn
97
+ block
98
+ variant="flat"
99
+ color="black"
100
+ class="text-none"
101
+ size="large"
102
+ :disabled="!validForm"
103
+ @click="submit()"
104
+ >
105
+ Submit
106
+ </v-btn>
107
+ </v-col>
108
+ </v-row>
109
+ </v-toolbar>
110
+ </v-card>
111
+ </template>
112
+
113
+ <script setup lang="ts">
114
+ const definedModel = defineModel<Array<string>>({
115
+ default: () => [],
116
+ });
117
+
118
+ const props = defineProps({
119
+ name: {
120
+ type: String,
121
+ default: "Role",
122
+ },
123
+ id: {
124
+ type: String,
125
+ default: "",
126
+ },
127
+ permissions: {
128
+ type: Object,
129
+ default: () => ({}),
130
+ },
131
+ originalPermissions: {
132
+ type: Object,
133
+ default: () => ({}),
134
+ },
135
+ });
136
+
137
+ const validForm = ref(false);
138
+ const message = ref("");
139
+ const disable = ref(false);
140
+
141
+ const emit = defineEmits(["success", "cancel"]);
142
+
143
+ const edit = defineModel<boolean>("edit", {
144
+ default: false,
145
+ });
146
+
147
+ function equalListValue() {
148
+ return JSON.stringify(definedModel.value) ===
149
+ JSON.stringify(props.originalPermissions)
150
+ ? "No changes made"
151
+ : "";
152
+ }
153
+
154
+ const { requireListRule } = useUtils();
155
+
156
+ const errorMessages = computed(() => {
157
+ const equalValue = equalListValue();
158
+ if (edit.value && equalValue) {
159
+ return equalValue;
160
+ }
161
+
162
+ const requiredValue = requireListRule(definedModel.value);
163
+ if (requiredValue) {
164
+ return requiredValue;
165
+ }
166
+
167
+ return "";
168
+ });
169
+
170
+ const { updatePermissionById } = useRole();
171
+
172
+ async function submit() {
173
+ disable.value = true;
174
+ try {
175
+ await updatePermissionById(props.id, definedModel.value);
176
+ emit("success");
177
+ } catch (error: any) {
178
+ message.value = error.response._data.message;
179
+ } finally {
180
+ disable.value = false;
181
+ }
182
+ }
183
+ </script>
@@ -0,0 +1,361 @@
1
+ <template>
2
+ <v-row no-gutters>
3
+ <v-col cols="12" class="mb-2">
4
+ <v-row no-gutters>
5
+ <v-btn
6
+ class="text-none"
7
+ rounded="pill"
8
+ variant="tonal"
9
+ @click="createDialog = true"
10
+ size="large"
11
+ v-if="canCreateRole"
12
+ >
13
+ Create role
14
+ </v-btn>
15
+ </v-row>
16
+ </v-col>
17
+ <v-col cols="12">
18
+ <v-card
19
+ width="100%"
20
+ variant="outlined"
21
+ border="thin"
22
+ rounded="lg"
23
+ :loading="loading"
24
+ >
25
+ <v-toolbar density="compact" color="grey-lighten-4">
26
+ <template #prepend>
27
+ <v-btn fab icon density="comfortable" @click="getRoles()">
28
+ <v-icon>mdi-refresh</v-icon>
29
+ </v-btn>
30
+ </template>
31
+
32
+ <template #append>
33
+ <v-row no-gutters justify="end" align="center">
34
+ <span class="mr-2 text-caption text-fontgray">
35
+ {{ pageRange }}
36
+ </span>
37
+ <local-pagination
38
+ v-model="page"
39
+ :length="pages"
40
+ @update:value="getRoles()"
41
+ />
42
+ </v-row>
43
+ </template>
44
+ </v-toolbar>
45
+
46
+ <v-data-table
47
+ :headers="props.headers"
48
+ :items="items"
49
+ item-value="_id"
50
+ items-per-page="20"
51
+ fixed-header
52
+ hide-default-footer
53
+ hide-default-header
54
+ @click:row="tableRowClickHandler"
55
+ style="max-height: calc(100vh - (180px))"
56
+ >
57
+ <template #item.permissions="{ value }">
58
+ <span class="text-caption font-weight-bold text-capitalize">
59
+ permissions
60
+ </span>
61
+ <v-chip>{{ value.length }}</v-chip>
62
+ </template>
63
+
64
+ <template #item.action-table="{ item }" v-if="canDeleteRole">
65
+ <v-menu :close-on-content-click="false" offset-y width="150">
66
+ <template v-slot:activator="{ props }">
67
+ <v-icon v-bind="props">mdi-dots-horizontal</v-icon>
68
+ </template>
69
+ <v-list>
70
+ <v-list-item @click="openDeleteDialog(item._id)">
71
+ Delete Role
72
+ </v-list-item>
73
+ </v-list>
74
+ </v-menu>
75
+ </template>
76
+ </v-data-table>
77
+ </v-card>
78
+ </v-col>
79
+
80
+ <!-- dialogs -->
81
+ <v-dialog v-model="createDialog" width="500" persistent>
82
+ <RolePermissionFormCreate
83
+ @cancel="createDialog = false"
84
+ :permissions="props.permissions"
85
+ :org="props.orgId"
86
+ @success="success()"
87
+ :type="props.type"
88
+ @success:create-more="getRoles()"
89
+ />
90
+ </v-dialog>
91
+
92
+ <v-dialog v-model="previewDialog" width="500" persistent>
93
+ <RolePermissionFormPreviewUpdate
94
+ @cancel="previewDialog = false"
95
+ @success="successfulUpdate()"
96
+ :permissions="Permissions"
97
+ :original-permissions="originalPermissions"
98
+ v-model="selectedPermissions"
99
+ v-model:edit="edit"
100
+ :name="name"
101
+ :id="roleId"
102
+ />
103
+ </v-dialog>
104
+
105
+ <ConfirmDialog
106
+ v-model="confirmDialog"
107
+ :loading="deleteLoading"
108
+ @submit="handleDeleteRole"
109
+ >
110
+ <template #title>
111
+ <span class="font-weight-medium text-h5">Delete Role</span>
112
+ </template>
113
+
114
+ <template #description>
115
+ <p class="text-subtitle-2">
116
+ Are you sure you want to delete this role? This action cannot be
117
+ undone.
118
+ </p>
119
+ </template>
120
+
121
+ <template #footer>
122
+ <v-btn
123
+ variant="text"
124
+ @click="confirmDialog = false"
125
+ :disabled="deleteLoading"
126
+ >
127
+ Close
128
+ </v-btn>
129
+ <v-btn
130
+ color="primary"
131
+ variant="flat"
132
+ @click="handleDeleteRole"
133
+ :loading="deleteLoading"
134
+ >
135
+ Delete Role
136
+ </v-btn>
137
+ </template>
138
+ </ConfirmDialog>
139
+
140
+ <Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />
141
+ </v-row>
142
+ </template>
143
+
144
+ <script setup lang="ts">
145
+ const props = defineProps({
146
+ orgId: {
147
+ type: String,
148
+ default: "",
149
+ },
150
+ customerId: {
151
+ type: String,
152
+ default: "",
153
+ },
154
+ siteId: {
155
+ type: String,
156
+ default: "",
157
+ },
158
+ type: {
159
+ type: String,
160
+ required: true,
161
+ default: "app",
162
+ },
163
+ permissions: {
164
+ type: Object,
165
+ required: true,
166
+ default: () => ({}),
167
+ },
168
+ headers: {
169
+ type: Array as PropType<Array<Record<string, any>>>,
170
+ default: () => [
171
+ {
172
+ title: "name",
173
+ value: "name",
174
+ },
175
+ {
176
+ title: "permissions",
177
+ value: "permissions",
178
+ },
179
+ { title: "Action", value: "action-table" },
180
+ ],
181
+ },
182
+ canCreateRole: {
183
+ type: Boolean,
184
+ default: false,
185
+ },
186
+ canViewRole: {
187
+ type: Boolean,
188
+ default: false,
189
+ },
190
+ canViewByRole: {
191
+ type: Boolean,
192
+ default: false,
193
+ },
194
+ canDeleteRole: {
195
+ type: Boolean,
196
+ default: false,
197
+ },
198
+ canUpdateRole: {
199
+ type: Boolean,
200
+ default: false,
201
+ },
202
+ });
203
+
204
+ const { headerSearch } = useLocal();
205
+
206
+ const { getRoles: _getRoles } = useRole();
207
+
208
+ const page = ref(1);
209
+ const pages = ref(0);
210
+ const pageRange = ref("-- - -- of --");
211
+
212
+ const message = ref("");
213
+ const messageSnackbar = ref(false);
214
+ const messageColor = ref("");
215
+
216
+ const items = ref<Array<Record<string, any>>>([]);
217
+
218
+ const {
219
+ data: getRoleReq,
220
+ refresh: getRoles,
221
+ status: getRoleReqStatus,
222
+ } = useLazyAsyncData(
223
+ "roles-permissions-get-all",
224
+ () =>
225
+ _getRoles({
226
+ page: page.value,
227
+ search: headerSearch.value,
228
+ type: props.type,
229
+ org: props.orgId,
230
+ }),
231
+ {
232
+ watch: [page, headerSearch],
233
+ }
234
+ );
235
+
236
+ const loading = computed(() => getRoleReqStatus.value === "pending");
237
+
238
+ watchEffect(() => {
239
+ if (getRoleReq.value) {
240
+ items.value = getRoleReq.value.items;
241
+ pages.value = getRoleReq.value.pages;
242
+ pageRange.value = getRoleReq.value.pageRange;
243
+ }
244
+ });
245
+
246
+ function tableRowClickHandler(_: any, data: any) {
247
+ previewDialog.value = true;
248
+ roleId.value = data.item._id;
249
+ }
250
+
251
+ const createDialog = ref(false);
252
+
253
+ function success() {
254
+ createDialog.value = false;
255
+ getRoles();
256
+ }
257
+
258
+ const previewDialog = ref(false);
259
+
260
+ const name = ref("");
261
+ const selectedPermissions = ref<Array<string>>([]);
262
+ const originalPermissions = ref<Array<string>>([]);
263
+ const edit = ref(false);
264
+
265
+ const { convertPermissionsToArray } = useUtils();
266
+
267
+ const roleId = ref("");
268
+
269
+ const { getRoleById: _getRoleById, deleteRole } = useRole();
270
+
271
+ const { data: role, refresh: getRoleById } = useLazyAsyncData(
272
+ "role-permissions-get-by-id",
273
+ () => _getRoleById(roleId.value)
274
+ );
275
+
276
+ watchEffect(() => {
277
+ if (roleId.value) {
278
+ getRoleById();
279
+ }
280
+ });
281
+
282
+ watchEffect(() => {
283
+ if (role.value) {
284
+ name.value = role.value.name;
285
+
286
+ selectedPermissions.value = role.value.permissions;
287
+ originalPermissions.value = role.value.permissions;
288
+ }
289
+ });
290
+
291
+ function filterPermissions(
292
+ allPermissions: TPermissions,
293
+ storedPermissions: string[]
294
+ ) {
295
+ const filteredPermissions: TPermissions = {};
296
+
297
+ if (!allPermissions || typeof allPermissions !== "object")
298
+ return filteredPermissions;
299
+
300
+ Object.entries(allPermissions).forEach(([resource, actions]) => {
301
+ if (!actions || typeof actions !== "object") return;
302
+ const filteredActions = Object.entries(actions)
303
+ .filter(([action]) => storedPermissions.includes(`${resource}:${action}`))
304
+ .reduce((acc: Record<string, any>, [action, data]) => {
305
+ acc[action] = data;
306
+ return acc;
307
+ }, {});
308
+
309
+ if (Object.keys(filteredActions).length > 0) {
310
+ filteredPermissions[resource] = filteredActions;
311
+ }
312
+ });
313
+
314
+ return filteredPermissions;
315
+ }
316
+
317
+ const Permissions = computed(() => {
318
+ return edit.value
319
+ ? props.permissions
320
+ : filterPermissions(props.permissions, originalPermissions.value);
321
+ });
322
+
323
+ function successfulUpdate() {
324
+ previewDialog.value = false;
325
+ getRoles();
326
+ useLocalSetup(props.type);
327
+ }
328
+
329
+ const confirmDialog = ref(false);
330
+ const selectedRoleId = ref<string | null>(null);
331
+ const deleteLoading = ref(false);
332
+
333
+ function openDeleteDialog(id: string) {
334
+ selectedRoleId.value = id;
335
+ confirmDialog.value = true;
336
+ }
337
+
338
+ function showMessage(msg: string, color: string) {
339
+ message.value = msg;
340
+ messageColor.value = color;
341
+ messageSnackbar.value = true;
342
+ }
343
+
344
+ async function handleDeleteRole() {
345
+ if (!selectedRoleId.value) return;
346
+ deleteLoading.value = true;
347
+ try {
348
+ const res = await deleteRole(selectedRoleId.value);
349
+
350
+ confirmDialog.value = false;
351
+ showMessage(res.message, "success");
352
+ getRoles();
353
+ } catch (error: any) {
354
+ const errorMessage = error?.response?._data?.message;
355
+ showMessage(errorMessage, "error");
356
+ } finally {
357
+ deleteLoading.value = false;
358
+ selectedRoleId.value = null;
359
+ }
360
+ }
361
+ </script>
@@ -0,0 +1,154 @@
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">
6
+ {{ props.title }}
7
+ </span>
8
+ </v-row>
9
+ </v-toolbar>
10
+ <v-card-text style="max-height: 100vh; overflow-y: auto">
11
+ <v-form v-model="validForm" :disabled="disable">
12
+ <v-row no-gutters>
13
+ <v-col cols="12" class="mt-2">
14
+ <v-row no-gutters>
15
+ <InputLabel class="text-capitalize" title="Email" required />
16
+ <v-col cols="12">
17
+ <v-text-field
18
+ v-model="email"
19
+ density="comfortable"
20
+ :rules="[requiredRule, emailRule]"
21
+ ></v-text-field>
22
+ </v-col>
23
+ </v-row>
24
+ </v-col>
25
+
26
+ <v-col cols="12" class="my-2">
27
+ <v-row no-gutters>
28
+ <v-col cols="12" class="text-center">
29
+ <span
30
+ class="text-none text-subtitle-2 font-weight-medium text-error"
31
+ >
32
+ {{ message }}
33
+ </span>
34
+ </v-col>
35
+ </v-row>
36
+ </v-col>
37
+ </v-row>
38
+ </v-form>
39
+ </v-card-text>
40
+
41
+ <v-toolbar>
42
+ <v-row class="px-6">
43
+ <v-col cols="6">
44
+ <v-btn
45
+ block
46
+ variant="text"
47
+ class="text-none"
48
+ size="large"
49
+ @click="cancel"
50
+ >
51
+ Cancel
52
+ </v-btn>
53
+ </v-col>
54
+
55
+ <v-col cols="6">
56
+ <v-btn
57
+ block
58
+ variant="flat"
59
+ color="black"
60
+ class="text-none"
61
+ size="large"
62
+ :disabled="!validForm"
63
+ @click="submit"
64
+ >
65
+ Submit
66
+ </v-btn>
67
+ </v-col>
68
+ </v-row>
69
+ </v-toolbar>
70
+ </v-card>
71
+ </template>
72
+
73
+ <script setup lang="ts">
74
+ const props = defineProps({
75
+ title: {
76
+ type: String,
77
+ default: "Service Provider Form",
78
+ },
79
+ org: {
80
+ type: String,
81
+ default: "",
82
+ },
83
+ siteId: {
84
+ type: String,
85
+ default: "",
86
+ },
87
+ siteName: {
88
+ type: String,
89
+ default: "",
90
+ },
91
+ type: {
92
+ type: String,
93
+ default: "app",
94
+ },
95
+ });
96
+
97
+ const emit = defineEmits<{
98
+ (e: "cancel"): void;
99
+ (e: "success"): void;
100
+ (e: "success:create-more"): void;
101
+ (e: "notify", payload: { message: string; color: string }): void;
102
+ }>();
103
+
104
+ const validForm = ref(false);
105
+
106
+ const email = ref("");
107
+ const selectedPermissions = ref([]);
108
+ const createMore = ref(false);
109
+ const disable = ref(false);
110
+
111
+ const { requiredRule, emailRule } = useUtils();
112
+
113
+ const message = ref("");
114
+
115
+ const { createServiceProviderInvite } = useServiceProvider();
116
+
117
+ async function submit() {
118
+ disable.value = true;
119
+
120
+ try {
121
+ await createServiceProviderInvite({
122
+ email: email.value,
123
+ siteId: props.siteId,
124
+ serviceProviderOrgId: props.org,
125
+ });
126
+
127
+ emit("success");
128
+ emit("success:create-more");
129
+ emit("notify", {
130
+ message: "Service provider created successfully",
131
+ color: "success",
132
+ });
133
+ } catch (error: any) {
134
+ const msg =
135
+ error?.response?._data?.message || "Failed to create service provider";
136
+ message.value = msg;
137
+
138
+ emit("notify", {
139
+ message: msg,
140
+ color: "error",
141
+ });
142
+ } finally {
143
+ disable.value = false;
144
+ }
145
+ }
146
+
147
+ function cancel() {
148
+ email.value = "";
149
+ selectedPermissions.value = [];
150
+ createMore.value = false;
151
+ message.value = "";
152
+ emit("cancel");
153
+ }
154
+ </script>