@7365admin1/layer-common 1.11.20 → 1.11.21

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.
@@ -1,34 +1,95 @@
1
1
  <template>
2
2
  <v-row no-gutters>
3
- <TableMain :headers="headers" :items="items" :loading="getVisitorPending" :page="page" :pages="pages"
4
- :extension-height="110" :offset="300" :pageRange="pageRange" :canCreate="canAddVisitor"
5
- @refresh="getVisitorRefresh" @update:page="handleUpdatePage" createLabel="Add Visitor" show-header
6
- @row-click="handleRowClick" @create="handleAddNew">
3
+ <TableMain
4
+ :headers="headers"
5
+ :items="items"
6
+ :loading="getVisitorPending"
7
+ :page="page"
8
+ :pages="pages"
9
+ :extension-height="110"
10
+ :offset="300"
11
+ :pageRange="pageRange"
12
+ :canCreate="canAddVisitor"
13
+ :canScanVisitorQRCode="canScanVisitorQRCode"
14
+ @refresh="getVisitorRefresh"
15
+ @update:page="handleUpdatePage"
16
+ createLabel="Add Visitor"
17
+ show-header
18
+ @row-click="handleRowClick"
19
+ @create="handleAddNew"
20
+ @scan="dialog.scanVisitorQRCode = true"
21
+ >
7
22
  <template #extension>
8
23
  <v-row no-gutters class="w-100 d-flex flex-column">
9
- <v-tabs v-model="activeTab" color="primary" :height="40" @update:model-value="toRoute" class="w-100">
10
- <v-tab v-for="tab in tabOptions" :value="tab.value" :key="tab.value" class="text-capitalize">
24
+ <v-tabs
25
+ v-model="activeTab"
26
+ color="primary"
27
+ :height="40"
28
+ @update:model-value="toRoute"
29
+ class="w-100"
30
+ >
31
+ <v-tab
32
+ v-for="tab in tabOptions"
33
+ :value="tab.value"
34
+ :key="tab.value"
35
+ class="text-capitalize"
36
+ >
11
37
  {{ tab.name }}
12
38
  </v-tab>
13
39
  </v-tabs>
14
40
 
15
- <v-card class="w-100 px-3 d-flex align-center ga-5 py-2" flat :height="60">
16
- <v-text-field v-model="searchInput" density="compact" placeholder="Search" clearable max-width="300"
17
- append-inner-icon="mdi-magnify" hide-details />
18
- <v-checkbox v-model="displayNotCheckedOut" class="text-subtitle-2" hide-details>
41
+ <v-card
42
+ class="w-100 px-3 d-flex align-center ga-5 py-2"
43
+ flat
44
+ :height="60"
45
+ >
46
+ <v-text-field
47
+ v-model="searchInput"
48
+ density="compact"
49
+ placeholder="Search"
50
+ clearable
51
+ max-width="300"
52
+ append-inner-icon="mdi-magnify"
53
+ hide-details
54
+ />
55
+ <v-checkbox
56
+ v-model="displayNotCheckedOut"
57
+ class="text-subtitle-2"
58
+ hide-details
59
+ >
19
60
  <template #label>
20
61
  <span class="text-caption">Not Checked Out</span>
21
62
  </template>
22
63
  </v-checkbox>
23
- <InputDatePicker v-model="dateFrom" density="compact" hide-details />
64
+ <InputDatePicker
65
+ v-model="dateFrom"
66
+ density="compact"
67
+ hide-details
68
+ />
24
69
  <InputDatePicker v-model="dateTo" density="compact" hide-details />
25
- <v-select v-if="activeTab == 'registered'" v-model="filterTypes" label="Filter by types" item-title="label"
26
- item-value="value" :items="visitorSelection" density="compact" clearable multiple max-width="200"
27
- hide-details>
70
+ <v-select
71
+ v-if="activeTab == 'registered'"
72
+ v-model="filterTypes"
73
+ label="Filter by types"
74
+ item-title="label"
75
+ item-value="value"
76
+ :items="visitorSelection"
77
+ density="compact"
78
+ clearable
79
+ multiple
80
+ max-width="200"
81
+ hide-details
82
+ >
28
83
  <template v-slot:selection="{ item, index }">
29
84
  <div class="d-flex align-center text-caption text-nowrap">
30
- <v-chip v-if="index === 0" color="error" :text="filterTypeSelectionLabel()" size="x-small"
31
- variant="tonal" class="ml-2" />
85
+ <v-chip
86
+ v-if="index === 0"
87
+ color="error"
88
+ :text="filterTypeSelectionLabel()"
89
+ size="x-small"
90
+ variant="tonal"
91
+ class="ml-2"
92
+ />
32
93
  </div>
33
94
  </template>
34
95
  </v-select>
@@ -43,8 +104,9 @@
43
104
  </span>
44
105
  <span class="text-capitalize">{{ item?.name }}</span>
45
106
  </span>
46
- <span class="text-grey text-caption" v-if="item?.members?.length > 0">( +{{ item?.members?.length }}
47
- members)</span>
107
+ <span class="text-grey text-caption" v-if="item?.members?.length > 0"
108
+ >( +{{ item?.members?.length }} members)</span
109
+ >
48
110
  </template>
49
111
 
50
112
  <template v-slot:item.type-company="{ item }">
@@ -52,7 +114,7 @@
52
114
  <v-icon icon="mdi-user" size="15" />
53
115
  <span v-if="item.type === 'contractor'" class="text-capitalize">{{
54
116
  formatCamelCaseToWords(item.contractorType)
55
- }}</span>
117
+ }}</span>
56
118
  <span v-else class="text-capitalize">{{ formatType(item) }}</span>
57
119
  </span>
58
120
  <span class="d-flex align-center ga-2">
@@ -88,109 +150,255 @@
88
150
  <template v-slot:item.checkin-out="{ item }">
89
151
  <v-row no-gutters class="d-flex flex-column py-2">
90
152
  <span class="d-flex align-center ga-2">
91
- <v-icon icon="mdi-clock-time-four-outline" color="green" size="20" />
153
+ <v-icon
154
+ icon="mdi-clock-time-four-outline"
155
+ color="green"
156
+ size="20"
157
+ />
92
158
  <span class="text-capitalize">{{
93
159
  UTCToLocalTIme(item.checkIn) || "-"
94
160
  }}</span>
95
161
  <span>
96
- <v-icon v-if="item?.snapshotEntryImage" size="17" icon="mdi-image"
97
- @click.stop="handleViewImage(item.snapshotEntryImage)" />
162
+ <v-icon
163
+ v-if="item?.snapshotEntryImage"
164
+ size="17"
165
+ icon="mdi-image"
166
+ @click.stop="handleViewImage(item.snapshotEntryImage)"
167
+ />
98
168
  </span>
99
169
  </span>
