@7365admin1/layer-common 1.11.17 → 1.11.19

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.
@@ -43,6 +43,8 @@
43
43
  </span>
44
44
  <span class="text-capitalize">{{ item?.name }}</span>
45
45
  </span>
46
+ <span class="text-grey text-caption" v-if="item?.members?.length > 0">( +{{ item?.members?.length }}
47
+ members)</span>
46
48
  </template>
47
49
 
48
50
  <template v-slot:item.type-company="{ item }">
@@ -84,36 +86,56 @@
84
86
  </template>
85
87
 
86
88
  <template v-slot:item.checkin-out="{ item }">
87
- <span class="d-flex align-center ga-2">
88
- <v-icon icon="mdi-clock-time-four-outline" color="green" size="20" />
89
- <span class="text-capitalize">{{
90
- UTCToLocalTIme(item.checkIn) || "-"
91
- }}</span>
92
- <span>
93
- <v-icon v-if="item?.snapshotEntryImage" size="17" icon="mdi-image"
94
- @click.stop="handleViewImage(item.snapshotEntryImage)" />
95
- </span>
96
- </span>
97
- <span class="d-flex align-center ga-2">
98
- <v-icon icon="mdi-clock-time-eight-outline" color="red" size="20" />
99
- <template v-if="item.checkOut">
89
+ <v-row no-gutters class="d-flex flex-column py-2">
90
+ <span class="d-flex align-center ga-2">
91
+ <v-icon icon="mdi-clock-time-four-outline" color="green" size="20" />
100
92
  <span class="text-capitalize">{{
101
- UTCToLocalTIme(item.checkOut) || "-"
102
- }}</span>
93
+ UTCToLocalTIme(item.checkIn) || "-"
94
+ }}</span>
103
95
  <span>
104
- <v-icon v-if="item?.snapshotExitImage" size="17" icon="mdi-image"
105
- @click.stop="handleViewImage(item.snapshotExitImage)" />
96
+ <v-icon v-if="item?.snapshotEntryImage" size="17" icon="mdi-image"
97
+ @click.stop="handleViewImage(item.snapshotEntryImage)" />
106
98
  </span>
107
- <span v-if="item?.manualCheckout">
108
- <TooltipInfo text="Manual Checkout" density="compact" size="x-small" />
99
+ </span>
100
+ <span class="d-flex align-center ga-2">
101
+ <v-icon icon="mdi-clock-time-eight-outline" color="red" size="20" />
102
+ <template v-if="item.checkOut">
103
+ <span class="text-capitalize">{{
104
+ UTCToLocalTIme(item.checkOut) || "-"
105
+ }}</span>
106
+ <span>
107
+ <v-icon v-if="item?.snapshotExitImage" size="17" icon="mdi-image"
108
+ @click.stop="handleViewImage(item.snapshotExitImage)" />
109
+ </span>
110
+ <span v-if="item?.manualCheckout">
111
+ <TooltipInfo text="Manual Checkout" density="compact" size="x-small" />
112
+ </span>
113
+ </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" />
109
118
  </span>
110
- </template>
111
- <span v-else-if="!item?.checkOut && (item?.status === 'registered' || item?.status === 'unregistered')">
112
- <v-btn size="x-small" class="text-capitalize" color="red" text="Checkout"
113
- :loading="loading.checkingOut && item?._id === selectedVisitorId" @click.stop="handleCheckout(item._id)"
114
- v-if="canCheckoutVisitor" />
115
119
  </span>
116
- </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
+
137
+ </div>
138
+ </v-row>
117
139
  </template>
118
140
 
119
141
  <template v-slot:item.action="{ item }">
@@ -121,6 +143,21 @@
121
143
  @click.stop="handleRegistrationUnregisteredVisitor(item)" />
122
144
  </template>
123
145
 
146
+ <template v-slot:item.checkInRemarks="{ item }">
147
+ <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>
151
+ </span>
152
+ </template>
153
+ <template v-slot:item.checkOutRemarks="{ item }">
154
+ <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>
158
+ </span>
159
+ </template>
160
+
124
161
  </TableMain>
125
162
 
126
163
  <v-dialog v-model="dialog.showSelection" width="450" persistent>
