@7365admin1/layer-common 3.0.22 → 3.0.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.
- package/CHANGELOG.md +12 -0
- package/components/DashboardMain.vue +981 -346
- package/components/Nfc/NFCPatrolReportMain.vue +48 -519
- package/components/Nfc/PatrolReport/DailyReportTab.vue +59 -0
- package/components/Nfc/PatrolReport/MonthlyReportTab.vue +59 -0
- package/components/Nfc/PatrolReport/PatrolActivityTable.vue +81 -0
- package/components/Nfc/PatrolReport/PatrolReportTab.vue +73 -0
- package/components/Nfc/PatrolReport/PatrolRouteSummary.vue +63 -0
- package/components/Nfc/PatrolReport/RemarksDialog.vue +37 -0
- package/components/Nfc/PatrolReport/ReportEmptyState.vue +24 -0
- package/components/Nfc/PatrolReport/ReportFilters.vue +88 -0
- package/components/Nfc/PatrolReport/ReportLocationHeader.vue +17 -0
- package/components/Nfc/PatrolReport/SummaryReportTable.vue +51 -0
- package/components/ServiceProviderMain.vue +183 -184
- package/components/VisitorManagement.vue +8 -0
- package/components/VisitorSocketPopUp.vue +10 -30
- package/composables/useNFCPatrolDailyReport.ts +27 -0
- package/composables/useNFCPatrolMonthlyReport.ts +27 -0
- package/composables/useNFCPatrolReport.ts +38 -0
- package/composables/useNFCPatrolReportExport.ts +31 -0
- package/composables/useNFCPatrolReportFilters.ts +39 -0
- package/composables/useServiceProvider.ts +2 -1
- package/package.json +1 -1
- package/services/nfcPatrolReport.ts +172 -0
- package/types/nfc-patrol-report.ts +73 -0
|
@@ -181,7 +181,6 @@
|
|
|
181
181
|
<v-card-text v-else class="text-body-2 text-medium-emphasis">
|
|
182
182
|
You do not have permission to view service providers.
|
|
183
183
|
</v-card-text>
|
|
184
|
-
|
|
185
184
|
</v-card>
|
|
186
185
|
</v-col>
|
|
187
186
|
</v-row>
|
|
@@ -415,151 +414,151 @@
|
|
|
415
414
|
</v-card>
|
|
416
415
|
</v-dialog>
|
|
417
416
|
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
<v-card-text class="sp-invite-body">
|
|
429
|
-
<v-form
|
|
430
|
-
v-model="validServiceProvider"
|
|
431
|
-
:disabled="disableServiceProvider"
|
|
432
|
-
>
|
|
433
|
-
<v-row no-gutters>
|
|
434
|
-
<!-- Email -->
|
|
435
|
-
<v-col cols="12">
|
|
436
|
-
<v-row no-gutters>
|
|
437
|
-
<InputLabel class="text-capitalize" title="Email" required />
|
|
438
|
-
<v-col cols="12">
|
|
439
|
-
<v-text-field
|
|
440
|
-
v-model="serviceProviderInvite.email"
|
|
441
|
-
variant="outlined"
|
|
442
|
-
density="comfortable"
|
|
443
|
-
:rules="[requiredRule, emailRule]"
|
|
444
|
-
></v-text-field>
|
|
445
|
-
</v-col>
|
|
446
|
-
</v-row>
|
|
447
|
-
</v-col>
|
|
448
|
-
|
|
449
|
-
<!-- Existing account block -->
|
|
450
|
-
<v-col cols="12" v-if="existingAccount">
|
|
451
|
-
<v-divider class="mb-6" />
|
|
452
|
-
|
|
453
|
-
<div class="sp-existing-title">Existing Account Verified</div>
|
|
454
|
-
|
|
455
|
-
<div class="sp-existing-copy">
|
|
456
|
-
{{ serviceProviderInvite.email }} is already onboarded.
|
|
457
|
-
Sending this invite will add this site to the list of
|
|
458
|
-
locations this company manages.
|
|
459
|
-
</div>
|
|
460
|
-
|
|
461
|
-
<v-row no-gutters>
|
|
462
|
-
<InputLabel title="Organization" />
|
|
463
|
-
<v-col cols="12">
|
|
464
|
-
<v-text-field
|
|
465
|
-
:model-value="existingAccount.text"
|
|
466
|
-
readonly
|
|
467
|
-
variant="outlined"
|
|
468
|
-
density="comfortable"
|
|
469
|
-
/>
|
|
470
|
-
</v-col>
|
|
471
|
-
</v-row>
|
|
472
|
-
</v-col>
|
|
473
|
-
|
|
474
|
-
<v-col cols="12">
|
|
475
|
-
<v-divider class="mb-6" />
|
|
476
|
-
</v-col>
|
|
417
|
+
<v-dialog v-model="createInviteDialog" width="580" persistent>
|
|
418
|
+
<v-card width="100%" rounded="lg" class="sp-invite-card">
|
|
419
|
+
<v-toolbar flat color="grey-lighten-4" height="76">
|
|
420
|
+
<v-row no-gutters class="fill-height px-6" align="center">
|
|
421
|
+
<span class="font-weight-bold text-h5">
|
|
422
|
+
Invite Service Provider
|
|
423
|
+
</span>
|
|
424
|
+
</v-row>
|
|
425
|
+
</v-toolbar>
|
|
477
426
|
|
|
478
|
-
|
|
479
|
-
|
|
427
|
+
<v-card-text class="sp-invite-body">
|
|
428
|
+
<v-form
|
|
429
|
+
v-model="validServiceProvider"
|
|
430
|
+
:disabled="disableServiceProvider"
|
|
431
|
+
>
|
|
432
|
+
<v-row no-gutters>
|
|
433
|
+
<!-- Email -->
|
|
480
434
|
<v-col cols="12">
|
|
481
435
|
<v-row no-gutters>
|
|
482
|
-
<InputLabel class="text-capitalize" title="
|
|
436
|
+
<InputLabel class="text-capitalize" title="Email" required />
|
|
483
437
|
<v-col cols="12">
|
|
484
|
-
<v-
|
|
485
|
-
v-model="serviceProviderInvite.
|
|
486
|
-
:items="serviceProviderInviteApps"
|
|
487
|
-
item-title="title"
|
|
488
|
-
item-value="value"
|
|
438
|
+
<v-text-field
|
|
439
|
+
v-model="serviceProviderInvite.email"
|
|
489
440
|
variant="outlined"
|
|
490
441
|
density="comfortable"
|
|
491
|
-
:rules="[requiredRule]"
|
|
492
|
-
></v-
|
|
442
|
+
:rules="[requiredRule, emailRule]"
|
|
443
|
+
></v-text-field>
|
|
493
444
|
</v-col>
|
|
494
445
|
</v-row>
|
|
495
446
|
</v-col>
|
|
496
447
|
|
|
497
|
-
|
|
448
|
+
<!-- Existing account block -->
|
|
449
|
+
<v-col cols="12" v-if="existingAccount">
|
|
450
|
+
<v-divider class="mb-6" />
|
|
451
|
+
|
|
452
|
+
<div class="sp-existing-title">Existing Account Verified</div>
|
|
453
|
+
|
|
454
|
+
<div class="sp-existing-copy">
|
|
455
|
+
{{ serviceProviderInvite.email }} is already onboarded. Sending
|
|
456
|
+
this invite will add this site to the list of locations this
|
|
457
|
+
company manages.
|
|
458
|
+
</div>
|
|
459
|
+
|
|
498
460
|
<v-row no-gutters>
|
|
499
|
-
<InputLabel
|
|
461
|
+
<InputLabel title="Organization" />
|
|
500
462
|
<v-col cols="12">
|
|
501
|
-
<v-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
item-title="title"
|
|
505
|
-
item-value="value"
|
|
463
|
+
<v-text-field
|
|
464
|
+
:model-value="existingAccount.text"
|
|
465
|
+
readonly
|
|
506
466
|
variant="outlined"
|
|
507
467
|
density="comfortable"
|
|
508
|
-
|
|
509
|
-
@update:model-value="setInviteSiteName"
|
|
510
|
-
></v-select>
|
|
468
|
+
/>
|
|
511
469
|
</v-col>
|
|
512
470
|
</v-row>
|
|
513
471
|
</v-col>
|
|
514
|
-
</template>
|
|
515
472
|
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
473
|
+
<v-col cols="12">
|
|
474
|
+
<v-divider class="mb-6" />
|
|
475
|
+
</v-col>
|
|
476
|
+
|
|
477
|
+
<!-- App & Site: only shown when no existing account is verified -->
|
|
478
|
+
<template v-if="!existingAccount">
|
|
479
|
+
<v-col cols="12">
|
|
480
|
+
<v-row no-gutters>
|
|
481
|
+
<InputLabel class="text-capitalize" title="App" required />
|
|
482
|
+
<v-col cols="12">
|
|
483
|
+
<v-select
|
|
484
|
+
v-model="serviceProviderInvite.app"
|
|
485
|
+
:items="serviceProviderInviteApps"
|
|
486
|
+
item-title="title"
|
|
487
|
+
item-value="value"
|
|
488
|
+
variant="outlined"
|
|
489
|
+
density="comfortable"
|
|
490
|
+
:rules="[requiredRule]"
|
|
491
|
+
></v-select>
|
|
492
|
+
</v-col>
|
|
493
|
+
</v-row>
|
|
525
494
|
</v-col>
|
|
526
|
-
</v-row>
|
|
527
|
-
</v-col>
|
|
528
|
-
</v-row>
|
|
529
|
-
</v-form>
|
|
530
|
-
</v-card-text>
|
|
531
495
|
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
496
|
+
<v-col cols="12">
|
|
497
|
+
<v-row no-gutters>
|
|
498
|
+
<InputLabel class="text-capitalize" title="Site" required />
|
|
499
|
+
<v-col cols="12">
|
|
500
|
+
<v-select
|
|
501
|
+
v-model="serviceProviderInvite.siteId"
|
|
502
|
+
:items="serviceProviderInviteSites"
|
|
503
|
+
item-title="title"
|
|
504
|
+
item-value="value"
|
|
505
|
+
variant="outlined"
|
|
506
|
+
density="comfortable"
|
|
507
|
+
:rules="[requiredRule]"
|
|
508
|
+
@update:model-value="setInviteSiteName"
|
|
509
|
+
></v-select>
|
|
510
|
+
</v-col>
|
|
511
|
+
</v-row>
|
|
512
|
+
</v-col>
|
|
513
|
+
</template>
|
|
545
514
|
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
515
|
+
<!-- Error message -->
|
|
516
|
+
<v-col cols="12" class="my-2">
|
|
517
|
+
<v-row no-gutters>
|
|
518
|
+
<v-col cols="12" class="text-center">
|
|
519
|
+
<span
|
|
520
|
+
class="text-none text-subtitle-2 font-weight-medium text-error"
|
|
521
|
+
>
|
|
522
|
+
{{ messageServiceProvider }}
|
|
523
|
+
</span>
|
|
524
|
+
</v-col>
|
|
525
|
+
</v-row>
|
|
526
|
+
</v-col>
|
|
527
|
+
</v-row>
|
|
528
|
+
</v-form>
|
|
529
|
+
</v-card-text>
|
|
530
|
+
|
|
531
|
+
<v-toolbar flat height="76" class="sp-invite-footer">
|
|
532
|
+
<v-row no-gutters class="fill-height">
|
|
533
|
+
<v-col cols="6" class="fill-height">
|
|
534
|
+
<v-btn
|
|
535
|
+
block
|
|
536
|
+
variant="flat"
|
|
537
|
+
class="text-none sp-invite-footer-btn"
|
|
538
|
+
height="76"
|
|
539
|
+
@click="setServiceProvider({ mode: 'invite', dialog: false })"
|
|
540
|
+
>
|
|
541
|
+
Back
|
|
542
|
+
</v-btn>
|
|
543
|
+
</v-col>
|
|
544
|
+
|
|
545
|
+
<v-col cols="6" class="fill-height">
|
|
546
|
+
<v-btn
|
|
547
|
+
block
|
|
548
|
+
variant="flat"
|
|
549
|
+
class="text-none sp-invite-submit-btn"
|
|
550
|
+
height="76"
|
|
551
|
+
:disabled="!validServiceProvider"
|
|
552
|
+
:loading="disableServiceProvider"
|
|
553
|
+
@click="submitServiceProviderInvite()"
|
|
554
|
+
>
|
|
555
|
+
Submit
|
|
556
|
+
</v-btn>
|
|
557
|
+
</v-col>
|
|
558
|
+
</v-row>
|
|
559
|
+
</v-toolbar>
|
|
560
|
+
</v-card>
|
|
561
|
+
</v-dialog>
|
|
563
562
|
|
|
564
563
|
<Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />
|
|
565
564
|
</template>
|
|
@@ -689,7 +688,7 @@ const headers = [
|
|
|
689
688
|
|
|
690
689
|
const { natureOfBusinessV3 } = useLocal();
|
|
691
690
|
const { requiredRule, emailRule, debounce } = useUtils();
|
|
692
|
-
const {getUserByEmail} = useUser()
|
|
691
|
+
const { getUserByEmail } = useUser();
|
|
693
692
|
|
|
694
693
|
const listTab = ref<ListTab>("active");
|
|
695
694
|
const page = ref(1);
|
|
@@ -732,14 +731,13 @@ const {
|
|
|
732
731
|
add: addServiceProvider,
|
|
733
732
|
createServiceProviderInvite,
|
|
734
733
|
updateStatus: updateServiceProviderStatus,
|
|
735
|
-
invite
|
|
734
|
+
invite,
|
|
736
735
|
} = useServiceProvider();
|
|
737
736
|
const { getAll: getAllMembers } = useMember();
|
|
738
737
|
|
|
739
|
-
const { getVerifications, cancelUserInvitation, getVerificationByEmail } =
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
} = useMember();
|
|
738
|
+
const { getVerifications, cancelUserInvitation, getVerificationByEmail } =
|
|
739
|
+
useVerification();
|
|
740
|
+
const { getOrgsByMembership } = useMember();
|
|
743
741
|
|
|
744
742
|
const existingAccount = ref<any>(null);
|
|
745
743
|
const checkingExistingAccount = ref(false);
|
|
@@ -774,22 +772,21 @@ async function checkExistingAccount(email: string) {
|
|
|
774
772
|
|
|
775
773
|
if (!user?._id) return;
|
|
776
774
|
|
|
777
|
-
const orgs = await getOrgs({
|
|
778
|
-
|
|
779
|
-
});
|
|
780
|
-
|
|
781
|
-
const matchedOrg = orgs.items?.find(
|
|
782
|
-
(org: any) => org.type === serviceProviderInvite.value.app
|
|
783
|
-
);
|
|
775
|
+
const orgs = await getOrgs({
|
|
776
|
+
user: user._id,
|
|
777
|
+
});
|
|
784
778
|
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
text: matchedOrg.text,
|
|
789
|
-
...matchedOrg,
|
|
790
|
-
};
|
|
791
|
-
}
|
|
779
|
+
const matchedOrg = orgs.items?.find(
|
|
780
|
+
(org: any) => org.type === serviceProviderInvite.value.app
|
|
781
|
+
);
|
|
792
782
|
|
|
783
|
+
if (matchedOrg) {
|
|
784
|
+
existingAccount.value = {
|
|
785
|
+
_id: matchedOrg.value,
|
|
786
|
+
text: matchedOrg.text,
|
|
787
|
+
...matchedOrg,
|
|
788
|
+
};
|
|
789
|
+
}
|
|
793
790
|
} catch (error) {
|
|
794
791
|
existingAccount.value = null;
|
|
795
792
|
} finally {
|
|
@@ -797,7 +794,6 @@ if (matchedOrg) {
|
|
|
797
794
|
}
|
|
798
795
|
}
|
|
799
796
|
|
|
800
|
-
|
|
801
797
|
watch(
|
|
802
798
|
() => serviceProviderInvite.value.email,
|
|
803
799
|
async (value) => {
|
|
@@ -876,7 +872,10 @@ function rowActionLabel(row: TableRow) {
|
|
|
876
872
|
|
|
877
873
|
function typeDisplay(type: string, nature?: string) {
|
|
878
874
|
if (nature && String(nature).trim()) return String(nature);
|
|
879
|
-
const list = natureOfBusinessV3.value as Array<{
|
|
875
|
+
const list = natureOfBusinessV3.value as Array<{
|
|
876
|
+
title?: string;
|
|
877
|
+
value?: string;
|
|
878
|
+
}>;
|
|
880
879
|
const hit = list?.find((x) => x.value === type);
|
|
881
880
|
return hit?.title ?? type ?? "-";
|
|
882
881
|
}
|
|
@@ -975,12 +974,12 @@ function mapInviteRows(raw: Record<string, any>[]): TableRow[] {
|
|
|
975
974
|
}
|
|
976
975
|
|
|
977
976
|
async function loadList() {
|
|
978
|
-
if (!props.siteId || !props.canViewServiceProviders) {
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
}
|
|
977
|
+
// if (!props.siteId || !props.canViewServiceProviders) {
|
|
978
|
+
// items.value = [];
|
|
979
|
+
// pages.value = 0;
|
|
980
|
+
// pageRange.value = "-- - -- of --";
|
|
981
|
+
// return;
|
|
982
|
+
// }
|
|
984
983
|
|
|
985
984
|
loading.value = true;
|
|
986
985
|
try {
|
|
@@ -1077,7 +1076,8 @@ async function confirmStatusChange() {
|
|
|
1077
1076
|
if (!statusActionRow.value) return;
|
|
1078
1077
|
|
|
1079
1078
|
statusUpdating.value = true;
|
|
1080
|
-
const nextStatus =
|
|
1079
|
+
const nextStatus =
|
|
1080
|
+
statusAction.value === "reactivate" ? "active" : "inactive";
|
|
1081
1081
|
try {
|
|
1082
1082
|
await updateServiceProviderStatus(statusActionRow.value._id, nextStatus);
|
|
1083
1083
|
showMessage(
|
|
@@ -1142,38 +1142,38 @@ function setServiceProvider({
|
|
|
1142
1142
|
createDialog.value = dialog;
|
|
1143
1143
|
}
|
|
1144
1144
|
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
email: "",
|
|
1150
|
-
description: "",
|
|
1151
|
-
orgId: props.orgId,
|
|
1152
|
-
siteId: props.siteId,
|
|
1153
|
-
siteName: site.value?.name ?? "",
|
|
1154
|
-
orgName: "Org Name",
|
|
1155
|
-
category: mode === "add" ? "internal" : "external",
|
|
1156
|
-
};
|
|
1157
|
-
|
|
1158
|
-
if (mode === "invite") {
|
|
1159
|
-
existingAccount.value = null;
|
|
1160
|
-
|
|
1161
|
-
serviceProviderInvite.value = {
|
|
1145
|
+
if (dialog) {
|
|
1146
|
+
serviceProvider.value = {
|
|
1147
|
+
name: "",
|
|
1148
|
+
type: "",
|
|
1162
1149
|
email: "",
|
|
1163
|
-
|
|
1150
|
+
description: "",
|
|
1151
|
+
orgId: props.orgId,
|
|
1164
1152
|
siteId: props.siteId,
|
|
1165
|
-
siteName: site.value?.name
|
|
1153
|
+
siteName: site.value?.name ?? "",
|
|
1154
|
+
orgName: "Org Name",
|
|
1155
|
+
category: mode === "add" ? "internal" : "external",
|
|
1166
1156
|
};
|
|
1167
|
-
}
|
|
1168
1157
|
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1158
|
+
if (mode === "invite") {
|
|
1159
|
+
existingAccount.value = null;
|
|
1160
|
+
|
|
1161
|
+
serviceProviderInvite.value = {
|
|
1162
|
+
email: "",
|
|
1163
|
+
app: defaultInviteApp,
|
|
1164
|
+
siteId: props.siteId,
|
|
1165
|
+
siteName: site.value?.name || props.siteName,
|
|
1166
|
+
};
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
createMoreServiceProvider.value = false;
|
|
1170
|
+
return;
|
|
1171
|
+
}
|
|
1172
1172
|
|
|
1173
|
-
serviceProvider.value.description = data.description ?? "";
|
|
1174
|
-
serviceProvider.value.email = data.email ?? "";
|
|
1175
|
-
serviceProvider.value.name = data.name ?? "";
|
|
1176
|
-
serviceProvider.value.type = data.type ?? "";
|
|
1173
|
+
serviceProvider.value.description = data.description ?? "";
|
|
1174
|
+
serviceProvider.value.email = data.email ?? "";
|
|
1175
|
+
serviceProvider.value.name = data.name ?? "";
|
|
1176
|
+
serviceProvider.value.type = data.type ?? "";
|
|
1177
1177
|
}
|
|
1178
1178
|
|
|
1179
1179
|
async function submitServiceProviderAdd() {
|
|
@@ -1210,10 +1210,9 @@ async function submitServiceProviderInvite() {
|
|
|
1210
1210
|
serviceProviderInvite.value.siteName ||
|
|
1211
1211
|
site.value?.name ||
|
|
1212
1212
|
props.siteName,
|
|
1213
|
+
app: serviceProviderInvite.value.app,
|
|
1213
1214
|
|
|
1214
|
-
inviteType: existingAccount.value
|
|
1215
|
-
? "create-org"
|
|
1216
|
-
: "organization-invite",
|
|
1215
|
+
inviteType: existingAccount.value ? "create-org" : "organization-invite",
|
|
1217
1216
|
});
|
|
1218
1217
|
|
|
1219
1218
|
showMessage("Invitation sent.", "success");
|
|
@@ -1604,6 +1604,10 @@ function handleRegistrationUnregisteredVisitor(item: Partial<TVisitor>) {
|
|
|
1604
1604
|
selectedVisitorId.value = id;
|
|
1605
1605
|
dialog.showSelection = true;
|
|
1606
1606
|
mode.value = "register";
|
|
1607
|
+
|
|
1608
|
+
if(!selectedVisitorDataObject.value){
|
|
1609
|
+
getVisitorRefresh();
|
|
1610
|
+
}
|
|
1607
1611
|
}
|
|
1608
1612
|
|
|
1609
1613
|
function handleViewImage(imageId: string) {
|
|
@@ -2053,6 +2057,10 @@ const { socketUnregisteredVisitorTrigger, visitorSocketData } =
|
|
|
2053
2057
|
const { _id } = visitorSocketData.value;
|
|
2054
2058
|
await handleRegistrationUnregisteredVisitor({ _id });
|
|
2055
2059
|
socketUnregisteredVisitorTrigger.value = false;
|
|
2060
|
+
|
|
2061
|
+
setTimeout(() => {
|
|
2062
|
+
visitorSocketData.value = null;
|
|
2063
|
+
}, 1000)
|
|
2056
2064
|
}, 1000)
|
|
2057
2065
|
}
|
|
2058
2066
|
})
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
</section> -->
|
|
33
33
|
|
|
34
34
|
<v-snackbar
|
|
35
|
-
v-if="!
|
|
35
|
+
v-if="!isUnregisteredVisitorRoute"
|
|
36
36
|
v-model="snackBarMessage.modal"
|
|
37
37
|
:color="snackBarMessage.color"
|
|
38
38
|
:timeout="snackBarMessage.timeout"
|
|
@@ -103,6 +103,8 @@ const { tab } = useVisitor();
|
|
|
103
103
|
const { socketUnregisteredVisitorTrigger, visitorSocketData } =
|
|
104
104
|
useVisitorSocket();
|
|
105
105
|
|
|
106
|
+
const APP_NAME = publicConfig.APP || "";
|
|
107
|
+
|
|
106
108
|
const socket = shallowRef<Socket | null>(null);
|
|
107
109
|
const status = ref("disconnected");
|
|
108
110
|
const newVisitor = ref<TVisitorSocketData | null>(null);
|
|
@@ -125,6 +127,7 @@ const permanentMessageDialog = reactive({
|
|
|
125
127
|
const path = computed(() => route.path);
|
|
126
128
|
const isVisitorManagementPath = (path: string) =>
|
|
127
129
|
path.includes("/visitor-management");
|
|
130
|
+
|
|
128
131
|
const isVisitorRoute = computed(
|
|
129
132
|
() =>
|
|
130
133
|
path.value === "/visitors" ||
|
|
@@ -197,7 +200,7 @@ const connectSocket = () => {
|
|
|
197
200
|
visitorSocketData.value = data;
|
|
198
201
|
newVisitor.value = data;
|
|
199
202
|
|
|
200
|
-
if (
|
|
203
|
+
if (isCheckIn) {
|
|
201
204
|
showTransientMessage(
|
|
202
205
|
`New plate detected: ${plateNumber}`,
|
|
203
206
|
"info",
|
|
@@ -207,20 +210,6 @@ const connectSocket = () => {
|
|
|
207
210
|
return;
|
|
208
211
|
}
|
|
209
212
|
|
|
210
|
-
if (isUnregisteredVisitorRoute.value && isCheckIn) {
|
|
211
|
-
if (isPlateNumberChanging) {
|
|
212
|
-
showTransientMessage(`New plate detected: ${plateNumber}`, "info", true);
|
|
213
|
-
} else {
|
|
214
|
-
snackBarMessage.modal = false;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
lastPlateNumber.value = plateNumber;
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
if (isCheckIn) {
|
|
222
|
-
lastPlateNumber.value = plateNumber;
|
|
223
|
-
}
|
|
224
213
|
|
|
225
214
|
if (data?.message) {
|
|
226
215
|
showTransientMessage(data.message, "error");
|
|
@@ -254,8 +243,10 @@ const goToUnregistered = async () => {
|
|
|
254
243
|
if (route.params.org && route.params.site) {
|
|
255
244
|
const defaultDateQuery = getDefaultDateQuery();
|
|
256
245
|
|
|
246
|
+
if(!APP_NAME) return;
|
|
247
|
+
|
|
257
248
|
await navigateTo({
|
|
258
|
-
path:
|
|
249
|
+
path: `/${route.params.org}/${route.params.site}/${APP_NAME === "security_agency" ? "visitor-management" : APP_NAME === "property_management_agency" ? "visitor-mgmt" : "visitor-management"}`,
|
|
259
250
|
query: {
|
|
260
251
|
tab: "unregistered",
|
|
261
252
|
dateFrom: route.query.dateFrom || defaultDateQuery.dateFrom,
|
|
@@ -279,7 +270,7 @@ watch(
|
|
|
279
270
|
disconnectSocket();
|
|
280
271
|
connectSocket();
|
|
281
272
|
},
|
|
282
|
-
{ immediate: true }
|
|
273
|
+
{ immediate: true, deep: true }
|
|
283
274
|
);
|
|
284
275
|
|
|
285
276
|
watch(
|
|
@@ -296,17 +287,6 @@ onUnmounted(() => {
|
|
|
296
287
|
disconnectSocket();
|
|
297
288
|
});
|
|
298
289
|
|
|
299
|
-
|
|
300
|
-
() => route.path,
|
|
301
|
-
(currentPath, previousPath) => {
|
|
302
|
-
if (
|
|
303
|
-
previousPath &&
|
|
304
|
-
isVisitorManagementPath(previousPath) &&
|
|
305
|
-
!isVisitorManagementPath(currentPath)
|
|
306
|
-
) {
|
|
307
|
-
handleCloseSnackbar();
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
);
|
|
290
|
+
|
|
311
291
|
|
|
312
292
|
</script>
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
NFCPatrolReportFilters,
|
|
3
|
+
NFCPatrolSummaryReport,
|
|
4
|
+
} from "../types/nfc-patrol-report";
|
|
5
|
+
import { useNFCPatrolReportService } from "../services/nfcPatrolReport";
|
|
6
|
+
|
|
7
|
+
export function useNFCPatrolDailyReport(filters: NFCPatrolReportFilters) {
|
|
8
|
+
const reportService = useNFCPatrolReportService();
|
|
9
|
+
const report = ref<NFCPatrolSummaryReport | null>(null);
|
|
10
|
+
const loading = ref(false);
|
|
11
|
+
|
|
12
|
+
async function fetchReport() {
|
|
13
|
+
loading.value = true;
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
report.value = await reportService.getDailyReport(filters);
|
|
17
|
+
} finally {
|
|
18
|
+
loading.value = false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
report,
|
|
24
|
+
loading,
|
|
25
|
+
fetchReport,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
NFCPatrolReportFilters,
|
|
3
|
+
NFCPatrolSummaryReport,
|
|
4
|
+
} from "../types/nfc-patrol-report";
|
|
5
|
+
import { useNFCPatrolReportService } from "../services/nfcPatrolReport";
|
|
6
|
+
|
|
7
|
+
export function useNFCPatrolMonthlyReport(filters: NFCPatrolReportFilters) {
|
|
8
|
+
const reportService = useNFCPatrolReportService();
|
|
9
|
+
const report = ref<NFCPatrolSummaryReport | null>(null);
|
|
10
|
+
const loading = ref(false);
|
|
11
|
+
|
|
12
|
+
async function fetchReport() {
|
|
13
|
+
loading.value = true;
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
report.value = await reportService.getMonthlyReport(filters);
|
|
17
|
+
} finally {
|
|
18
|
+
loading.value = false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
report,
|
|
24
|
+
loading,
|
|
25
|
+
fetchReport,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
NFCPatrolActivity,
|
|
3
|
+
NFCPatrolReport,
|
|
4
|
+
NFCPatrolReportFilters,
|
|
5
|
+
} from "../types/nfc-patrol-report";
|
|
6
|
+
import { useNFCPatrolReportService } from "../services/nfcPatrolReport";
|
|
7
|
+
|
|
8
|
+
export function useNFCPatrolReport(filters: NFCPatrolReportFilters) {
|
|
9
|
+
const reportService = useNFCPatrolReportService();
|
|
10
|
+
const report = ref<NFCPatrolReport | null>(null);
|
|
11
|
+
const loading = ref(false);
|
|
12
|
+
const selectedActivityRemarks = ref("");
|
|
13
|
+
const dialogRemarks = ref(false);
|
|
14
|
+
|
|
15
|
+
async function fetchReport() {
|
|
16
|
+
loading.value = true;
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
report.value = await reportService.getPatrolReport(filters);
|
|
20
|
+
} finally {
|
|
21
|
+
loading.value = false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function openRemarksDialog(activity: NFCPatrolActivity) {
|
|
26
|
+
selectedActivityRemarks.value = activity.remarks || "No remarks provided";
|
|
27
|
+
dialogRemarks.value = true;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
report,
|
|
32
|
+
loading,
|
|
33
|
+
selectedActivityRemarks,
|
|
34
|
+
dialogRemarks,
|
|
35
|
+
fetchReport,
|
|
36
|
+
openRemarksDialog,
|
|
37
|
+
};
|
|
38
|
+
}
|