100
- <span class="d-flex align-center ga-2">
170
+
171
+ <span
172
+ v-if="
173
+ !item.checkOut &&
174
+ (item?.status === 'registered' ||
175
+ item?.status === 'unregistered') &&
176
+ canCheckoutVisitor
177
+ "
178
+ >
179
+ <span
180
+ class="d-flex align-center ga-2"
181
+ v-bind="menuProps"
182
+ style="cursor: pointer"
183
+ >
184
+ <v-icon
185
+ icon="mdi-clock-time-eight-outline"
186
+ color="red"
187
+ size="20"
188
+ />
189
+ <v-btn
190
+ size="x-small"
191
+ class="text-capitalize"
192
+ color="red"
193
+ text="Checkout"
194
+ :loading="
195
+ loading.checkingOut && item?._id === selectedVisitorId
196
+ "
197
+ />
198
+ </span>
199
+ </span>
200
+ <span v-else class="d-flex align-center ga-2">
101
201
  <v-icon icon="mdi-clock-time-eight-outline" color="red" size="20" />
102
202
  <template v-if="item.checkOut">
103
203
  <span class="text-capitalize">{{
104
204
  UTCToLocalTIme(item.checkOut) || "-"
105
205
  }}</span>
106
206
  <span>
107
- <v-icon v-if="item?.snapshotExitImage" size="17" icon="mdi-image"
108
- @click.stop="handleViewImage(item.snapshotExitImage)" />
207
+ <v-icon
208
+ v-if="item?.snapshotExitImage"
209
+ size="17"
210
+ icon="mdi-image"
211
+ @click.stop="handleViewImage(item.snapshotExitImage)"
212
+ />
109
213
  </span>
110
214
  <span v-if="item?.manualCheckout">
111
- <TooltipInfo text="Manual Checkout" density="compact" size="x-small" />
215
+ <TooltipInfo
216
+ text="Manual Checkout"
217
+ density="compact"
218
+ size="x-small"
219
+ />
112
220
  </span>
113
221
  </template>
114
- <span v-else-if="!item?.checkOut && (item?.status === 'registered' || item?.status === 'unregistered')">
115
- <v-btn size="x-small" class="text-capitalize" color="red" text="Checkout"
116
- :loading="loading.checkingOut && item?._id === selectedVisitorId" @click.stop="handleCheckout(item._id)"
117
- v-if="canCheckoutVisitor" />
118
- </span>
119
222
  </span>
120
- <div v-if="(item.visitorPass?.length ?? 0) > 0 || (item.passKeys?.length ?? 0) > 0"
121
- class="d-flex flex-wrap ga-1 mt-1" @click.stop="handleCheckout(item._id)">
122
- <v-chip v-for="pass in item.visitorPass" :key="(pass as any)._id ?? (pass as any).keyId"
123
- prepend-icon="mdi-card-bulleted-outline" size="x-small" variant="tonal" color="blue">
124
- {{ (pass as any)?.prefixAndName }}
125
- </v-chip>
126
- <v-chip v-for="key in item.passKeys" :key="(key as any)._id ?? (key as any).keyId" prepend-icon="mdi-key"
127
- size="x-small" variant="tonal" color="orange">
128
- {{ (key as any)?.prefixAndName }}
129
- </v-chip>
130
- </div>
131
- <div v-if="showAddPassKeyButton(item)" class="d-flex flex-wrap ga-1 mt-1 mt-2"
132
- @click.stop="handleCheckout(item._id)">
133
- <v-chip size="x-small" variant="tonal" prepend-icon="mdi-key" @click.stop="handleOpenAddPassKey(item)">
134
- Add Pass/Key
135
- </v-chip>
136
223
 
224
+ <div
225
+ v-if="showAddPassKeyButton(item)"
226
+ class="d-flex flex-wrap ga-1 mt-1"
227
+ v-bind="menuProps"
228
+ style="cursor: pointer"
229
+ >
230
+ <v-chip
231
+ size="x-small"
232
+ variant="tonal"
233
+ prepend-icon="mdi-key"
234
+ @click.stop="handleOpenAddPassKey(item)"
235
+ >Add Pass/Key</v-chip
236
+ >
137
237
  </div>
238
+
239
+ <v-menu :close-on-content-click="true">
240
+ <template v-slot:activator="{ props: menuProps }">
241
+ <div
242
+ v-if="
243
+ (item.visitorPass?.length ?? 0) > 0 ||
244
+ (item.passKeys?.length ?? 0) > 0
245
+ "
246
+ class="d-flex flex-wrap ga-1 mt-1"
247
+ v-bind="menuProps"
248
+ style="cursor: pointer"
249
+ >
250
+ <v-chip
251
+ v-for="pass in item.visitorPass"
252
+ :key="(pass as any)._id ?? (pass as any).keyId"
253
+ prepend-icon="mdi-card-bulleted-outline"
254
+ size="x-small"
255
+ variant="tonal"
256
+ color="blue"
257
+ >
258
+ {{ (pass as any)?.prefixAndName }}
259
+ </v-chip>
260
+ <v-chip
261
+ v-for="key in item.passKeys"
262
+ :key="(key as any)._id ?? (key as any).keyId"
263
+ prepend-icon="mdi-key"
264
+ size="x-small"
265
+ variant="tonal"
266
+ color="orange"
267
+ >
268
+ {{ (key as any)?.prefixAndName }}
269
+ </v-chip>
270
+ </div>
271
+ </template>
272
+ <v-list density="compact">
273
+ <v-list-item
274
+ prepend-icon="mdi-logout"
275
+ title="Checkout"
276
+ @click.stop="handleCheckout(item._id)"
277
+ />
278
+ <v-list-item
279
+ v-if="
280
+ (item.visitorPass?.length ?? 0) > 0 ||
281
+ (item.passKeys?.length ?? 0) > 0
282
+ "
283
+ prepend-icon="mdi-card-bulleted-outline"
284
+ :title="item.checkOut ? 'View Pass/Key' : 'Edit Pass/Key'"
285
+ @click.stop="handleOpenEditPassKey(item)"
286
+ />
287
+ <v-list-item
288
+ v-if="showAddPassKeyButton(item)"
289
+ prepend-icon="mdi-plus"
290
+ title="Add Pass/Key"
291
+ @click.stop="handleOpenAddPassKey(item)"
292
+ />
293
+ </v-list>
294
+ </v-menu>
138
295
  </v-row>
139
296
  </template>
140
297
 
141
298
  <template v-slot:item.action="{ item }">
142
- <v-btn v-if="activeTab === 'unregistered' && canAddVisitor" size="small" color="primary" text="Register"
143
- @click.stop="handleRegistrationUnregisteredVisitor(item)" />
299
+ <v-btn
300
+ v-if="activeTab === 'unregistered' && canAddVisitor"
301
+ size="small"
302
+ color="primary"
303
+ text="Register"
304
+ @click.stop="handleRegistrationUnregisteredVisitor(item)"
305
+ />
144
306
  </template>
145
307
 
146
308
  <template v-slot:item.checkInRemarks="{ item }">
147
309
  <span>
