@7365admin1/layer-common 1.8.0

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 (198) hide show
  1. package/.changeset/README.md +8 -0
  2. package/.changeset/config.json +11 -0
  3. package/.editorconfig +12 -0
  4. package/.github/workflows/main.yml +17 -0
  5. package/.github/workflows/publish.yml +39 -0
  6. package/.nuxtrc +1 -0
  7. package/.playground/app.vue +41 -0
  8. package/.playground/eslint.config.mjs +6 -0
  9. package/.playground/nuxt.config.ts +22 -0
  10. package/.playground/pages/feedback.vue +30 -0
  11. package/CHANGELOG.md +263 -0
  12. package/README.md +73 -0
  13. package/app.vue +3 -0
  14. package/components/AccessCardAddForm.vue +363 -0
  15. package/components/AccessManagement.vue +420 -0
  16. package/components/Avatar/Main.vue +68 -0
  17. package/components/BillingMain.vue +66 -0
  18. package/components/BtnUploadFile.vue +139 -0
  19. package/components/BuildingForm.vue +303 -0
  20. package/components/BuildingManagement/buildings.vue +335 -0
  21. package/components/BuildingManagement/units.vue +350 -0
  22. package/components/BuildingUnitFormAdd.vue +441 -0
  23. package/components/BuildingUnitFormEdit.vue +429 -0
  24. package/components/CameraForm.vue +264 -0
  25. package/components/CameraMain.vue +352 -0
  26. package/components/Card/DeleteConfirmation.vue +51 -0
  27. package/components/Card/MemberInfoSummary.vue +44 -0
  28. package/components/Card/Toggle.vue +25 -0
  29. package/components/Chat/Bubbles.vue +53 -0
  30. package/components/Chat/Information.vue +416 -0
  31. package/components/Chat/ListCard.vue +62 -0
  32. package/components/Chat/Message.vue +158 -0
  33. package/components/Chat/Navigation.vue +150 -0
  34. package/components/ConfirmDialog.vue +66 -0
  35. package/components/Container/Standard.vue +33 -0
  36. package/components/DashboardPlaceholder.vue +1524 -0
  37. package/components/Dialog/DeleteConfirmation.vue +51 -0
  38. package/components/Dialog/ReplaceAutofillPrompt.vue +49 -0
  39. package/components/Dialog/UpdateMoreAction.vue +103 -0
  40. package/components/DocumentForm.vue +187 -0
  41. package/components/DocumentManagement.vue +376 -0
  42. package/components/Editor.vue +95 -0
  43. package/components/EntryPassMain.vue +518 -0
  44. package/components/Feedback/Form.vue +173 -0
  45. package/components/FeedbackDetail.vue +599 -0
  46. package/components/FeedbackMain.vue +588 -0
  47. package/components/FormDialog.vue +65 -0
  48. package/components/ImageCarousel.vue +138 -0
  49. package/components/Input/Date.vue +177 -0
  50. package/components/Input/DateTimePicker.vue +131 -0
  51. package/components/Input/File.vue +236 -0
  52. package/components/Input/FileV2.vue +234 -0
  53. package/components/Input/InputPhoneNumberV2.vue +164 -0
  54. package/components/Input/ListGroupSelection.vue +96 -0
  55. package/components/Input/NRICNumber.vue +53 -0
  56. package/components/Input/NewDate.vue +123 -0
  57. package/components/Input/Number.vue +124 -0
  58. package/components/Input/Password.vue +22 -0
  59. package/components/Input/PhoneNumber.vue +188 -0
  60. package/components/Input/VehicleNumber.vue +49 -0
  61. package/components/InputLabel.vue +22 -0
  62. package/components/InvitationForm.vue +359 -0
  63. package/components/InvitationMain.vue +310 -0
  64. package/components/Layout/Header.vue +129 -0
  65. package/components/Layout/NavigationDrawer.vue +44 -0
  66. package/components/ListItem.vue +35 -0
  67. package/components/ListView.vue +87 -0
  68. package/components/LocalPagination.vue +31 -0
  69. package/components/MemberMain.vue +459 -0
  70. package/components/NFC/NFCPatrolReportMain.vue +591 -0
  71. package/components/NFC/NFCPatrolRouteForm.vue +596 -0
  72. package/components/NFC/NFCPatrolRouteMain.vue +539 -0
  73. package/components/NFC/NFCTagForm.vue +236 -0
  74. package/components/NFC/NFCTagMain.vue +337 -0
  75. package/components/NFC/PatrolSettings.vue +130 -0
  76. package/components/NavigationItem.vue +83 -0
  77. package/components/NumberSettingField.vue +107 -0
  78. package/components/OnlineFormConfigurationForm.vue +290 -0
  79. package/components/OnlineFormsConfiguration.vue +429 -0
  80. package/components/PeopleForm.vue +452 -0
  81. package/components/PlaceholderComponent.vue +34 -0
  82. package/components/RolePermissionFormCreate.vue +161 -0
  83. package/components/RolePermissionFormPreviewUpdate.vue +183 -0
  84. package/components/RolePermissionMain.vue +361 -0
  85. package/components/SearchVehicleNumberUser.vue +91 -0
  86. package/components/ServiceProviderFormCreate.vue +154 -0
  87. package/components/ServiceProviderMain.vue +547 -0
  88. package/components/SignaturePad.vue +73 -0
  89. package/components/Snackbar.vue +23 -0
  90. package/components/SpecificAttr.vue +53 -0
  91. package/components/SupplyManagement.vue +292 -0
  92. package/components/SwitchContext.vue +108 -0
  93. package/components/TableList.vue +150 -0
  94. package/components/TableListSecondary.vue +164 -0
  95. package/components/TableMain.vue +142 -0
  96. package/components/TableWithButton.vue +94 -0
  97. package/components/VehicleUpdateMoreAction.vue +84 -0
  98. package/components/VideoPlayer.vue +125 -0
  99. package/components/VisitorForm.vue +659 -0
  100. package/components/VisitorFormSelection.vue +53 -0
  101. package/components/VisitorManagement.vue +490 -0
  102. package/components/WorkOrder/Create.vue +284 -0
  103. package/components/WorkOrder/Detail.vue +71 -0
  104. package/components/WorkOrder/ListView.vue +96 -0
  105. package/components/WorkOrder/Main.vue +489 -0
  106. package/components/Workorder.vue +1 -0
  107. package/composables/useAddress.ts +107 -0
  108. package/composables/useBuilding.ts +250 -0
  109. package/composables/useBuildingUnit.ts +116 -0
  110. package/composables/useCard.ts +46 -0
  111. package/composables/useCommonPermission.ts +207 -0
  112. package/composables/useCustomer.ts +113 -0
  113. package/composables/useCustomerSite.ts +56 -0
  114. package/composables/useDashboard.ts +31 -0
  115. package/composables/useDashboardData.ts +425 -0
  116. package/composables/useDocument.ts +57 -0
  117. package/composables/useFacility.ts +246 -0
  118. package/composables/useFeedback.ts +119 -0
  119. package/composables/useFile.ts +55 -0
  120. package/composables/useInvoice.ts +18 -0
  121. package/composables/useLocal.ts +131 -0
  122. package/composables/useLocalAuth.ts +137 -0
  123. package/composables/useLocalSetup.ts +13 -0
  124. package/composables/useMember.ts +111 -0
  125. package/composables/useNFCPatrolRoute.ts +77 -0
  126. package/composables/useNFCPatrolSettings.ts +19 -0
  127. package/composables/useNFCPatrolTag.ts +53 -0
  128. package/composables/useOnlineForm.ts +67 -0
  129. package/composables/useOrg.ts +129 -0
  130. package/composables/usePDFDownload.ts +25 -0
  131. package/composables/usePaymentMethod.ts +101 -0
  132. package/composables/usePeople.ts +81 -0
  133. package/composables/usePermission.ts +54 -0
  134. package/composables/usePhoneCountries.ts +561 -0
  135. package/composables/usePrice.ts +15 -0
  136. package/composables/usePromoCode.ts +36 -0
  137. package/composables/useRecapPermission.ts +26 -0
  138. package/composables/useRole.ts +104 -0
  139. package/composables/useSecurityUtils.ts +18 -0
  140. package/composables/useServiceProvider.ts +224 -0
  141. package/composables/useSite.ts +109 -0
  142. package/composables/useSiteEntryPassSettings.ts +46 -0
  143. package/composables/useSiteSettings.ts +123 -0
  144. package/composables/useSubscription.ts +150 -0
  145. package/composables/useUser.ts +132 -0
  146. package/composables/useUtils.ts +445 -0
  147. package/composables/useVerification.ts +34 -0
  148. package/composables/useVisitor.ts +120 -0
  149. package/composables/useWorkOrder.ts +85 -0
  150. package/error.vue +41 -0
  151. package/layouts/plain.vue +7 -0
  152. package/middleware/01.auth.ts +20 -0
  153. package/middleware/02.org.ts +21 -0
  154. package/middleware/03.customer.ts +13 -0
  155. package/middleware/member.ts +4 -0
  156. package/nuxt.config.ts +54 -0
  157. package/package.json +39 -0
  158. package/pages/index.vue +3 -0
  159. package/pages/payment-method-linked.vue +31 -0
  160. package/pages/require-customer.vue +56 -0
  161. package/pages/require-organization-membership.vue +47 -0
  162. package/pages/unauthorized.vue +29 -0
  163. package/plugins/API.ts +21 -0
  164. package/plugins/iconify.client.ts +5 -0
  165. package/plugins/secure-member.client.ts +86 -0
  166. package/plugins/vuetify.ts +62 -0
  167. package/public/bg-camera.jpg +0 -0
  168. package/public/bg-city.jpg +0 -0
  169. package/public/bg-condo.jpg +0 -0
  170. package/public/images/icons/delete-icon.png +0 -0
  171. package/public/sprite.svg +1 -0
  172. package/tsconfig.json +3 -0
  173. package/types/address.d.ts +13 -0
  174. package/types/building.d.ts +27 -0
  175. package/types/camera.d.ts +31 -0
  176. package/types/card.d.ts +22 -0
  177. package/types/customer.d.ts +27 -0
  178. package/types/document.d.ts +6 -0
  179. package/types/feedback.d.ts +68 -0
  180. package/types/local.d.ts +74 -0
  181. package/types/member.d.ts +21 -0
  182. package/types/online-form.d.ts +15 -0
  183. package/types/org.d.ts +13 -0
  184. package/types/people.d.ts +24 -0
  185. package/types/permission.d.ts +25 -0
  186. package/types/phone-number.d.ts +10 -0
  187. package/types/price.d.ts +17 -0
  188. package/types/promo-code.d.ts +19 -0
  189. package/types/role.d.ts +11 -0
  190. package/types/select.d.ts +4 -0
  191. package/types/service-provider.d.ts +15 -0
  192. package/types/site.d.ts +20 -0
  193. package/types/subscription.d.ts +23 -0
  194. package/types/user.d.ts +19 -0
  195. package/types/verification.d.ts +20 -0
  196. package/types/visitor.d.ts +42 -0
  197. package/types/work-order.d.ts +42 -0
  198. package/utils/phoneMasks.ts +1703 -0
