@7365admin1/layer-common 3.0.21 → 3.0.23

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 (32) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/components/DashboardMain.vue +211 -58
  3. package/components/InvitationMain.vue +32 -3
  4. package/components/MemberMain.vue +1 -1
  5. package/components/Nfc/NFCPatrolReportMain.vue +48 -541
  6. package/components/Nfc/PatrolReport/DailyReportTab.vue +59 -0
  7. package/components/Nfc/PatrolReport/MonthlyReportTab.vue +59 -0
  8. package/components/Nfc/PatrolReport/PatrolActivityTable.vue +81 -0
  9. package/components/Nfc/PatrolReport/PatrolReportTab.vue +73 -0
  10. package/components/Nfc/PatrolReport/PatrolRouteSummary.vue +63 -0
  11. package/components/Nfc/PatrolReport/RemarksDialog.vue +37 -0
  12. package/components/Nfc/PatrolReport/ReportEmptyState.vue +24 -0
  13. package/components/Nfc/PatrolReport/ReportFilters.vue +88 -0
  14. package/components/Nfc/PatrolReport/ReportLocationHeader.vue +17 -0
  15. package/components/Nfc/PatrolReport/SummaryReportTable.vue +51 -0
  16. package/components/ScheduleTaskMain.vue +47 -12
  17. package/components/ServiceProviderMain.vue +182 -184
  18. package/components/UnitMain.vue +8 -1
  19. package/components/VisitorForm.vue +2 -0
  20. package/components/VisitorManagement.vue +31 -0
  21. package/components/VisitorSocketPopUp.vue +292 -0
  22. package/composables/useNFCPatrolDailyReport.ts +27 -0
  23. package/composables/useNFCPatrolMonthlyReport.ts +27 -0
  24. package/composables/useNFCPatrolReport.ts +38 -0
  25. package/composables/useNFCPatrolReportExport.ts +31 -0
  26. package/composables/useNFCPatrolReportFilters.ts +39 -0
  27. package/composables/useVisitor.ts +3 -0
  28. package/composables/useVisitorSocket.ts +25 -0
  29. package/package.json +2 -1
  30. package/services/nfcPatrolReport.ts +172 -0
  31. package/types/nfc-patrol-report.ts +73 -0
  32. package/types/verification.d.ts +6 -1
@@ -1,7 +1,6 @@
1
1
  <template>
2
2
  <v-row no-gutters class="border-thin pa-6 rounded-lg">
3
3
  <v-col cols="12">
4
- <!-- Header -->
5
4
  <v-row no-gutters class="mb-4" align="center">
6
5
  <v-col cols="12" md="6">
7
6
  <v-btn
@@ -13,412 +12,59 @@
13
12
  Patrol Report Log
14
13
  </v-btn>
15
14
  </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
15
  </v-row>
29
16
 
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>
17
+ <v-tabs v-model="activeTab" class="mb-6" bg-color="transparent" grow>
18
+ <v-tab value="patrol" class="text-none border-thin">Patrol Report</v-tab>
33
19
  <v-tab value="daily" class="text-none border-thin">Daily Report</v-tab>
34
20
  <v-tab value="monthly" class="text-none border-thin">Monthly Report</v-tab>
35
21
  </v-tabs>
36
22
 
37
23
  <v-window v-model="activeTab" class="pt-4">
38
- <!-- Patrol Report Tab -->
39
24
  <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>
25
+ <PatrolReportTab
26
+ :active="activeTab === 'patrol'"
27
+ :filters="filters"
28
+ :options="options"
29
+ @update:filters="updateFilters"
30
+ @export="exportReport"
31
+ />
252
32
  </v-window-item>
253
33
 
254
- <!-- Daily Report Tab -->
255
34
  <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>
35
+ <DailyReportTab
36
+ :active="activeTab === 'daily'"
37
+ :filters="filters"
38
+ :options="options"
39
+ @update:filters="updateFilters"
40
+ @export="exportReport"
41
+ />
263
42
  </v-window-item>
264
43
 
265
- <!-- Monthly Report Tab -->
266
44
  <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>
45
+ <MonthlyReportTab
46
+ :active="activeTab === 'monthly'"
47
+ :filters="filters"
48
+ :options="options"
49
+ @update:filters="updateFilters"
50
+ @export="exportReport"
51
+ />
274
52
  </v-window-item>