148
- <v-btn variant="text" color="blue-darken-2" density="compact" size="small"
149
- @click.stop="handleOpenRemarks(item, 'checkIn')">{{ item.checkInRemarks ? "View Remarks" : "Add Remarks"
150
- }}</v-btn>
310
+ <v-btn
311
+ variant="text"
312
+ color="blue-darken-2"
313
+ density="compact"
314
+ size="small"
315
+ @click.stop="handleOpenRemarks(item, 'checkIn')"
316
+ >{{ item.checkInRemarks ? "View Remarks" : "Add Remarks" }}</v-btn
317
+ >
151
318
  </span>
152
319
  </template>
153
320
  <template v-slot:item.checkOutRemarks="{ item }">
154
321
  <span>
155
- <v-btn variant="text" color="blue-darken-2" density="compact" size="small"
156
- @click.stop="handleOpenRemarks(item, 'checkOut')">{{ item.checkOutRemarks ? "View Remarks" : "Add Remarks"
157
- }}</v-btn>
322
+ <v-btn
323
+ variant="text"
324
+ color="blue-darken-2"
325
+ density="compact"
326
+ size="small"
327
+ @click.stop="handleOpenRemarks(item, 'checkOut')"
328
+ >{{ item.checkOutRemarks ? "View Remarks" : "Add Remarks" }}</v-btn
329
+ >
158
330
  </span>
159
331
  </template>
160
-
161
332
  </TableMain>
162
333
 
163
334
  <v-dialog v-model="dialog.showSelection" width="450" persistent>
164
- <VisitorFormSelection :mode="mode" @cancel="dialog.showSelection = false" @select="handleSelectVisitorType" />
335
+ <VisitorFormSelection
336
+ :mode="mode"
337
+ @cancel="dialog.showSelection = false"
338
+ @select="handleSelectVisitorType"
339
+ />
165
340
  </v-dialog>
166
341
 
167
- <v-dialog v-model="dialog.showForm" v-if="activeVisitorFormType" width="450" persistent>
168
- <VisitorForm :mode="mode" :org="orgId" :site="siteId" :visitor-data="selectedVisitorDataObject"
169
- :type="activeVisitorFormType" @back="handleClickBack" @done="handleVisitorFormDone"
170
- @done:more="handleVisitorFormCreateMore" @close:all="handleCloseAll" />
342
+ <v-dialog
343
+ v-model="dialog.showForm"
344
+ v-if="activeVisitorFormType"
345
+ width="450"
346
+ persistent
347
+ >
348
+ <VisitorForm
349
+ :mode="mode"
350
+ :org="orgId"
351
+ :site="siteId"
352
+ :visitor-data="selectedVisitorDataObject"
353
+ :type="activeVisitorFormType"
354
+ @back="handleClickBack"
355
+ @done="handleVisitorFormDone"
356
+ @done:more="handleVisitorFormCreateMore"
357
+ @close:all="handleCloseAll"
358
+ />
171
359
  </v-dialog>
172
360
 
173
361
  <v-dialog v-model="dialog.viewVisitor" width="450" persistent>
174
- <VehicleUpdateMoreAction title="Preview" :can-update="false" :can-delete="canDeleteVisitor"
175
- @close="dialog.viewVisitor = false" edit-button-label="Edit Visitor" delete-button-label="Delete Visitor"
176
- @delete="handleDeleteVisitor">
362
+ <VehicleUpdateMoreAction
363
+ title="Preview"
364
+ :can-update="false"
365
+ :can-delete="false"
366
+ @close="dialog.viewVisitor = false"
367
+ edit-button-label="Edit Visitor"
368
+ >
177
369
  <template v-slot:content>
178
370
  <v-row no-gutters class="mb-4">
179
371
  <v-col v-for="(label, key) in formattedFields" :key="key" cols="12">
180
- <span v-if="
181
- key === 'checkOut' &&
182
- !selectedVisitorObject[key] &&
183
- canCheckoutVisitor
184
- " class="d-flex align-center">
372
+ <span
373
+ v-if="
374
+ key === 'checkOut' &&
375
+ !selectedVisitorObject[key] &&
376
+ canCheckoutVisitor
377
+ "
378
+ class="d-flex align-center"
379
+ >
185
380
  <strong>{{ label }}:</strong>
186
- <v-btn size="x-small" class="ml-3 text-capitalize" color="red" text="Checkout"
187
- :disabled="loading.checkingOut" @click="handleCheckout(selectedVisitorId as string)" />
381
+ <v-btn
382
+ size="x-small"
383
+ class="ml-3 text-capitalize"
384
+ color="red"
385
+ text="Checkout"
386
+ :disabled="loading.checkingOut"
387
+ @click="handleCheckout(selectedVisitorId as string)"
388
+ />
188
389
  </span>
189
390
 
190
- <span v-else-if="selectedVisitorObject[key]" class="d-flex ga-3 align-center"><strong>{{ label
191
- }}:</strong>
391
+ <span
392
+ v-else-if="selectedVisitorObject[key]"
393
+ class="d-flex ga-3 align-center"
394
+ ><strong>{{ label }}:</strong>
192
395
  {{ formatValues(key, selectedVisitorObject[key]) }}
193
- <TooltipInfo v-if="key === 'checkOut'" text="Manual Checkout" density="compact" size="x-small" />
396
+ <TooltipInfo
397
+ v-if="key === 'checkOut'"
398
+ text="Manual Checkout"
399
+ density="compact"
400
+ size="x-small"
401
+ />
194
402
  </span>
195
403
  </v-col>
196
404
  </v-row>
@@ -198,17 +406,15 @@
198
406
  </VehicleUpdateMoreAction>
199
407
  </v-dialog>
200
408
 
201
- <v-dialog v-model="dialog.deleteConfirmation" width="450" persistent>
202
- <CardDeleteConfirmation prompt-title="Are you sure want to delete this visitor?"
203
- :loading="loading.deletingVisitor" @close="dialog.deleteConfirmation = false"
204
- @delete="handleProceedDeleteVisitor" />
205
- </v-dialog>
206
-
207
409
  <v-dialog v-model="dialog.snapshotImage" max-width="700">
208
410
  <v-card>
209
411
  <v-card-title class="d-flex justify-space-between align-center">
210
412
  <span>Snapshot</span>
211
- <v-btn icon="mdi-close" variant="text" @click="dialog.snapshotImage = false" />
413
+ <v-btn
414
+ icon="mdi-close"
415
+ variant="text"
416
+ @click="dialog.snapshotImage = false"
417
+ />
212
418
  </v-card-title>
213
419
  <v-card-text class="pa-2 d-flex justify-center">
214
420
  <v-img :src="snapshotImageUrl" max-height="600" contain />
@@ -218,23 +424,51 @@
218
424
 
219
425
  <v-dialog v-model="dialog.remarks" max-width="450" persistent>
220
426
  <v-card>
