@7365admin1/layer-common 1.11.22 → 1.11.24

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.
@@ -0,0 +1,292 @@
1
+ <template>
2
+ <v-card width="100%" :loading="processing">
3
+ <v-toolbar>
4
+ <v-row
5
+ no-gutters
6
+ class="fill-height px-6 d-flex justify-space-between align-center"
7
+ align="center"
8
+ >
9
+ <span class="font-weight-bold text-h5 text-capitalize">
10
+ Visitor Information
11
+ </span>
12
+ <ButtonClose @click="emit('close')" />
13
+ </v-row>
14
+ </v-toolbar>
15
+ <v-card-text style="max-height: 100vh; overflow-y: auto" class="pa-5 my-3">
16
+ <div class="w-100 d-flex justify-space-between ga-2">
17
+ <!-- <span v-if="withStep2 || withStep3" class="text-subtitle-2 font-weight-bold" style="text-wrap: nowrap">Step
18
+ <span class="text-primary-button">{{ contractorStep }}</span>/{{ withStep3 ? 3 : withStep2 ? 2 : 1 }}</span> -->
19
+ </div>
20
+ <!-- <v-form ref="formRef" v-model="validForm" :disabled="processing" @click="errorMessage = ''"> -->
21
+ <v-row no-gutters class="pt-4">
22
+ <v-col cols="12">
23
+ <InputLabel class="text-capitalize" title="Full Name" />
24
+ <v-text-field
25
+ v-model="visitorInfo.name"
26
+ density="comfortable"
27
+ readonly
28
+ />
29
+ </v-col>
30
+
31
+ <v-col v-if="!visitorInfo.checkIn" cols="12">
32
+ <InputLabel class="text-capitalize" title="NRIC/Passport/ID No." />
33
+ <v-text-field
34
+ v-if="!visitorInfo.checkIn"
35
+ v-model="visitorInfo.nric"
36
+ density="comfortable"
37
+ hide-details
38
+ clearable
39
+ />
40
+ <v-text-field
41
+ v-else
42
+ v-model="visitorNric"
43
+ density="comfortable"
44
+ hide-details
45
+ readonly
46
+ />
47
+ </v-col>
48
+
49
+ <v-col v-if="!visitorInfo.checkIn" cols="12" class="mt-4">
50
+ <InputLabel
51
+ class="text-capitalize"
52
+ title="Vehicle Number (Optional)"
53
+ />
54
+ <InputVehicleNumber
55
+ v-if="!visitorInfo.checkIn"
56
+ v-model="visitorInfo.plateNumber"
57
+ density="comfortable"
58
+ hide-details
59
+ clearable
60
+ />
61
+ <InputVehicleNumber
62
+ v-else
63
+ v-model="visitorPlateNumber"
64
+ density="comfortable"
65
+ hide-details
66
+ readonly
67
+ />
68
+ </v-col>
69
+
70
+ <!-- <v-col cols="12" class="mt-4">
71
+ <InputLabel class="text-capitalize" title="Type" />
72
+ <v-text-field
73
+ v-model="visitorInfo.type"
74
+ density="comfortable"
75
+ hide-details
76
+ readonly
77
+ />
78
+ </v-col> -->
79
+
80
+ <v-col v-if="!visitorInfo.checkIn" cols="12" class="mt-4">
81
+ <InputLabel class="text-capitalize" title="Phone Number" />
82
+ <InputPhoneNumberV2
83
+ v-model="visitorInfo.contact"
84
+ density="comfortable"
85
+ :readonly="true"
86
+ />
87
+ </v-col>
88
+
89
+ <v-col cols="12">
90
+ <InputLabel class="text-capitalize" title="Location" />
91
+ <v-text-field v-model="location" density="comfortable" readonly />
92
+ </v-col>
93
+
94
+ <v-col v-if="!visitorInfo.checkIn" cols="12">
95
+ <InputLabel class="text-capitalize" title="Purpose" />
96
+ <v-textarea
97
+ v-model="visitorInfo.purpose"
98
+ density="comfortable"
99
+ :rows="2"
100
+ no-resize
101
+ readonly
102
+ />
103
+ </v-col>
104
+
105
+ <v-col v-if="!visitorInfo.checkIn" cols="12">
106
+ <InputLabel class="text-capitalize" title="Remarks" />
107
+ <v-textarea
108
+ v-model="visitorInfo.remarks"
109
+ density="comfortable"
110
+ :rows="2"
111
+ no-resize
112
+ />
113
+ </v-col>
114
+
115
+ <v-col v-if="!visitorInfo.checkIn" cols="12">
116
+ <InputLabel class="text-capitalize" title="Visitor Pass" />
117
+ <PassInformation
118
+ v-model:pass="visitorInfo.visitorPass"
119
+ :site="prop.site"
120
+ :type="visitorInfo.type"
121
+ :hideKeys="true"
122
+ :clearable="true"
123
+ />
124
+ </v-col>
125
+
126
+ <v-col v-else cols="12">
127
+ <v-card elevation="4" height="100%" width="100%">
128
+ <v-col cols="12" class="d-flex justify-center pb-0">
129
+ <span
130
+ class="text-h6 font-weight-bold d-flex text-center text-success"
131
+ >
132
+ {{
133
+ visitorInfo.checkIn
134
+ ? standardFormatDateTime(visitorInfo.checkIn)
135
+ : "N/A"
136
+ }}
137
+ </span>
138
+ </v-col>
139
+ <v-col cols="12" class="d-flex justify-center">
140
+ Actual Check In
141
+ </v-col>
142
+ </v-card>
143
+ </v-col>
144
+
145
+ <!-- <v-col cols="12" class="mt-4">
146
+ <v-row no-gutters class="pt-2">
147
+ <v-col cols="6" class="pr-1">
148
+ <v-card elevation="3" height="100%" width="100%">
149
+ <v-col cols="12" class="d-flex justify-center pb-0">
150
+ <span
151
+ class="text-h6 font-weight-bold d-flex text-center text-success"
152
+ >
153
+ {{
154
+ visitorInfo.checkIn
155
+ ? standardFormatDateTime(visitorInfo.checkIn)
156
+ : "N/A"
157
+ }}
158
+ </span>
159
+ </v-col>
160
+ <v-col cols="12" class="d-flex justify-center">
161
+ Actual Check In
162
+ </v-col>
163
+ </v-card>
164
+ </v-col>
165
+ <v-col cols="6" class="pl-1">
166
+ <v-card elevation="3" height="100%" width="100%">
167
+ <v-col cols="12" class="d-flex justify-center pb-0">
168
+ <span
169
+ class="text-h6 font-weight-bold d-flex text-center text-error"
170
+ >
171
+ {{
172
+ visitorInfo.checkOut
173
+ ? standardFormatDateTime(visitorInfo.checkOut)
174
+ : "N/A"
175
+ }}
176
+ </span>
177
+ </v-col>
178
+ <v-col cols="12" class="d-flex justify-center">
179
+ Actual Check Out
180
+ </v-col>
181
+ </v-card>
182
+ </v-col>
183
+ </v-row>
184
+ </v-col> -->
185
+ </v-row>
186
+ <!-- </v-form> -->
187
+ </v-card-text>
188
+
189
+ <v-toolbar density="compact">
190
+ <v-row no-gutters>
191
+ <v-col cols="6">
192
+ <v-btn text="Close" block size="48" tile @click="emit('close')" />
193
+ </v-col>
194
+ <v-col cols="6">
195
+ <v-btn
196
+ v-if="!visitorInfo.checkIn && !visitorInfo.checkOut"
197
+ block
198
+ text="Check In"
199
+ variant="flat"
200
+ color="success"
201
+ size="48"
202
+ tile
203
+ :disabled="processing"
204
+ @click="emit('check-in-out', 'checkIn', visitorInfo)"
205
+ :loading="processing"
206
+ />
207
+ <v-btn
208
+ v-if="visitorInfo.checkIn && !visitorInfo.checkOut"
209
+ block
210
+ text="Confirm Check Out"
211
+ variant="flat"
212
+ color="error"
213
+ size="48"
214
+ tile
215
+ :disabled="processing"
216
+ @click="emit('check-in-out', 'checkOut', visitorInfo)"
217
+ :loading="processing"
218
+ />
219
+ </v-col>
220
+ </v-row>
221
+ </v-toolbar>
222
+ </v-card>
223
+ </template>
224
+ <script setup lang="ts">
225
+ const prop = defineProps({
226
+ site: {
227
+ type: String,
228
+ required: true,
229
+ },
230
+ visitorData: {
231
+ type: Object as PropType<Partial<TVisitor>>,
232
+ default: {},
233
+ },
234
+ processing: {
235
+ type: Boolean,
236
+ required: false,
237
+ },
238
+ });
239
+
240
+ const emit = defineEmits(["check-in-out", "close"]);
241
+
242
+ const { standardFormatDateTime } = useUtils();
243
+
244
+ const visitorInfo = ref(prop.visitorData);
245
+
246
+ const visitorNric = computed({
247
+ get: () =>
248
+ visitorInfo.value && visitorInfo.value.checkIn
249
+ ? visitorInfo.value.nric
250
+ : null,
251
+ set: () => {}, // readonly, do nothing on set
252
+ });
253
+
254
+ const visitorPlateNumber = computed({
255
+ get: () =>
256
+ visitorInfo.value && visitorInfo.value.checkIn
257
+ ? visitorInfo.value.plateNumber
258
+ : null,
259
+ set: () => {}, // readonly, do nothing on set
260
+ });
261
+
262
+ // watchEffect(() => {
263
+ // if (visitorInfo.value.plateNumber) {
264
+ // visitorInfo.value.type = "guest";
265
+ // } else {
266
+ // visitorInfo.value.type = "walk-in";
267
+ // }
268
+ // });
269
+
270
+ const location = computed({
271
+ get: () => {
272
+ if (
273
+ visitorInfo.value &&
274
+ visitorInfo.value.block &&
275
+ visitorInfo.value.level &&
276
+ visitorInfo.value.unitName
277
+ ) {
278
+ return `${visitorInfo.value.block} / ${visitorInfo.value.level} / ${visitorInfo.value.unitName}`;
279
+ } else if (
280
+ visitorInfo.value &&
281
+ visitorInfo.value.block &&
282
+ !visitorInfo.value.level &&
283
+ !visitorInfo.value.unitName
284
+ ) {
285
+ return visitorInfo.value.block;
286
+ } else {
287
+ return "N/A";
288
+ }
289
+ },
290
+ set: () => {}, // readonly, do nothing on set
291
+ });
292
+ </script>
@@ -475,15 +475,13 @@ async function handleAddNewContractorType() {
475
475
 
476
476
  async function handleSelectCompanyName(company: string) {
477
477
  visitor.company = company
478
+ // const selected = companyAutofillDataArray.value.find(x => x.companyName?.includes(company))
479
+ // if (!selected) return
478
480
 
479
- const selected = companyAutofillDataArray.value.find(x => x.companyName?.includes(company))
480
- if (!selected) return
481
-
482
- visitor.block = selected.block || ""
483
- visitor.level = selected.level || ""
484
- visitor.unit = selected.unit || ""
485
- visitor.unitName = selected.unitName || ""
486
-
481
+ // visitor.block = selected.block || ""
482
+ // visitor.level = selected.level || ""
483
+ // visitor.unit = selected.unit || ""
484
+ // visitor.unitName = selected.unitName || ""
487
485
  }
488
486
 
489
487
  const companyCombo = ref(null)
@@ -169,11 +169,33 @@
169
169
  </span>
170
170
 
171
171
  <span
172
- v-if="!item.checkOut && (item?.status === 'registered' || item?.status === 'unregistered') && canCheckoutVisitor">
173
- <span class="d-flex align-center ga-2" v-bind="menuProps" style="cursor:pointer">
174
- <v-icon icon="mdi-clock-time-eight-outline" color="red" size="20" />
175
- <v-btn size="x-small" class="text-capitalize" color="red" text="Checkout"
176
- :loading="loading.checkingOut && item?._id === selectedVisitorId" @click.stop="handleCheckout(item._id)" />
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
+ @click.stop="handleCheckout(item._id)"
198
+ />
177
199
  </span>
178
200
  </span>
179
201
  <span v-else class="d-flex align-center ga-2">
@@ -249,17 +271,62 @@
249
271
  </div>
250
272
  </template>
251
273
  <v-list density="compact">
252
- <v-list-item v-if="!item?.checkOut" prepend-icon="mdi-logout" title="Checkout" @click.stop="handleCheckout(item._id)" />
253
- <v-list-item v-if="(item.visitorPass?.length ?? 0) > 0 || (item.passKeys?.length ?? 0) > 0"
254
- prepend-icon="mdi-card-bulleted-outline" :title="item.checkOut ? 'View Pass/Key' :'Edit Pass/Key'"
255
- @click.stop="handleOpenEditPassKey(item)" />
256
- <v-list-item v-if="showAddPassKeyButton(item)" prepend-icon="mdi-plus" title="Add Pass/Key"
257
- @click.stop="handleOpenAddPassKey(item)" />
274
+ <v-list-item
275
+ v-if="!item?.checkOut"
276
+ prepend-icon="mdi-logout"
277
+ title="Checkout"
278
+ @click.stop="handleCheckout(item._id)"
279
+ />
280
+ <v-list-item
281
+ v-if="
282
+ (item.visitorPass?.length ?? 0) > 0 ||
283
+ (item.passKeys?.length ?? 0) > 0
284
+ "
285
+ prepend-icon="mdi-card-bulleted-outline"
286
+ :title="item.checkOut ? 'View Pass/Key' : 'Edit Pass/Key'"
287
+ @click.stop="handleOpenEditPassKey(item)"
288
+ />
289
+ <v-list-item
290
+ v-if="showAddPassKeyButton(item)"
291
+ prepend-icon="mdi-plus"
292
+ title="Add Pass/Key"
293
+ @click.stop="handleOpenAddPassKey(item)"
294
+ />
258
295
  </v-list>
259
296
  </v-menu>
260
297
  </v-row>
261
298
  </template>
262
299
 
300
+ <template v-slot:item.arrival-date-time="{ item }">
301
+ <v-row no-gutters class="d-flex flex-column py-2">
302
+ <span class="d-flex align-center ga-2">
303
+ <v-icon icon="mdi-calendar" size="20" />
304
+ {{ standardFormatDate(item.expectedCheckIn) || "-" }}
305
+ </span>
306
+ <span class="d-flex align-center ga-2">
307
+ <v-icon icon="mdi-clock-time-four-outline" size="20" />
308
+ {{ formatTime(item.expectedCheckIn) || "-" }}
309
+ </span>
310
+
311
+ <span v-if="!item.checkIn && canUpdateVisitor">
312
+ <span class="d-flex align-center ga-2 cursor-pointer">
313
+ <v-icon
314
+ icon="mdi-clock-time-eight-outline"
315
+ color="success"
316
+ size="20"
317
+ />
318
+ <v-btn
319
+ size="x-small"
320
+ class="text-capitalize"
321
+ color="success"
322
+ text="Checkin"
323
+ @click.stop="handleCheckIn(item)"
324
+ />
325
+ </span>
326
+ </span>
327
+ </v-row>
328
+ </template>
329
+
263
330
  <template v-slot:item.action="{ item }">
264
331
  <v-btn
265
332
  v-if="activeTab === 'unregistered' && canAddVisitor"
@@ -459,6 +526,25 @@
459
526
  <p class="text-body-2 mb-3">
460
527
  Please ensure all passes and keys are returned before checking out.
461
528
  </p>
529
+
530
+ <div>
531
+ <InputLabel class="text-capitalize" title="Full Name" />
532
+ <v-text-field
533
+ v-model="selectedVisitorObject.name"
534
+ density="comfortable"
535
+ readonly
536
+ />
537
+ </div>
538
+
539
+ <div>
540
+ <InputLabel class="text-capitalize" title="Location" />
541
+ <v-text-field
542
+ v-model="selectedVisitorObject.location"
543
+ density="comfortable"
544
+ readonly
545
+ />
546
+ </div>
547
+
462
548
  <div v-if="passReturnStatuses.length > 0" class="mb-2">
463
549
  <p class="text-caption text-medium-emphasis mb-1">Passes</p>
464
550
  <v-row
@@ -609,14 +695,34 @@
609
695
 
610
696
  <ScanVisitorQRCode
611
697
  :dialog="dialog.scanVisitorQRCode"
698
+ :site="siteId"
699
+ @open-visitor-data-from-scanned-qr-code-dialog="
700
+ handleShowVisitorDataFromScannedQRCodeDialog
701
+ "
612
702
  @close-dialog="dialog.scanVisitorQRCode = false"
613
703
  />
614
704
 
705
+ <v-dialog
706
+ v-model="dialog.showVisitorDataFromScannedQRCode"
707
+ width="450"
708
+ persistent
709
+ >
710
+ <VisitorDataFromScannedQRCodeForm
711
+ :site="siteId"
712
+ :visitor-data="visitorDataFromScannedQRCode"
713
+ @check-in-out="handleVisitorDataFromScannedQRCodeCheckInOut"
714
+ :processing="isVisitorDataFromScannedQRCodeCheckingInOut"
715
+ @close="handleCloseVisitorDataFromScannedQRCodeDialog"
716
+ />
717
+ </v-dialog>
718
+
615
719
  <Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />
616
720
  </v-row>
617
721
  </template>
618
722
 
619
723
  <script setup lang="ts">
724
+ import { errorConverter } from "../utils/data";
725
+
620
726
  definePageMeta({
621
727
  middleware: ["01-auth", "02-org"],
622
728
  });
@@ -644,10 +750,24 @@ const props = defineProps({
644
750
  },
645
751
  });
