@7365admin1/layer-common 1.11.20 → 1.11.22
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/AddPassKeyToVisitor.vue +117 -56
- package/components/AreaMain.vue +10 -8
- package/components/BulletinBoardView.vue +158 -16
- package/components/OvernightParkingAvailability.vue +286 -151
- package/components/ScanVisitorQRCode.vue +157 -0
- package/components/SiteSettings.vue +303 -243
- package/components/TableMain.vue +72 -21
- package/components/UnitMain.vue +10 -8
- package/components/VisitorForm.vue +1 -1
- package/components/VisitorManagement.vue +598 -229
- package/composables/useOrg.ts +16 -0
- package/composables/useVisitor.ts +12 -0
- package/package.json +1 -1
- package/plugins/html5-qrcode.client.js +8 -0
- package/types/overnight-parking.d.ts +3 -2
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-dialog
|
|
3
|
+
v-model="props.dialog"
|
|
4
|
+
transition="dialog-bottom-transition"
|
|
5
|
+
width="700"
|
|
6
|
+
max-width="700"
|
|
7
|
+
persistent
|
|
8
|
+
@after-enter="handleScanVisitorQRCode"
|
|
9
|
+
>
|
|
10
|
+
<v-container class="d-flex justify-center" max-height="90vh">
|
|
11
|
+
<!-- QR code reader container -->
|
|
12
|
+
<v-card
|
|
13
|
+
elevation="2"
|
|
14
|
+
class="d-flex flex-column align-center pa-2 w-100 h-100"
|
|
15
|
+
>
|
|
16
|
+
<v-toolbar>
|
|
17
|
+
<v-card-title class="text-h5"> Scan QR Code </v-card-title>
|
|
18
|
+
<v-spacer />
|
|
19
|
+
<v-btn
|
|
20
|
+
color="grey-darken-1"
|
|
21
|
+
icon="mdi-close"
|
|
22
|
+
@click="closeDialog()"
|
|
23
|
+
/>
|
|
24
|
+
</v-toolbar>
|
|
25
|
+
|
|
26
|
+
<div
|
|
27
|
+
id="reader"
|
|
28
|
+
class="d-flex justify-center align-center w-100 h-100"
|
|
29
|
+
style="height: calc(100vh - 64px)"
|
|
30
|
+
>
|
|
31
|
+
<!-- The QR code scanner box -->
|
|
32
|
+
<!-- This is where the QR code scanner will be displayed -->
|
|
33
|
+
</div>
|
|
34
|
+
<!-- Show Error Messages -->
|
|
35
|
+
<div v-if="showNotFoundMessage" class="text-error mt-8">
|
|
36
|
+
<p>{{ errorMessage }}</p>
|
|
37
|
+
</div>
|
|
38
|
+
<!-- Switch camera button inside the reader box -->
|
|
39
|
+
<v-btn color="primary" icon class="mt-4" @click="switchCamera()">
|
|
40
|
+
<v-icon icon="mdi-camera-switch" large />
|
|
41
|
+
</v-btn>
|
|
42
|
+
</v-card>
|
|
43
|
+
</v-container>
|
|
44
|
+
</v-dialog>
|
|
45
|
+
<Snackbar v-model="messageSnackbar" :text="message" :color="messageColor" />
|
|
46
|
+
</template>
|
|
47
|
+
<script setup lang="ts">
|
|
48
|
+
const { $Html5Qrcode }: any = useNuxtApp();
|
|
49
|
+
|
|
50
|
+
const props = defineProps({
|
|
51
|
+
dialog: {
|
|
52
|
+
type: Boolean,
|
|
53
|
+
default: false,
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
const emit = defineEmits(["closeDialog"]);
|
|
58
|
+
|
|
59
|
+
const message = ref("");
|
|
60
|
+
const messageColor = ref("");
|
|
61
|
+
const messageSnackbar = ref(false);
|
|
62
|
+
|
|
63
|
+
function showMessage(msg: string, color: string) {
|
|
64
|
+
message.value = msg;
|
|
65
|
+
messageColor.value = color;
|
|
66
|
+
messageSnackbar.value = true;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const html5QrCodeInstance = ref<any>(null);
|
|
70
|
+
const cameraFacingMode = ref<string>("environment");
|
|
71
|
+
|
|
72
|
+
const showNotFoundMessage = ref<boolean>(false);
|
|
73
|
+
const errorMessage = ref<string>("");
|
|
74
|
+
|
|
75
|
+
const handleScanVisitorQRCode = async () => {
|
|
76
|
+
console.log("startScanner cameraFacingMode", cameraFacingMode.value);
|
|
77
|
+
console.log("STARTING QR Code Scanner...");
|
|
78
|
+
if (html5QrCodeInstance.value) return;
|
|
79
|
+
const config = { fps: 10, qrbox: { width: 250, height: 250 } };
|
|
80
|
+
html5QrCodeInstance.value = new $Html5Qrcode("reader");
|
|
81
|
+
html5QrCodeInstance.value
|
|
82
|
+
.start(
|
|
83
|
+
{ facingMode: cameraFacingMode.value },
|
|
84
|
+
config,
|
|
85
|
+
async (qrCodeMessage: string) => {
|
|
86
|
+
showNotFoundMessage.value = false;
|
|
87
|
+
// Automatically navigate to the scanned URL if it's a valid link
|
|
88
|
+
if (isValidUrl(qrCodeMessage)) {
|
|
89
|
+
console.log(`QR Code value: ${qrCodeMessage}`);
|
|
90
|
+
window.location.href = qrCodeMessage;
|
|
91
|
+
} else {
|
|
92
|
+
showNotFoundMessage.value = true;
|
|
93
|
+
errorMessage.value = "Invalid url";
|
|
94
|
+
showMessage("Invalid url", "error");
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
(msg: string) => {
|
|
98
|
+
if (msg === "QR Code no longer in front") {
|
|
99
|
+
showNotFoundMessage.value = true;
|
|
100
|
+
errorMessage.value = msg;
|
|
101
|
+
showMessage(msg, "error");
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
)
|
|
105
|
+
.catch((err: any) => {
|
|
106
|
+
showMessage(`Unable to start scanning, error: ${err}`, "error");
|
|
107
|
+
});
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const isValidUrl = (string: string) => {
|
|
111
|
+
try {
|
|
112
|
+
new URL(string);
|
|
113
|
+
return true;
|
|
114
|
+
} catch (_) {
|
|
115
|
+
return false;
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const switchCamera = async () => {
|
|
120
|
+
await stopScanner();
|
|
121
|
+
cameraFacingMode.value =
|
|
122
|
+
cameraFacingMode.value === "environment" ? "user" : "environment";
|
|
123
|
+
showMessage(
|
|
124
|
+
`Switched to ${
|
|
125
|
+
cameraFacingMode.value === "environment" ? "Back" : "Front"
|
|
126
|
+
} Camera`,
|
|
127
|
+
"info"
|
|
128
|
+
);
|
|
129
|
+
handleScanVisitorQRCode();
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const closeDialog = () => {
|
|
133
|
+
emit("closeDialog");
|
|
134
|
+
stopScanner();
|
|
135
|
+
};
|
|
136
|
+
|
|
137
|
+
const stopScanner = () => {
|
|
138
|
+
return new Promise<void>((resolve, reject) => {
|
|
139
|
+
if (html5QrCodeInstance.value) {
|
|
140
|
+
html5QrCodeInstance.value
|
|
141
|
+
.stop()
|
|
142
|
+
.then(() => {
|
|
143
|
+
html5QrCodeInstance.value.clear();
|
|
144
|
+
html5QrCodeInstance.value = null;
|
|
145
|
+
showNotFoundMessage.value = false;
|
|
146
|
+
resolve(); // Resolve the promise when the scanner is fully stopped
|
|
147
|
+
})
|
|
148
|
+
.catch((err: any) => {
|
|
149
|
+
showMessage("Unable to stop scanning.", err);
|
|
150
|
+
reject(err); // Reject the promise if there's an error
|
|
151
|
+
});
|
|
152
|
+
} else {
|
|
153
|
+
resolve(); // Resolve immediately if no scanner instance exists
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
};
|
|
157
|
+
</script>
|