221
- <v-card-title class="d-flex justify-space-between align-center pt-4 px-4">
222
- <span>{{ remarksType === 'checkIn' ? 'Check-In Remarks' : 'Check-Out Remarks' }}</span>
223
- <v-btn icon="mdi-close" variant="text" @click="dialog.remarks = false" />
427
+ <v-card-title
428
+ class="d-flex justify-space-between align-center pt-4 px-4"
429
+ >
430
+ <span>{{
431
+ remarksType === "checkIn" ? "Check-In Remarks" : "Check-Out Remarks"
432
+ }}</span>
433
+ <v-btn
434
+ icon="mdi-close"
435
+ variant="text"
436
+ @click="dialog.remarks = false"
437
+ />
224
438
  </v-card-title>
225
439
  <v-card-text class="px-4 pb-2">
226
- <v-textarea v-model="remarksInput" label="Remarks" rows="4" auto-grow variant="outlined"
227
- :readonly="remarksViewOnly" />
440
+ <v-textarea
441
+ v-model="remarksInput"
442
+ label="Remarks"
443
+ rows="4"
444
+ auto-grow
445
+ variant="outlined"
446
+ :readonly="remarksViewOnly"
447
+ />
228
448
  </v-card-text>
229
449
  <v-toolbar class="pa-0" density="compact">
230
450
  <v-row no-gutters>
231
451
  <v-col cols="6">
232
- <v-btn variant="text" block :disabled="loading.savingRemarks"
233
- @click="dialog.remarks = false">Cancel</v-btn>
452
+ <v-btn
453
+ variant="text"
454
+ block
455
+ :disabled="loading.savingRemarks"
456
+ @click="dialog.remarks = false"
457
+ >Cancel</v-btn
458
+ >
234
459
  </v-col>
235
460
  <v-col cols="6">
236
- <v-btn color="primary" variant="flat" height="48" rounded="0" block :loading="loading.savingRemarks"
237
- :disabled="!remarksInput.trim()" @click="handleSaveRemarks">Save</v-btn>
461
+ <v-btn
462
+ color="primary"
463
+ variant="flat"
464
+ height="48"
465
+ rounded="0"
466
+ block
467
+ :loading="loading.savingRemarks"
468
+ :disabled="!remarksInput.trim()"
469
+ @click="handleSaveRemarks"
470
+ >Save</v-btn
471
+ >
238
472
  </v-col>
239
473
  </v-row>
240
474
  </v-toolbar>
@@ -244,54 +478,134 @@
244
478
  <v-dialog v-model="dialog.returnPassesKeys" max-width="450" persistent>
245
479
  <v-card>
246
480
  <v-toolbar density="compact" color="">
247
- <v-row no-gutters class="d-flex fill-height justify-space-between align-center px-4">
481
+ <v-row
482
+ no-gutters
483
+ class="d-flex fill-height justify-space-between align-center px-4"
484
+ >
248
485
  <span class="font-weight-bold">Return Passes &amp; Keys</span>
249
- <v-btn icon="mdi-close" variant="text" @click="dialog.returnPassesKeys = false" />
486
+ <v-btn
487
+ icon="mdi-close"
488
+ variant="text"
489
+ @click="dialog.returnPassesKeys = false"
490
+ />
250
491
  </v-row>
251
492
  </v-toolbar>
252
493
  <v-card-text class="px-4 pb-2">
253
- <p class="text-body-2 mb-3">Please ensure all passes and keys are returned before checking out.</p>
494
+ <p class="text-body-2 mb-3">
495
+ Please ensure all passes and keys are returned before checking out.
496
+ </p>
254
497
  <div v-if="passReturnStatuses.length > 0" class="mb-2">
255
498
  <p class="text-caption text-medium-emphasis mb-1">Passes</p>
256
- <v-row no-gutters v-for="pass in passReturnStatuses" :key="(pass as any)._id ?? (pass as any).keyId"
257
- class="d-flex flex-wrap justify-space-between align-center ga-5 mb-2">
258
- <v-chip prepend-icon="mdi-card-bulleted-outline" size="small" variant="tonal" color="blue">
499
+ <v-row
500
+ no-gutters
501
+ v-for="pass in passReturnStatuses"
502
+ :key="(pass as any)._id ?? (pass as any).keyId"
503
+ class="d-flex flex-wrap justify-space-between align-center ga-5 mb-2"
504
+ >
505
+ <v-chip
506
+ prepend-icon="mdi-card-bulleted-outline"
507
+ size="small"
508
+ variant="tonal"
509
+ color="blue"
510
+ >
259
511
  {{ (pass as any)?.prefixAndName }}
260
512
  </v-chip>
261
- <v-select hide-details max-width="200px" density="compact" :items="passStatusOptions" item-title="label"
262
- item-value="value" v-model="pass.status" :disabled="selectedVisitorObject.checkOut"></v-select>
263
- <v-textarea v-if="pass.status === 'Lost' || pass.status === 'Damaged'" no-resize rows="3" class="w-100"
264
- density="compact" v-model="pass.remarks" :disabled="selectedVisitorObject.checkOut"></v-textarea>
513
+ <v-select
514
+ hide-details
515
+ max-width="200px"
516
+ density="compact"
517
+ :items="passStatusOptions"
518
+ item-title="label"
519
+ item-value="value"
520
+ v-model="pass.status"
521
+ :disabled="selectedVisitorObject.checkOut"
522
+ ></v-select>
523
+ <v-textarea
524
+ v-if="pass.status === 'Lost' || pass.status === 'Damaged'"
525
+ no-resize
526
+ rows="3"
527
+ class="w-100"
528
+ density="compact"
529
+ v-model="pass.remarks"
530
+ :disabled="selectedVisitorObject.checkOut"
531
+ ></v-textarea>
265
532
  </v-row>
266
533
  </div>
267
- <div v-if="(keyReturnStatuses.length > 0)" class="mb-2">
534
+ <div v-if="keyReturnStatuses.length > 0" class="mb-2">
268
535
  <p class="text-caption text-medium-emphasis mb-1">Keys</p>
269
- <v-row no-gutters v-for="key in keyReturnStatuses" :key="(key as any)._id ?? (key as any).keyId"
270
- class="d-flex flex-wrap justify-space-between align-center ga-5 mb-2">
271
- <v-chip prepend-icon="mdi-key" size="small" variant="tonal" color="orange">
536
+ <v-row
537
+ no-gutters
538
+ v-for="key in keyReturnStatuses"
539
+ :key="(key as any)._id ?? (key as any).keyId"
540
+ class="d-flex flex-wrap justify-space-between align-center ga-5 mb-2"
541
+ >
542
+ <v-chip
543
+ prepend-icon="mdi-key"
544
+ size="small"
545
+ variant="tonal"
546
+ color="orange"
547
+ >
272
548
  {{ (key as any)?.prefixAndName }}
273
549
  </v-chip>
