@7365admin1/layer-common 3.1.2-staging.38 → 3.1.2

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/.github/workflows/publish-staging.yml +0 -11
  2. package/CHANGELOG.md +6 -0
  3. package/components/AddEqupmentForm.vue +1 -52
  4. package/components/CameraMain.vue +6 -5
  5. package/components/DashboardMain.vue +87 -231
  6. package/components/EquipmentManagementMain.vue +0 -56
  7. package/components/InvitationMain.vue +3 -4
  8. package/components/ManageChecklistMain.vue +38 -44
  9. package/components/Nfc/NFCPatrolReportMain.vue +38 -146
  10. package/components/Nfc/PatrolReport/DailyReportTab.vue +6 -10
  11. package/components/Nfc/PatrolReport/MonthlyReportTab.vue +9 -19
  12. package/components/Nfc/PatrolReport/PatrolActivityTable.vue +0 -20
  13. package/components/Nfc/PatrolReport/PatrolReportTab.vue +3 -5
  14. package/components/Nfc/PatrolReport/ReportFilters.vue +20 -52
  15. package/components/Nfc/PatrolReport/SummaryReportTable.vue +0 -22
  16. package/components/PhotoUpload.vue +4 -19
  17. package/components/ServiceProviderMain.vue +25 -59
  18. package/components/VisitorForm.vue +18 -78
  19. package/components/VisitorManagement.vue +16 -12
  20. package/composables/useCleaningSchedulePermission.ts +51 -16
  21. package/composables/useEquipment.ts +0 -2
  22. package/composables/useLocalAuth.ts +1 -1
  23. package/composables/useNFCPatrolDailyReport.ts +4 -3
  24. package/composables/useNFCPatrolMonthlyReport.ts +30 -62
  25. package/composables/useNFCPatrolReport.ts +0 -2
  26. package/composables/useServiceProvider.ts +0 -21
  27. package/package.json +1 -1
  28. package/types/customer.d.ts +1 -2
  29. package/types/equipment.d.ts +1 -5
  30. package/types/nfc-patrol-report.ts +1 -19
  31. package/components/Nfc/PatrolReport/MonthlyReportTable.vue +0 -69
  32. package/components/Nfc/PatrolReport/ReportDatePicker.vue +0 -61
@@ -46,19 +46,6 @@
46
46
  </v-row>
47
47
  </template>
48
48
 
49
- <template #item.attachment="{ value }">
50
- <v-btn
51
- v-if="value"
52
- size="small"
53
- variant="tonal"
54
- class="text-none"
55
- @click.stop="viewAttachment(value)"
56
- >
57
- View Image
58
- </v-btn>
59
- <span v-else>—</span>
60
- </template>
61
-
62
49
  <template #item.status="{ value }">
63
50
  <v-chip class="text-capitalize">{{ value || "N/A" }}</v-chip>
64
51
  </template>
@@ -74,7 +61,6 @@
74
61
  v-model="dialogShowForm"
75
62
  v-model:name="equipmentName"
76
63
  v-model:unitOfMeasurement="equipmentUnit"
77
- v-model:attachment="equipmentAttachment"
78
64
  :mode="dialogMode"
79
65
  :equipmentData="editingEquipment"
80
66
  :site="props.site"
@@ -256,29 +242,6 @@
256
242
  </v-card>
257
243
  </v-dialog>
258
244
 
259
- <v-dialog v-model="showAttachmentDialog" max-width="720" persistent>
260
- <v-card rounded="lg">
261
- <v-card-title class="d-flex align-center pa-4">
262
- <span class="text-h6 font-weight-bold">Attachment</span>
263
-
264
- <v-spacer />
265
-
266
- <v-btn
267
- icon="mdi-close"
268
- variant="text"
269
- size="small"
270
- @click="(showAttachmentDialog = false), (attachmentUrl = '')"
271
- />
272
- </v-card-title>
273
-
274
- <v-divider />
275
-
276
- <v-card-text class="pa-6">
277
- <v-img :src="attachmentUrl" contain />
278
- </v-card-text>
279
- </v-card>
280
- </v-dialog>
281
-
282
245
  <Snackbar
