@7365admin1/layer-common 3.1.2-staging.37 → 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 (31) 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 +29 -46
  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/package.json +1 -1
  27. package/types/customer.d.ts +1 -2
  28. package/types/equipment.d.ts +1 -5
  29. package/types/nfc-patrol-report.ts +1 -19
  30. package/components/Nfc/PatrolReport/MonthlyReportTable.vue +0 -69
  31. package/components/Nfc/PatrolReport/ReportDatePicker.vue +0 -61
@@ -4,9 +4,9 @@
4
4
  :model-value="filters"
5
5
  :options="options"
6
6
  @update:model-value="$emit('update:filters', $event)"
7
- @export="(type) => $emit('export', type)"
7
+ @export="$emit('export')"
8
8
  />
9
- <div class="report-export">
9
+
10
10
  <v-divider :thickness="1" class="border-opacity-100" />
11
11
 
12
12
  <template v-if="report">
@@ -30,7 +30,6 @@
30
30
  <ReportEmptyState v-else-if="!loading" />
31
31
 
32
32
  <RemarksDialog v-model="dialogRemarks" :remarks="selectedActivityRemarks" />
33
- </div>
34
33
  </div>
35
34
  </template>
36
35
 
@@ -56,7 +55,7 @@ const props = defineProps<{
56
55
 
57
56
  defineEmits<{
58
57
  "update:filters": [value: NFCPatrolReportFilters];
59
- export: [type: "pdf" | "csv"];
58
+ export: [];
60
59
  }>();
61
60
 
62
61
  const {
@@ -78,5 +77,4 @@ watch(
78
77
  },
79
78
  { immediate: true },
80
79
  );
81
-
82
80
  </script>
@@ -16,12 +16,7 @@
16
16
  />
17
17
  </v-col>
18
18
 
19
- <v-col
20
- v-if="showTimeFilter"
21
- cols="12"
22
- md="2"
23
- class="px-md-2 mb-2 mb-md-0"
24
- >
19
+ <v-col cols="12" md="2" class="px-md-2 mb-2 mb-md-0">
25
20
  <v-select
26
21
  :model-value="modelValue.timeRange"
27
22
  :items="options.timeRanges"
@@ -35,14 +30,10 @@
35
30
  />
36
31
  </v-col>
37
32
 
38
- <v-col
39
- v-if="showDateFilter"
40
- cols="12"
41
- md="2"
42
- class="px-md-2 mb-2 mb-md-0"
43
- >
44
- <ReportDatePicker
33
+ <v-col cols="12" md="2" class="px-md-2 mb-2 mb-md-0">
34
+ <v-text-field
45
35
  :model-value="modelValue.date"
36
+ type="date"
46
37
  variant="outlined"
47
38
  density="comfortable"
48
39
  rounded="lg"
@@ -55,31 +46,17 @@
55
46
  <v-spacer />
56
47
 
57
48
  <v-col cols="12" md="2" class="pl-md-2">
58
- <v-menu>
59
- <template #activator="{ props: menuProps }">
60
- <v-btn
61
- v-bind="menuProps"
62
- variant="outlined"
63
- block
64
- size="large"
65
- rounded="lg"
66
- class="text-none"
67
- prepend-icon="mdi-export"
68
- >
69
- Export
70
- </v-btn>
71
- </template>
72
-
73
- <v-list density="compact">
74
- <v-list-item @click="$emit('export', 'pdf')">
75
- <v-list-item-title>PDF</v-list-item-title>
76
- </v-list-item>
77
-
78
- <v-list-item @click="$emit('export', 'csv')">
79
- <v-list-item-title>CSV</v-list-item-title>
80
- </v-list-item>
81
- </v-list>
82
- </v-menu>
49
+ <v-btn
50
+ variant="outlined"
51
+ block
52
+ size="large"
53
+ rounded="lg"
54
+ class="text-none"
55
+ prepend-icon="mdi-export"
56
+ @click="$emit('export')"
57
+ >
58
+ Export
59
+ </v-btn>
83
60
  </v-col>
84
61
  </v-row>
85
62
  </template>
@@ -89,24 +66,15 @@ import type {
89
66
  NFCPatrolReportFilterOptions,
90
67
  NFCPatrolReportFilters,
91
68
  } from "../../../types/nfc-patrol-report";
92
- import ReportDatePicker from "./ReportDatePicker.vue";
93
69
 
94
- const props = withDefaults(
95
- defineProps<{
96
- modelValue: NFCPatrolReportFilters;
97
- options: NFCPatrolReportFilterOptions;
98
- showTimeFilter?: boolean;
99
- showDateFilter?: boolean;
100
- }>(),
101
- {
102
- showTimeFilter: true,
103
- showDateFilter: true,
104
- },
105
- );;
70
+ const props = defineProps<{
71
+ modelValue: NFCPatrolReportFilters;
72
+ options: NFCPatrolReportFilterOptions;
73
+ }>();
106
74
 
107
75
  const emit = defineEmits<{
108
76
  "update:modelValue": [value: NFCPatrolReportFilters];
109
- export: [type: "pdf" | "csv"];
77
+ export: [];
110
78
  }>();
111
79
 
112
80
  function updateFilter(key: keyof NFCPatrolReportFilters, value: unknown) {
@@ -8,8 +8,6 @@
8
8
  <tr>
9
9
  <th>Patrol Route Name</th>
10
10
  <th>Security Check Schedule</th>
11
- <th>Security Personnel</th>
12
- <th>Signature</th>
13
11
  <th>Checked</th>
14
12
  <th>Missed</th>
15
13
  <th>Status</th>
@@ -22,17 +20,6 @@
22
20
  <v-icon size="small" class="mr-1">mdi-clock-outline</v-icon>
23
21
  {{ row.securityCheckSchedule }}
24
22
  </td>
25
- <td>{{ row.guardName || "-" }}</td>
26
- <td>
27
- <v-img
28
- v-if="row.guardSignatureFileId"
29
- :src="getFileUrl(row.guardSignatureFileId)"
30
- :alt="`${row.guardName || 'Guard'} signature`"
31
- class="guard-signature"
32
- contain
33
- />
34
- <span v-else>-</span>
35
- </td>
36
23
  <td>{{ row.checked }}</td>
37
24
  <td>{{ row.missed }}</td>
38
25
  <td>
@@ -58,16 +45,7 @@ defineProps<{
58
45
  rows: NFCPatrolReportSummaryRow[];
59
46
  }>();
60
47
 
61
- const { getFileUrl } = useFile();
62
-
63
48
  function statusClass(status: NFCPatrolReportSummaryStatus) {
64
49
  return status === "Completed" ? "text-success" : "text-error";
65
50
  }
66
51
  </script>
67
-
68
- <style scoped>
69
- .guard-signature {
70
- width: 80px;
71
- height: 40px;
72
- }
73
- </style>
@@ -59,21 +59,6 @@
59
59
  </v-col>
60
60
  </v-row>
61
61
 
62
- <v-dialog v-model="showPhotoPreview" max-width="900">
63
- <v-card>
64
- <v-card-actions class="pa-2 justify-end">
65
- <v-btn
66
- icon="mdi-close"
67
- variant="text"
68
- @click="showPhotoPreview = false"
69
- />
70
- </v-card-actions>
71
- <v-card-text class="pa-2 pt-0">
72
- <v-img :src="selectedPhoto" contain max-height="80vh" />
73
- </v-card-text>
74
- </v-card>
75
- </v-dialog>
76
-
77
62
  <v-dialog v-model="photoOptionsDialog" max-width="420">
78
63
  <v-card>
79
64
  <v-card-title class="d-flex align-center pa-4">
@@ -211,8 +196,6 @@ const photos = ref<string[]>([...props.modelValue]);
211
196
  const photosIds = ref<string[]>([...props.photoIds]);
212
197
  const photoOptionsDialog = ref(false);
213
198
  const showCameraDialog = ref(false);
214
- const showPhotoPreview = ref(false);
215
- const selectedPhoto = ref("");
216
199
  const videoRef = ref<HTMLVideoElement | null>(null);
217
200
  const canvasRef = ref<HTMLCanvasElement | null>(null);
218
201
  const fileInputRef = ref<HTMLInputElement | null>(null);
@@ -222,8 +205,10 @@ const uploading = ref(false);
222
205
  const { addFile } = useFile();
223
206
 
224
207
  function viewPhoto(photoData: string) {
225
- selectedPhoto.value = photoData;
226
- showPhotoPreview.value = true;
208
+ const link = document.createElement("a");
209
+ link.href = photoData;
210
+ link.target = "_blank";
211
+ link.click();
227
212
  }
228
213
 
229
214
  watch(
@@ -548,7 +548,7 @@
548
548
  variant="flat"
549
549
  class="text-none sp-invite-submit-btn"
550
550
  height="76"
551
- :disabled="!canSubmitInvite"
551
+ :disabled="!validServiceProvider"
552
552
  :loading="disableServiceProvider"
553
553
  @click="submitServiceProviderInvite()"
554
554
  >
@@ -574,7 +574,6 @@ type ListTab = "active" | "pending" | "inactive";
574
574
 
575
575
  type TableRow = {
576
576
  _id: string;
577
- userId: string;
578
577
  serviceProviderOrgId: string;
579
578
  companyName: string;
580
579
  email: string;
@@ -734,10 +733,11 @@ const {
734
733
  updateStatus: updateServiceProviderStatus,
735
734
  invite,
736
735
  } = useServiceProvider();
737
- const { getAllByUserId } = useMember();
736
+ const { getAll: getAllMembers } = useMember();
738
737
 
739
738
  const { getVerifications, cancelUserInvitation, getVerificationByEmail } =
740
739
  useVerification();
740
+ const { getOrgsByMembership } = useMember();
741
741
 
742
742
  const existingAccount = ref<any>(null);
743
743
  const checkingExistingAccount = ref(false);
@@ -757,10 +757,11 @@ const createInviteDialog = ref(false);
757
757
  // const loadingInviteRoles = ref(false);
758
758
  // const serviceProviderInviteRoles = ref<Array<Record<string, any>>>([]);
759
759
 
760
+ const { getByUserType } = useMember();
761
+ const { getOrgs } = useOrg();
760
762
 
761
763
  async function checkExistingAccount(email: string) {
762
764
  existingAccount.value = null;
763
- messageServiceProvider.value = "";
764
765
 
765
766
  if (!email.trim() || emailRule(email) !== true) return;
766
767
 
@@ -769,50 +770,30 @@ async function checkExistingAccount(email: string) {
769
770
  try {
770
771
  const user = await getUserByEmail(email);
771
772
 
772
- if (!user?._id) return;
773
-
774
- const members = await getAllByUserId(user._id);
775
-
776
- const appMember = (members.items ?? []).find(
777
- (member: any) => member.type === serviceProviderInvite.value.app
778
- );
779
-
780
- if (!appMember) {
781
- existingAccount.value = null;
782
- return;
783
- }
773
+ if (!user?._id) return;
784
774
 
785
- if (
786
- appMember.org === props.orgId &&
787
- (appMember.siteId || "") === (props.siteId || "")
788
- ) {
789
- existingAccount.value = null;
790
- messageServiceProvider.value =
791
- "This user is already a member of this service provider.";
792
- return;
793
- }
775
+ const orgs = await getOrgs({
776
+ user: user._id,
777
+ });
794
778
 
795
- existingAccount.value = {
796
- _id: appMember.org,
797
- text: appMember.orgName,
798
- org: appMember.org,
799
- orgName: appMember.orgName,
800
- siteId: appMember.siteId,
801
- siteName: appMember.siteName,
802
- };
779
+ const matchedOrg = orgs.items?.find(
780
+ (org: any) => org.type === serviceProviderInvite.value.app
781
+ );
803
782
 
783
+ if (matchedOrg) {
784
+ existingAccount.value = {
785
+ _id: matchedOrg.value,
786
+ text: matchedOrg.text,
787
+ ...matchedOrg,
788
+ };
789
+ }
804
790
  } catch (error) {
805
791
  existingAccount.value = null;
806
792
  } finally {
807
793
  checkingExistingAccount.value = false;
808
794
  }
809
795
  }
810
- const canSubmitInvite = computed(() => {
811
- return (
812
- validServiceProvider.value &&
813
- !messageServiceProvider.value
814
- );
815
- });
796
+
816
797
  watch(
817
798
  () => serviceProviderInvite.value.email,
818
799
  async (value) => {
@@ -958,7 +939,6 @@ function formatEmailCell(value: unknown): string {
958
939
  function mapProviderRows(raw: Record<string, any>[]): TableRow[] {
959
940
  return raw.map((row) => ({
960
941
  _id: String(row._id ?? ""),
961
- userId: String(row.user ?? ""),
962
942
  serviceProviderOrgId: String(row.serviceProviderOrgId ?? ""),
963
943
  companyName: row.name ?? "-",
964
944
  email: formatEmailCell(row.email),
@@ -981,7 +961,6 @@ function inviteTypeLabel(t: string) {
981
961
  function mapInviteRows(raw: Record<string, any>[]): TableRow[] {
982
962
  return raw.map((row) => ({
983
963
  _id: String(row._id ?? ""),
984
- userId: String(row.user ?? ""),
985
964
  serviceProviderOrgId: String(row.metadata?.serviceProviderOrgId ?? ""),
986
965
  companyName: row.metadata?.name || "-",
987
966
  email: formatEmailCell(row.email),
@@ -1050,12 +1029,16 @@ async function openView(row: TableRow) {
1050
1029
 
1051
1030
  loadingMembers.value = true;
1052
1031
  try {
1053
- const data = await getAllByUserId(row.userId);
1054
-
1032
+ const data = await getAllMembers({
1033
+ page: 1,
1034
+ limit: 1000,
1035
+ org: row.serviceProviderOrgId,
1036
+ status: "active",
1037
+ });
1055
1038
  serviceProviderMembers.value = (data.items ?? []).map((member: any) => ({
1056
- _id: member._id,
1057
- name: member.name || "-",
1058
- role: member.role || "-",
1039
+ _id: String(member._id ?? ""),
1040
+ name: member.name || member.fullName || member.email || "-",
1041
+ role: member.roleName || member.role?.name || "-",
1059
1042
  }));
1060
1043
  } catch (error: any) {
1061
1044
  showMessage(errorConverter(error), "error");
@@ -36,17 +36,10 @@
36
36
  </template>
37
37
 
38
38
  <v-list v-if="nricSearchResults.length" class="pa-1 phone-search-results">
39
- <div class="search-results-scroll">
40
- <v-list-item v-for="(item, index) in nricSearchResults" :key="item._id || index"
41
- @click="selectNricSearchResult(item)" class="cursor-pointer nric-search-item">
42
- <VisitorSearchResultSummary :item="item" />
43
- </v-list-item>
44
- </div>
45
- <div class="search-results-close pa-1">
46
- <v-btn block variant="flat" color="red" @click.stop="closeAutofillSearchResults('nric')">
47
- Close
48
- </v-btn>
49
- </div>
39
+ <v-list-item v-for="(item, index) in nricSearchResults" :key="item._id || index"
40
+ @click="selectNricSearchResult(item)" class="cursor-pointer nric-search-item">
41
+ <VisitorSearchResultSummary :item="item" />
42
+ </v-list-item>
50
43
  </v-list>
51
44
  </v-menu>
52
45
  </v-col>
@@ -65,17 +58,10 @@
65
58
  </template>
66
59
 
67
60
  <v-list v-if="phoneSearchResults.length" class="pa-1 phone-search-results">
68
- <div class="search-results-scroll">
69
- <v-list-item v-for="(item, index) in phoneSearchResults" :key="item._id || index"
70
- @click="selectPhoneNumberSearchResult(item)" class="cursor-pointer nric-search-item">
71
- <VisitorSearchResultSummary :item="item" />
72
- </v-list-item>
73
- </div>
74
- <div class="search-results-close pa-1">
75
- <v-btn block variant="flat" color="red" @click.stop="closeAutofillSearchResults('contact')">
76
- Close
77
- </v-btn>
78
- </div>
61
+ <v-list-item v-for="(item, index) in phoneSearchResults" :key="item._id || index"
62
+ @click="selectPhoneNumberSearchResult(item)" class="cursor-pointer nric-search-item">
63
+ <VisitorSearchResultSummary :item="item" />
64
+ </v-list-item>
79
65
  </v-list>
80
66
  </v-menu>
81
67
  </v-col>
@@ -91,23 +77,15 @@
91
77
  <v-menu v-model="vehicleSearchMenu" location="bottom" offset-y :close-on-content-click="false">
92
78
  <template #activator="{ props }">
93
79
  <InputVehicleNumber v-bind="props" v-model="visitor.plateNumber" density="comfortable"
94
- @update:model-value="handleUpdateVehicleNumber" @focus="handleFocusPlateNumber"
80
+ @update:model-value="handleUpdateVehicleNumber" @focus="isPlateNumberFieldFocused = true"
95
81
  @blur="isPlateNumberFieldFocused = false" />
96
82
  </template>
97
83
 
98
84
  <v-list v-if="vehicleSearchResults.length" class="pa-1 phone-search-results">
99
- <div class="search-results-scroll">
100
- <v-list-item v-for="(item, index) in vehicleSearchResults" :key="item._id || index"
101
- @click="selectPlateNumberSearchResult(item)" class="cursor-pointer nric-search-item">
102
- <VisitorSearchResultSummary :item="item" />
103
- </v-list-item>
104
- </div>
105
- <div class="search-results-close pa-1">
106
- <v-btn block variant="flat" color="red"
107
- @click.stop="closeAutofillSearchResults('vehicleNumber')">
108
- Close
109
- </v-btn>
110
- </div>
85
+ <v-list-item v-for="(item, index) in vehicleSearchResults" :key="item._id || index"
86
+ @click="selectPlateNumberSearchResult(item)" class="cursor-pointer nric-search-item">
87
+ <VisitorSearchResultSummary :item="item" />
88
+ </v-list-item>
111
89
  </v-list>
112
90
  </v-menu>
113
91
  </v-col>
@@ -330,10 +308,10 @@
330
308
 
331
309
  <div class="nric-selected-person d-flex align-center justify-space-between ga-3 mb-5">
332
310
  <span>{{ selectedNricSearchResult.name || "Unknown" }}</span>
333
- <span v-if="!visitor.nric || currentAutofillSource === 'nric'" class="text-no-wrap">NRIC: {{ selectedNricSearchResult.nric || "N/A" }}</span>
311
+ <span class="text-no-wrap">NRIC: {{ selectedNricSearchResult.nric || "N/A" }}</span>
334
312
  </div>
335
313
 
336
- <template v-if="(!visitor.contact || currentAutofillSource === 'contact') && selectedNricContactOptions.length >= 1">
314
+ <template v-if="!visitor.contact && selectedNricContactOptions.length >= 1">
337
315
  <h3 class="nric-options-section-title font-weight-bold mb-2">Contact</h3>
338
316
  <v-radio-group v-model="selectedNricContact" hide-details color="success" class="nric-option-group">
339
317
  <v-radio v-for="contact in selectedNricContactOptions" :key="contact" :label="contact" :value="contact"
@@ -341,7 +319,7 @@
341
319
  </v-radio-group>
342
320
  </template>
343
321
 
344
- <template v-if="(!visitor.plateNumber || currentAutofillSource === 'vehicleNumber') && selectedNricPlateOptions.length >= 1">
322
+ <template v-if="!visitor.plateNumber && selectedNricPlateOptions.length >= 1">
345
323
  <h3 class="nric-options-section-title font-weight-bold mb-2 mt-5">Vehicle</h3>
346
324
  <v-radio-group v-model="selectedNricPlate" hide-details color="success" class="nric-option-group">
347
325
  <v-radio v-for="plate in selectedNricPlateOptions" :key="plate" :label="plate" :value="plate"
@@ -1066,8 +1044,8 @@ function selectAutofillSearchResult(item: Partial<TPeople>, source: Exclude<Auto
1066
1044
  const selectedPlate =
1067
1045
  findMatchingPlateOption(plateOptions, visitor.plateNumber) || plateOptions[0] || "";
1068
1046
 
1069
- const needsContactChoice = (!visitor.contact?.trim() || source === 'contact') && contactOptions.length > 1;
1070
- const needsPlateChoice = (!visitor.plateNumber?.trim() || source === 'vehicleNumber') && plateOptions.length > 1;
1047
+ const needsContactChoice = !visitor.contact?.trim() && contactOptions.length > 1;
1048
+ const needsPlateChoice = !visitor.plateNumber?.trim() && plateOptions.length > 1;
1071
1049
 
1072
1050
  if (needsContactChoice || needsPlateChoice) {
1073
1051
  nricSearchMenu.value = false;
@@ -1088,23 +1066,6 @@ function selectAutofillSearchResult(item: Partial<TPeople>, source: Exclude<Auto
1088
1066
  });
1089
1067
  }
1090
1068
 
1091
- function closeAutofillSearchResults(source: Exclude<AutofillSource, null>) {
1092
- if (source === "nric") {
1093
- nricSearchMenu.value = false;
1094
- nricSearchResults.value = [];
1095
- }
1096
-
1097
- if (source === "contact") {
1098
- phoneSearchMenu.value = false;
1099
- phoneSearchResults.value = [];
1100
- }
1101
-
1102
- if (source === "vehicleNumber") {
1103
- vehicleSearchMenu.value = false;
1104
- vehicleSearchResults.value = [];
1105
- }
1106
- }
1107
-
1108
1069
  function closeNricAutofillOptions() {
1109
1070
  dialog.nricAutofillOptions = false;
1110
1071
  selectedNricSearchResult.value = null;
@@ -1542,15 +1503,6 @@ function handleUpdateVehicleNumber() {
1542
1503
  debounceFetchPlateNumber();
1543
1504
  }
1544
1505
 
1545
- const handleFocusPlateNumber = () => {
1546
- isPlateNumberFieldFocused.value = true;
1547
- if (prop.mode === 'register') {
1548
-
1549
- handleUpdateVehicleNumber();
1550
- }
1551
- };
1552
-
1553
-
1554
1506
  function backToSelection() {
1555
1507
  emit("back");
1556
1508
  message.value = "";
@@ -2156,22 +2108,10 @@ onMounted(() => {
2156
2108
  }
2157
2109
 
2158
2110
  .phone-search-results {
2159
- display: flex;
2160
- flex-direction: column;
2161
2111
  max-height: 400px;
2162
- overflow: hidden;
2163
- }
2164
-
2165
- .search-results-scroll {
2166
- flex: 1 1 auto;
2167
- min-height: 0;
2168
2112
  overflow-y: auto;
2169
2113
  }
2170
2114
 
2171
- .search-results-close {
2172
- flex: 0 0 auto;
2173
- }
2174
-
2175
2115
  .nric-options-card {
2176
2116
  border-radius: 16px !important;
2177
2117
  }
@@ -825,8 +825,10 @@
825
825
  item-title="label"
826
826
  item-value="value"
827
827
  v-model="pass.status"
828
- :disabled="pass.status == 'Removed'"
829
- />
828
+ :disabled="
829
+ selectedVisitorObject.checkOut || pass.status == 'Removed'
830
+ "
831
+ ></v-select>
830
832
  <v-textarea
831
833
  v-if="pass.status === 'Lost' || pass.status === 'Damaged'"
832
834
  no-resize
@@ -834,7 +836,8 @@
834
836
  class="w-100"
835
837
  density="compact"
836
838
  v-model="pass.remarks"
837
- />
839
+ :disabled="selectedVisitorObject.checkOut"
840
+ ></v-textarea>
838
841
  </v-row>
839
842
  </div>
840
843
  <div v-if="keyReturnStatuses.length > 0" class="mb-2">
@@ -861,8 +864,10 @@
861
864
  item-title="label"
862
865
  item-value="value"
863
866
  v-model="key.status"
864
- :disabled="key.status == 'Removed'"
865
- />
867
+ :disabled="
868
+ selectedVisitorObject.checkOut || key.status == 'Removed'
869
+ "
870
+ ></v-select>
866
871
  <v-textarea
867
872
  v-if="key.status === 'Lost' || key.status === 'Damaged'"
868
873
  no-resize
@@ -870,7 +875,8 @@
870
875
  class="w-100"
871
876
  density="compact"
872
877
  v-model="key.remarks"
873
- />
878
+ :disabled="selectedVisitorObject.checkOut"
879
+ ></v-textarea>
874
880
  </v-row>
875
881
  </div>
876
882
 
@@ -880,11 +886,11 @@
880
886
  color="blue"
881
887
  density="comfortable"
882
888
  class="text-capitalize"
889
+ :disabled="selectedVisitorObject.checkOut"
883
890
  :loading="loading.updatingPassKeys"
884
891
  @click.stop="handleUpdatePassKeys"
892
+ >Update Pass/Keys</v-btn
885
893
  >
886
- Update Pass/Keys
887
- </v-btn>
888
894
  </v-row>
889
895
  </v-card-text>
890
896
  <v-toolbar class="pa-0" density="compact">
@@ -894,9 +900,8 @@
894
900
  variant="text"
895
901
  block
896
902
  @click="dialog.returnPassesKeys = false"
903
+ >Close</v-btn
897
904
  >
898
- Close
899
- </v-btn>
900
905
  </v-col>
901
906
  <v-col cols="6">
902
907
  <v-btn
@@ -910,9 +915,8 @@
910
915
  !canConfirmCheckout || selectedVisitorObject.checkOut
911
916
  "
912
917
  @click="proceedCheckout"
918
+ >Confirm Checkout</v-btn
913
919
  >
914
- Confirm Checkout
915
- </v-btn>
916
920
  </v-col>
917
921
  </v-row>
918
922
  </v-toolbar>