274
- <v-select hide-details max-width="200px" density="compact" :items="passStatusOptions" item-title="label"
275
- item-value="value" v-model="key.status" :disabled="selectedVisitorObject.checkOut"></v-select>
276
- <v-textarea v-if="key.status === 'Lost' || key.status === 'Damaged'" no-resize rows="3" class="w-100"
277
- density="compact" v-model="key.remarks" :disabled="selectedVisitorObject.checkOut"></v-textarea>
550
+ <v-select
551
+ hide-details
552
+ max-width="200px"
553
+ density="compact"
554
+ :items="passStatusOptions"
555
+ item-title="label"
556
+ item-value="value"
557
+ v-model="key.status"
558
+ :disabled="selectedVisitorObject.checkOut"
559
+ ></v-select>
560
+ <v-textarea
561
+ v-if="key.status === 'Lost' || key.status === 'Damaged'"
562
+ no-resize
563
+ rows="3"
564
+ class="w-100"
565
+ density="compact"
566
+ v-model="key.remarks"
567
+ :disabled="selectedVisitorObject.checkOut"
568
+ ></v-textarea>
278
569
  </v-row>
279
570
  </div>
280
571
 
281
572
  <v-row no-gutters class="my-5">
282
- <v-btn variant="flat" color="blue" density="comfortable" class="text-capitalize" :disabled="selectedVisitorObject.checkOut"
283
- :loading="loading.updatingPassKeys" @click.stop="handleUpdatePassKeys" >Update Pass/Keys</v-btn>
573
+ <v-btn
574
+ variant="flat"
575
+ color="blue"
576
+ density="comfortable"
577
+ class="text-capitalize"
578
+ :disabled="selectedVisitorObject.checkOut"
579
+ :loading="loading.updatingPassKeys"
580
+ @click.stop="handleUpdatePassKeys"
581
+ >Update Pass/Keys</v-btn
582
+ >
284
583
  </v-row>
285
584
  </v-card-text>
286
585
  <v-toolbar class="pa-0" density="compact">
287
586
  <v-row no-gutters>
288
587
  <v-col cols="6">
289
- <v-btn variant="text" block
290
- @click="dialog.returnPassesKeys = false">Close</v-btn>
588
+ <v-btn
589
+ variant="text"
590
+ block
591
+ @click="dialog.returnPassesKeys = false"
592
+ >Close</v-btn
593
+ >
291
594
  </v-col>
292
595
  <v-col cols="6">
293
- <v-btn color="red" variant="flat" height="48" rounded="0" block :loading="loading.checkingOut"
294
- :disabled="!canConfirmCheckout || selectedVisitorObject.checkOut" @click="proceedCheckout">Confirm Checkout</v-btn>
596
+ <v-btn
597
+ color="red"
598
+ variant="flat"
599
+ height="48"
600
+ rounded="0"
601
+ block
602
+ :loading="loading.checkingOut"
603
+ :disabled="
604
+ !canConfirmCheckout || selectedVisitorObject.checkOut
605
+ "
606
+ @click="proceedCheckout"
607
+ >Confirm Checkout</v-btn
608
+ >
295
609
  </v-col>
296
610
  </v-row>
297
611
  </v-toolbar>
@@ -299,10 +613,40 @@
299
613
  </v-dialog>
300
614
 
301
615
  <v-dialog v-model="dialog.addPassKey" width="450" persistent>
302
- <AddPassKeyToVisitor :visitor="selectedVisitorDataObject" :site="siteId" @close="dialog.addPassKey = false"
303
- @update="getVisitorRefresh" />
616
+ <AddPassKeyToVisitor
617
+ mode="add"
618
+ :visitor="selectedVisitorDataObject"
619
+ :site="siteId"
620
+ @close="dialog.addPassKey = false"
621
+ @done="
622
+ () => {
623
+ dialog.addPassKey = false;
624
+ getVisitorRefresh();
625
+ }
626
+ "
627
+ />
304
628
  </v-dialog>
305
629
 
630
+ <v-dialog v-model="dialog.editPassKey" width="450" persistent>
631
+ <AddPassKeyToVisitor
632
+ mode="edit"
633
+ :visitor="selectedVisitorDataObject"
634
+ :site="siteId"
635
+ @close="dialog.editPassKey = false"
636
+ @done="
637
+ () => {
638
+ dialog.editPassKey = false;
639
+ getVisitorRefresh();
640
+ }
641
+ "
642
+ />
643
+ </v-dialog>
644
+
645
+ <ScanVisitorQRCode
646
+ :dialog="dialog.scanVisitorQRCode"
647
+ @close-dialog="dialog.scanVisitorQRCode = false"
648
+ />
649
+
306
650
  <Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />
307
651
  </v-row>
308
652
  </template>