646
752
 
647
- const { getVisitors, visitorSelection, typeFieldMap, updateVisitor } =
648
- useVisitor();
649
- const { debounce, formatCamelCaseToWords, formatDate, UTCToLocalTIme } =
650
- useUtils();
753
+ const { authenticate, currentUser } = useLocalAuth();
754
+ authenticate();
755
+
756
+ const {
757
+ getVisitors,
758
+ visitorSelection,
759
+ typeFieldMap,
760
+ updateVisitor,
761
+ visitorDataFromScannedQRCodeCheckIn,
762
+ } = useVisitor();
763
+ const {
764
+ debounce,
765
+ formatCamelCaseToWords,
766
+ formatDate,
767
+ formatTime,
768
+ UTCToLocalTIme,
769
+ standardFormatDate,
770
+ } = useUtils();
651
771
  const { formatLocation } = useSecurityUtils();
652
772
  const { getFileUrlAnpr } = useFile();
653
773
  // const { status: visitorStatus, search } = useRoute().query as { status: string, search: string};
@@ -697,6 +817,7 @@ const dialog = reactive({
697
817
  addPassKey: false,
698
818
  editPassKey: false,
699
819
  scanVisitorQRCode: false,
820
+ showVisitorDataFromScannedQRCode: false,
700
821
  });