@@ -179,6 +216,93 @@
179
216
  </v-card>
180
217
  </v-dialog>
181
218
 
219
+ <v-dialog v-model="dialog.remarks" max-width="450" persistent>
220
+ <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" />
224
+ </v-card-title>
225
+ <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" />
228
+ </v-card-text>
229
+ <v-toolbar class="pa-0" density="compact">
230
+ <v-row no-gutters>
231
+ <v-col cols="6">
232
+ <v-btn variant="text" block :disabled="loading.savingRemarks"
233
+ @click="dialog.remarks = false">Cancel</v-btn>
234
+ </v-col>
235
+ <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>
238
+ </v-col>
239
+ </v-row>
240
+ </v-toolbar>
241
+ </v-card>
242
+ </v-dialog>
243
+
244
+ <v-dialog v-model="dialog.returnPassesKeys" max-width="450" persistent>
245
+ <v-card>
246
+ <v-toolbar density="compact" color="">
247
+ <v-row no-gutters class="d-flex fill-height justify-space-between align-center px-4">
248
+ <span class="font-weight-bold">Return Passes &amp; Keys</span>
249
+ <v-btn icon="mdi-close" variant="text" @click="dialog.returnPassesKeys = false" />
250
+ </v-row>
251
+ </v-toolbar>
252
+ <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>
254
+ <div v-if="passReturnStatuses.length > 0" class="mb-2">
255
+ <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">
259
+ {{ (pass as any)?.prefixAndName }}
260
+ </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>
265
+ </v-row>
266
+ </div>
267
+ <div v-if="(keyReturnStatuses.length > 0)" class="mb-2">
268
+ <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">
272
+ {{ (key as any)?.prefixAndName }}
273
+ </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>
278
+ </v-row>
279
+ </div>
280
+
281
+ <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>
284
+ </v-row>
285
+ </v-card-text>
286
+ <v-toolbar class="pa-0" density="compact">
287
+ <v-row no-gutters>
288
+ <v-col cols="6">
289
+ <v-btn variant="text" block
290
+ @click="dialog.returnPassesKeys = false">Close</v-btn>
291
+ </v-col>
292
+ <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>
295
+ </v-col>
296
+ </v-row>
297
+ </v-toolbar>
298
+ </v-card>
299
+ </v-dialog>
300
+
301
+ <v-dialog v-model="dialog.addPassKey" width="450" persistent>
302
+ <AddPassKeyToVisitor :visitor="selectedVisitorDataObject" :site="siteId" @close="dialog.addPassKey = false"
303
+ @update="getVisitorRefresh" />
304
+ </v-dialog>
305
+
182
306
  <Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />
183
307
  </v-row>
184
308
  </template>
@@ -256,6 +380,8 @@ const loading = reactive({
256
380
  deletingVisitor: false,
257
381
  fetchingVisitors: false,
258
382
  checkingOut: false,
383
+ savingRemarks: false,
384
+ updatingPassKeys: false,
259
385
  });
260
386
 
