@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,518 @@
1
+ <template>
2
+ <v-skeleton-loader
3
+ type="card"
4
+ :width="'100%'"
5
+ :height="'200px'"
6
+ v-if="loading"
7
+ />
8
+ <v-row no-gutters class="" v-if="!loading">
9
+ <v-col cols="12" elevation="3" class="border">
10
+ <v-row no-gutters class="px-6 pt-4">
11
+ <div class="d-flex mt-7 pb-5">
12
+ <p class="mr-6 font-weight-medium flex-grow-1">
13
+ Physical / Key Pass
14
+ <span class="d-block text-caption text-grey-darken-1 mt-1">
15
+ A Physical Pass Card is a tangible identification or access card
16
+ used for entry and verification purposes at a specific site or
17
+ property. Its primary functions include granting authorized
18
+ access, enhancing security, and tracking attendance or movement.
19
+ </span>
20
+ </p>
21
+ <v-switch
22
+ color="success"
23
+ hide-details
24
+ v-model="currentEntryPassSettings.physicalPass"
25
+ @update:modelValue="updateEntryPassSettingsPhysicalPass()"
26
+ ></v-switch>
27
+ </div>
28
+ <v-divider thickness="1"></v-divider>
29
+ <div class="d-flex mt-7 pb-5">
30
+ <p class="mr-6 font-weight-medium flex-grow-1">
31
+ NFC / QR Code Pass
32
+ <span class="d-block text-caption text-grey-darken-1 mt-1">
33
+ NFC Card Pass is a type of access card that uses Near Field
34
+ Communication (NFC) technology to enable secure and convenient
35
+ entry to a site or property. This technology facilitates wireless
36
+ communication between the card and an NFC reader when they are
37
+ placed in close proximity (typically within 4 cm).
38
+ </span>
39
+ </p>
40
+ <v-switch
41
+ color="success"
42
+ hide-details
43
+ v-model="currentEntryPassSettings.nfcPass"
44
+ @update:modelValue="updateEntryPassSettingsNfcPass()"
45
+ ></v-switch>
46
+ </div>
47
+ <v-divider thickness="1"></v-divider>
48
+ <div class="d-flex w-100 mt-7 pb-10">
49
+ <p class="mr-6 font-weight-medium flex-grow-1">
50
+ Upload Access Cards Template
51
+ <span class="d-block text-caption text-grey-darken-1 mt-1">
52
+ <a
53
+ target="_blank"
54
+ class="text-truncate d-flex items-center text-decoration-none"
55
+ href=""
56
+ >
57
+ <v-icon class="mr-2" size="24px"> mdi-paperclip </v-icon>
58
+ template
59
+ </a>
60
+ </span>
61
+ </p>
62
+ <v-btn
63
+ variant="flat"
64
+ color="error"
65
+ size="small"
66
+ style="height: 40px; margin-left: auto"
67
+ prepend-icon="mdi-file-document-remove-outline"
68
+ >
69
+ Remove
70
+ </v-btn>
71
+ </div>
72
+ <v-divider thickness="1"></v-divider>
73
+ <div class="d-flex w-100 mt-7 pb-10">
74
+ <p class="mr-6 font-weight-medium flex-grow-1">
75
+ Printer Setup
76
+ <v-col cols="12">
77
+ <v-row>
78
+ <v-col cols="3">
79
+ <v-text-field
80
+ label="Vendor ID"
81
+ hide-details
82
+ clearable
83
+ v-model="currentEntryPassSettings.printerVendorId"
84
+ ></v-text-field>
85
+ </v-col>
86
+ <v-col cols="3">
87
+ <v-text-field
88
+ label="Product ID"
89
+ hide-details
90
+ clearable
91
+ v-model="currentEntryPassSettings.printerProductId"
92
+ ></v-text-field>
93
+ </v-col>
94
+ <v-col cols="3">
95
+ <v-btn
96
+ color="primary"
97
+ variant="outlined"
98
+ prepend-icon="mdi-magnify"
99
+ block
100
+ >
101
+ Scan Printer
102
+ </v-btn>
103
+ </v-col>
104
+ <v-col cols="3">
105
+ <v-btn
106
+ color="success"
107
+ variant="outlined"
108
+ prepend-icon="mdi-printer-check"
109
+ block
110
+ >
111
+ Test & Print
112
+ </v-btn>
113
+ </v-col>
114
+ </v-row>
115
+ <v-row class="mt-4">
116
+ <v-col cols="12" sm="6" md="4">
117
+ <v-btn
118
+ color="primary"
119
+ variant="flat"
120
+ prepend-icon="mdi-content-save"
121
+ block
122
+ @click="savePrinterSettings()"
123
+ >
124
+ Save Settings
125
+ </v-btn>
126
+ </v-col>
127
+ </v-row>
128
+ </v-col>
129
+ </p>
130
+ </div>
131
+
132
+ <v-divider thickness="1"></v-divider>
133
+
134
+ <div class="d-flex w-100 mt-7 pb-10">
135
+ <p class="mr-6 font-weight-medium flex-grow-1">
136
+ QR Code Template
137
+ <span class="d-block text-caption text-grey-darken-1 mt-1">
138
+ <v-col cols="12">
139
+ <v-row>
140
+ <v-col cols="12">
141
+ <v-text-field
142
+ label="Header"
143
+ placeholder="Enter qr code header eg. Welcome to Company Name"
144
+ hide-details
145
+ density="comfortable"
146
+ clearable
147
+ v-model="currentEntryPassSettings.qrCodeTemplateHeader"
148
+ ></v-text-field>
149
+ </v-col>
150
+ <v-col cols="12">
151
+ <v-text-field
152
+ label="Subtext"
153
+ placeholder="Enter qr code sub header"
154
+ hide-details
155
+ density="comfortable"
156
+ clearable
157
+ class="mb-2"
158
+ v-model="
159
+ currentEntryPassSettings.qrCodeTemplateHeaderSubText
160
+ "
161
+ ></v-text-field>
162
+ </v-col>
163
+ <v-row class="mt-3">
164
+ <v-col cols="12" md="2">
165
+ <v-btn color="primary" variant="flat" block>
166
+ Preview
167
+ </v-btn>
168
+ </v-col>
169
+ <v-col cols="12" md="2">
170
+ <v-btn
171
+ color="primary"
172
+ variant="flat"
173
+ block
174
+ @click="saveQrCodeTemplate()"
175
+ >
176
+ Save
177
+ </v-btn>
178
+ </v-col>
179
+ </v-row>
180
+ </v-row>
181
+ </v-col>
182
+ </span>
183
+ </p>
184
+ </div>
185
+
186
+ <v-divider thickness="1"></v-divider>
187
+
188
+ <div class="d-flex w-100 mt-7 pb-10">
189
+ <p class="mr-6 font-weight-medium flex-grow-1">
190
+ Resident-app Disclaimer Message
191
+ <span class="d-block text-caption text-grey-darken-1 mt-1">
192
+ <v-col cols="12">
193
+ <v-row no-gutters>
194
+ <v-col cols="12" class="mb-5">
195
+ <v-textarea
196
+ label="Disclaimer Message"
197
+ placeholder="Enter disclaimer message for resident app"
198
+ hide-details
199
+ density="comfortable"
200
+ clearable
201
+ rows="5"
202
+ auto-grow
203
+ v-model="currentEntryPassSettings.disclaimerMessage"
204
+ ></v-textarea>
205
+ </v-col>
206
+ <v-row class="mt-3">
207
+ <v-col cols="12" md="2">
208
+ <v-btn
209
+ color="primary"
210
+ variant="flat"
211
+ block
212
+ @click="saveResidentAppDisclaimerMsg()"
213
+ >
214
+ Save
215
+ </v-btn>
216
+ </v-col>
217
+ </v-row>
218
+ </v-row>
219
+ </v-col>
220
+ </span>
221
+ </p>
222
+ </div>
223
+
224
+ <v-divider thickness="1"></v-divider>
225
+
226
+ <div class="d-flex w-100 mt-7 pb-10">
227
+ <p class="mr-6 font-weight-medium flex-grow-1">
228
+ Entrypass URL
229
+ <span class="d-block text-caption text-grey-darken-1 mt-1">
230
+ <v-col>
231
+ <v-text-field
232
+ label="Enter entrypass URL"
233
+ placeholder="https://example.com"
234
+ outlined
235
+ clearable
236
+ hide-details
237
+ v-model="currentEntryPassSettings.url"
238
+ />
239
+ </v-col>
240
+ <v-col>
241
+ <v-btn color="primary" @click="saveEntryPassUrl()">Save</v-btn>
242
+ </v-col>
243
+ </span>
244
+ </p>
245
+ </div>
246
+ </v-row>
247
+ </v-col>
248
+
249
+ <Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />
250
+ </v-row>
251
+ </template>
252
+ <script lang="ts" setup>
253
+ definePageMeta({
254
+ middleware: ["01-auth", "02-org"],
255
+ memberOnly: true,
256
+ });
257
+ const prop = defineProps({
258
+ site: {
259
+ type: String,
260
+ required: true,
261
+ },
262
+ siteName: {
263
+ type: String,
264
+ required: true,
265
+ },
266
+
267
+ orgId: {
268
+ type: String,
269
+ required: true,
270
+ },
271
+ });
272
+
273
+ const currentEntryPassSettings = ref<Record<string, any>>({
274
+ _id: "",
275
+ site: "",
276
+ org: "",
277
+ isEnabled: true,
278
+ physicalPass: false,
279
+ nfcPass: false,
280
+ printerVendorId: "",
281
+ printerProductId: "",
282
+ qrCodeTemplateHeader: "",
283
+ qrCodeTemplateHeaderSubText: "",
284
+ qrCodeTemplateDate: "",
285
+ disclaimerMessage: "",
286
+ url: "",
287
+ status: "",
288
+ createdBy: "",
289
+ updatedBy: "",
290
+ createdAt: "",
291
+ updatedAt: "",
292
+ deletedAt: "",
293
+ });
294
+
295
+ const entryPassSettingsPayload = ref<Record<string, any>>({
296
+ site: "",
297
+ org: "",
298
+ isEnabled: true,
299
+ physicalPass: false,
300
+ nfcPass: false,
301
+ printerVendorId: "",
302
+ printerProductId: "",
303
+ qrCodeTemplateHeader: "",
304
+ qrCodeTemplateHeaderSubText: "",
305
+ qrCodeTemplateDate: "",
306
+ disclaimerMessage: "",
307
+ url: "",
308
+ status: "",
309
+ });
310
+
311
+ const {
312
+ getBySiteId: _getSiteEntryPassSettings,
313
+ add: _add,
314
+ updateBySiteId: _updateBySiteId,
315
+ } = useSiteEntryPassSettings();
316
+
317
+ const route = useRoute();
318
+ const siteId = route.params.site as string;
319
+ const orgId = route.params.org as string;
320
+
321
+ const message = ref("");
322
+ const messageSnackbar = ref(false);
323
+ const messageColor = ref("");
324
+
325
+ const {
326
+ data: getSiteEntryPassSettingsReq,
327
+ refresh: getSiteEntryPassSettings,
328
+ status: getSiteEntryPassSettingsReqStatus,
329
+ } = useLazyAsyncData("get-site-entry-pass-settings", () =>
330
+ _getSiteEntryPassSettings(prop.site as string)
331
+ );
332
+
333
+ const loading = computed(
334
+ () => getSiteEntryPassSettingsReqStatus.value === "pending"
335
+ );
336
+
337
+ watchEffect(() => {
338
+ if (getSiteEntryPassSettingsReq.value) {
339
+ currentEntryPassSettings.value = getSiteEntryPassSettingsReq.value;
340
+ // console.log("currentEntryPassSettings", currentEntryPassSettings.value);
341
+ // console.log(currentEntryPassSettings.value._id);
342
+ }
343
+ });
344
+
345
+ async function addPayload() {
346
+ const payload = {
347
+ site: siteId,
348
+ org: orgId,
349
+ isEnabled: true,
350
+ physicalPass: currentEntryPassSettings.value.physicalPass,
351
+ nfcPass: currentEntryPassSettings.value.nfcPass,
352
+ printerVendorId: currentEntryPassSettings.value.printerVendorId,
353
+ printerProductId: currentEntryPassSettings.value.printerProductId,
354
+ qrCodeTemplateHeader: currentEntryPassSettings.value.qrCodeTemplateHeader,
355
+ qrCodeTemplateHeaderSubText:
356
+ currentEntryPassSettings.value.qrCodeTemplateHeaderSubText,
357
+ qrCodeTemplateDate: currentEntryPassSettings.value.qrCodeTemplateDate,
358
+ disclaimerMessage: currentEntryPassSettings.value.disclaimerMessage,
359
+ url: currentEntryPassSettings.value.url,
360
+ status: "Active",
361
+ };
362
+ entryPassSettingsPayload.value = payload;
363
+ }
364
+
365
+ async function updatePayload() {
366
+ const payload = {
367
+ isEnabled: true,
368
+ physicalPass: currentEntryPassSettings.value.physicalPass,
369
+ nfcPass: currentEntryPassSettings.value.nfcPass,
370
+ printerVendorId: currentEntryPassSettings.value.printerVendorId,
371
+ printerProductId: currentEntryPassSettings.value.printerProductId,
372
+ qrCodeTemplateHeader: currentEntryPassSettings.value.qrCodeTemplateHeader,
373
+ qrCodeTemplateHeaderSubText:
374
+ currentEntryPassSettings.value.qrCodeTemplateHeaderSubText,
375
+ qrCodeTemplateDate: currentEntryPassSettings.value.qrCodeTemplateDate,
376
+ disclaimerMessage: currentEntryPassSettings.value.disclaimerMessage,
377
+ url: currentEntryPassSettings.value.url,
378
+ status: "Active",
379
+ };
380
+ entryPassSettingsPayload.value = payload;
381
+ }
382
+
383
+ async function updateEntryPassSettingsPhysicalPass() {
384
+ if (!currentEntryPassSettings.value._id) {
385
+ addPayload();
386
+ entryPassSettingsPayload.value.physicalPass =
387
+ currentEntryPassSettings.value.physicalPass;
388
+ await _add(entryPassSettingsPayload.value);
389
+ showMessage("Entry Pass Settings added successfully!", "success");
390
+ } else {
391
+ updatePayload();
392
+ entryPassSettingsPayload.value.physicalPass =
393
+ currentEntryPassSettings.value.physicalPass;
394
+ await _updateBySiteId(
395
+ entryPassSettingsPayload.value,
396
+ currentEntryPassSettings.value.site
397
+ );
398
+ showMessage("Entry Pass Settings updated successfully!", "success");
399
+ }
400
+ getSiteEntryPassSettings();
401
+ }
402
+
403
+ async function updateEntryPassSettingsNfcPass() {
404
+ if (!currentEntryPassSettings.value._id) {
405
+ addPayload();
406
+ entryPassSettingsPayload.value.nfcPass =
407
+ currentEntryPassSettings.value.nfcPass;
408
+ await _add(entryPassSettingsPayload.value);
409
+ showMessage("Entry Pass Settings added successfully!", "success");
410
+ } else {
411
+ updatePayload();
412
+ entryPassSettingsPayload.value.nfcPass =
413
+ currentEntryPassSettings.value.nfcPass;
414
+ await _updateBySiteId(
415
+ entryPassSettingsPayload.value,
416
+ currentEntryPassSettings.value.site
417
+ );
418
+ showMessage("Entry Pass Settings updated successfully!", "success");
419
+ }
420
+ getSiteEntryPassSettings();
421
+ }
422
+
423
+ async function savePrinterSettings() {
424
+ if (!currentEntryPassSettings.value._id) {
425
+ addPayload();
426
+ entryPassSettingsPayload.value.printerVendorId =
427
+ currentEntryPassSettings.value.printerVendorId;
428
+ entryPassSettingsPayload.value.printerProductId =
429
+ currentEntryPassSettings.value.printerProductId;
430
+ await _add(entryPassSettingsPayload.value);
431
+ showMessage("Entry Pass Settings added successfully!", "success");
432
+ } else {
433
+ updatePayload();
434
+ entryPassSettingsPayload.value.printerVendorId =
435
+ currentEntryPassSettings.value.printerVendorId;
436
+ entryPassSettingsPayload.value.printerProductId =
437
+ currentEntryPassSettings.value.printerProductId;
438
+ console.log(
439
+ "entryPassSettingsPayload.value",
440
+ entryPassSettingsPayload.value
441
+ );
442
+ await _updateBySiteId(
443
+ entryPassSettingsPayload.value,
444
+ currentEntryPassSettings.value.site
445
+ );
446
+ showMessage("Entry Pass Settings updated successfully!", "success");
447
+ }
448
+ getSiteEntryPassSettings();
449
+ }
450
+
451
+ async function saveQrCodeTemplate() {
452
+ if (!currentEntryPassSettings.value._id) {
453
+ addPayload();
454
+ entryPassSettingsPayload.value.qrCodeTemplateHeader =
455
+ currentEntryPassSettings.value.qrCodeTemplateHeader;
456
+ entryPassSettingsPayload.value.qrCodeTemplateHeaderSubText =
457
+ currentEntryPassSettings.value.qrCodeTemplateHeaderSubText;
458
+ await _add(entryPassSettingsPayload.value);
459
+ showMessage("Entry Pass Settings added successfully!", "success");
460
+ } else {
461
+ updatePayload();
462
+ entryPassSettingsPayload.value.qrCodeTemplateHeader =
463
+ currentEntryPassSettings.value.qrCodeTemplateHeader;
464
+ entryPassSettingsPayload.value.qrCodeTemplateHeaderSubText =
465
+ currentEntryPassSettings.value.qrCodeTemplateHeaderSubText;
466
+ await _updateBySiteId(
467
+ entryPassSettingsPayload.value,
468
+ currentEntryPassSettings.value.site
469
+ );
470
+ showMessage("Entry Pass Settings updated successfully!", "success");
471
+ }
472
+ getSiteEntryPassSettings();
473
+ }
474
+
475
+ async function saveResidentAppDisclaimerMsg() {
476
+ if (!currentEntryPassSettings.value._id) {
477
+ addPayload();
478
+ entryPassSettingsPayload.value.disclaimerMessage =
479
+ currentEntryPassSettings.value.disclaimerMessage;
480
+ await _add(entryPassSettingsPayload.value);
481
+ showMessage("Entry Pass Settings added successfully!", "success");
482
+ } else {
483
+ updatePayload();
484
+ entryPassSettingsPayload.value.disclaimerMessage =
485
+ currentEntryPassSettings.value.disclaimerMessage;
486
+ await _updateBySiteId(
487
+ entryPassSettingsPayload.value,
488
+ currentEntryPassSettings.value.site
489
+ );
490
+ showMessage("Entry Pass Settings updated successfully!", "success");
491
+ }
492
+ getSiteEntryPassSettings();
493
+ }
494
+
495
+ async function saveEntryPassUrl() {
496
+ if (!currentEntryPassSettings.value._id) {
497
+ addPayload();
498
+ entryPassSettingsPayload.value.url = currentEntryPassSettings.value.url;
499
+ await _add(entryPassSettingsPayload.value);
500
+ showMessage("Entry Pass Settings added successfully!", "success");
501
+ } else {
502
+ updatePayload();
503
+ entryPassSettingsPayload.value.url = currentEntryPassSettings.value.url;
504
+ await _updateBySiteId(
505
+ entryPassSettingsPayload.value,
506
+ currentEntryPassSettings.value.site
507
+ );
508
+ showMessage("Entry Pass Settings updated successfully!", "success");
509
+ }
510
+ getSiteEntryPassSettings();
511
+ }
512
+
513
+ function showMessage(msg: string, color: string) {
514
+ message.value = msg;
515
+ messageColor.value = color;
516
+ messageSnackbar.value = true;
517
+ }
518
+ </script>
@@ -0,0 +1,173 @@
1
+ <template>
2
+ <FormDialog v-model="dialog" @close="closeDialog">
3
+ <template #title>
4
+ <span class="text-h6 font-weight-medium pt-1 text-capitalize">
5
+ {{ isEditMode ? "Edit Feedback" : "Create Feedback" }}
6
+ </span>
7
+ </template>
8
+
9
+ <InputFile
10
+ :attachments="displayedAttachments"
11
+ :errored-images="localErroredImages"
12
+ :max-files="maxFiles"
13
+ @add="handleFileAdded"
14
+ @delete="deleteFile"
15
+ @errored="onImageError"
16
+ />
17
+
18
+ <v-autocomplete
19
+ v-model="localFeedback.subject"
20
+ :items="subjects"
21
+ item-title="title"
22
+ item-value="value"
23
+ item-props
24
+ variant="outlined"
25
+ density="compact"
26
+ class="mb-2"
27
+ clearable
28
+ :custom-filter="customFilter"
29
+ :rules="[requiredRule]"
30
+ >
31
+ <template #label> Subject <span class="text-red">*</span> </template>
32
+ </v-autocomplete>
33
+
34
+ <v-autocomplete
35
+ v-model="localFeedback.category"
36
+ :items="categories"
37
+ item-title="title"
38
+ item-value="value"
39
+ item-props
40
+ label="Category"
41
+ variant="outlined"
42
+ density="compact"
43
+ class="mb-2"
44
+ clearable
45
+ :rules="[requiredRule]"
46
+ >
47
+ <template #label> Category <span class="text-red">*</span> </template>
48
+ </v-autocomplete>
49
+
50
+ <v-text-field
51
+ label="Location"
52
+ variant="outlined"
53
+ density="compact"
54
+ v-model="localFeedback.location"
55
+ :rules="[requiredRule]"
56
+ >
57
+ <template #label> Location <span class="text-red">*</span> </template>
58
+ </v-text-field>
59
+
60
+ <v-textarea
61
+ label="Description"
62
+ variant="outlined"
63
+ density="compact"
64
+ auto-grow
65
+ rows="4"
66
+ v-model="localFeedback.description"
67
+ :rules="[requiredRule]"
68
+ >
69
+ <template #label> Description <span class="text-red">*</span> </template>
70
+ </v-textarea>
71
+
72
+ <template #footer>
73
+ <v-btn
74
+ color="primary-button"
75
+ class="text-capitalize mb-4"
76
+ block
77
+ height="40"
78
+ :loading="loading"
79
+ :disabled="loading || !isFormValid"
80
+ @click="submitFeedback"
81
+ >
82
+ Submit
83
+ </v-btn>
84
+ </template>
85
+ </FormDialog>
86
+ </template>
87
+
88
+ <script setup lang="ts">
89
+ const props = defineProps<{
90
+ modelValue: boolean;
91
+ feedback: TFeedbackCreate;
92
+ isEditMode: boolean;
93
+ loading: boolean;
94
+ categories: { title: string; value: string }[];
95
+ erroredImages?: string[];
96
+ maxFiles?: number;
97
+ }>();
98
+
99
+ const emit = defineEmits<{
100
+ (e: "update:modelValue", value: boolean): void;
101
+ (e: "update:feedback", value: TFeedbackCreate): void;
102
+ (e: "close"): void;
103
+ (e: "submit", payload: TFeedbackCreate): void;
104
+ (e: "fileAdded", file: File): void;
105
+ (e: "fileDeleted", url: string): void;
106
+ }>();
107
+
108
+ const dialog = computed({
109
+ get: () => props.modelValue,
110
+ set: (val) => emit("update:modelValue", val),
111
+ });
112
+
113
+ const localFeedback = computed({
114
+ get: () => props.feedback,
115
+ set: (val) => emit("update:feedback", val),
116
+ });
117
+
118
+ const localErroredImages = ref<string[]>(props.erroredImages || []);
119
+
120
+ watch(
121
+ () => props.erroredImages,
122
+ (val) => {
123
+ if (val) localErroredImages.value = val;
124
+ }
125
+ );
126
+
127
+ const displayedAttachments = computed(() => {
128
+ return localFeedback.value.attachments || [];
129
+ });
130
+
131
+ const { requiredRule } = useUtils();
132
+
133
+ const isFormValid = computed(() => {
134
+ return (
135
+ localFeedback.value.subject &&
136
+ localFeedback.value.category &&
137
+ localFeedback.value.location &&
138
+ localFeedback.value.description
139
+ );
140
+ });
141
+
142
+ function handleFileAdded(file: File) {
143
+ emit("fileAdded", file);
144
+ }
145
+
146
+ function deleteFile(url: string) {
147
+ emit("fileDeleted", url);
148
+ }
149
+
150
+ function onImageError(file: string) {
151
+ if (!localErroredImages.value.includes(file)) {
152
+ localErroredImages.value.push(file);
153
+ }
154
+ }
155
+
156
+ function closeDialog() {
157
+ dialog.value = false;
158
+ emit("close");
159
+ }
160
+
161
+ function submitFeedback() {
162
+ emit("submit", { ...localFeedback.value });
163
+ }
164
+
165
+ const { subjects } = useLocal();
166
+
167
+ const customFilter = (value: string, query: string, item: any) => {
168
+ const title = item?.raw?.title?.toLowerCase() || "";
169
+ const subtitle = item?.raw?.subtitle?.toLowerCase() || "";
170
+ const search = query.toLowerCase();
171
+ return title.includes(search) || subtitle.includes(search);
172
+ };
173
+ </script>