@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,591 @@
1
+ <template>
2
+ <v-row no-gutters class="border-thin pa-6 rounded-lg">
3
+ <v-col cols="12">
4
+ <!-- Header -->
5
+ <v-row no-gutters class="mb-4" align="center">
6
+ <v-col cols="12" md="6">
7
+ <v-btn
8
+ variant="text"
9
+ prepend-icon="mdi-chevron-left"
10
+ class="text-none"
11
+ @click="goBack"
12
+ >
13
+ Patrol Report Log
14
+ </v-btn>
15
+ </v-col>
16
+ <v-col cols="12" md="6" class="d-flex justify-end">
17
+ <v-btn
18
+ color="primary"
19
+
20
+ variant="flat"
21
+ size="large"
22
+ class="text-none px-8"
23
+ prepend-icon="mdi-plus"
24
+ >
25
+ Create Routes & Schedule
26
+ </v-btn>
27
+ </v-col>
28
+ </v-row>
29
+
30
+ <!-- Tabs -->
31
+ <v-tabs v-model="activeTab" class="mb-6 " bg-color="transparent" grow>
32
+ <v-tab value="patrol" class="text-none border-thin" >Patrol Report</v-tab>
33
+ <v-tab value="daily" class="text-none border-thin">Daily Report</v-tab>
34
+ <v-tab value="monthly" class="text-none border-thin">Monthly Report</v-tab>
35
+ </v-tabs>
36
+
37
+ <v-window v-model="activeTab" class="pt-4">
38
+ <!-- Patrol Report Tab -->
39
+ <v-window-item value="patrol">
40
+ <!-- Filters -->
41
+ <v-row no-gutters class="mb-6">
42
+ <v-col cols="12" md="3" class="pr-md-2 mb-2 mb-md-0">
43
+ <v-select
44
+ v-model="selectedRoute"
45
+ :items="routes"
46
+ label="Select Route"
47
+ variant="outlined"
48
+ density="comfortable"
49
+ rounded="lg"
50
+ hide-details
51
+ bg-color="white"
52
+ />
53
+ </v-col>
54
+ <v-col cols="12" md="2" class="px-md-2 mb-2 mb-md-0">
55
+ <v-select
56
+ v-model="selectedTimeRange"
57
+ :items="timeRanges"
58
+ label="Time Range"
59
+ variant="outlined"
60
+ density="comfortable"
61
+ rounded="lg"
62
+ hide-details
63
+ bg-color="white"
64
+ />
65
+ </v-col>
66
+ <v-col cols="12" md="2" class="px-md-2 mb-2 mb-md-0">
67
+ <v-text-field
68
+ v-model="selectedDate"
69
+ type="date"
70
+ variant="outlined"
71
+ density="comfortable"
72
+ rounded="lg"
73
+ hide-details
74
+ bg-color="white"
75
+ />
76
+ </v-col>
77
+ <v-col cols="12" md="3" class="px-md-2 mb-2 mb-md-0">
78
+ <v-btn
79
+ color="primary"
80
+ block
81
+ size="large"
82
+ rounded="lg"
83
+ class="text-none"
84
+ @click="loadReport"
85
+ >
86
+ Select Routes & Schedule
87
+ </v-btn>
88
+ </v-col>
89
+ <v-col cols="12" md="2" class="pl-md-2">
90
+ <v-btn
91
+ variant="outlined"
92
+ block
93
+ size="large"
94
+ rounded="lg"
95
+ class="text-none"
96
+ prepend-icon="mdi-export"
97
+ @click="exportReport"
98
+ >
99
+ Export
100
+ </v-btn>
101
+ </v-col>
102
+ </v-row>
103
+
104
+ <v-divider :thickness="1" class="border-opacity-100"></v-divider>
105
+
106
+
107
+ <!-- Location Card -->
108
+ <v-card
109
+ v-if="locationData"
110
+ class=" text-center pa-8 mt-2"
111
+ variant="flat"
112
+ rounded="lg"
113
+ >
114
+ <v-icon size="64" class="mb-4">mdi-office-building</v-icon>
115
+ <h2 class="text-h5 mb-2">{{ locationData.name }}</h2>
116
+ <p class="text-body-2 text-medium-emphasis">
117
+ {{ locationData.address }}
118
+ </p>
119
+ </v-card>
120
+ <v-divider :thickness="1" class="border-opacity-100 mb-6"></v-divider>
121
+ <!-- Route Summary -->
122
+ <v-card v-if="routeSummary" class="mb-6" variant="flat" rounded="lg">
123
+ <v-card-title class="d-flex justify-space-between align-center">
124
+ <span>Patrol Route Summary: {{ routeSummary.routeName }}</span>
125
+ <span class="text-body-2 text-medium-emphasis">
126
+ Tolerance: {{ routeSummary.tolerance }} mins
127
+ </span>
128
+ </v-card-title>
129
+ <v-card-text class="pa-0">
130
+ <v-table class=" border-thin">
131
+ <thead>
132
+ <tr>
133
+ <th>Time</th>
134
+ <th>Start</th>
135
+ <th>End</th>
136
+ <th>Total travel time</th>
137
+ </tr>
138
+ </thead>
139
+ <tbody>
140
+ <tr>
141
+ <td class="font-weight-medium">Schedule</td>
142
+ <td>
143
+ <v-icon size="small" class="mr-1">mdi-clock-outline</v-icon>
144
+ {{ routeSummary.schedule.start }}
145
+ </td>
146
+ <td>
147
+ <v-icon size="small" class="mr-1">mdi-clock-outline</v-icon>
148
+ {{ routeSummary.schedule.end }}
149
+ </td>
150
+ <td>
151
+ <v-icon size="small" class="mr-1">mdi-clock-outline</v-icon>
152
+ {{ routeSummary.schedule.totalTime }}
153
+ </td>
154
+ </tr>
155
+ <tr>
156
+ <td class="font-weight-medium">Actual</td>
157
+ <td>
158
+ <v-icon size="small" class="mr-1">mdi-clock-outline</v-icon>
159
+ {{ routeSummary.actual.start }}
160
+ </td>
161
+ <td>
162
+ <v-icon size="small" class="mr-1">mdi-clock-outline</v-icon>
163
+ {{ routeSummary.actual.end }}
164
+ </td>
165
+ <td>
166
+ <v-icon size="small" class="mr-1">mdi-clock-outline</v-icon>
167
+ {{ routeSummary.actual.totalTime }}
168
+ </td>
169
+ </tr>
170
+ </tbody>
171
+ </v-table>
172
+ </v-card-text>
173
+ </v-card>
174
+
175
+ <!-- Patrol Activity -->
176
+ <v-card
177
+ v-if="patrolActivity.length"
178
+ variant="flat"
179
+ rounded="lg"
180
+ >
181
+ <v-card-title>Patrol Activity</v-card-title>
182
+ <v-card-text class="pa-0">
183
+ <v-table class="border-thin">
184
+ <thead>
185
+ <tr>
186
+ <th>Checkpoints</th>
187
+ <th>Start - End Time</th>
188
+ <th>
189
+ Travel time<br />
190
+ <span class="text-caption text-medium-emphasis">Actual/Expected</span>
191
+ </th>
192
+ <th>Status</th>
193
+ </tr>
194
+ </thead>
195
+ <tbody>
196
+ <tr
197
+ v-for="activity in patrolActivity"
198
+ :key="activity.id"
199
+ :class="{ 'cursor-pointer': activity.status === 'Skipped' }"
200
+ @click="activity.status === 'Skipped' && openRemarksDialog(activity)"
201
+ >
202
+ <td>{{ activity.checkpoint }}</td>
203
+ <td>
204
+ <v-icon size="small" class="mr-1">mdi-clock-outline</v-icon>
205
+ {{ activity.startTime }}
206
+ <v-icon size="small" class="mx-2">mdi-arrow-right</v-icon>
207
+ <v-icon size="small" class="mr-1">mdi-clock-outline</v-icon>
208
+ {{ activity.endTime }}
209
+ </td>
210
+ <td>
211
+ <v-icon size="small" class="mr-1">mdi-clock-outline</v-icon>
212
+ {{ activity.actualTime }} / {{ activity.expectedTime }}
213
+ </td>
214
+ <td>
215
+ <v-chip
216
+ :color="getStatusColor(activity.status)"
217
+ size="small"
218
+ variant="flat"
219
+ >
220
+ {{ activity.status }}
221
+ <v-icon
222
+ v-if="activity.status === 'Skipped'"
223
+ size="small"
224
+ class="ml-1"
225
+ >
226
+ mdi-flag
227
+ </v-icon>
228
+ </v-chip>
229
+ </td>
230
+ </tr>
231
+ </tbody>
232
+ </v-table>
233
+ </v-card-text>
234
+ </v-card>
235
+
236
+ <!-- Empty State -->
237
+ <v-card
238
+ v-if="!routeSummary && !loading"
239
+ class="text-center pa-12"
240
+ variant="outlined"
241
+ rounded="lg"
242
+ >
243
+ <v-icon size="64" color="grey-lighten-1" class="mb-4">
244
+ mdi-clipboard-text-outline
245
+ </v-icon>
246
+ <h3 class="text-h6 mb-2">No Patrol Report Selected</h3>
247
+ <p class="text-body-2 text-medium-emphasis">
248
+ Please select a route, time range, and date to view the patrol
249
+ report
250
+ </p>
251
+ </v-card>
252
+ </v-window-item>
253
+
254
+ <!-- Daily Report Tab -->
255
+ <v-window-item value="daily">
256
+ <v-card class="text-center pa-12" variant="outlined" rounded="lg">
257
+ <v-icon size="64" color="grey-lighten-1" class="mb-4">
258
+ mdi-calendar-today
259
+ </v-icon>
260
+ <h3 class="text-h6 mb-2">Daily Report</h3>
261
+ <p class="text-body-2 text-medium-emphasis">Coming soon...</p>
262
+ </v-card>
263
+ </v-window-item>
264
+
265
+ <!-- Monthly Report Tab -->
266
+ <v-window-item value="monthly">
267
+ <v-card class="text-center pa-12" variant="outlined" rounded="lg">
268
+ <v-icon size="64" color="grey-lighten-1" class="mb-4">
269
+ mdi-calendar-month
270
+ </v-icon>
271
+ <h3 class="text-h6 mb-2">Monthly Report</h3>
272
+ <p class="text-body-2 text-medium-emphasis">Coming soon...</p>
273
+ </v-card>
274
+ </v-window-item>
275
+ </v-window>
276
+ </v-col>
277
+
278
+ <!-- Skip Checkpoint Remarks Dialog -->
279
+ <v-dialog v-model="dialogRemarks" max-width="600" persistent>
280
+ <v-card rounded="xl">
281
+ <v-card-title class="d-flex align-center pa-6">
282
+ <span class="text-h6">Skip Checkpoint Remarks</span>
283
+ <v-spacer />
284
+ <v-btn
285
+ icon="mdi-close"
286
+ variant="text"
287
+ size="small"
288
+ @click="dialogRemarks = false"
289
+ />
290
+ </v-card-title>
291
+
292
+ <v-card-text class="px-6 pb-6">
293
+ <v-textarea
294
+ :model-value="selectedActivityRemarks"
295
+ variant="outlined"
296
+ rounded="lg"
297
+ readonly
298
+ rows="4"
299
+ hide-details
300
+ />
301
+ </v-card-text>
302
+ </v-card>
303
+ </v-dialog>
304
+
305
+ <!-- Select Routes & Schedule Dialog -->
306
+ <v-dialog v-model="dialogSelectRoute" max-width="680" persistent>
307
+ <v-card rounded="xl">
308
+ <v-card-title class="pa-6">
309
+ <v-btn
310
+ icon="mdi-chevron-left"
311
+ variant="text"
312
+ size="small"
313
+ @click="dialogSelectRoute = false"
314
+ />
315
+ <span class="text-h6 ml-2">Select Routes & Schedule</span>
316
+ </v-card-title>
317
+
318
+ <v-card-text class="px-6 pb-6">
319
+ <!-- Route Selector -->
320
+ <v-select
321
+ v-model="dialogRoute"
322
+ :items="routes"
323
+ variant="outlined"
324
+ rounded="lg"
325
+ density="comfortable"
326
+ hide-details
327
+ class="mb-4"
328
+ />
329
+
330
+ <!-- Date and Time Row -->
331
+ <v-row no-gutters>
332
+ <v-col cols="12" md="6" class="pr-md-2">
333
+ <v-text-field
334
+ v-model="dialogDate"
335
+ type="date"
336
+ variant="outlined"
337
+ rounded="lg"
338
+ density="comfortable"
339
+ hide-details
340
+ prepend-inner-icon="mdi-calendar"
341
+ />
342
+ </v-col>
343
+ <v-col cols="12" md="6" class="pl-md-2 mt-2 mt-md-0">
344
+ <v-select
345
+ v-model="dialogTime"
346
+ :items="timeRanges"
347
+ variant="outlined"
348
+ rounded="lg"
349
+ density="comfortable"
350
+ hide-details
351
+ prepend-inner-icon="mdi-clock-outline"
352
+ />
353
+ </v-col>
354
+ </v-row>
355
+ </v-card-text>
356
+
357
+ <!-- Action Buttons -->
358
+ <v-card-actions class="px-6 pb-6">
359
+ <v-row no-gutters>
360
+ <v-col cols="6" class="pr-2">
361
+ <v-btn
362
+ block
363
+ size="x-large"
364
+ variant="outlined"
365
+ rounded="lg"
366
+ class="text-none"
367
+ @click="dialogSelectRoute = false"
368
+ >
369
+ Cancel
370
+ </v-btn>
371
+ </v-col>
372
+ <v-col cols="6" class="pl-2">
373
+ <v-btn
374
+ block
375
+ size="x-large"
376
+ color="primary"
377
+ rounded="lg"
378
+ class="text-none"
379
+ @click="submitSelection"
380
+ >
381
+ Submit
382
+ </v-btn>
383
+ </v-col>
384
+ </v-row>
385
+ </v-card-actions>
386
+ </v-card>
387
+ </v-dialog>
388
+ </v-row>
389
+ </template>
390
+
391
+ <script setup lang="ts">
392
+ interface PatrolActivity {
393
+ id: string;
394
+ checkpoint: string;
395
+ startTime: string;
396
+ endTime: string;
397
+ actualTime: string;
398
+ expectedTime: string;
399
+ status: "Completed" | "Skipped";
400
+ remarks?: string;
401
+ }
402
+
403
+ interface RouteSummary {
404
+ routeName: string;
405
+ tolerance: number;
406
+ schedule: {
407
+ start: string;
408
+ end: string;
409
+ totalTime: string;
410
+ };
411
+ actual: {
412
+ start: string;
413
+ end: string;
414
+ totalTime: string;
415
+ };
416
+ }
417
+
418
+ interface LocationData {
419
+ name: string;
420
+ address: string;
421
+ }
422
+
423
+ const props = defineProps<{
424
+ site: string;
425
+ orgId: string;
426
+ }>();
427
+
428
+ const router = useRouter();
429
+
430
+ // State
431
+ const activeTab = ref("patrol");
432
+ const selectedRoute = ref("WH01 Patrol Route");
433
+ const selectedTimeRange = ref("15:00 - 17:00");
434
+ const selectedDate = ref("2025-11-27");
435
+ const loading = ref(false);
436
+
437
+ // Dialog state
438
+ const dialogSelectRoute = ref(false);
439
+ const dialogRoute = ref("WH01 Patrol Route");
440
+ const dialogDate = ref("2025-11-27");
441
+ const dialogTime = ref("15:00 - 17:00");
442
+
443
+ // Remarks dialog state
444
+ const dialogRemarks = ref(false);
445
+ const selectedActivityRemarks = ref("");
446
+
447
+ // Mock data - replace with actual API calls
448
+ const routes = ref([
449
+ "WH01 Patrol Route",
450
+ "WH02 Patrol Route",
451
+ "WH03 Patrol Route",
452
+ ]);
453
+
454
+ const timeRanges = ref([
455
+ "15:00 - 17:00",
456
+ "08:00 - 10:00",
457
+ "13:00 - 15:00",
458
+ "18:00 - 20:00",
459
+ ]);
460
+
461
+ const locationData = ref<LocationData>({
462
+ name: "Winsland Homes",
463
+ address: "221A Upper Thomson Road THOMSON RIDGE ESTATE",
464
+ });
465
+
466
+ const routeSummary = ref<RouteSummary>({
467
+ routeName: "WH01 Patrol Route",
468
+ tolerance: 30,
469
+ schedule: {
470
+ start: "14:00",
471
+ end: "15:00",
472
+ totalTime: "25 mins",
473
+ },
474
+ actual: {
475
+ start: "14:01",
476
+ end: "14:16",
477
+ totalTime: "15 mins",
478
+ },
479
+ });
480
+
481
+ const patrolActivity = ref<PatrolActivity[]>([
482
+ {
483
+ id: "1",
484
+ checkpoint: "Point 1 WH01",
485
+ startTime: "14:01",
486
+ endTime: "14:04",
487
+ actualTime: "3:00 mins",
488
+ expectedTime: "5:00 mins",
489
+ status: "Skipped",
490
+ remarks: "Raining",
491
+ },
492
+ {
493
+ id: "2",
494
+ checkpoint: "Point 2 WH02",
495
+ startTime: "14:04",
496
+ endTime: "14:07",
497
+ actualTime: "3:00 mins",
498
+ expectedTime: "5:00 mins",
499
+ status: "Completed",
500
+ },
501
+ {
502
+ id: "3",
503
+ checkpoint: "Point 3 WH03",
504
+ startTime: "14:07",
505
+ endTime: "15:10",
506
+ actualTime: "3:00 mins",
507
+ expectedTime: "5:00 mins",
508
+ status: "Completed",
509
+ },
510
+ {
511
+ id: "4",
512
+ checkpoint: "Point 4 WH04",
513
+ startTime: "14:10",
514
+ endTime: "14:13",
515
+ actualTime: "3:00 mins",
516
+ expectedTime: "5:00 mins",
517
+ status: "Completed",
518
+ },
519
+ {
520
+ id: "5",
521
+ checkpoint: "Point 5 WH05",
522
+ startTime: "14:13",
523
+ endTime: "14:16",
524
+ actualTime: "3:00 mins",
525
+ expectedTime: "5:00 mins",
526
+ status: "Completed",
527
+ },
528
+ ]);
529
+
530
+ // Methods
531
+ const goBack = () => {
532
+ router.back();
533
+ };
534
+
535
+ const loadReport = () => {
536
+ // Open the dialog
537
+ dialogRoute.value = selectedRoute.value;
538
+ dialogDate.value = selectedDate.value;
539
+ dialogTime.value = selectedTimeRange.value;
540
+ dialogSelectRoute.value = true;
541
+ };
542
+
543
+ const submitSelection = () => {
544
+ // Update the main filters with dialog values
545
+ selectedRoute.value = dialogRoute.value;
546
+ selectedDate.value = dialogDate.value;
547
+ selectedTimeRange.value = dialogTime.value;
548
+
549
+ // Close the dialog
550
+ dialogSelectRoute.value = false;
551
+
552
+ // TODO: Implement report loading based on filters
553
+ console.log("Loading report...", {
554
+ route: selectedRoute.value,
555
+ timeRange: selectedTimeRange.value,
556
+ date: selectedDate.value,
557
+ });
558
+ };
559
+
560
+ const exportReport = () => {
561
+ // TODO: Implement export functionality
562
+ console.log("Exporting report...");
563
+ };
564
+
565
+ const getStatusColor = (status: string) => {
566
+ return status === "Completed" ? "success" : "error";
567
+ };
568
+
569
+ const openRemarksDialog = (activity: PatrolActivity) => {
570
+ selectedActivityRemarks.value = activity.remarks || "No remarks provided";
571
+ dialogRemarks.value = true;
572
+ };
573
+
574
+ // TODO: Add API integration
575
+ // TODO: Add data fetching based on filters
576
+ // TODO: Implement Daily and Monthly reports
577
+ </script>
578
+
579
+ <style scoped>
580
+ .cursor-pointer {
581
+ cursor: pointer;
582
+ }
583
+
584
+ .cursor-pointer:hover {
585
+ background-color: rgba(0, 0, 0, 0.04);
586
+ }
587
+
588
+ .v-table {
589
+ border-radius: 0;
590
+ }
591
+ </style>