701
822
 
702
823
  const snapshotImageUrl = ref("");
@@ -709,7 +830,9 @@ const headers = computed(() => [
709
830
  { title: "Type/Company", value: "type-company" },
710
831
  { title: "Location", value: "location" },
711
832
  { title: "Contact/Vehicle No.", value: "contact-vehicleNumber" },
712
- { title: "Check In/Out", value: "checkin-out" },
833
+ ...(activeTab.value != "guests"
834
+ ? [{ title: "Check In/Out", value: "checkin-out" }]
835
+ : [{ title: "Arrival Date / Time", value: "arrival-date-time" }]),
713
836
  ...(activeTab.value === "resident-transactions"
714
837
  ? [
715
838
  { title: "Check-in Remarks", value: "checkInRemarks" },
@@ -814,7 +937,7 @@ const {
814
937
 
815
938
  if (activeTab.value === "guests") {
816
939
  params.type = "guest";
817
- params.status = "pending";
940
+ params.status = "approved";
818
941
  } else if (activeTab.value === "resident-transactions") {
819
942
  params.status = "registered";
820
943
  params.type = "resident,tenant";
@@ -850,7 +973,9 @@ watch(getVisitorReq, (newData: any) => {
850
973
  const selectedVisitorObject = computed(() => {
851
974
  const obj = items.value.find((x: any) => x?._id === selectedVisitorId.value);
852
975
  if (!obj) return {};
976
+
853
977
  const type = obj?.type as TVisitorType | undefined;
978
+
854
979
  let includedKeys: string[] = [
855
980
  "checkIn",
856
981
  "checkOut",
@@ -859,9 +984,23 @@ const selectedVisitorObject = computed(() => {
859
984
  "snapshotExitImage",
860
985
  ];
861
986
  includedKeys.unshift(...(typeFieldMap[type] ?? []));
862
- return Object.fromEntries(
863
- Object.entries(obj).filter(([key]) => includedKeys.includes(key))
864
- );
987
+
988
+ let locationString = "N/A";
989
+
990
+ if (obj?.block || obj?.level || obj?.unitName) {
991
+ locationString = `${obj.block} / ${obj.level} / ${obj.unitName}`;
992
+ } else if (obj?.block) {
993
+ locationString = obj.block;
994
+ } else {
995
+ locationString = "N/A";
996
+ }
997
+
998
+ return {
999
+ ...Object.fromEntries(
1000
+ Object.entries(obj).filter(([key]) => includedKeys.includes(key))
1001
+ ),
1002
+ location: locationString,
1003
+ };
865
1004
  });
866
1005
 
867
1006
  function formatValues(key: string, value: any) {
@@ -878,6 +1017,71 @@ function formatValues(key: string, value: any) {
878
1017
  return value;
879
1018
  }
880
1019
 
1020
+ const visitorDataFromScannedQRCode = ref<Record<string, any>>({});
1021
+
1022
+ function handleShowVisitorDataFromScannedQRCodeDialog(
1023
+ scannedData: Record<string, any>
1024
+ ) {
1025
+ visitorDataFromScannedQRCode.value = scannedData;
1026
+
1027
+ const { checkIn, checkOut, _id, visitorPass } = scannedData;
1028
+ const hasPasses = (visitorPass?.length ?? 0) > 0;
1029
+
1030
+ // 1. If they are checked in and HAVE passes/keys, go to the Return screen
1031
+ if (checkIn && !checkOut && hasPasses) {
1032
+ handleCheckout(_id);
1033
+ return;
1034
+ }
1035
+
1036
+ // 2. Default Case: Show visitor data (Entry, already checked out, or checked in with no passes)
1037
+ dialog.showVisitorDataFromScannedQRCode = true;
1038
+ }
1039
+
1040
+ const isVisitorDataFromScannedQRCodeCheckingInOut = ref(false);
1041
+
1042
+ async function handleVisitorDataFromScannedQRCodeCheckInOut(
1043
+ type: string,
1044
+ visitorData: Record<string, any>
1045
+ ) {
1046
+ try {
1047
+ isVisitorDataFromScannedQRCodeCheckingInOut.value = true;
1048
+ if (type != "checkOut") {
1049
+ await visitorDataFromScannedQRCodeCheckIn({
1050
+ type,
1051
+ filter: {
1052
+ _id: visitorData._id,
1053
+ },
1054
+ update: {
1055
+ updatedBy: currentUser.value._id,
1056
+ visitorPass: visitorData.visitorPass.find(
1057
+ (i: Record<string, any>) => i.keyId === null
1058
+ )
1059
+ ? undefined
1060
+ : visitorData.visitorPass,
1061
+ nric: visitorData.nric ?? "",
1062
+ plateNumber: visitorData.plateNumber ?? "",
1063
+ },
1064
+ userType: "site",
1065
+ });
1066
+ showMessage("Visitor successfully checked-in!", "info");
1067
+ } else {
1068
+ selectedVisitorId.value = visitorData._id;
1069
+ await proceedCheckout();
1070
+ }
1071
+ handleCloseVisitorDataFromScannedQRCodeDialog();
1072
+ getVisitorRefresh();
1073
+ } catch (error) {
1074
+ showMessage(errorConverter(error), "error");
1075
+ } finally {
1076
+ isVisitorDataFromScannedQRCodeCheckingInOut.value = false;
1077
+ }
1078
+ }
1079
+
1080
+ function handleCloseVisitorDataFromScannedQRCodeDialog() {
1081
+ dialog.showVisitorDataFromScannedQRCode = false;
1082
+ visitorDataFromScannedQRCode.value = {};
1083
+ }
1084
+
881
1085
  function handleAddNew() {
882
1086
  dialog.showSelection = true;
883
1087
  activeVisitorFormType.value = null;
@@ -1058,6 +1262,11 @@ const canConfirmCheckout = computed(() => {
1058
1262
  });
1059
1263
  });
1060
1264
 
1265
+ async function handleCheckIn(user: Record<string, any>) {
1266
+ visitorDataFromScannedQRCode.value = user;
1267
+ dialog.showVisitorDataFromScannedQRCode = true;
1268
+ }
1269
+
1061
1270
  function handleCheckout(userId: string) {
1062
1271
  if (!userId) {
1063
1272
  showMessage("Invalid userId", "error");