275
53
  </v-window>
276
54
  </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
55
  </v-row>
389
56
  </template>
390
57
 
391
58
  <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
- }
59
+ import type {
60
+ NFCPatrolReportFilters,
61
+ NFCPatrolReportTab,
62
+ } from "../../types/nfc-patrol-report";
63
+ import { useNFCPatrolReportExport } from "../../composables/useNFCPatrolReportExport";
64
+ import { useNFCPatrolReportFilters } from "../../composables/useNFCPatrolReportFilters";
65
+ import DailyReportTab from "./PatrolReport/DailyReportTab.vue";
66
+ import MonthlyReportTab from "./PatrolReport/MonthlyReportTab.vue";
67
+ import PatrolReportTab from "./PatrolReport/PatrolReportTab.vue";
422
68
 
423
69
  const props = defineProps<{
424
70
  site: string;
@@ -426,166 +72,27 @@ const props = defineProps<{
426
72
  }>();
427
73
 
428
74
  const router = useRouter();
75
+ const activeTab = ref<NFCPatrolReportTab>("patrol");
76
+ const { filters, options, fetchOptions } = useNFCPatrolReportFilters(props.site);
77
+ const { exportReport: exportActiveReport } = useNFCPatrolReportExport();
429
78
 
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
- });
79
+ onMounted(fetchOptions);
465
80
 
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 = () => {
81
+ function goBack() {
532
82
  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
83
  }
583
84
 
584
- .cursor-pointer:hover {
585
- background-color: rgba(0, 0, 0, 0.04);
85
+ function updateFilters(value: NFCPatrolReportFilters) {
86
+ filters.route = value.route;
87
+ filters.timeRange = value.timeRange;
88
+ filters.date = value.date;
586
89
  }
587
90
 
588
- .v-table {
589
- border-radius: 0;
91
+ async function exportReport() {
92
+ await exportActiveReport(activeTab.value, {
93
+ route: filters.route,
94
+ timeRange: filters.timeRange,
95
+ date: filters.date,
96
+ });
590
97
  }
591
- </style>
98
+ </script>
@@ -0,0 +1,59 @@
1
+ <template>
2
+ <div>
3
+ <ReportFilters
4
+ :model-value="filters"
5
+ :options="options"
6
+ @update:model-value="$emit('update:filters', $event)"
7
+ @export="$emit('export')"
8
+ />
9
+
10
+ <v-divider :thickness="1" class="border-opacity-100" />
11
+
12
+ <template v-if="report">
13
+ <ReportLocationHeader :location="report.location" />
14
+ <v-divider :thickness="1" class="border-opacity-100 mb-6" />
15
+ <SummaryReportTable :title="report.title" :rows="report.rows" />
16
+ </template>
17
+
18
+ <ReportEmptyState
19
+ v-else-if="!loading"
20
+ title="No Daily Report Selected"
21
+ message="Please select a route, time range, and date to view the daily report"
22
+ />
23
+ </div>
24
+ </template>
25
+
26
+ <script setup lang="ts">
27
+ import type {
28
+ NFCPatrolReportFilterOptions,
29
+ NFCPatrolReportFilters,
30
+ } from "../../../types/nfc-patrol-report";
31
+ import { useNFCPatrolDailyReport } from "../../../composables/useNFCPatrolDailyReport";
32
+ import ReportEmptyState from "./ReportEmptyState.vue";
33
+ import ReportFilters from "./ReportFilters.vue";
34
+ import ReportLocationHeader from "./ReportLocationHeader.vue";
35
+ import SummaryReportTable from "./SummaryReportTable.vue";
36
+
37
+ const props = defineProps<{
38
+ active: boolean;
39
+ filters: NFCPatrolReportFilters;
40
+ options: NFCPatrolReportFilterOptions;
41
+ }>();
42
+
43
+ defineEmits<{
44
+ "update:filters": [value: NFCPatrolReportFilters];
45
+ export: [];
46
+ }>();
47
+
48
+ const { report, loading, fetchReport } = useNFCPatrolDailyReport(props.filters);
49
+
50
+ watch(
51
+ () => [props.filters.route, props.filters.timeRange, props.filters.date, props.active],
52
+ () => {
53
+ if (props.active) {
54
+ void fetchReport();
55
+ }
56
+ },
57
+ { immediate: true },
58
+ );
59
+ </script>