283
246
  v-model="messageSnackbar"
284
247
  :text="snackbarMessage"
@@ -290,7 +253,6 @@ import useEquipment from "../composables/useEquipment";
290
253
  import useStock from "../composables/useStock";
291
254
  import useUtils from "../composables/useUtils";
292
255
  import useEquipmentManagement from "../composables/useEquipmentManagement";
293
- import useFile from "../composables/useFile";
294
256
 
295
257
  const props = defineProps({
296
258
  orgId: { type: String, default: "" },
@@ -318,7 +280,6 @@ const siteName = ref<string>("");
318
280
  const submitting = ref(false);
319
281
 
320
282
  const headers = [
321
- { title: "Image", value: "attachment" },
322
283
  { title: "Name", value: "name" },
323
284
  { title: "Available Stock Qty", value: "qty" },
324
285
  { title: "Status", value: "status" },
@@ -332,7 +293,6 @@ const {
332
293
  deleteEquipment,
333
294
  } = useEquipment();
334
295
  const { debounce, requiredRule } = useUtils();
335
- const { getFileUrl } = useFile();
336
296
 
337
297
  const searchInput = ref("");
338
298
  const startDate = ref("");
@@ -392,21 +352,11 @@ const dialogMode = ref<"add" | "edit">("add");
392
352
  const editingEquipment = ref<Record<string, any>>({});
393
353
  const equipmentName = ref("");
394
354
  const equipmentUnit = ref("");
395
- const equipmentAttachment = ref("");
396
355
 
397
356
  const stockActionFormRef = ref<any>(null);
398
357
  const stockActionValid = ref(false);
399
358
 
400
359
  const snackbarMessage = ref("");
401
- const showAttachmentDialog = ref(false);
402
- const attachmentUrl = ref("");
403
-
404
- function viewAttachment(attachmentId: string) {
405
- if (!attachmentId) return;
406
-
407
- attachmentUrl.value = getFileUrl(attachmentId);
408
- showAttachmentDialog.value = true;
409
- }
410
360
 
411
361
  function showMessage(msg: string, color: string = "error") {
412
362
  message.value = msg;
@@ -420,7 +370,6 @@ function onCreateUnit() {
420
370
  editingEquipment.value = {};
421
371
  equipmentName.value = "";
422
372
  equipmentUnit.value = "";
423
- equipmentAttachment.value = "";
424
373
  dialogShowForm.value = true;
425
374
  }
426
375
 
@@ -430,9 +379,6 @@ async function _createEquipment() {
430
379
  const payload: TEquipmentCreate = {
431
380
  name: equipmentName.value,
432
381
  unitOfMeasurement: equipmentUnit.value,
433
- ...(equipmentAttachment.value
434
- ? { attachment: equipmentAttachment.value }
435
- : {}),
436
382
  };
437
383
 
438
384
  let response;
@@ -452,7 +398,6 @@ async function _createEquipment() {
452
398
  editingEquipment.value = {};
453
399
  equipmentName.value = "";
454
400
  equipmentUnit.value = "";
455
- equipmentAttachment.value = "";
456
401
 
457
402
  await getEquipmentsRefresh();
458
403
  } catch (error: any) {
@@ -510,7 +455,6 @@ const onEditFromMoreAction = async () => {
510
455
  editingEquipment.value = response;
511
456
  equipmentName.value = response.name || "";
512
457
  equipmentUnit.value = response.unitOfMeasurement || "";
513
- equipmentAttachment.value = response.attachment || "";
514
458
  dialogShowForm.value = true;
515
459
  };
516
460
 
@@ -221,7 +221,7 @@ const headers = computed(() => {
221
221
  title: "Status",
222
222
  value: "status",
223
223
  },
224
-
224
+
225
225
  ];
226
226
 
227
227
  if (props.status === "pending" && props.cancelInvitation) {
@@ -270,11 +270,10 @@ const {
270
270
  page: page.value,
271
271
  status: props.status,
272
272
  search: headerSearch.value,
273
- // type: "user-invite,member-invite",
274
- type: "member-invite",
273
+ type: "user-invite,member-invite",
275
274
  app: props.app,
276
275
  orgId: props.org,
277
- // siteId: props.siteId,
276
+ siteId: props.siteId,
278
277
  }),
279
278
  {
280
279
  watch: [() => props.status]
@@ -97,10 +97,7 @@
97
97
  Rejected
98
98
  </v-chip>
99
99
  </div>
100
- <div
101
- v-if="item.remarks"
102
- class="text-body-2 text-medium-emphasis"
103
- >
100
+ <div v-if="item.remarks" class="text-body-2 text-medium-emphasis">
104
101
  {{ item.remarks }}
105
102
  </div>
106
103
  <div
@@ -228,7 +225,11 @@
228
225
  <v-card-text class="pa-4">
229
226
  <v-row>
230
227
  <v-col cols="12">
231
- <InputLabel title="Remarks" :required="false" class="mb-2" />
228
+ <InputLabel
229
+ title="Remarks (Optional)"
230
+ :required="false"
231
+ class="mb-2"
232
+ />
232
233
  <v-textarea
233
234
  v-model="modalData.remark"
234
235
  placeholder="Enter your remarks here"
@@ -242,7 +243,7 @@
242
243
  <v-col cols="12">
243
244
  <v-divider class="mb-4" />
244
245
  <PhotoUpload
245
- title="Take/Upload Photos"
246
+ title="Take/Upload Photo"
246
247
  :required="false"
247
248
  v-model="modalData.photos"
248
249
  v-model:photo-ids="modalData.photoIds"
@@ -304,38 +305,31 @@
304
305
 
305
306
  <v-divider />
306
307
 
307
- <v-toolbar class="pa-0" density="compact">
308
- <v-row no-gutters>
309
- <v-col cols="6" class="pa-0">
310
- <v-btn
311
- block
312
- variant="text"
313
- class="text-none"
314
- size="large"
315
- height="48"
316
- :disabled="rejectModal.submitting"
317
- @click="closeRejectDialog"
318
- >
319
- Cancel
320
- </v-btn>
321
- </v-col>
322
-
323
- <v-col cols="6" class="pa-0">
324
- <v-btn
325
- block
326
- variant="flat"
327
- color="black"
328
- class="text-none font-weight-bold rounded-0"
329
- height="48"
330
- :loading="rejectModal.submitting"
331
- :disabled="!isRejectModalValid || rejectModal.submitting"
332
- @click="submitRejectDialog"
333
- >
334
- Confirm
335
- </v-btn>
336
- </v-col>
337
- </v-row>
338
- </v-toolbar>
308
+ <v-card-actions class="pa-0">
309
+ <v-btn
310
+ color="grey"
311
+ variant="flat"
312
+ rounded="0"
313
+ class="flex-grow-1 text-none"
314
+ height="48"
315
+ :disabled="rejectModal.submitting"
316
+ @click="closeRejectDialog"
317
+ >
318
+ Cancel
319
+ </v-btn>
320
+ <v-btn
321
+ color="error"
322
+ variant="flat"
323
+ rounded="0"
324
+ class="flex-grow-1 text-none"
325
+ height="48"
326
+ :loading="rejectModal.submitting"
327
+ :disabled="!isRejectModalValid || rejectModal.submitting"
328
+ @click="submitRejectDialog"
329
+ >
330
+ Confirm
331
+ </v-btn>
332
+ </v-card-actions>
339
333
  </v-card>
340
334
  </v-dialog>
341
335
 
@@ -441,12 +435,12 @@ const { back } = useUtils();
441
435
  const route = useRoute();
442
436
  const scheduleTitle = computed(() => {
443
437
  const path = route.path;
444
- if (path.includes("cleaning-schedule")) return "Cleaning Checklist";
445
- if (path.includes("technician-schedule")) return "Technician Checklist";
446
- if (path.includes("landscape-schedule")) return "Landscape Checklist";
447
- if (path.includes("pool-schedule")) return "Pool Checklist";
448
- if (path.includes("pest-schedule")) return "Pest Checklist";
449
- return "Cleaner Checklist";
438
+ if (path.includes('cleaning-schedule')) return 'Cleaning Checklist';
439
+ if (path.includes('technician-schedule')) return 'Technician Checklist';
440
+ if (path.includes('landscape-schedule')) return 'Landscape Checklist';
441
+ if (path.includes('pool-schedule')) return 'Pool Checklist';
442
+ if (path.includes('pest-schedule')) return 'Pest Checklist';
443
+ return 'Cleaner Checklist';
450
444
  });
451
445
 
452
446
  const canAddRemarks = computed(() => props.canAddRemarks);
@@ -14,63 +14,44 @@
14
14
  </v-col>
15
15
  </v-row>
16
16
 
17
- <v-tabs
18
- v-model="activeTab"
19
- class="mb-6"
20
- bg-color="transparent"
21
- grow
22
- >
23
- <v-tab value="patrol" class="text-none border-thin">
24
- Patrol Report
25
- </v-tab>
26
-
27
- <v-tab value="daily" class="text-none border-thin">
28
- Daily Report
29
- </v-tab>
30
-
31
- <v-tab value="monthly" class="text-none border-thin">
32
- Monthly Report
33
- </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>
19
+ <v-tab value="daily" class="text-none border-thin">Daily Report</v-tab>
20
+ <v-tab value="monthly" class="text-none border-thin">Monthly Report</v-tab>
34
21
  </v-tabs>
35
22
 
36
23
  <v-window v-model="activeTab" class="pt-4">
37
24
  <v-window-item value="patrol">
38
- <div v-if="activeTab === 'patrol'">
39
- <PatrolReportTab
40
- :active="true"
41
- :site="site"
42
- :filters="filters"
43
- :options="options"
44
- @update:filters="updateFilters"
45
- @export="exportReport"
46
- />
47
- </div>
25
+ <PatrolReportTab
26
+ :active="activeTab === 'patrol'"
27
+ :site="site"
28
+ :filters="filters"
29
+ :options="options"
30
+ @update:filters="updateFilters"
31
+ @export="exportReport"
32
+ />
48
33
  </v-window-item>
49
34
 
50
35
  <v-window-item value="daily">
51
- <div v-if="activeTab === 'daily'">
52
- <DailyReportTab
53
- :active="true"
54
- :site="site"
55
- :filters="filters"
56
- :options="options"
57
- @update:filters="updateFilters"
58
- @export="exportReport"
59
- />
60
- </div>
36
+ <DailyReportTab
37
+ :active="activeTab === 'daily'"
38
+ :site="site"
39
+ :filters="filters"
40
+ :options="options"
41
+ @update:filters="updateFilters"
42
+ @export="exportReport"
43
+ />
61
44
  </v-window-item>
62
45
 
63
46
  <v-window-item value="monthly">
64
- <div v-if="activeTab === 'monthly'">
65
- <MonthlyReportTab
66
- :active="true"
67
- :site="site"
68
- :filters="filters"
69
- :options="options"
70
- @update:filters="updateFilters"
71
- @export="exportReport"
72
- />
73
- </div>
47
+ <MonthlyReportTab
48
+ :active="activeTab === 'monthly'"
49
+ :site="site"
50
+ :filters="filters"
51
+ :options="options"
52
+ @update:filters="updateFilters"
53
+ @export="exportReport"
54
+ />
74
55
  </v-window-item>
75
56
  </v-window>
76
57
  </v-col>
@@ -78,20 +59,15 @@
78
59
  </template>
79
60
 
80
61
  <script setup lang="ts">
81
- import html2canvas from "html2canvas";
82
- import jsPDF from "jspdf";
83
-
84
62
  import type {
85
63
  NFCPatrolReportFilters,
86
64
  NFCPatrolReportTab,
87
65
  } from "../../types/nfc-patrol-report";
88
-
66
+ import { useNFCPatrolReportExport } from "../../composables/useNFCPatrolReportExport";
89
67
  import { useNFCPatrolReportFilters } from "../../composables/useNFCPatrolReportFilters";
90
-
91
- import PatrolReportTab from "./PatrolReport/PatrolReportTab.vue";
92
68
  import DailyReportTab from "./PatrolReport/DailyReportTab.vue";
93
69
  import MonthlyReportTab from "./PatrolReport/MonthlyReportTab.vue";
94
-
70
+ import PatrolReportTab from "./PatrolReport/PatrolReportTab.vue";
95
71
 
96
72
  const props = defineProps<{
97
73
  site: string;
@@ -99,16 +75,11 @@ const props = defineProps<{
99
75
  }>();
100
76
 
101
77
  const router = useRouter();
102
-
103
-
104
78
  const activeTab = ref<NFCPatrolReportTab>("patrol");
79
+ const { filters, options, fetchOptions } = useNFCPatrolReportFilters(props.site);
80
+ const { exportReport: exportActiveReport } = useNFCPatrolReportExport();
105
81
 
106
- const { filters, options, fetchOptions } =
107
- useNFCPatrolReportFilters(props.site);
108
-
109
- onMounted(() => {
110
- fetchOptions();
111
- });
82
+ onMounted(fetchOptions);
112
83
 
113
84
  function goBack() {
114
85
  router.back();
@@ -120,90 +91,11 @@ function updateFilters(value: NFCPatrolReportFilters) {
120
91
  filters.date = value.date;
121
92
  }
122
93
 
123
- async function exportReport(type: "pdf" | "csv") {
124
- const report = document.querySelector(
125
- ".report-export",
126
- ) as HTMLElement | null;
127
-
128
- if (!report) return;
129
-
130
- if (type === "pdf") {
131
- const canvas = await html2canvas(report, {
132
- scale: 2,
133
- useCORS: true,
134
- backgroundColor: "#fff",
135
- });
136
-
137
- const pdf = new jsPDF("p", "mm", "a4");
138
-
139
- const pdfWidth = pdf.internal.pageSize.getWidth();
140
- const pdfHeight = pdf.internal.pageSize.getHeight();
141
-
142
- const imgWidth = pdfWidth;
143
- const imgHeight = (canvas.height * imgWidth) / canvas.width;
144
-
145
- const imgData = canvas.toDataURL("image/png");
146
-
147
- let heightLeft = imgHeight;
148
- let position = 0;
149
-
150
- pdf.addImage(imgData, "PNG", 0, position, imgWidth, imgHeight);
151
-
152
- heightLeft -= pdfHeight;
153
-
154
- while (heightLeft > 0) {
155
- position -= pdfHeight;
156
-
157
- pdf.addPage();
158
- pdf.addImage(imgData, "PNG", 0, position, imgWidth, imgHeight);
159
-
160
- heightLeft -= pdfHeight;
161
- }
162
-
163
- pdf.save(`${activeTab.value}-report.pdf`);
164
- return;
165
- }
166
-
167
- const table = report.querySelector("table");
168
-
169
- if (!table) return;
170
-
171
- const csv = Array.from(table.querySelectorAll("tr"))
172
- .map((row) =>
173
- Array.from(row.querySelectorAll("th,td"))
174
- .map((cell) => escapeCsvCell(getCsvCellValue(cell)))
175
- .join(","),
176
- )
177
- .join("\n");
178
-
179
- const blob = new Blob([csv], {
180
- type: "text/csv;charset=utf-8;",
94
+ async function exportReport() {
95
+ await exportActiveReport(activeTab.value, {
96
+ route: filters.route,
97
+ timeRange: filters.timeRange,
98
+ date: filters.date,
181
99
  });
182
-
183
- const link = document.createElement("a");
184
-
185
- link.href = URL.createObjectURL(blob);
186
- link.download = `${activeTab.value}-report.csv`;
187
- link.click();
188
-
189
- URL.revokeObjectURL(link.href);
190
- }
191
-
192
- function getCsvCellValue(cell: Element) {
193
- const image = cell.querySelector("img");
194
-
195
- if (image) {
196
- const imageUrl = image.currentSrc || image.src;
197
-
198
- if (imageUrl) {
199
- return imageUrl;
200
- }
201
- }
202
-
203
- return cell.textContent?.trim() ?? "";
204
- }
205
-
206
- function escapeCsvCell(value: string) {
207
- return `"${value.replace(/"/g, '""')}"`;
208
100
  }
209
101
  </script>
@@ -3,11 +3,10 @@
3
3
  <ReportFilters
4
4
  :model-value="filters"
5
5
  :options="options"
6
- :show-time-filter="false"
7
6
  @update:model-value="$emit('update:filters', $event)"
8
- @export="(type) => $emit('export', type)"
7
+ @export="$emit('export')"
9
8
  />
10
- <div class="report-export">
9
+
11
10
  <v-divider :thickness="1" class="border-opacity-100" />
12
11
 
13
12
  <template v-if="report">
@@ -16,7 +15,6 @@
16
15
  <SummaryReportTable :title="report.title" :rows="report.rows" />
17
16
  </template>
18
17
 
19
-
20
18
  <ReportEmptyState
21
19
  v-else-if="!loading && notFound"
22
20
  title="No Daily Report"
@@ -24,7 +22,6 @@
24
22
  />
25
23
 
26
24
  <ReportEmptyState v-else-if="!loading" />
27
- </div>
28
25
  </div>
29
26
  </template>
30
27
 
@@ -41,23 +38,23 @@ import SummaryReportTable from "./SummaryReportTable.vue";
41
38
 
42
39
  const props = defineProps<{
43
40
  active: boolean;
44
- site: string;
41
+ site: string; // ✅ thêm
45
42
  filters: NFCPatrolReportFilters;
46
43
  options: NFCPatrolReportFilterOptions;
47
44
  }>();
48
45
 
49
46
  defineEmits<{
50
47
  "update:filters": [value: NFCPatrolReportFilters];
51
- export: [type: "pdf" | "csv"];
48
+ export: [];
52
49
  }>();
53
50
 
54
51
  const { report, loading, notFound, fetchReport } = useNFCPatrolDailyReport(
55
52
  props.filters,
56
- props.site,
53
+ props.site, // ✅
57
54
  );
58
55
 
59
56
  watch(
60
- () => [props.filters.route, props.filters.date, props.active],
57
+ () => [props.filters.route, props.filters.timeRange, props.filters.date, props.active],
61
58
  () => {
62
59
  if (props.active) {
63
60
  void fetchReport();
@@ -65,5 +62,4 @@ watch(
65
62
  },
66
63
  { immediate: true },
67
64
  );
68
-
69
65
  </script>
@@ -3,30 +3,23 @@
3
3
  <ReportFilters
4
4
  :model-value="filters"
5
5
  :options="options"
6
- :show-time-filter="false"
7
- :show-date-filter="false"
8
6
  @update:model-value="$emit('update:filters', $event)"
9
- @export="(type) => $emit('export', type)"
7
+ @export="$emit('export')"
10
8
  />
11
- <div class="report-export">
9
+
12
10
  <v-divider :thickness="1" class="border-opacity-100" />
13
11
 
14
12
  <template v-if="report">
15
13
  <ReportLocationHeader :location="report.location" />
16
14
  <v-divider :thickness="1" class="border-opacity-100 mb-6" />
17
-
18
- <MonthlyReportTable
19
- :title="report.title"
20
- :rows="report.rows"
21
- />
15
+ <SummaryReportTable :title="report.title" :rows="report.rows" />
22
16
  </template>
23
17
 
24
18
  <ReportEmptyState
25
19
  v-else-if="!loading"
26
- title="No Monthly Report"
27
- message="No patrol log found for this route"
20
+ title="No Monthly Report Selected"
21
+ message="Please select a route, time range, and date to view the monthly report"
28
22
  />
29
- </div>
30
23
  </div>
31
24
  </template>
32
25
 
@@ -35,13 +28,11 @@ import type {
35
28
  NFCPatrolReportFilterOptions,
36
29
  NFCPatrolReportFilters,
37
30
  } from "../../../types/nfc-patrol-report";
38
-
39
31
  import { useNFCPatrolMonthlyReport } from "../../../composables/useNFCPatrolMonthlyReport";
40
-
41
32
  import ReportEmptyState from "./ReportEmptyState.vue";
42
33
  import ReportFilters from "./ReportFilters.vue";
43
34
  import ReportLocationHeader from "./ReportLocationHeader.vue";
44
- import MonthlyReportTable from "./MonthlyReportTable.vue";
35
+ import SummaryReportTable from "./SummaryReportTable.vue";
45
36
 
46
37
  const props = defineProps<{
47
38
  active: boolean;
@@ -52,14 +43,14 @@ const props = defineProps<{
52
43
 
53
44
  defineEmits<{
54
45
  "update:filters": [value: NFCPatrolReportFilters];
55
- export: [type: "pdf" | "csv"];
46
+ export: [];
56
47
  }>();
57
48
 
58
- const { report, loading, notFound, fetchReport } =
49
+ const { report, loading, fetchReport } =
59
50
  useNFCPatrolMonthlyReport(props.filters, props.site);
60
51
 
61
52
  watch(
62
- () => [props.filters.route, props.active],
53
+ () => [props.filters.route, props.filters.timeRange, props.filters.date, props.active],
63
54
  () => {
64
55
  if (props.active) {
65
56
  void fetchReport();
@@ -67,5 +58,4 @@ watch(
67
58
  },
68
59
  { immediate: true },
69
60
  );
70
-
71
61
  </script>
@@ -7,8 +7,6 @@
7
7
  <thead>
8
8
  <tr>
9
9
  <th>Checkpoints</th>
10
- <th>Security Personnel</th>
11
- <th>Signature</th>
12
10
  <th>Start - End Time</th>
13
11
  <th>
14
12
  Travel time<br />
@@ -25,17 +23,6 @@
25
23
  @click="handleActivityClick(activity)"
26
24
  >
27
25
  <td>{{ activity.checkpoint }}</td>
28
- <td>{{ activity.guardName || "-" }}</td>
29
- <td>
30
- <v-img
31
- v-if="activity.guardSignatureFileId"
32
- :src="getFileUrl(activity.guardSignatureFileId)"
33
- :alt="`${activity.guardName || 'Guard'} signature`"
34
- class="guard-signature"
35
- contain
36
- />
37
- <span v-else>-</span>
38
- </td>
39
26
  <td>
40
27
  <v-icon size="small" class="mr-1">mdi-clock-outline</v-icon>
41
28
  {{ activity.startTime }}
@@ -72,8 +59,6 @@ defineProps<{
72
59
  activities: NFCPatrolActivity[];
73
60
  }>();
74
61
 
75
- const { getFileUrl } = useFile();
76
-
77
62
  const emit = defineEmits<{
78
63
  remarks: [activity: NFCPatrolActivity];
79
64
  }>();
@@ -93,9 +78,4 @@ function handleActivityClick(activity: NFCPatrolActivity) {
93
78
  .cursor-pointer {
94
79
  cursor: pointer;
95
80
  }
96
-
97
- .guard-signature {
98
- width: 80px;
99
- height: 40px;
100
- }
101
81
  </style>