@@ -0,0 +1,459 @@
1
+ <template>
2
+ <v-row no-gutters>
3
+ <v-col cols="12" class="mb-2">
4
+ <v-row no-gutters>
5
+ <v-btn
6
+ v-if="props.seatManagement !== 'index'"
7
+ class="text-none"
8
+ rounded="pill"
9
+ variant="tonal"
10
+ :to="{
11
+ name: props.seatManagement,
12
+ params: { organization: props.orgId },
13
+ }"
14
+ size="large"
15
+ >
16
+ Manage seats
17
+ </v-btn>
18
+ </v-row>
19
+ </v-col>
20
+
21
+ <v-col cols="12">
22
+ <v-card width="100%" variant="outlined" border="thin" rounded="lg">
23
+ <v-toolbar density="compact" color="grey-lighten-4">
24
+ <template #prepend>
25
+ <v-btn fab icon density="comfortable" @click="getAll()">
26
+ <v-icon>mdi-refresh</v-icon>
27
+ </v-btn>
28
+ </template>
29
+
30
+ <template #append>
31
+ <v-row no-gutters justify="end" align="center">
32
+ <span class="mr-2 text-caption text-font gray">
33
+ {{ pageRange }}
34
+ </span>
35
+ <local-pagination
36
+ v-model="page"
37
+ :length="pages"
38
+ @update:value="getAll()"
39
+ />
40
+ </v-row>
41
+ </template>
42
+
43
+ <template #extension>
44
+ <v-tabs>
45
+ <v-tab
46
+ v-for="tab in [
47
+ { name: 'Active', status: 'active' },
48
+ { name: 'Suspended', status: 'suspended' },
49
+ ]"
50
+ :key="tab.status"
51
+ :to="{
52
+ name: props.route,
53
+ params: setRouteParams({
54
+ status: tab.status,
55
+ orgId: props.orgId,
56
+ }),
57
+ }"
58
+ >
59
+ {{ tab.name }}
60
+ </v-tab>
61
+ </v-tabs>
62
+ </template>
63
+ </v-toolbar>
64
+
65
+ <v-data-table
66
+ :headers="props.headers"
67
+ :items="items"
68
+ item-value="_id"
69
+ items-per-page="20"
70
+ fixed-header
71
+ hide-default-footer
72
+ style="max-height: calc(100vh - (126px))"
73
+ :loading="loading"
74
+ >
75
+ <template #item.nature="{ item }">
76
+ {{ replaceMatch(item.nature, "_", " ") }}
77
+ </template>
78
+ <template #item.action-table="{ item }">
79
+ <v-menu
80
+ v-if="
81
+ (status === 'active' &&
82
+ (canSuspendMembers || canDeleteMembers)) ||
83
+ (status === 'suspended' &&
84
+ (canActivateMembers || canDeleteMembers))
85
+ "
86
+ v-model="item.menuOpen"
87
+ :close-on-content-click="false"
88
+ offset-y
89
+ width="150"
90
+ >
91
+ <template v-slot:activator="{ props }">
92
+ <v-icon v-bind="props">mdi-dots-horizontal</v-icon>
93
+ </template>
94
+ <v-list>
95
+ <v-list-item
96
+ v-if="props.assignRole"
97
+ @click="
98
+ setMember({
99
+ dialog: true,
100
+ mode: 'assign-role',
101
+ role: item,
102
+ })
103
+ "
104
+ >
105
+ Assign Role
106
+ </v-list-item>
107
+
108
+ <v-list-item
109
+ v-if="status === 'active' && canSuspendMembers"
110
+ @click="openUpdateDialog(item._id, 'suspended')"
111
+ >
112
+ Suspend
113
+ </v-list-item>
114
+ <v-list-item
115
+ v-if="status === 'suspended' && canActivateMembers"
116
+ @click="openUpdateDialog(item._id, 'active')"
117
+ >
118
+ Activate
119
+ </v-list-item>
120
+ <v-list-item
121
+ v-if="canDeleteMembers"
122
+ @click="openUpdateDialog(item._id, 'deleted')"
123
+ >
124
+ Delete
125
+ </v-list-item>
126
+ </v-list>
127
+ </v-menu>
128
+ </template>
129
+ </v-data-table>
130
+ </v-card>
131
+ </v-col>
132
+ <ConfirmDialog
133
+ v-model="confirmDialog"
134
+ :loading="updateLoading"
135
+ @submit="handleUpdateMemberStatus"
136
+ >
137
+ <template #title>
138
+ <span class="font-weight-medium text-h5">
139
+ {{ updateActionText }} Member</span
140
+ >
141
+ </template>
142
+
143
+ <template #description>
144
+ <p class="text-subtitle-2">
145
+ Are you sure you want to {{ updateActionText }} this Member? This
146
+ action cannot be undone.
147
+ </p>
148
+ </template>
149
+
150
+ <template #footer>
151
+ <v-btn
152
+ variant="text"
153
+ @click="confirmDialog = false"
154
+ :disabled="updateLoading"
155
+ >
156
+ Close
157
+ </v-btn>
158
+ <v-btn
159
+ color="primary"
160
+ variant="flat"
161
+ @click="handleUpdateMemberStatus"
162
+ :loading="updateLoading"
163
+ >
164
+ {{ updateActionText }} Member
165
+ </v-btn>
166
+ </template>
167
+ </ConfirmDialog>
168
+
169
+ <Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />
170
+
171
+ <v-dialog v-model="assignRoleDialog" max-width="400px">
172
+ <v-card>
173
+ <v-card-title class="text-h5">Assign Role</v-card-title>
174
+ <v-card-text>
175
+ <v-form v-model="memberRoleForm" @submit.prevent="updateMemberRole()">
176
+ <v-row no-gutters>
177
+ <v-col cols="12" class="mb-2">
178
+ <v-row no-gutters>
179
+ <InputLabel class="text-capitalize" title="Name" required />
180
+ <v-col cols="12">
181
+ <v-select
182
+ v-model="selectedRole"
183
+ :items="roles"
184
+ item-value="_id"
185
+ item-title="name"
186
+ density="comfortable"
187
+ :rules="[requiredRule]"
188
+ :error-messages="
189
+ selectedRole === selectedMemberRole
190
+ ? 'Role already assigned'
191
+ : ''
192
+ "
193
+ persistent-hint
194
+ ></v-select>
195
+ </v-col>
196
+
197
+ <v-col cols="12" class="text-error text-center">
198
+ {{ message }}
199
+ </v-col>
200
+ </v-row>
201
+ </v-col>
202
+
203
+ <v-col cols="12">
204
+ <v-row>
205
+ <v-col cols="6">
206
+ <v-btn
207
+ block
208
+ variant="text"
209
+ @click="setMember({ mode: 'assign-role' })"
210
+ >
211
+ Cancel
212
+ </v-btn>
213
+ </v-col>
214
+ <v-col cols="6">
215
+ <v-btn
216
+ block
217
+ variant="flat"
218
+ color="black"
219
+ :disabled="!memberRoleForm"
220
+ type="submit"
221
+ >
222
+ Submit
223
+ </v-btn>
224
+ </v-col>
225
+ </v-row>
226
+ </v-col>
227
+ </v-row>
228
+ </v-form>
229
+ </v-card-text>
230
+ </v-card>
231
+ </v-dialog>
232
+ </v-row>
233
+ </template>
234
+
235
+ <script setup lang="ts">
236
+ const props = defineProps({
237
+ orgId: {
238
+ type: String,
239
+ default: "",
240
+ },
241
+ customerId: {
242
+ type: String,
243
+ default: "",
244
+ },
245
+ siteId: {
246
+ type: String,
247
+ default: "",
248
+ },
249
+ status: {
250
+ type: String,
251
+ default: "active",
252
+ },
253
+ type: {
254
+ type: String,
255
+ default: "organization",
256
+ },
257
+ seatManagement: {
258
+ type: String,
259
+ default: "index",
260
+ },
261
+ inviteMember: {
262
+ type: String,
263
+ default: "index",
264
+ },
265
+ route: {
266
+ type: String,
267
+ default: "index",
268
+ },
269
+ canActivateMembers: {
270
+ type: Boolean,
271
+ default: false,
272
+ },
273
+ canSuspendMembers: {
274
+ type: Boolean,
275
+ default: false,
276
+ },
277
+ canDeleteMembers: {
278
+ type: Boolean,
279
+ default: false,
280
+ },
281
+ assignRole: {
282
+ type: Boolean,
283
+ default: false,
284
+ },
285
+ headers: {
286
+ type: Array as PropType<Array<Record<string, string>>>,
287
+ default: () => [
288
+ {
289
+ title: "Name",
290
+
291
+ value: "name",
292
+ },
293
+ {
294
+ title: "Role",
295
+
296
+ value: "roleName",
297
+ },
298
+ {
299
+ title: "Organization",
300
+
301
+ value: "orgName",
302
+ },
303
+ {
304
+ title: "Status",
305
+
306
+ value: "status",
307
+ },
308
+ {
309
+ title: "Action",
310
+ value: "action-table",
311
+ },
312
+ ],
313
+ },
314
+ });
315
+
316
+ const items = ref<Array<Record<string, any>>>([]);
317
+ const page = ref(1);
318
+ const pages = ref(10);
319
+ const pageRange = ref("-- - -- of --");
320
+
321
+ const message = ref("");
322
+ const messageSnackbar = ref(false);
323
+ const messageColor = ref("");
324
+
325
+ const {
326
+ getAll: _getAll,
327
+ updateMemberStatus: _updateMemberStatus,
328
+ updateMemberRole: _updateMemberRole,
329
+ } = useMember();
330
+
331
+ const { headerSearch } = useLocal();
332
+ const { replaceMatch, setRouteParams, requiredRule } = useUtils();
333
+
334
+ const {
335
+ data: getAllReq,
336
+ refresh: getAll,
337
+ status: getAllReqStatus,
338
+ } = useLazyAsyncData("get-all-members", () =>
339
+ _getAll({
340
+ status: props.status,
341
+ org: props.orgId,
342
+ search: headerSearch.value,
343
+ page: page.value,
344
+ type: props.type,
345
+ })
346
+ );
347
+
348
+ const loading = computed(() => getAllReqStatus.value === "pending");
349
+
350
+ watchEffect(() => {
351
+ if (getAllReq.value) {
352
+ items.value = getAllReq.value.items;
353
+ pages.value = getAllReq.value.pages;
354
+ pageRange.value = getAllReq.value.pageRange;
355
+ }
356
+ });
357
+
358
+ watch(headerSearch, () => {
359
+ getAll();
360
+ });
361
+
362
+ const confirmDialog = ref(false);
363
+ const selectedMemberId = ref<string | null>(null);
364
+ const updateLoading = ref(false);
365
+ const updateAction = ref("");
366
+
367
+ const memberRoleForm = ref(false);
368
+ const assignRoleDialog = ref(false);
369
+ const selectedRole = ref<string | null>(null);
370
+ const selectedMemberRole = ref("");
371
+
372
+ function setMember({
373
+ dialog = false,
374
+ mode = "",
375
+ role = {} as Record<string, any>,
376
+ } = {}) {
377
+ if (mode === "assign-role") {
378
+ assignRoleDialog.value = dialog;
379
+ }
380
+
381
+ selectedMemberId.value = role._id;
382
+ selectedRole.value = role.role;
383
+ selectedMemberRole.value = role.role;
384
+ }
385
+
386
+ const roles = ref<Array<Record<string, any>>>([]);
387
+ const { getRoles } = useRole();
388
+ const { data: getAllRoleReq } = useLazyAsyncData("get-roles", () =>
389
+ getRoles({ org: props.orgId, type: props.type, limit: 20 })
390
+ );
391
+
392
+ watchEffect(() => {
393
+ if (getAllRoleReq.value) {
394
+ roles.value = getAllRoleReq.value.items;
395
+ }
396
+ });
397
+
398
+ watchEffect(() => {
399
+ if (selectedRole.value) {
400
+ message.value = "";
401
+ }
402
+ });
403
+
404
+ async function updateMemberRole() {
405
+ try {
406
+ await _updateMemberRole(
407
+ selectedMemberId.value ?? "",
408
+ selectedRole.value ?? "",
409
+ props.type,
410
+ props.orgId
411
+ );
412
+ await setMember({ mode: "assign-role" });
413
+ await getAll();
414
+ } catch (error: any) {
415
+ message.value = error?.response?._data?.message || "Failed to update role";
416
+ }
417
+ }
418
+
419
+ function openUpdateDialog(id: string, action: string) {
420
+ updateAction.value = action;
421
+ selectedMemberId.value = id;
422
+ confirmDialog.value = true;
423
+ }
424
+
425
+ function showMessage(msg: string, color: string) {
426
+ message.value = msg;
427
+ messageColor.value = color;
428
+ messageSnackbar.value = true;
429
+ }
430
+
431
+ async function handleUpdateMemberStatus() {
432
+ if (!selectedMemberId.value) return;
433
+ updateLoading.value = true;
434
+ try {
435
+ const res = await _updateMemberStatus(
436
+ selectedMemberId.value,
437
+ updateAction.value
438
+ );
439
+
440
+ confirmDialog.value = false;
441
+ showMessage(res.message, "success");
442
+ getAll();
443
+ } catch (error: any) {
444
+ const errorMessage = error?.response?._data?.message;
445
+ showMessage(errorMessage, "error");
446
+ } finally {
447
+ updateLoading.value = false;
448
+ selectedMemberId.value = null;
449
+ }
450
+ }
451
+ const updateActionText = computed(() => {
452
+ const map: Record<string, string> = {
453
+ active: "Activate",
454
+ suspended: "Suspend",
455
+ deleted: "Delete",
456
+ };
457
+ return map[updateAction.value] || updateAction.value;
458
+ });
459
+ </script>