@@ -317,15 +661,15 @@ const props = defineProps({
317
661
  type: Boolean,
318
662
  default: true,
319
663
  },
320
- canViewVisitor: {
664
+ canScanVisitorQRCode: {
321
665
  type: Boolean,
322
666
  default: true,
323
667
  },
324
- canUpdateVisitor: {
668
+ canViewVisitor: {
325
669
  type: Boolean,
326
670
  default: true,
327
671
  },
328
- canDeleteVisitor: {
672
+ canUpdateVisitor: {
329
673
  type: Boolean,
330
674
  default: true,
331
675
  },
@@ -335,21 +679,16 @@ const props = defineProps({
335
679
  },
336
680
  });
337
681
 
338
- const {
339
- getVisitors,
340
- visitorSelection,
341
- typeFieldMap,
342
- deleteVisitor,
343
- updateVisitor,
344
- } = useVisitor();
682
+ const { getVisitors, visitorSelection, typeFieldMap, updateVisitor } =
683
+ useVisitor();
345
684
  const { debounce, formatCamelCaseToWords, formatDate, UTCToLocalTIme } =
346
685
  useUtils();
347
686
  const { formatLocation } = useSecurityUtils();
348
687
  const { getFileUrlAnpr } = useFile();
349
688
  // const { status: visitorStatus, search } = useRoute().query as { status: string, search: string};
350
689
 
351
- const route = useRoute()
352
- const router = useRouter()
690
+ const route = useRoute();
691
+ const router = useRouter();
353
692
  const { org: orgId, site: siteId } = route.params as {
354
693
  org: string;
355
694
  site: string;
@@ -377,7 +716,6 @@ const messageColor = ref("");
377
716
  const messageSnackbar = ref(false);
378
717
 
379
718
  const loading = reactive({
380
- deletingVisitor: false,
381
719
  fetchingVisitors: false,
382
720
  checkingOut: false,
383
721
  savingRemarks: false,
@@ -388,15 +726,16 @@ const dialog = reactive({
388
726
  showSelection: false,
389
727
  showForm: false,
390
728
  viewVisitor: false,
391
- deleteConfirmation: false,
392
729
  snapshotImage: false,
393
730
  remarks: false,
394
731
  returnPassesKeys: false,
395
- addPassKey: false
732
+ addPassKey: false,
733
+ editPassKey: false,
734
+ scanVisitorQRCode: false,
396
735
  });
397
736
 
398
737
  const snapshotImageUrl = ref("");
399
- const remarksType = ref<'checkIn' | 'checkOut'>('checkIn');
738
+ const remarksType = ref<"checkIn" | "checkOut">("checkIn");
400
739
  const remarksInput = ref("");
401
740
  const remarksViewOnly = ref(false);
402
741
 
@@ -406,10 +745,16 @@ const headers = computed(() => [
406
745
  { title: "Location", value: "location" },
407
746
  { title: "Contact/Vehicle No.", value: "contact-vehicleNumber" },
408
747
  { title: "Check In/Out", value: "checkin-out" },
409
- ...(activeTab.value === "resident-transactions" ? [{ title: "Check-in Remarks", value: "checkInRemarks" }, { title: "Check-out Remarks", value: "checkOutRemarks" }] : []),
410
- ...(activeTab.value === 'unregistered' ? [{ title: "Action", value: "action" }] : [])
411
- ])
412
-
748
+ ...(activeTab.value === "resident-transactions"
749
+ ? [
750
+ { title: "Check-in Remarks", value: "checkInRemarks" },
751
+ { title: "Check-out Remarks", value: "checkOutRemarks" },
752
+ ]
753
+ : []),
754
+ ...(activeTab.value === "unregistered"
755
+ ? [{ title: "Action", value: "action" }]
756
+ : []),
757
+ ]);
413
758
 
414
759
  const tabOptions = [
415
760
  { name: "Registered", value: "registered" },
@@ -452,7 +797,6 @@ const formattedFields = {
452
797
  checkOut: "Check Out",
453
798
  snapshotExitImage: "Exit Image",
454
799
  remarks: "Remarks",
455
-
456
800
  } as const;
457
801
 
458
802
  function filterTypeSelectionLabel() {
@@ -465,14 +809,14 @@ const passStatusOptions = [
465
809
  { label: "Not Returned", value: "In Use" },
466
810
  { label: "Damaged", value: "Damaged" },
467
811
  { label: "Lost", value: "Lost" },
468
- ]
812
+ ];
469
813
 
470
814
  function toRoute(tab: any) {
471
- items.value = []
815
+ items.value = [];
472
816
 
473
817
  const obj = tabOptions.find((x) => x.value === tab);
474
818
  if (!obj) return;
475
- page.value = 1
819
+ page.value = 1;
476
820
  navigateTo({
477
821
  name: routeName,
478
822
  params: {
@@ -483,54 +827,51 @@ function toRoute(tab: any) {
483
827
  // },
484
828
  });
485
829
  }
486
-
487
830
  const {
488
831
  data: getVisitorReq,
489
832
  refresh: getVisitorRefresh,
490
833
  pending: getVisitorPending,
491
834
  } = await useLazyAsyncData(
492
- `get-all-visitors-${activeTab.value}-${page.value}-${siteId}`,
835
+ "get-all-visitors",
493
836
  async () => {
494
-
495
- // Optional delay (if needed)
496
- await new Promise(resolve => setTimeout(resolve, 100))
497
-
498
837
  const params: any = {
499
838
  page: page.value,
500
839
  site: siteId,
501
840
  search: searchInput.value,
502
841
  dateTo: normalizeDateOnly(dateTo.value),
503
842
  dateFrom: normalizeDateOnly(dateFrom.value),
504
- type: (filterTypes.value.length === 0 && activeTab.value === 'registered' ? "contractor,delivery,walk-in,pick-up,drop-off,guest" : filterTypes.value.filter(Boolean).join(",")),
505
- checkedOut: displayNotCheckedOut.value ? false : undefined
506
- }
507
-
508
- // if (activeTab.value !== "guests") {
509
- // params.status = activeTab.value
510
- // } else if (activeTab.value === "guests") {
511
- // params.type = "guest"
512
- // params.status = "pending"
513
- // }
843
+ type:
844
+ filterTypes.value.length === 0 && activeTab.value === "registered"
845
+ ? "contractor,delivery,walk-in,pick-up,drop-off,guest"
846
+ : filterTypes.value.filter(Boolean).join(","),
847
+ checkedOut: displayNotCheckedOut.value ? false : undefined,
848
+ };
514
849
 
515
850
  if (activeTab.value === "guests") {
516
- params.type = "guest"
517
- params.status = "pending"
851
+ params.type = "guest";
852
+ params.status = "pending";
518
853
  } else if (activeTab.value === "resident-transactions") {
519
- params.status = "registered"
520
- params.type = "resident,tenant"
854
+ params.status = "registered";
855
+ params.type = "resident,tenant";
521
856
  } else {
522
- params.status = activeTab.value
857
+ params.status = activeTab.value;
523
858
  }
524
859
 
525
- return await getVisitors(params)
860
+ return await getVisitors(params);
526
861
  },
527
862
  {
528
863
  watch: [
529
864
  page,
865
+ searchInput,
866
+ dateFrom,
867
+ dateTo,
868
+ filterTypes,
869
+ activeTab,
870
+ displayNotCheckedOut,
530
871
  ],
531
- immediate: false
872
+ immediate: true,
532
873
  }
533
- )
874
+ );
534
875
 
535
876
  watch(getVisitorReq, (newData: any) => {
536
877
  if (newData) {
@@ -542,11 +883,16 @@ watch(getVisitorReq, (newData: any) => {
542
883
  });
543
884
 
544
885
  const selectedVisitorObject = computed(() => {
545
-
546
886
  const obj = items.value.find((x: any) => x?._id === selectedVisitorId.value);
547
887
  if (!obj) return {};
548
888
  const type = obj?.type as TVisitorType | undefined;
549
- let includedKeys: string[] = ["checkIn", "checkOut", "plateNumber", "snapshotEntryImage", "snapshotExitImage"];
889
+ let includedKeys: string[] = [
890
+ "checkIn",
891
+ "checkOut",
892
+ "plateNumber",
893
+ "snapshotEntryImage",
894
+ "snapshotExitImage",
895
+ ];
550
896
  includedKeys.unshift(...(typeFieldMap[type] ?? []));
551
897
  return Object.fromEntries(
552
898
  Object.entries(obj).filter(([key]) => includedKeys.includes(key))
@@ -567,8 +913,6 @@ function formatValues(key: string, value: any) {
567
913
  return value;
568
914
  }
569
915
 
570
-
571
-
572
916
  function handleAddNew() {
573
917
  dialog.showSelection = true;
574
918
  activeVisitorFormType.value = null;
@@ -588,9 +932,17 @@ function showAddPassKeyButton(item: any) {
588
932
  const hasPasses = (item?.visitorPass?.length ?? 0) > 0;
589
933
  const hasKeys = (item?.passKeys?.length ?? 0) > 0;
590
934
 
591
- const isTypeWithPassKey = ["contractor", "guest", "walk-in"].includes(item?.type);
935
+ const isTypeWithPassKey = ["contractor", "guest", "walk-in"].includes(
936
+ item?.type
937
+ );
592
938
 
593
- return !hasPasses && !hasKeys && isTypeWithPassKey && item?.status === "registered" && !item?.checkOut;
939
+ return (
940
+ !hasPasses &&
941
+ !hasKeys &&
942
+ isTypeWithPassKey &&
943
+ item?.status === "registered" &&
944
+ !item?.checkOut
945
+ );
594
946
  }
595
947
 
596
948
  function handleSelectVisitorType(type: TVisitorType) {
@@ -616,11 +968,6 @@ function handleVisitorFormCreateMore() {
616
968
  dialog.showForm = false;
617
969
  }
618
970
 
619
- function handleDeleteVisitor() {
620
- dialog.deleteConfirmation = true;
621
- dialog.viewVisitor = false;
622
- }
623
-
624
971
  function showMessage(msg: string, color: string) {
625
972
  message.value = msg;
626
973
  messageColor.value = color;
@@ -650,10 +997,19 @@ function handleOpenAddPassKey(item: any) {
650
997
  dialog.addPassKey = true;
651
998
  }
652
999
 
653
- function handleOpenRemarks(item: any, type: 'checkIn' | 'checkOut') {
1000
+ function handleOpenEditPassKey(item: any) {
1001
+ selectedVisitorId.value = item?._id;
1002
+ if (selectedVisitorDataObject.value.checkOut) {
1003
+ dialog.returnPassesKeys = true;
1004
+ handleCheckout(selectedVisitorId.value as string);
1005
+ } else dialog.editPassKey = true;
1006
+ }
1007
+
1008
+ function handleOpenRemarks(item: any, type: "checkIn" | "checkOut") {
654
1009
  selectedVisitorId.value = item?._id;
655
1010
  remarksType.value = type;
656
- const existingRemarks = type === 'checkIn' ? item?.checkInRemarks : item?.checkOutRemarks;
1011
+ const existingRemarks =
1012
+ type === "checkIn" ? item?.checkInRemarks : item?.checkOutRemarks;
657
1013
  remarksInput.value = existingRemarks || "";
658
1014
  remarksViewOnly.value = !!existingRemarks;
659
1015
  dialog.remarks = true;
@@ -663,16 +1019,20 @@ async function handleSaveRemarks() {
663
1019
  if (!remarksInput.value.trim() || !selectedVisitorId.value) return;
664
1020
  try {
665
1021
  loading.savingRemarks = true;
666
- const payload = remarksType.value === 'checkIn'
667
- ? { checkInRemarks: remarksInput.value.trim() }
668
- : { checkOutRemarks: remarksInput.value.trim() };
1022
+ const payload =
1023
+ remarksType.value === "checkIn"
1024
+ ? { checkInRemarks: remarksInput.value.trim() }
1025
+ : { checkOutRemarks: remarksInput.value.trim() };
669
1026
  await updateVisitor(selectedVisitorId.value, payload);
670
1027
  showMessage("Remarks saved successfully!", "info");
671
1028
  await getVisitorRefresh();
672
1029
  dialog.remarks = false;
673
1030
  } catch (error: any) {
674
1031
  const errorMessage = error?.response?._data?.message;
675
- showMessage(errorMessage || "Something went wrong. Please try again later.", "error");
1032
+ showMessage(
1033
+ errorMessage || "Something went wrong. Please try again later.",
1034
+ "error"
1035
+ );
676
1036
  } finally {
677
1037
  loading.savingRemarks = false;
678
1038
  }
@@ -684,11 +1044,19 @@ async function handleUpdatePassKeys() {
684
1044
  loading.updatingPassKeys = true;
685
1045
  const payload: any = {};
686
1046
  if (passReturnStatuses.value.length > 0) {
687
- const passReturnStatusesPayload = passReturnStatuses.value.map(p => ({ keyId: p.keyId, status: p.status, remarks: p.remarks }));
1047
+ const passReturnStatusesPayload = passReturnStatuses.value.map((p) => ({
1048
+ keyId: p.keyId,
1049
+ status: p.status,
1050
+ remarks: p.remarks,
1051
+ }));
688
1052
  payload.visitorPass = passReturnStatusesPayload;
689
1053
  }
690
1054
  if (keyReturnStatuses.value.length > 0) {
691
- const keyReturnStatusesPayload = keyReturnStatuses.value.map(k => ({ keyId: k.keyId, status: k.status, remarks: k.remarks }));
1055
+ const keyReturnStatusesPayload = keyReturnStatuses.value.map((k) => ({
1056
+ keyId: k.keyId,
1057
+ status: k.status,
1058
+ remarks: k.remarks,
1059
+ }));
692
1060
  payload.passKeys = keyReturnStatusesPayload;
693
1061
  }
694
1062
  await updateVisitor(selectedVisitorId.value, payload);
@@ -696,50 +1064,35 @@ async function handleUpdatePassKeys() {
696
1064
  await getVisitorRefresh();
697
1065
  } catch (error: any) {
698
1066
  const errorMessage = error?.response?._data?.message;
699
- showMessage(errorMessage || "Something went wrong. Please try again later.", "error");
700
- } finally {
701
- loading.updatingPassKeys = false;
702
- }
703
- }
704
-
705
-
706
- async function handleProceedDeleteVisitor() {
707
- try {
708
- loading.deletingVisitor = true;
709
- const userId = selectedVisitorId.value;
710
- const res = await deleteVisitor(userId as string);
711
- if (res) {
712
- showMessage("Visitor successfully deleted!", "info");
713
- await getVisitorRefresh();
714
- dialog.deleteConfirmation = false;
715
- }
716
- } catch (error: any) {
717
- const errorMessage = error?.response?._data?.message;
718
- console.log("[ERROR]", error);
719
1067
  showMessage(
720
1068
  errorMessage || "Something went wrong. Please try again later.",
721
1069
  "error"
722
1070
  );
723
1071
  } finally {
724
- loading.deletingVisitor = false;
1072
+ loading.updatingPassKeys = false;
725
1073
  }
726
1074
  }
727
1075
 
728
-
729
- const passReturnStatuses = ref<{ keyId: string, status: string, prefixAndName: string, remarks: string }[]>([]);
730
- const keyReturnStatuses = ref<{ keyId: string, status: string, prefixAndName: string, remarks: string }[]>([]);
1076
+ const passReturnStatuses = ref<
1077
+ { keyId: string; status: string; prefixAndName: string; remarks: string }[]
1078
+ >([]);
1079
+ const keyReturnStatuses = ref<
1080
+ { keyId: string; status: string; prefixAndName: string; remarks: string }[]
1081
+ >([]);
731
1082
 
732
1083
  const canConfirmCheckout = computed(() => {
733
1084
  const allEntries = [...passReturnStatuses.value, ...keyReturnStatuses.value];
734
1085
  return allEntries.every((entry) => {
735
- if (!entry.status || entry.status === 'In Use') return false;
736
- if ((entry.status === 'Lost' || entry.status === 'Damaged') && !entry.remarks.trim()) return false;
1086
+ if (!entry.status || entry.status === "In Use") return false;
1087
+ if (
1088
+ (entry.status === "Lost" || entry.status === "Damaged") &&
1089
+ !entry.remarks.trim()
1090
+ )
1091
+ return false;
737
1092
  return true;
738
1093
  });
739
1094
  });
740
1095
 
741
-
742
-
743
1096
  function handleCheckout(userId: string) {
744
1097
  if (!userId) {
745
1098
  showMessage("Invalid userId", "error");
@@ -753,8 +1106,22 @@ function handleCheckout(userId: string) {
753
1106
 
754
1107
  if (hasPasses || hasKeys) {
755
1108
  const visitor = items.value.find((x: any) => x?._id === userId);
756
- passReturnStatuses.value = ((visitor?.visitorPass as any[]) || []).map((p: any) => ({ keyId: p.keyId, status: p.status ?? "In Use", remarks: '', prefixAndName: p.prefixAndName }));
757
- keyReturnStatuses.value = ((visitor?.passKeys as any[]) || []).map((k: any) => ({ keyId: k.keyId, status: k.status ?? "In Use", remarks: '', prefixAndName: k.prefixAndName }));
1109
+ passReturnStatuses.value = ((visitor?.visitorPass as any[]) || []).map(
1110
+ (p: any) => ({
1111
+ keyId: p.keyId,
1112
+ status: p.status ?? "In Use",
1113
+ remarks: "",
1114
+ prefixAndName: p.prefixAndName,
1115
+ })
1116
+ );
1117
+ keyReturnStatuses.value = ((visitor?.passKeys as any[]) || []).map(
1118
+ (k: any) => ({
1119
+ keyId: k.keyId,
1120
+ status: k.status ?? "In Use",
1121
+ remarks: "",
1122
+ prefixAndName: k.prefixAndName,
1123
+ })
1124
+ );
758
1125
  dialog.returnPassesKeys = true;
759
1126
  return;
760
1127
  }
@@ -769,13 +1136,25 @@ async function proceedCheckout() {
769
1136
  try {
770
1137
  loading.checkingOut = true;
771
1138
 
772
- const passReturnStatusesPayload = passReturnStatuses.value.map(p => ({ keyId: p.keyId, status: p.status, remarks: p.remarks }));
773
- const keyReturnStatusesPayload = keyReturnStatuses.value.map(k => ({ keyId: k.keyId, status: k.status, remarks: k.remarks }));
1139
+ const passReturnStatusesPayload = passReturnStatuses.value.map((p) => ({
1140
+ keyId: p.keyId,
1141
+ status: p.status,
1142
+ remarks: p.remarks,
1143
+ }));
1144
+ const keyReturnStatusesPayload = keyReturnStatuses.value.map((k) => ({
1145
+ keyId: k.keyId,
1146
+ status: k.status,
1147
+ remarks: k.remarks,
1148
+ }));
774
1149
 
775
1150
  const res = await updateVisitor(userId as string, {
776
1151
  checkOut: new Date().toISOString(),
777
- ...(passReturnStatuses.value.length > 0 ? { visitorPass: passReturnStatusesPayload } : {}),
778
- ...(keyReturnStatuses.value.length > 0 ? { passKeys: keyReturnStatusesPayload } : {}),
1152
+ ...(passReturnStatuses.value.length > 0
1153
+ ? { visitorPass: passReturnStatusesPayload }
1154
+ : {}),
1155
+ ...(keyReturnStatuses.value.length > 0
1156
+ ? { passKeys: keyReturnStatusesPayload }
1157
+ : {}),
779
1158
  });
780
1159
  if (res) {
781
1160
  showMessage("Visitor successfully checked-out!", "info");
@@ -795,11 +1174,23 @@ async function proceedCheckout() {
795
1174
  }
796
1175
  }
797
1176
 
798
-
799
-
800
1177
  const updateRouteQuery = debounce(
801
1178
  // (search: string, from: string, to: string, types: string[], status, checkedOut) => {
802
- ({ search, from, to, types, tab, checkedOut }: { search: string, from: string, to: string, types: string[], tab: string, checkedOut: boolean }) => {
1179
+ ({
1180
+ search,
1181
+ from,
1182
+ to,
1183
+ types,
1184
+ tab,
1185
+ checkedOut,
1186
+ }: {
1187
+ search: string;
1188
+ from: string;
1189
+ to: string;
1190
+ types: string[];
1191
+ tab: string;
1192
+ checkedOut: boolean;
1193
+ }) => {
803
1194
  router.replace({
804
1195
  query: {
805
1196
  ...route.query,
@@ -808,7 +1199,9 @@ const updateRouteQuery = debounce(
808
1199
  dateTo: to || undefined,
809
1200
  type: types.filter(Boolean).join(",") || undefined,
810
1201
  tab: tab || undefined,
811
- ...(checkedOut === true ? { checkedOut: "true" } : { checkedOut: undefined })
1202
+ ...(checkedOut === true
1203
+ ? { checkedOut: "true" }
1204
+ : { checkedOut: undefined }),
812
1205
  },
813
1206
  });
814
1207
  },
@@ -824,22 +1217,33 @@ watch(
824
1217
  dateTo.value = normalizedTo;
825
1218
 
826
1219
  // updateRouteQuery(search, from, to, types, status, checkedOut)
827
- updateRouteQuery({ search, from: normalizedFrom, to: normalizedTo, types, tab, checkedOut })
828
- getVisitorRefresh();
1220
+ updateRouteQuery({
1221
+ search,
1222
+ from: normalizedFrom,
1223
+ to: normalizedTo,
1224
+ types,
1225
+ tab,
1226
+ checkedOut,
1227
+ });
1228
+ // getVisitorRefresh();
829
1229
  },
830
1230
  { deep: true }
831
1231
  );
832
-
833
-
1232
+ watch([searchInput, dateFrom, dateTo, filterTypes, activeTab], () => {
1233
+ page.value = 1;
1234
+ });
834
1235
 
835
1236
  onMounted(() => {
836
- activeTab.value = (route.query.tab as string) || "unregistered"
1237
+ activeTab.value = (route.query.tab as string) || "unregistered";
837
1238
  searchInput.value = (route.query.search as string) || "";
838
1239
  dateFrom.value = normalizeDateOnly((route.query.dateFrom as string) || "");
839
1240
  dateTo.value = normalizeDateOnly((route.query.dateTo as string) || "");
840
- filterTypes.value = ((route.query.type as string)?.split(",") || []).filter(Boolean) as TVisitorType[];
841
- displayNotCheckedOut.value = (route.query.checkedOut as string) == 'true' || false
842
- })
1241
+ filterTypes.value = ((route.query.type as string)?.split(",") || []).filter(
1242
+ Boolean
1243
+ ) as TVisitorType[];
1244
+ displayNotCheckedOut.value =
1245
+ (route.query.checkedOut as string) == "true" || false;
1246
+ });
843
1247
  </script>
844
1248
 
845
1249
  <style scoped></style>