261
387
  const dialog = reactive({
@@ -264,9 +390,15 @@ const dialog = reactive({
264
390
  viewVisitor: false,
265
391
  deleteConfirmation: false,
266
392
  snapshotImage: false,
393
+ remarks: false,
394
+ returnPassesKeys: false,
395
+ addPassKey: false
267
396
  });
268
397
 
269
398
  const snapshotImageUrl = ref("");
399
+ const remarksType = ref<'checkIn' | 'checkOut'>('checkIn');
400
+ const remarksInput = ref("");
401
+ const remarksViewOnly = ref(false);
270
402
 
271
403
  const headers = computed(() => [
272
404
  { title: "Name", value: "name" },
@@ -274,6 +406,7 @@ const headers = computed(() => [
274
406
  { title: "Location", value: "location" },
275
407
  { title: "Contact/Vehicle No.", value: "contact-vehicleNumber" },
276
408
  { title: "Check In/Out", value: "checkin-out" },
409
+ ...(activeTab.value === "resident-transactions" ? [{ title: "Check-in Remarks", value: "checkInRemarks" }, { title: "Check-out Remarks", value: "checkOutRemarks" }] : []),
277
410
  ...(activeTab.value === 'unregistered' ? [{ title: "Action", value: "action" }] : [])
278
411
  ])
279
412
 
@@ -314,7 +447,15 @@ function filterTypeSelectionLabel() {
314
447
  return `${length} selected ${length === 1 ? "type" : "types"}` as string;
315
448
  }
316
449
 
450
+ const passStatusOptions = [
451
+ { label: "Returned", value: "Returned" },
452
+ { label: "Not Returned", value: "In Use" },
453
+ { label: "Damaged", value: "Damaged" },
454
+ { label: "Lost", value: "Lost" },
455
+ ]
456
+
317
457
  function toRoute(tab: any) {
458
+ items.value = []
318
459
 
319
460
  const obj = tabOptions.find((x) => x.value === tab);
320
461
  if (!obj) return;
@@ -358,7 +499,7 @@ const {
358
499
  // params.status = "pending"
359
500
  // }
360
501
 
361
- if(activeTab.value === "guests"){
502
+ if (activeTab.value === "guests") {
362
503
  params.type = "guest"
363
504
  params.status = "pending"
364
505
  } else if (activeTab.value === "resident-transactions") {
@@ -381,6 +522,7 @@ const {
381
522
  watch(getVisitorReq, (newData: any) => {
382
523
  if (newData) {
383
524
  items.value = newData.items ?? [];
525
+ // items.value = [{ _id: "testid", name: "John Doe", type: "Contractor", company: "ABC Corp", location: "Block A, Level 1, Unit 101", contact: "12345678", plateNumber: "SGX1234A", checkIn: new Date().toISOString(), checkOut: null, status: "registered", visitorPass: [{ _id: "1", keyId: "pass1", prefixAndName: "VIP Pass" }, { _id: "2", keyId: "pass2", prefixAndName: "VIP Pass 2" }], passKeys: [{ _id: "1", keyId: "key2", prefixAndName: "Master Key" }] }];
384
526
  pages.value = newData.pages ?? 0;
385
527
  pageRange.value = newData?.pageRange ?? "-- - -- of --";
386
528
  }
@@ -412,6 +554,8 @@ function formatValues(key: string, value: any) {
412
554
  return value;
413
555
  }
414
556
 
557
+
558
+
415
559
  function handleAddNew() {
416
560
  dialog.showSelection = true;
417
561
  activeVisitorFormType.value = null;
@@ -427,6 +571,15 @@ function handleUpdatePage(newPageNum: number) {
427
571
  page.value = newPageNum;
428
572
  }
429
573
 
574
+ function showAddPassKeyButton(item: any) {
575
+ const hasPasses = (item?.visitorPass?.length ?? 0) > 0;
576
+ const hasKeys = (item?.passKeys?.length ?? 0) > 0;
577
+
578
+ const isTypeWithPassKey = ["contractor", "guest", "walk-in"].includes(item?.type);
579
+
580
+ return !hasPasses && !hasKeys && isTypeWithPassKey && item?.status === "registered" && !item?.checkOut;
581
+ }
582
+
430
583
  function handleSelectVisitorType(type: TVisitorType) {
431
584
  dialog.showSelection = false;
432
585
  dialog.showForm = true;
@@ -479,6 +632,63 @@ function handleViewImage(imageId: string) {
479
632
  dialog.snapshotImage = true;
480
633
  }
481
634
 
635
+ function handleOpenAddPassKey(item: any) {
636
+ selectedVisitorId.value = item?._id;
637
+ dialog.addPassKey = true;
638
+ }
639
+
640
+ function handleOpenRemarks(item: any, type: 'checkIn' | 'checkOut') {
641
+ selectedVisitorId.value = item?._id;
642
+ remarksType.value = type;
643
+ const existingRemarks = type === 'checkIn' ? item?.checkInRemarks : item?.checkOutRemarks;
644
+ remarksInput.value = existingRemarks || "";
645
+ remarksViewOnly.value = !!existingRemarks;
646
+ dialog.remarks = true;
647
+ }
648
+
649
+ async function handleSaveRemarks() {
650
+ if (!remarksInput.value.trim() || !selectedVisitorId.value) return;
651
+ try {
652
+ loading.savingRemarks = true;
653
+ const payload = remarksType.value === 'checkIn'
654
+ ? { checkInRemarks: remarksInput.value.trim() }
655
+ : { checkOutRemarks: remarksInput.value.trim() };
656
+ await updateVisitor(selectedVisitorId.value, payload);
657
+ showMessage("Remarks saved successfully!", "info");
658
+ await getVisitorRefresh();
659
+ dialog.remarks = false;
660
+ } catch (error: any) {
661
+ const errorMessage = error?.response?._data?.message;
662
+ showMessage(errorMessage || "Something went wrong. Please try again later.", "error");
663
+ } finally {
664
+ loading.savingRemarks = false;
665
+ }
666
+ }
667
+
668
+ async function handleUpdatePassKeys() {
669
+ if (!selectedVisitorId.value) return;
670
+ try {
671
+ loading.updatingPassKeys = true;
672
+ const payload: any = {};
673
+ if (passReturnStatuses.value.length > 0) {
674
+ const passReturnStatusesPayload = passReturnStatuses.value.map(p => ({ keyId: p.keyId, status: p.status, remarks: p.remarks }));
675
+ payload.visitorPass = passReturnStatusesPayload;
676
+ }
677
+ if (keyReturnStatuses.value.length > 0) {
678
+ const keyReturnStatusesPayload = keyReturnStatuses.value.map(k => ({ keyId: k.keyId, status: k.status, remarks: k.remarks }));
679
+ payload.passKeys = keyReturnStatusesPayload;
680
+ }
681
+ await updateVisitor(selectedVisitorId.value, payload);
682
+ showMessage("Pass/Key statuses updated successfully!", "info");
683
+ await getVisitorRefresh();
684
+ } catch (error: any) {
685
+ const errorMessage = error?.response?._data?.message;
686
+ showMessage(errorMessage || "Something went wrong. Please try again later.", "error");
687
+ } finally {
688
+ loading.updatingPassKeys = false;
689
+ }
690
+ }
691
+
482
692
 
483
693
  async function handleProceedDeleteVisitor() {
484
694
  try {
@@ -502,22 +712,63 @@ async function handleProceedDeleteVisitor() {
502
712
  }
503
713
  }
504
714
 
505
- async function handleCheckout(userId: string) {
715
+
716
+ const passReturnStatuses = ref<{ keyId: string, status: string, prefixAndName: string, remarks: string }[]>([]);
717
+ const keyReturnStatuses = ref<{ keyId: string, status: string, prefixAndName: string, remarks: string }[]>([]);
718
+
719
+ const canConfirmCheckout = computed(() => {
720
+ const allEntries = [...passReturnStatuses.value, ...keyReturnStatuses.value];
721
+ return allEntries.every((entry) => {
722
+ if (!entry.status || entry.status === 'In Use') return false;
723
+ if ((entry.status === 'Lost' || entry.status === 'Damaged') && !entry.remarks.trim()) return false;
724
+ return true;
725
+ });
726
+ });
727
+
728
+
729
+
730
+ function handleCheckout(userId: string) {
506
731
  if (!userId) {
507
732
  showMessage("Invalid userId", "error");
508
733
  return;
509
734
  }
510
735
  selectedVisitorId.value = userId;
511
736
 
737
+ const visitor = items.value.find((x: any) => x?._id === userId);
738
+ const hasPasses = (visitor?.visitorPass?.length ?? 0) > 0;
739
+ const hasKeys = (visitor?.passKeys?.length ?? 0) > 0;
740
+
741
+ if (hasPasses || hasKeys) {
742
+ const visitor = items.value.find((x: any) => x?._id === userId);
743
+ passReturnStatuses.value = ((visitor?.visitorPass as any[]) || []).map((p: any) => ({ keyId: p.keyId, status: p.status ?? "In Use", remarks: '', prefixAndName: p.prefixAndName }));
744
+ keyReturnStatuses.value = ((visitor?.passKeys as any[]) || []).map((k: any) => ({ keyId: k.keyId, status: k.status ?? "In Use", remarks: '', prefixAndName: k.prefixAndName }));
745
+ dialog.returnPassesKeys = true;
746
+ return;
747
+ }
748
+
749
+ proceedCheckout();
750
+ }
751
+
752
+ async function proceedCheckout() {
753
+ const userId = selectedVisitorId.value;
754
+ if (!userId) return;
755
+
512
756
  try {
513
757
  loading.checkingOut = true;
758
+
759
+ const passReturnStatusesPayload = passReturnStatuses.value.map(p => ({ keyId: p.keyId, status: p.status, remarks: p.remarks }));
760
+ const keyReturnStatusesPayload = keyReturnStatuses.value.map(k => ({ keyId: k.keyId, status: k.status, remarks: k.remarks }));
761
+
514
762
  const res = await updateVisitor(userId as string, {
515
763
  checkOut: new Date().toISOString(),
764
+ ...(passReturnStatuses.value.length > 0 ? { visitorPass: passReturnStatusesPayload } : {}),
765
+ ...(keyReturnStatuses.value.length > 0 ? { passKeys: keyReturnStatusesPayload } : {}),
516
766
  });
517
767
  if (res) {
518
768
  showMessage("Visitor successfully checked-out!", "info");
519
769
  await getVisitorRefresh();
520
770
  dialog.viewVisitor = false;
771
+ dialog.returnPassesKeys = false;
521
772
  }
522
773
  } catch (error: any) {
523
774
  const errorMessage = error?.response?._data?.message;
@@ -195,6 +195,7 @@ export default function useKey() {
195
195
  organization,
196
196
  startDateTime,
197
197
  endDateTime,
198
+ statuses
198
199
  }: {
199
200
  page?: number;
200
201
  search?: string | ISearch;
@@ -204,6 +205,7 @@ export default function useKey() {
204
205
  organization?: string;
205
206
  startDateTime?: string;
206
207
  endDateTime?: string;
208
+ statuses?: string[];
207
209
  } = {}) {
208
210
  /*
209
211
  search here should accept
@@ -220,6 +222,7 @@ export default function useKey() {
220
222
  organization,
221
223
  startDateTime,
222
224
  endDateTime,
225
+ statuses
223
226
  },
224
227
  });
225
228
  }
@@ -381,5 +384,6 @@ export default function useKey() {
381
384
  passTypesStatus,
382
385
  getCountTotalKeys,
383
386
  getKeyWithSequence,
387
+ getKeysByKeyPageSearch
384
388
  };
385
389
  }
@@ -29,7 +29,7 @@ export default function useLocalAuth() {
29
29
 
30
30
  const currentUser = useState(
31
31
  "currentUser",
32
- (): TUser => JSON.parse(JSON.stringify(user))
32
+ (): TUser | null => JSON.parse(JSON.stringify(user))
33
33
  );
34
34
 
35
35
  async function authenticate() {
@@ -41,9 +41,7 @@ export default function useLocalAuth() {
41
41
  );
42
42
 
43
43
  watchEffect(() => {
44
- if (getCurrentUserReq.value) {
45
- currentUser.value = getCurrentUserReq.value;
46
- }
44
+ currentUser.value = getCurrentUserReq.value as TUser | null;
47
45
  });
48
46
 
49
47
  watchEffect(() => {
@@ -98,6 +98,19 @@ export default function () {
98
98
  });
99
99
  }
100
100
 
101
+ async function updateSiteInformation(
102
+ siteId: string,
103
+ payload: { bgImage: string; description: string; docs: { id: string; name: string }[] }
104
+ ) {
105
+ return await useNuxtApp().$api<Record<string, any>>(
106
+ `/api/sites/information/id/${siteId}`,
107
+ {
108
+ method: "PATCH",
109
+ body: payload,
110
+ }
111
+ );
112
+ }
113
+
101
114
  async function setSiteGuardPosts(siteId: string, value: number) {
102
115
  return await useNuxtApp().$api<Record<string, any>>(
103
116
  `/api/sites/guard-post/id/${siteId}`,
@@ -138,6 +151,7 @@ export default function () {
138
151
  updateSiteCamera,
139
152
  deleteSiteCameraById,
140
153
  updateSitebyId,
154
+ updateSiteInformation,
141
155
  getOvernightParkingAvailability,
142
156
  updateOvernightParkingAvailability
143
157
  };
@@ -269,14 +269,18 @@ export default function useTemplateReusable() {
269
269
  _id,
270
270
  site,
271
271
  status,
272
+ userType,
273
+ updatedBy,
272
274
  }: {
273
275
  _id?: string;
274
276
  site?: string;
275
277
  status?: string;
278
+ userType?: string;
279
+ updatedBy?: string;
276
280
  }) {
277
281
  return useNuxtApp().$api("/api/qr-code-templates/v1", {
278
282
  method: "PUT",
279
- body: { _id, site, status },
283
+ body: { _id, site, status, userType, updatedBy },
280
284
  });
281
285
  }
282
286
 
@@ -27,7 +27,7 @@ export default function useVehicle() {
27
27
  }
28
28
 
29
29
  async function updateVehicle(id: string, payload: Partial<TVehiclePayload>) {
30
- return await useNuxtApp().$api<Record<string, any>>(`/api/vehicles/${id}`, {
30
+ return await useNuxtApp().$api<Record<string, any>>(`/api/vehicles/id/${id}`, {
31
31
  method: "PUT",
32
32
  body: payload,
33
33
  });
@@ -51,11 +51,11 @@ export default function useVehicle() {
51
51
  }
52
52
  );
53
53
  }
54
-
54
+
55
55
  interface IDeleteVehicleParams {
56
56
  site: string;
57
57
  id: string;
58
- recno: string;
58
+ recno?: string;
59
59
  type: "whitelist" | "blocklist";
60
60
  }
61
61
 
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@7365admin1/layer-common",
3
3
  "license": "MIT",
4
4
  "type": "module",
5
- "version": "1.11.17",
5
+ "version": "1.11.19",
6
6
  "author": "7365admin1",
7
7
  "main": "./nuxt.config.ts",
8
8
  "publishConfig": {
@@ -9,6 +9,7 @@ declare type TVehicle = {
9
9
  block: number | "";
10
10
  level: string;
11
11
  unit: string;
12
+ uniName?: string; // For display purposes, the API will return the unit name if available
12
13
  nric?: string | null;
13
14
  remarks?: string;
14
15
  seasonPassType?: string;
@@ -43,4 +44,4 @@ declare type TVehiclePayload = Pick<
43
44
  | "site"
44
45
  | "org"
45
46
  | "peopleId"
46
- > & { plateNumber: string[] };
47
+ > & { plateNumber?: string | string[] };
@@ -20,11 +20,15 @@ declare type TVisitor = {
20
20
  org: string;
21
21
  site: string,
22
22
  manualCheckout?: boolean;
23
+ visitorPass?: TPassKeyPayload[];
24
+ passKeys?: TPassKeyPayload[]
25
+ checkInRemarks?: string;
26
+ checkOutRemarks?: string;
23
27
  };
24
28
 
25
29
  declare type TVisitorType = "contractor" | "delivery" | "walk-in" | "pick-up" | "drop-off" | "guest";
26
30
 
27
- declare type TVisitorPayload = Pick<TVisitor, "name" | "type" | "company" | "block" | "level" | "unit" | "unitName" | "contact" | "plateNumber" | "checkOut" | "contractorType" | "deliveryType" | "nric" | "contact" | "remarks" | "attachments" | "org" | "site" | "status"> & {
31
+ declare type TVisitorPayload = Pick<TVisitor, "name" | "type" | "company" | "block" | "level" | "unit" | "unitName" | "contact" | "plateNumber" | "checkOut" | "contractorType" | "deliveryType" | "nric" | "contact" | "remarks" | "attachments" | "org" | "site" | "status" | "visitorPass" | "passKeys" | "checkInRemarks" | "checkOutRemarks"> & {
28
32
  members?: TMemberInfo[]
29
33
  }
30
34
 
@@ -38,6 +42,13 @@ declare type TDefaultOptionObj = {
38
42
  declare type TMemberInfo = {
39
43
  name: string;
40
44
  nric: string;
41
- visitorPass: string;
45
+ visitorPass?: string;
46
+ passKeys?: TPassKeyPayload[];
42
47
  contact: string
43
48
  }
49
+
50
+ declare type TPassKeyPayload = {
51
+ keyId: string;
52
+ status?: string;
53
+ remarks?: string;
54
+ }