@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,284 @@
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 Work Order" : "Create Work Order" }}
6
+ </span>
7
+ </template>
8
+
9
+ <InputFile
10
+ :attachments="displayedAttachments"
11
+ :errored-images="localErroredImages"
12
+ :max-files="maxFiles"
13
+ :created-from="props.createdFrom"
14
+ @add="handleFileAdded"
15
+ @delete="deleteFile"
16
+ @errored="onImageError"
17
+ />
18
+
19
+ <v-autocomplete
20
+ v-model="workOrder.subject"
21
+ :items="subjects"
22
+ item-title="title"
23
+ item-value="value"
24
+ item-props
25
+ label="Subject"
26
+ variant="outlined"
27
+ density="compact"
28
+ class="mb-2"
29
+ :clearable="
30
+ props.createdFrom === 'feedback' && workOrder.subject !== ''
31
+ ? false
32
+ : true
33
+ "
34
+ :readonly="
35
+ props.createdFrom === 'feedback' && workOrder.subject !== ''
36
+ ? true
37
+ : false
38
+ "
39
+ :custom-filter="customFilter"
40
+ :rules="[requiredRule]"
41
+ >
42
+ <template #label> Subject <span class="text-red">*</span> </template>
43
+ </v-autocomplete>
44
+
45
+ <v-autocomplete
46
+ v-model="workOrder.category"
47
+ :items="categories"
48
+ item-title="title"
49
+ item-value="value"
50
+ item-props
51
+ label="Category"
52
+ variant="outlined"
53
+ density="compact"
54
+ class="mb-2"
55
+ :clearable="
56
+ props.createdFrom === 'feedback' && workOrder.category !== ''
57
+ ? false
58
+ : true
59
+ "
60
+ :readonly="
61
+ props.createdFrom === 'feedback' && workOrder.category !== ''
62
+ ? true
63
+ : false
64
+ "
65
+ :rules="[requiredRule]"
66
+ >
67
+ <template #label> Category <span class="text-red">*</span> </template>
68
+ </v-autocomplete>
69
+
70
+ <v-checkbox v-model="workOrder.highPriority" density="compact" class="ma-0">
71
+ <template #label>
72
+ <span class="text-caption">
73
+ Set work order as High Priority (Optional)
74
+ </span>
75
+ </template>
76
+ </v-checkbox>
77
+
78
+ <!-- <v-autocomplete
79
+ label="Block"
80
+ variant="outlined"
81
+ density="compact"
82
+ v-model="workOrder.block"
83
+ :items="blocks"
84
+ class="mt-1"
85
+ clearable
86
+ /> -->
87
+
88
+ <!-- <v-autocomplete
89
+ label="Level"
90
+ variant="outlined"
91
+ density="compact"
92
+ v-model="workOrder.level"
93
+ :items="levels"
94
+ class="mt-1"
95
+ clearable
96
+ /> -->
97
+
98
+ <v-autocomplete
99
+ label="Unit"
100
+ variant="outlined"
101
+ density="compact"
102
+ v-model="workOrder.unit"
103
+ :items="units"
104
+ class="mt-1"
105
+ clearable
106
+ :rules="[requiredRule]"
107
+ >
108
+ <template #label> Unit <span class="text-red">*</span> </template>
109
+ </v-autocomplete>
110
+
111
+ <!-- <v-text-field
112
+ label="Specific Location"
113
+ variant="outlined"
114
+ density="compact"
115
+ v-model="workOrder.location"
116
+ class="mt-1"
117
+ dense
118
+ :readonly="
119
+ props.createdFrom === 'feedback' && workOrder.location !== ''
120
+ ? true
121
+ : false
122
+ "
123
+ /> -->
124
+
125
+ <v-textarea
126
+ label="Work Order Description"
127
+ variant="outlined"
128
+ density="compact"
129
+ v-model="workOrder.description"
130
+ class="mt-1"
131
+ rows="4"
132
+ clearable
133
+ auto-grow
134
+ :rules="[requiredRule]"
135
+ >
136
+ <template #label> Description <span class="text-red">*</span> </template>
137
+ </v-textarea>
138
+
139
+ <template #footer>
140
+ <v-btn
141
+ color="primary-button"
142
+ class="text-capitalize mb-4"
143
+ block
144
+ height="40"
145
+ :loading="loading"
146
+ :disabled="loading || !isFormValid"
147
+ @click="submitWorkOrder"
148
+ >
149
+ Submit
150
+ </v-btn>
151
+ </template>
152
+ </FormDialog>
153
+ </template>
154
+
155
+ <script setup lang="ts">
156
+ import useBuildingUnit from "../../composables/useBuildingUnit";
157
+
158
+ const props = defineProps<{
159
+ modelValue: boolean;
160
+ createdFrom: string;
161
+ isEditMode: boolean;
162
+ loading: boolean;
163
+ categories: { title: string; value: string }[];
164
+ erroredImages?: string[];
165
+ maxFiles?: number;
166
+ blocks?: string[];
167
+ levels?: string[];
168
+ units?: string[];
169
+ specificLocations?: string[];
170
+ }>();
171
+
172
+ const workOrder = defineModel("workOrder", {
173
+ default: {
174
+ subject: "",
175
+ category: "",
176
+ highPriority: false,
177
+ unit: "",
178
+ location: "",
179
+ description: "",
180
+ attachments: [],
181
+ },
182
+ });
183
+
184
+ const emit = defineEmits([
185
+ "update:modelValue",
186
+ "update:workOrder",
187
+ "close",
188
+ "submit",
189
+ "fileAdded",
190
+ "fileDeleted",
191
+ ]);
192
+
193
+ const dialog = computed({
194
+ get: () => props.modelValue,
195
+ set: (val) => emit("update:modelValue", val),
196
+ });
197
+
198
+ const localErroredImages = ref<string[]>(props.erroredImages || []);
199
+
200
+ watch(
201
+ () => props.erroredImages,
202
+ (val) => {
203
+ if (val) localErroredImages.value = val;
204
+ }
205
+ );
206
+
207
+ const displayedAttachments = computed(() => {
208
+ return workOrder.value.attachments || [];
209
+ });
210
+
211
+ const { requiredRule } = useUtils();
212
+
213
+ const isFormValid = computed(() => {
214
+ return (
215
+ workOrder.value.subject &&
216
+ workOrder.value.category &&
217
+ workOrder.value.unit &&
218
+ workOrder.value.description
219
+ );
220
+ });
221
+
222
+ function handleFileAdded(file: File) {
223
+ emit("fileAdded", file);
224
+ }
225
+
226
+ function deleteFile(url: string) {
227
+ emit("fileDeleted", url);
228
+ }
229
+
230
+ function onImageError(file: string) {
231
+ if (!localErroredImages.value.includes(file)) {
232
+ localErroredImages.value.push(file);
233
+ }
234
+ }
235
+
236
+ function closeDialog() {
237
+ dialog.value = false;
238
+ emit("close");
239
+ }
240
+
241
+ function submitWorkOrder() {
242
+ emit("submit", { ...workOrder.value });
243
+ }
244
+
245
+ const units = ref<Array<{ title: string; value: string }>>([]);
246
+
247
+ const { getAll } = useBuildingUnit();
248
+ const { data } = await useLazyAsyncData("get-building-units-by-status", () =>
249
+ getAll({ status: "active" })
250
+ );
251
+
252
+ watchEffect(() => {
253
+ if (data.value && data.value.items && data.value.items.length > 0) {
254
+ units.value = data.value.items.map((item: any) => {
255
+ return {
256
+ title: `${item.name} - ${item.level} - ${item.buildingName}`,
257
+ value: item._id,
258
+ };
259
+ });
260
+ }
261
+ });
262
+
263
+ const workOrderUnit = computed(() => {
264
+ return workOrder.value.unit;
265
+ });
266
+
267
+ watch(workOrderUnit, (val: string) => {
268
+ if (val) {
269
+ const unit = units.value.find((unit: any) => unit.value === val);
270
+ if (unit) {
271
+ workOrder.value.location = unit.title;
272
+ }
273
+ }
274
+ });
275
+
276
+ const { subjects } = useLocal();
277
+
278
+ const customFilter = (value: string, query: string, item: any) => {
279
+ const title = item?.raw?.title?.toLowerCase() || "";
280
+ const subtitle = item?.raw?.subtitle?.toLowerCase() || "";
281
+ const search = query.toLowerCase();
282
+ return title.includes(search) || subtitle.includes(search);
283
+ };
284
+ </script>
@@ -0,0 +1,71 @@
1
+ <template>
2
+ <div class="feedback-detail-wrapper">
3
+ <v-row no-gutters class="fill-height">
4
+ <v-col cols="12" xl="7" lg="7" md="7" class="fill-height">
5
+ <div class="panel-container border-e">
6
+ <ChatMessage :type="'workOrder'" />
7
+ </div>
8
+ </v-col>
9
+ <v-col cols="12" xl="5" lg="5" md="5" class="fill-height">
10
+ <div class="panel-container">
11
+ <ChatInformation
12
+ :item="workOrder"
13
+ :service-providers="_serviceProviders"
14
+ :type="'workOrder'"
15
+ @edit="openEditDialog"
16
+ @mark-complete-request="showCompleteDialog = true"
17
+ @delete="showDeleteDialog = true"
18
+ />
19
+ </div>
20
+ </v-col>
21
+ </v-row>
22
+ </div>
23
+ </template>
24
+ <script lang="ts" setup>
25
+ const route = useRoute();
26
+ const id = route.params.id;
27
+
28
+ const {
29
+ workOrder,
30
+ workOrders,
31
+ getWorkOrderById,
32
+ getWorkOrders: _getWorkOrders,
33
+ } = useWorkOrder();
34
+
35
+ const { getServiceProviderNames } = useServiceProvider();
36
+
37
+ const _getWorkOrderById = async () => {
38
+ try {
39
+ const data = await getWorkOrderById(id as string);
40
+ workOrder.value = data;
41
+ } catch (error) {
42
+ console.error("Error fetching feedback:", error);
43
+ }
44
+ };
45
+
46
+ _getWorkOrderById();
47
+
48
+ const _serviceProviders = ref<TServiceProviderName[]>([]);
49
+
50
+ const _getServiceProviderNames = async () => {
51
+ try {
52
+ const response = await getServiceProviderNames();
53
+ if (!response) return;
54
+
55
+ _serviceProviders.value = response.items.map((provider) => ({
56
+ _id: provider._id as string,
57
+ name: provider.name,
58
+ }));
59
+ } catch (error) {
60
+ console.error("Error fetching service providers:", error);
61
+ }
62
+ };
63
+
64
+ _getServiceProviderNames();
65
+
66
+ const showCreateDialog = ref(false);
67
+ const showCompleteDialog = ref(false);
68
+ const showDeleteDialog = ref(false);
69
+
70
+ function openEditDialog() {}
71
+ </script>
@@ -0,0 +1,96 @@
1
+ <template>
2
+ <TableListSecondary
3
+ :headers="headers"
4
+ :items="workOrders"
5
+ :pages="pages"
6
+ :page-range="pageRange"
7
+ :loading="loading"
8
+ :height="'calc(100vh - 177px)'"
9
+ v-model:page="page"
10
+ v-model="selected"
11
+ @update:pagination="_getWorkOrders"
12
+ @row-click="handleRowClick"
13
+ @click:create="emit('click:create')"
14
+ :length="pages"
15
+ >
16
+ <template #title>
17
+ <span class="text-h6 font-weight-regular">Work Order</span>
18
+ </template>
19
+ <template #action-button>
20
+ <v-btn
21
+ color="primary-button"
22
+ variant="flat"
23
+ class="ml-4 text-capitalize"
24
+ @click="emit('click:create')"
25
+ >
26
+ Work Order
27
+ </v-btn>
28
+ </template>
29
+
30
+ <template #createdAt="{ item }">
31
+ {{
32
+ new Date(item.createdAt).toLocaleString("en-GB", {
33
+ day: "2-digit",
34
+ month: "2-digit",
35
+ year: "numeric",
36
+ hour: "2-digit",
37
+ minute: "2-digit",
38
+ hour12: false,
39
+ })
40
+ }}
41
+ </template>
42
+
43
+ <template #status="{ item }">
44
+ <v-chip
45
+ :color="getColorStatus(item.status || 'No Status')"
46
+ text-color="white"
47
+ variant="flat"
48
+ >
49
+ {{ item.status || "No Status" }}
50
+ </v-chip>
51
+ </template>
52
+ </TableListSecondary>
53
+ </template>
54
+
55
+ <script lang="ts" setup>
56
+ const emit = defineEmits(["click:create", "update:pagination"]);
57
+
58
+ const { page, pages, pageRange, workOrders, getWorkOrders } = useWorkOrder();
59
+ const { getColorStatus } = useUtils();
60
+
61
+ const message = ref("");
62
+ const messageColor = ref("");
63
+ const messageSnackbar = ref(false);
64
+ const loading = ref(false);
65
+ const height = ref("500px");
66
+ const selected = ref<string[]>([]);
67
+
68
+ const headers = ref([
69
+ { title: "Created By", value: "createdByName" },
70
+ { title: "Subject", value: "subject" },
71
+ { title: "Category", value: "application" },
72
+ { title: "Status", value: "status" },
73
+ { title: "Date", value: "createdAt" },
74
+ ]);
75
+
76
+ async function _getWorkOrders() {
77
+ loading.value = true;
78
+
79
+ try {
80
+ await getWorkOrders({
81
+ page: page.value,
82
+ });
83
+
84
+ emit("update:pagination", {
85
+ page: page.value,
86
+ pages: pages.value,
87
+ });
88
+ } catch (error) {
89
+ console.error("Error fetching feedbacks:", error);
90
+ } finally {
91
+ loading.value = false;
92
+ }
93
+ }
94
+
95
+ _getWorkOrders();
96
+ </script>