@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,489 @@
1
+ <template>
2
+ <v-row no-gutters>
3
+ <v-col cols="12" class="mb-2">
4
+ <v-row no-gutters align="center" justify="space-between">
5
+ <v-btn
6
+ class="text-none text-capitalize"
7
+ rounded="pill"
8
+ variant="tonal"
9
+ size="large"
10
+ @click="(showCreateDialog = true), (isEditMode = false)"
11
+ v-if="canCreateWorkOrder"
12
+ >
13
+ Create Work Order
14
+ </v-btn>
15
+
16
+ <v-text-field
17
+ v-model="searchText"
18
+ placeholder="Search work order..."
19
+ variant="outlined"
20
+ density="comfortable"
21
+ clearable
22
+ hide-details
23
+ class="ml-2"
24
+ style="max-width: 250px"
25
+ />
26
+ </v-row>
27
+ </v-col>
28
+ <v-col cols="12">
29
+ <v-card
30
+ width="100%"
31
+ variant="outlined"
32
+ border="thin"
33
+ rounded="lg"
34
+ :loading="loading"
35
+ >
36
+ <v-toolbar density="compact" color="grey-lighten-4">
37
+ <template #prepend>
38
+ <v-btn fab icon density="comfortable" @click="updatePage(1)">
39
+ <v-icon>mdi-refresh</v-icon>
40
+ </v-btn>
41
+ </template>
42
+
43
+ <template #append>
44
+ <v-row no-gutters justify="end" align="center">
45
+ <span class="mr-2 text-caption text-fontgray">
46
+ {{ pageRange }}
47
+ </span>
48
+ <local-pagination
49
+ v-model="page"
50
+ :length="pages"
51
+ @update:value="updatePage"
52
+ />
53
+ </v-row>
54
+ </template>
55
+ </v-toolbar>
56
+
57
+ <v-data-table
58
+ :headers="headers"
59
+ :items="items"
60
+ item-value="_id"
61
+ items-per-page="20"
62
+ fixed-header
63
+ hide-default-footer
64
+ :hide-default-header="false"
65
+ @click:row="tableRowClickHandler"
66
+ style="max-height: calc(100vh - (200px))"
67
+ >
68
+ </v-data-table>
69
+ </v-card>
70
+ </v-col>
71
+ </v-row>
72
+
73
+ <WorkOrderCreate
74
+ v-model="showCreateDialog"
75
+ created-from="workOrder"
76
+ :work-order="_workOrder"
77
+ @update:work-order="(val: TWorkOrderCreate) => (_workOrder = val)"
78
+ :is-edit-mode="isEditMode"
79
+ :loading="isSubmitting"
80
+ :categories="serviceProviders"
81
+ :theme="theme"
82
+ :errored-images="erroredImages"
83
+ :max-files="5"
84
+ :message-fn="showMessage"
85
+ @close="handleCloseDialog"
86
+ @file-added="handleFileAdded"
87
+ @file-deleted="deleteFile"
88
+ @submit="submitWorkOrder"
89
+ />
90
+
91
+ <Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />
92
+
93
+ <!-- Preview Dialog -->
94
+ <v-dialog v-model="dialogPreview" width="450" persistent v-if="canViewWorkOrders">
95
+ <v-card width="100%">
96
+ <v-card-text style="max-height: 100vh; overflow-y: auto" class="pb-0">
97
+ <v-row no-gutters v-if="selectedWorkOrder" class="mb-4">
98
+ <v-col cols="12">
99
+ <strong>Subject:</strong> {{ selectedWorkOrder.subject }}
100
+ </v-col>
101
+ <v-col cols="12">
102
+ <strong>Category:</strong>
103
+ {{ selectedWorkOrder.category }}
104
+ </v-col>
105
+ <v-col cols="12">
106
+ <strong>Status:</strong>
107
+ {{ selectedWorkOrder.status }}
108
+ </v-col>
109
+ </v-row>
110
+ </v-card-text>
111
+ <v-toolbar class="pa-0" density="compact">
112
+ <v-row no-gutters>
113
+ <v-col cols="6" class="pa-0">
114
+ <v-btn
115
+ block
116
+ variant="text"
117
+ class="text-none"
118
+ size="large"
119
+ @click="dialogPreview = false"
120
+ height="48"
121
+ >
122
+ Close
123
+ </v-btn>
124
+ </v-col>
125
+ <v-col cols="6" class="pa-0">
126
+ <v-menu>
127
+ <template #activator="{ props }">
128
+ <v-btn
129
+ block
130
+ variant="flat"
131
+ color="black"
132
+ class="text-none"
133
+ height="48"
134
+ v-bind="props"
135
+ tile
136
+ >
137
+ More actions
138
+ </v-btn>
139
+ </template>
140
+
141
+ <v-list class="pa-0">
142
+ <v-list-item @click="onViewWorkOrder(selectedWorkOrder)" v-if="canViewWorkOrderDetails">
143
+ <v-list-item-title class="text-subtitle-2">
144
+ View
145
+ </v-list-item-title>
146
+ </v-list-item>
147
+ <v-list-item @click="editWorkOrder(selectedWorkOrder)" v-if="canUpdateWorkOrder">
148
+ <v-list-item-title class="text-subtitle-2">
149
+ Edit
150
+ </v-list-item-title>
151
+ </v-list-item>
152
+
153
+ <v-list-item
154
+ @click="confirmDeleteWorkOrder(selectedWorkOrder)"
155
+ class="text-red"
156
+ v-if="canDeleteWorkOrder"
157
+ >
158
+ <v-list-item-title class="text-subtitle-2">
159
+ Delete
160
+ </v-list-item-title>
161
+ </v-list-item>
162
+ </v-list>
163
+ </v-menu>
164
+ </v-col>
165
+ </v-row>
166
+ </v-toolbar>
167
+ </v-card>
168
+ </v-dialog>
169
+ </template>
170
+
171
+ <script setup lang="ts">
172
+ import { useTheme } from "vuetify";
173
+ const emit = defineEmits(["click:create", "update:pagination"]);
174
+
175
+ const props = defineProps({
176
+ detailRoute: {
177
+ type: String,
178
+ default: "index",
179
+ },
180
+ orgId: {
181
+ type: String,
182
+ default: "",
183
+ },
184
+ customerId: {
185
+ type: String,
186
+ default: "",
187
+ },
188
+ siteId: {
189
+ type: String,
190
+ default: "",
191
+ },
192
+ canCreateWorkOrder: {
193
+ type: Boolean,
194
+ default: false,
195
+ },
196
+ canViewWorkOrders: {
197
+ type: Boolean,
198
+ default: false,
199
+ },
200
+ canViewWorkOrderDetails: {
201
+ type: Boolean,
202
+ default: false,
203
+ },
204
+ canDeleteWorkOrder: {
205
+ type: Boolean,
206
+ default: false,
207
+ },
208
+ canUpdateWorkOrder: {
209
+ type: Boolean,
210
+ default: false,
211
+ },
212
+ category: {
213
+ type: String,
214
+ default: "",
215
+ },
216
+ });
217
+
218
+ const theme = useTheme().name;
219
+ const showCreateDialog = ref(false);
220
+ const isEditMode = ref(false);
221
+ const erroredImages = ref<string[]>([]);
222
+
223
+ const message = ref("");
224
+ const messageColor = ref("");
225
+ const messageSnackbar = ref(false);
226
+
227
+ const { getColorStatus, formatDate } = useUtils();
228
+
229
+ const _workOrder = ref<TWorkOrderCreate>({
230
+ attachments: [],
231
+ category: "",
232
+ subject: "",
233
+ location: "",
234
+ description: "",
235
+ highPriority: false,
236
+ block: "",
237
+ level: "",
238
+ unit: "",
239
+ serviceProvider: "",
240
+ assignee: "",
241
+ organization: "",
242
+ site: "",
243
+ });
244
+
245
+ function showMessage(msg: string, color: string) {
246
+ message.value = msg;
247
+ messageColor.value = color;
248
+ messageSnackbar.value = true;
249
+ }
250
+
251
+ const headers: Array<Record<string, any>> = [
252
+ { title: "Created By", value: "createdByName", align: "start" },
253
+ { title: "Subject", value: "subject", align: "start" },
254
+ { title: "Category", value: "category", align: "start" },
255
+ { title: "Date", value: "createdAt", align: "start" },
256
+ { title: "Status", value: "status", align: "start" },
257
+ { title: "", value: "action-table", align: "end" },
258
+ ];
259
+
260
+ const submitting = ref(false);
261
+ const selected = ref<string[]>([]);
262
+ const route = useRoute();
263
+ const { customers } = useCustomer();
264
+
265
+ const {
266
+ getWorkOrders: _getWorkOrders,
267
+ createWorkOrder,
268
+ getWorkOrderById,
269
+ updateWorkOrder,
270
+ } = useWorkOrder();
271
+
272
+ const page = ref(1);
273
+ const pages = ref(0);
274
+ const pageRange = ref("-- - -- of --");
275
+ const items = ref<Array<Record<string, any>>>([]);
276
+
277
+ const {
278
+ data: getAllWorkOrderReq,
279
+ refresh: getAllReqRefresh,
280
+ status: getAllReqStatus,
281
+ } = useLazyAsyncData("get-all-work-orders-" + props.category, () =>
282
+ _getWorkOrders({
283
+ page: page.value,
284
+ site: route.params.site as string,
285
+ category: props.category,
286
+ })
287
+ );
288
+
289
+ const loading = computed(() => getAllReqStatus.value === "pending");
290
+ const onNextPrevPageLoading = ref(false);
291
+
292
+ watchEffect(() => {
293
+ if (getAllWorkOrderReq.value) {
294
+ items.value = getAllWorkOrderReq.value.items;
295
+ pages.value = getAllWorkOrderReq.value.pages;
296
+ pageRange.value = getAllWorkOrderReq.value.pageRange;
297
+ }
298
+ });
299
+
300
+ async function updatePage(pageVal: any) {
301
+ onNextPrevPageLoading.value = true;
302
+ page.value = pageVal;
303
+ const response = await _getWorkOrders({
304
+ page: page.value,
305
+ site: route.params.site as string,
306
+ category: props.category,
307
+ });
308
+ if (response) {
309
+ items.value = response.items;
310
+ pages.value = response.pages;
311
+ pageRange.value = response.pageRange;
312
+ onNextPrevPageLoading.value = false;
313
+ }
314
+ }
315
+
316
+ function onSelectedUpdate(newSelected: string[]) {
317
+ selected.value = newSelected;
318
+ }
319
+
320
+ function handleRowClick(row: any) {
321
+ const org = useRoute().params.org || "defaultOrg";
322
+ const site = useRoute().params.site || "defaultSite";
323
+ const id = row._id;
324
+ useRouter().push({
325
+ name: "work-order-details",
326
+ params: {
327
+ org,
328
+ site,
329
+ id,
330
+ },
331
+ });
332
+ }
333
+
334
+ function resetWorkOrderForm() {
335
+ _workOrder.value = {
336
+ attachments: [],
337
+ category: "",
338
+ subject: "",
339
+ location: "",
340
+ description: "",
341
+ highPriority: false,
342
+ block: "",
343
+ level: "",
344
+ unit: "",
345
+ serviceProvider: "",
346
+ assignee: "",
347
+ organization: "",
348
+ site: "",
349
+ };
350
+ }
351
+
352
+ function handleCloseDialog() {
353
+ resetWorkOrderForm();
354
+ isEditMode.value = false;
355
+ showCreateDialog.value = false;
356
+ }
357
+
358
+ const serviceProviders = ref<
359
+ Array<{ title: string; value: string; subtitle: string }>
360
+ >([]);
361
+
362
+ const { getBySiteAsServiceProvider } = useCustomerSite();
363
+
364
+ const { data: getAllReq } = useLazyAsyncData(
365
+ "get-by-site-as-service-provider",
366
+ () => getBySiteAsServiceProvider(useRoute().params.site as string)
367
+ );
368
+
369
+ watchEffect(() => {
370
+ if (getAllReq.value) {
371
+ serviceProviders.value = getAllReq.value.map((i: any) => ({
372
+ title: i.nature.replace(/_/g, " "),
373
+ subtitle: i.title,
374
+ value: i.nature,
375
+ }));
376
+ }
377
+ });
378
+
379
+ const { addFile, deleteFile: _deleteFile } = useFile();
380
+
381
+ const API_DO_STORAGE_ENDPOINT =
382
+ useRuntimeConfig().public.API_DO_STORAGE_ENDPOINT;
383
+
384
+ async function handleFileAdded(file: File) {
385
+ try {
386
+ const res = await addFile(file);
387
+ const uploadedId = res?.id;
388
+ if (uploadedId) {
389
+ const url = `${API_DO_STORAGE_ENDPOINT}/${uploadedId}`;
390
+ _workOrder.value.attachments = _workOrder.value.attachments ?? [];
391
+ _workOrder.value.attachments.push(url);
392
+ }
393
+ } catch (error) {
394
+ console.error("Error uploading file:", error);
395
+ showMessage("Failed to upload file", "error");
396
+ }
397
+ }
398
+
399
+ async function deleteFile(value: string) {
400
+ try {
401
+ await _deleteFile(value);
402
+ _workOrder.value.attachments = (_workOrder.value.attachments ?? []).filter(
403
+ (file) => file !== value
404
+ );
405
+ } catch (error) {
406
+ console.log(error);
407
+ showMessage("Failed to delete file", "error");
408
+ }
409
+ }
410
+
411
+ const _workOrderId = ref<string | null>(null);
412
+
413
+ const isSubmitting = ref(false);
414
+
415
+ async function submitWorkOrder() {
416
+ try {
417
+ isSubmitting.value = true;
418
+
419
+ const payload = {
420
+ ..._workOrder.value,
421
+ organization: route.params.org as string,
422
+ site: route.params.site as string,
423
+ };
424
+
425
+ let res: Record<string, any> = {};
426
+
427
+ if (isEditMode.value) {
428
+ res = await updateWorkOrder(_workOrderId.value as string, payload);
429
+ } else {
430
+ res = await createWorkOrder(payload);
431
+ }
432
+
433
+ showMessage(res.message, "success");
434
+ showCreateDialog.value = false;
435
+ resetWorkOrderForm();
436
+ getAllReqRefresh();
437
+ } catch (err) {
438
+ showMessage((err as Error).message, "error");
439
+ } finally {
440
+ isSubmitting.value = false;
441
+ }
442
+ }
443
+
444
+ function onViewWorkOrder(item: any) {
445
+ const route = useRoute();
446
+ const org = route.params.org;
447
+ const customer = route.params.customer;
448
+ const site = route.params.site;
449
+ const id = item._id;
450
+ useRouter().push({
451
+ name: props.detailRoute,
452
+ params: { org, site, id },
453
+ });
454
+ }
455
+
456
+ async function editWorkOrder(item: any) {
457
+ try {
458
+ const _workOrders = await getWorkOrderById(item._id);
459
+ console.log(_workOrders);
460
+ _workOrder.value = {
461
+ attachments: (_workOrders.attachments || []) as string[],
462
+ category: _workOrders.category || "",
463
+ subject: _workOrders.subject || "",
464
+ description: _workOrders.description || "",
465
+ highPriority: _workOrders.highPriority || false,
466
+ unit: _workOrders.location || "",
467
+ };
468
+ _workOrderId.value = item._id;
469
+ isEditMode.value = true;
470
+ showCreateDialog.value = true;
471
+ dialogPreview.value = false;
472
+ } catch (error) {
473
+ showMessage("Failed to load full work order", "error");
474
+ }
475
+ }
476
+
477
+ async function _updateWorkOrder() {}
478
+
479
+ function confirmDeleteWorkOrder(item: any) {}
480
+
481
+ function tableRowClickHandler(_: any, data: any) {
482
+ selectedWorkOrder.value = data.item;
483
+ dialogPreview.value = true;
484
+ }
485
+
486
+ const dialogPreview = ref(false);
487
+ const selectedWorkOrder = ref<TWorkOrder | null>(null);
488
+ const searchText = ref("");
489
+ </script>
@@ -0,0 +1 @@
1
+ <template><PlaceholderComponent /></template>
@@ -0,0 +1,107 @@
1
+ export default function useAddress() {
2
+ function add({
3
+ type = "",
4
+ user = "",
5
+ org = "",
6
+ country = "",
7
+ countryCode = "",
8
+ phoneNumber = "",
9
+ address = "",
10
+ continuedAddress = "",
11
+ city = "",
12
+ province = "",
13
+ postalCode = "",
14
+ taxId = "",
15
+ } = {}) {
16
+ return useNuxtApp().$api("/api/addresses", {
17
+ method: "POST",
18
+ body: {
19
+ type,
20
+ user,
21
+ org,
22
+ country,
23
+ countryCode,
24
+ phoneNumber,
25
+ address,
26
+ continuedAddress,
27
+ city,
28
+ province,
29
+ postalCode,
30
+ taxId,
31
+ },
32
+ });
33
+ }
34
+
35
+ function getByUserId(user = "") {
36
+ return useNuxtApp().$api<TAddress>(`/api/addresses/user/${user}`);
37
+ }
38
+
39
+ const _address = useState("address", (): TAddress => {
40
+ return {
41
+ type: "",
42
+ user: "",
43
+ org: "",
44
+ country: "",
45
+ address: "",
46
+ continuedAddress: "",
47
+ city: "",
48
+ province: "",
49
+ postalCode: "",
50
+ taxId: "",
51
+ };
52
+ });
53
+
54
+ function reset() {
55
+ _address.value.type = "";
56
+ _address.value.user = "";
57
+ _address.value.org = "";
58
+ _address.value.country = "";
59
+ _address.value.address = "";
60
+ _address.value.continuedAddress = "";
61
+ _address.value.city = "";
62
+ _address.value.province = "";
63
+ _address.value.postalCode = "";
64
+ _address.value.taxId = "";
65
+ }
66
+
67
+ function set({
68
+ type = "",
69
+ user = "",
70
+ org = "",
71
+ country = "",
72
+ address = "",
73
+ continuedAddress = "",
74
+ city = "",
75
+ province = "",
76
+ postalCode = "",
77
+ taxId = "",
78
+ } = {}) {
79
+ _address.value.type = type;
80
+ _address.value.user = user;
81
+ _address.value.org = org;
82
+ _address.value.country = country;
83
+ _address.value.address = address;
84
+ _address.value.continuedAddress = continuedAddress;
85
+ _address.value.city = city;
86
+ _address.value.province = province;
87
+ _address.value.postalCode = postalCode;
88
+ _address.value.taxId = taxId;
89
+ }
90
+
91
+ const { address, city, province, postalCode, country } = _address.value;
92
+
93
+ const completeAddress = computed(() => {
94
+ return `${address ? `${address}, ` : ""}${
95
+ city ? `${city}, ` : ""
96
+ } ${province} ${postalCode ? `${postalCode}, ` : ""} ${country}`;
97
+ });
98
+
99
+ return {
100
+ add,
101
+ reset,
102
+ set,
103
+ getByUserId,
104
+ address: _address,
105
+ completeAddress,
106
+ };
107
+ }