@7365admin1/layer-common 3.2.2-staging.116 → 3.2.2-staging.120
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/components/AddPassKeyToVisitor.vue +95 -73
- package/components/BulletinBoardView.vue +9 -6
- package/components/CameraMain.vue +35 -47
- package/components/DeliveryCompany.vue +34 -20
- package/components/IncidentReport/Authorities.vue +30 -18
- package/components/MemberInformation.vue +23 -16
- package/components/NotificationSettings.vue +66 -54
- package/components/OnlineFormsConfiguration.vue +41 -42
- package/components/OvernightParkingAvailability.vue +49 -26
- package/components/ScanVisitorQRCode.vue +64 -28
- package/components/SearchVehicleNumberUser.vue +39 -37
- package/components/SiteSettings.vue +4 -1
- package/components/VehicleAddSelection.vue +48 -32
- package/components/VehicleForm.vue +112 -129
- package/components/VehicleUpdateMoreAction.vue +59 -46
- package/components/VisitorDataFromScannedQRCodeForm.vue +90 -65
- package/components/VisitorFormSelection.vue +40 -37
- package/components/VisitorPassKeyQRScanner.vue +65 -18
- package/components/VisitorSocketPopUp.vue +21 -13
- package/components/VisitorsReportPreview.vue +41 -29
- package/package.json +1 -1
|
@@ -1,24 +1,21 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<v-card width="100%" :loading="processing">
|
|
3
|
-
<
|
|
4
|
-
<v-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
<v-row no-gutters class="ga-1">
|
|
2
|
+
<v-card width="100%" class="screen-modal passkey" :loading="processing">
|
|
3
|
+
<div class="passkey__head">
|
|
4
|
+
<v-card-title>{{ isEditMode ? "Edit" : "Assign" }} Pass & Keys</v-card-title>
|
|
5
|
+
<AppButton
|
|
6
|
+
variant="icon"
|
|
7
|
+
icon="mdi-close"
|
|
8
|
+
aria-label="Close"
|
|
9
|
+
@click="emit('close')"
|
|
10
|
+
/>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
<div class="screen-modal__body passkey__body">
|
|
14
|
+
<!-- `.filter-field` is the design's input, and it is a descendant
|
|
15
|
+
selector, so both autocompletes get it from this one class. -->
|
|
16
|
+
<v-row no-gutters class="ga-1 filter-field">
|
|
18
17
|
<v-col cols="12">
|
|
19
|
-
<span class="
|
|
20
|
-
Name: {{ prop.visitor.name }}
|
|
21
|
-
</span>
|
|
18
|
+
<span class="passkey__name">Name: {{ prop.visitor.name }}</span>
|
|
22
19
|
</v-col>
|
|
23
20
|
|
|
24
21
|
<!-- Pass section -->
|
|
@@ -27,15 +24,11 @@
|
|
|
27
24
|
|
|
28
25
|
<!-- Existing pass -->
|
|
29
26
|
<div v-if="existingPass" class="d-flex align-center ga-2 mb-2">
|
|
30
|
-
<
|
|
31
|
-
|
|
32
|
-
color="blue"
|
|
33
|
-
variant="tonal"
|
|
34
|
-
size="small"
|
|
35
|
-
>
|
|
27
|
+
<StatusChip tone="info" :dot="false">
|
|
28
|
+
<v-icon icon="mdi-card-bulleted-outline" size="13" />
|
|
36
29
|
{{ existingPass.prefixAndName }}
|
|
37
|
-
</
|
|
38
|
-
<span class="
|
|
30
|
+
</StatusChip>
|
|
31
|
+
<span class="passkey__current">(current)</span>
|
|
39
32
|
</div>
|
|
40
33
|
|
|
41
34
|
<!-- New pass selector -->
|
|
@@ -79,21 +72,26 @@
|
|
|
79
72
|
v-if="existingKeys.length > 0"
|
|
80
73
|
class="d-flex flex-wrap ga-1 mb-2"
|
|
81
74
|
>
|
|
82
|
-
|
|
75
|
+
<!-- The design's tag chip, keeping the remove control the product
|
|
76
|
+
already had: the tone and the shape are the shared ones, only
|
|
77
|
+
the close button is drawn inside rather than by Vuetify. -->
|
|
78
|
+
<StatusChip
|
|
83
79
|
v-for="key in existingKeys.filter((k) => k.status != 'Removed')"
|
|
84
80
|
:key="key.keyId"
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
variant="tonal"
|
|
88
|
-
size="small"
|
|
89
|
-
closable
|
|
90
|
-
@click:close="removeExistingKey(key)"
|
|
81
|
+
tone="warn"
|
|
82
|
+
:dot="false"
|
|
91
83
|
>
|
|
84
|
+
<v-icon icon="mdi-key" size="13" />
|
|
92
85
|
{{ key.prefixAndName }}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
86
|
+
<button
|
|
87
|
+
class="passkey__remove"
|
|
88
|
+
:aria-label="`Remove ${key.prefixAndName}`"
|
|
89
|
+
@click="removeExistingKey(key)"
|
|
90
|
+
>
|
|
91
|
+
<v-icon icon="mdi-close-circle" size="14" />
|
|
92
|
+
</button>
|
|
93
|
+
</StatusChip>
|
|
94
|
+
<span class="passkey__current align-self-center">(current)</span>
|
|
97
95
|
</div>
|
|
98
96
|
|
|
99
97
|
<!-- New keys selector -->
|
|
@@ -132,41 +130,16 @@
|
|
|
132
130
|
</v-row>
|
|
133
131
|
|
|
134
132
|
<v-row v-if="errorMessage" no-gutters class="mt-2">
|
|
135
|
-
<p class="
|
|
136
|
-
{{ errorMessage }}
|
|
137
|
-
</p>
|
|
138
|
-
</v-row>
|
|
139
|
-
</v-card-text>
|
|
140
|
-
|
|
141
|
-
<v-toolbar density="compact">
|
|
142
|
-
<v-row no-gutters>
|
|
143
|
-
<v-col cols="6">
|
|
144
|
-
<v-btn
|
|
145
|
-
tile
|
|
146
|
-
block
|
|
147
|
-
variant="text"
|
|
148
|
-
class="text-none"
|
|
149
|
-
size="48"
|
|
150
|
-
text="Cancel"
|
|
151
|
-
@click="emit('close')"
|
|
152
|
-
/>
|
|
153
|
-
</v-col>
|
|
154
|
-
<v-col cols="6">
|
|
155
|
-
<v-btn
|
|
156
|
-
tile
|
|
157
|
-
block
|
|
158
|
-
variant="flat"
|
|
159
|
-
color="black"
|
|
160
|
-
class="text-none"
|
|
161
|
-
size="48"
|
|
162
|
-
:text="isEditMode ? 'Save' : 'Assign'"
|
|
163
|
-
:disabled="!canSubmit"
|
|
164
|
-
:loading="processing"
|
|
165
|
-
@click="handleSubmit"
|
|
166
|
-
/>
|
|
167
|
-
</v-col>
|
|
133
|
+
<p class="passkey__error">{{ errorMessage }}</p>
|
|
168
134
|
</v-row>
|
|
169
|
-
</
|
|
135
|
+
</div>
|
|
136
|
+
|
|
137
|
+
<div class="passkey__footer">
|
|
138
|
+
<AppButton variant="ghost" @click="emit('close')">Cancel</AppButton>
|
|
139
|
+
<AppButton :disabled="!canSubmit" @click="handleSubmit">
|
|
140
|
+
{{ isEditMode ? "Save" : "Assign" }}
|
|
141
|
+
</AppButton>
|
|
142
|
+
</div>
|
|
170
143
|
</v-card>
|
|
171
144
|
</template>
|
|
172
145
|
|
|
@@ -448,4 +421,53 @@ async function handleSubmit() {
|
|
|
448
421
|
}
|
|
449
422
|
</script>
|
|
450
423
|
|
|
451
|
-
<style scoped
|
|
424
|
+
<style scoped>
|
|
425
|
+
.passkey__head {
|
|
426
|
+
display: flex;
|
|
427
|
+
align-items: center;
|
|
428
|
+
justify-content: space-between;
|
|
429
|
+
padding-right: 12px;
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
.passkey__body {
|
|
433
|
+
padding: 4px 20px 0;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
.passkey__name,
|
|
437
|
+
.passkey__current {
|
|
438
|
+
font-size: var(--fs-cell);
|
|
439
|
+
color: var(--text2);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
.passkey__error {
|
|
443
|
+
width: 100%;
|
|
444
|
+
margin: 0;
|
|
445
|
+
text-align: center;
|
|
446
|
+
font-size: var(--fs-cell);
|
|
447
|
+
color: var(--err);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/* The chip's own remove control - `currentColor`, so it stays on whatever
|
|
451
|
+
tone the chip carries rather than picking a second colour. */
|
|
452
|
+
.passkey__remove {
|
|
453
|
+
display: inline-flex;
|
|
454
|
+
margin-left: 2px;
|
|
455
|
+
padding: 0;
|
|
456
|
+
border: none;
|
|
457
|
+
background: none;
|
|
458
|
+
color: inherit;
|
|
459
|
+
cursor: pointer;
|
|
460
|
+
opacity: 0.75;
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
.passkey__remove:hover {
|
|
464
|
+
opacity: 1;
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
.passkey__footer {
|
|
468
|
+
display: flex;
|
|
469
|
+
justify-content: flex-end;
|
|
470
|
+
gap: 8px;
|
|
471
|
+
padding: 16px 20px 20px;
|
|
472
|
+
}
|
|
473
|
+
</style>
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<v-card width="100%" :loading="processing">
|
|
2
|
+
<v-card width="100%" class="screen-modal" :loading="processing">
|
|
3
3
|
<v-toolbar>
|
|
4
4
|
<v-row no-gutters class="fill-height px-6" align="center">
|
|
5
|
-
<span class="
|
|
5
|
+
<span class="screen-card-title text-capitalize">
|
|
6
6
|
Preview Announcement
|
|
7
7
|
</span>
|
|
8
8
|
</v-row>
|
|
9
9
|
</v-toolbar>
|
|
10
10
|
|
|
11
|
-
<v-card-text
|
|
11
|
+
<v-card-text
|
|
12
|
+
style="max-height: 100vh; overflow-y: auto"
|
|
13
|
+
class="screen-modal__body pb-0 my-3"
|
|
14
|
+
>
|
|
12
15
|
<v-row no-gutters>
|
|
13
16
|
<template v-for="(label, key) in formattedFields" :key="key">
|
|
14
17
|
<v-col cols="12" class="mb-5">
|
|
@@ -39,7 +42,7 @@
|
|
|
39
42
|
<v-col class="font-weight-bold">Attachments:</v-col>
|
|
40
43
|
<v-col cols="9" class="px-10">
|
|
41
44
|
<template v-if="videosArray.length > 0">
|
|
42
|
-
<div class="text-caption
|
|
45
|
+
<div class="text-caption screen-hint mb-1">
|
|
43
46
|
Videos ({{ videosArray.length }})
|
|
44
47
|
</div>
|
|
45
48
|
<v-list density="compact" class="pa-0 rounded-lg border mb-3">
|
|
@@ -71,7 +74,7 @@
|
|
|
71
74
|
|
|
72
75
|
<template v-if="photosArray.length > 0">
|
|
73
76
|
<div
|
|
74
|
-
class="text-caption
|
|
77
|
+
class="text-caption screen-hint mb-1"
|
|
75
78
|
:class="{ 'mt-3': videosArray.length > 0 }"
|
|
76
79
|
>
|
|
77
80
|
Photos ({{ photosArray.length }})
|
|
@@ -110,7 +113,7 @@
|
|
|
110
113
|
|
|
111
114
|
<template v-if="filesArray.length > 0">
|
|
112
115
|
<div
|
|
113
|
-
class="text-caption
|
|
116
|
+
class="text-caption screen-hint mb-1"
|
|
114
117
|
:class="{
|
|
115
118
|
'mt-3': videosArray.length > 0 || photosArray.length > 0,
|
|
116
119
|
}"
|
|
@@ -1,57 +1,45 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-row no-gutters>
|
|
3
3
|
<v-col cols="12">
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
class="text-none"
|
|
18
|
-
@click="dialogAdd = true"
|
|
19
|
-
>
|
|
4
|
+
<!-- Two `grey-lighten-4` bars - one above the table, one below - are one
|
|
5
|
+
CardToolbar on the card's own surface. The literal grey stayed white
|
|
6
|
+
on the dark theme's card; measured as four 48px white slabs. -->
|
|
7
|
+
<AppCard class="table-card">
|
|
8
|
+
<CardToolbar :count="pageRange">
|
|
9
|
+
<template #left>
|
|
10
|
+
<AppButton
|
|
11
|
+
variant="icon"
|
|
12
|
+
icon="mdi-refresh"
|
|
13
|
+
aria-label="Refresh"
|
|
14
|
+
@click="getCameraRefresh()"
|
|
15
|
+
/>
|
|
16
|
+
<AppButton v-if="!prop.readOnly" @click="dialogAdd = true">
|
|
20
17
|
Add
|
|
21
|
-
</
|
|
18
|
+
</AppButton>
|
|
22
19
|
</template>
|
|
23
|
-
</v-toolbar>
|
|
24
|
-
|
|
25
|
-
<v-card-text class="pa-0 bg-red">
|
|
26
|
-
<v-data-table
|
|
27
|
-
:headers="computedHeaders"
|
|
28
|
-
:items="items"
|
|
29
|
-
fixed-header
|
|
30
|
-
hide-default-footer
|
|
31
|
-
@click:row="handleRowClick"
|
|
32
|
-
style="max-height: 300px"
|
|
33
|
-
>
|
|
34
|
-
<template #item.host="{ value }">
|
|
35
|
-
{{ maskHostUrl(value) }}
|
|
36
|
-
</template>
|
|
37
|
-
</v-data-table>
|
|
38
|
-
</v-card-text>
|
|
39
20
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
<local-pagination
|
|
47
|
-
v-model="page"
|
|
48
|
-
:length="pages"
|
|
49
|
-
@update:value="$emit('update:value', $event)"
|
|
50
|
-
/>
|
|
51
|
-
</v-row>
|
|
21
|
+
<template #right>
|
|
22
|
+
<local-pagination
|
|
23
|
+
v-model="page"
|
|
24
|
+
:length="pages"
|
|
25
|
+
@update:value="$emit('update:value', $event)"
|
|
26
|
+
/>
|
|
52
27
|
</template>
|
|
53
|
-
</
|
|
54
|
-
|
|
28
|
+
</CardToolbar>
|
|
29
|
+
|
|
30
|
+
<v-data-table
|
|
31
|
+
:headers="computedHeaders"
|
|
32
|
+
:items="items"
|
|
33
|
+
fixed-header
|
|
34
|
+
hide-default-footer
|
|
35
|
+
@click:row="handleRowClick"
|
|
36
|
+
style="max-height: 300px"
|
|
37
|
+
>
|
|
38
|
+
<template #item.host="{ value }">
|
|
39
|
+
{{ maskHostUrl(value) }}
|
|
40
|
+
</template>
|
|
41
|
+
</v-data-table>
|
|
42
|
+
</AppCard>
|
|
55
43
|
</v-col>
|
|
56
44
|
|
|
57
45
|
<!-- dialog -->
|
|
@@ -1,22 +1,27 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-row no-gutters class="pa-3">
|
|
3
3
|
<v-col cols="12">
|
|
4
|
-
<
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
4
|
+
<AppCard class="delivery-company__card">
|
|
5
|
+
<!--
|
|
6
|
+
The one toolbar the design puts on top of the card. It was a
|
|
7
|
+
hardcoded grey-lighten-4 bar, which stays light in dark mode
|
|
8
|
+
and painted as a white slab there.
|
|
9
|
+
-->
|
|
10
|
+
<CardToolbar>
|
|
11
|
+
<template #left>
|
|
12
|
+
<span v-if="!hideTitle" class="screen-card-title">
|
|
13
|
+
Delivery Companies
|
|
14
|
+
</span>
|
|
15
|
+
</template>
|
|
10
16
|
|
|
11
|
-
<template #
|
|
12
|
-
<
|
|
13
|
-
@click="handleAdd">
|
|
17
|
+
<template #right>
|
|
18
|
+
<AppButton v-if="!props.readOnly" @click="handleAdd">
|
|
14
19
|
Add
|
|
15
|
-
</
|
|
20
|
+
</AppButton>
|
|
16
21
|
</template>
|
|
17
|
-
</
|
|
22
|
+
</CardToolbar>
|
|
18
23
|
|
|
19
|
-
<
|
|
24
|
+
<div class="pa-0" style="min-height: 100px;">
|
|
20
25
|
<template v-if="companies.length > 0">
|
|
21
26
|
<draggable :list="companies" item-key="index" class="drag-area"
|
|
22
27
|
:disabled="editingIndex !== null">
|
|
@@ -60,11 +65,11 @@
|
|
|
60
65
|
</draggable>
|
|
61
66
|
</template>
|
|
62
67
|
|
|
63
|
-
<div v-else class="text-center py-5">
|
|
68
|
+
<div v-else class="screen-empty text-center py-5">
|
|
64
69
|
No delivery companies added yet.
|
|
65
70
|
</div>
|
|
66
|
-
</
|
|
67
|
-
</
|
|
71
|
+
</div>
|
|
72
|
+
</AppCard>
|
|
68
73
|
</v-col>
|
|
69
74
|
|
|
70
75
|
<v-dialog v-model="dialog.add" persistent width="450">
|
|
@@ -82,12 +87,13 @@
|
|
|
82
87
|
</v-card-text>
|
|
83
88
|
|
|
84
89
|
<v-toolbar>
|
|
85
|
-
<v-row no-gutters justify="end" align="center" class="px-5">
|
|
86
|
-
<
|
|
87
|
-
|
|
88
|
-
|
|
90
|
+
<v-row no-gutters justify="end" align="center" class="px-5 ga-2">
|
|
91
|
+
<AppButton variant="ghost" @click="dialog.add = false">
|
|
92
|
+
Cancel
|
|
93
|
+
</AppButton>
|
|
94
|
+
<AppButton @click="saveEdit(companies.length)">
|
|
89
95
|
Add
|
|
90
|
-
</
|
|
96
|
+
</AppButton>
|
|
91
97
|
</v-row>
|
|
92
98
|
</v-toolbar>
|
|
93
99
|
</v-card>
|
|
@@ -237,4 +243,12 @@ watch(initialCompanies, (val) => {
|
|
|
237
243
|
.drag-handle {
|
|
238
244
|
cursor: grab;
|
|
239
245
|
}
|
|
246
|
+
|
|
247
|
+
/* The size cap the v-card carried as max-width/max-height attributes, kept
|
|
248
|
+
verbatim so the panel does not grow to the full page width. */
|
|
249
|
+
.delivery-company__card {
|
|
250
|
+
max-width: 700px;
|
|
251
|
+
max-height: 500px;
|
|
252
|
+
overflow-y: auto;
|
|
253
|
+
}
|
|
240
254
|
</style>
|
|
@@ -2,37 +2,39 @@
|
|
|
2
2
|
<v-row no-gutters class="px-5 pt-4">
|
|
3
3
|
<!-- Authorities (Police/SCDF/Ambulance called in at the scene) -->
|
|
4
4
|
<v-col cols="12" class="border-b pb-5 mb-5 mt-1">
|
|
5
|
-
<p class="
|
|
5
|
+
<p class="screen-card-title mb-2">
|
|
6
6
|
Authorities (Police/SCDF/Ambulance called in at the scene)?
|
|
7
7
|
</p>
|
|
8
8
|
<p
|
|
9
9
|
v-if="authorities?.authoritiesValue == 'no'"
|
|
10
|
-
class="mt-2 text-
|
|
10
|
+
class="report-answer mt-2 text-capitalize"
|
|
11
11
|
>
|
|
12
12
|
{{ authorities?.authoritiesValue }}
|
|
13
13
|
</p>
|
|
14
14
|
|
|
15
|
-
<v-
|
|
16
|
-
v-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
</
|
|
15
|
+
<AppCard v-else class="table-card mt-5">
|
|
16
|
+
<v-data-table
|
|
17
|
+
:headers="authoritiesTableHeader"
|
|
18
|
+
:items="authorities?.authoritiesCalled"
|
|
19
|
+
fixed-header
|
|
20
|
+
hide-default-footer
|
|
21
|
+
:hide-default-header="false"
|
|
22
|
+
items-per-page="100"
|
|
23
|
+
style="max-height: calc(100vh - (200px))"
|
|
24
|
+
>
|
|
25
|
+
</v-data-table>
|
|
26
|
+
</AppCard>
|
|
27
27
|
</v-col>
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
<!-- `w-100` + `mx-2` made the card 16px wider than its column, so its right
|
|
29
|
+
corner was clipped off. The card supplies its own edge now. -->
|
|
30
|
+
<AppCard class="table-card w-100 my-8">
|
|
31
|
+
<v-table class="responsive-table elevation-0">
|
|
30
32
|
<thead>
|
|
31
33
|
<tr>
|
|
32
34
|
<th
|
|
33
35
|
v-for="(item, index) in concernHeader"
|
|
34
36
|
:key="index"
|
|
35
|
-
class="text-left
|
|
37
|
+
class="text-left border-e"
|
|
36
38
|
>
|
|
37
39
|
{{ item }}
|
|
38
40
|
</th>
|
|
@@ -196,10 +198,20 @@
|
|
|
196
198
|
</tr>
|
|
197
199
|
</tbody>
|
|
198
200
|
</v-table>
|
|
199
|
-
</
|
|
201
|
+
</AppCard>
|
|
200
202
|
</v-row>
|
|
201
203
|
</template>
|
|
202
204
|
|
|
205
|
+
<style scoped>
|
|
206
|
+
/* The prototype states no size for a plain answer line, so it takes the body
|
|
207
|
+
row's own type rather than Vuetify's `text-h6`. */
|
|
208
|
+
.report-answer {
|
|
209
|
+
font-size: var(--fs-cell);
|
|
210
|
+
font-weight: var(--fw-cell);
|
|
211
|
+
color: var(--text);
|
|
212
|
+
}
|
|
213
|
+
</style>
|
|
214
|
+
|
|
203
215
|
<script lang="ts" setup>
|
|
204
216
|
definePageMeta({
|
|
205
217
|
middleware: ["01-auth", "02-org"],
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<v-row no-gutters class="w-100">
|
|
3
|
-
<
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
<AppCard class="w-100 pa-4">
|
|
4
|
+
<!-- GHOST, not primary: the handoff names "Scan QR Code" in its
|
|
5
|
+
ghost/secondary list, alongside Bulk Upload, Download Report and
|
|
6
|
+
Export. Stays a `v-btn` because `block` has no AppButton
|
|
7
|
+
equivalent, so the design's button is applied as a class. -->
|
|
8
|
+
<v-btn block :height="38" text="Scan QR Code" variant="outlined"
|
|
9
|
+
class="screen-btn-ghost" prepend-icon="mdi-qrcode" @click="handleScanQRPass" />
|
|
7
10
|
<v-form ref="formRef" v-model="validForm" :disabled="processing" @click="errorScanPassMessage = ''">
|
|
8
11
|
<v-row no-gutters class="pt-5 ga-2">
|
|
9
12
|
<v-col cols="12">
|
|
@@ -81,22 +84,26 @@
|
|
|
81
84
|
|
|
82
85
|
<v-row class="pt-3" justify="space-between">
|
|
83
86
|
<v-col cols="6">
|
|
84
|
-
|
|
85
|
-
|
|
87
|
+
<!-- The primitive rather than a class on a v-btn: these two
|
|
88
|
+
need nothing Vuetify owns, and AppButton is the only way
|
|
89
|
+
they draw at the handoff's 40px / 38px. -->
|
|
90
|
+
<AppButton icon="mdi-plus" :disabled="!validForm" @click="handleAddMember">
|
|
91
|
+
Add Member
|
|
92
|
+
</AppButton>
|
|
86
93
|
</v-col>
|
|
87
94
|
<v-col cols="6" align="end">
|
|
88
|
-
<
|
|
89
|
-
|
|
95
|
+
<AppButton variant="ghost" icon="mdi-refresh" @click.stop="handleClearForm">
|
|
96
|
+
Clear Form
|
|
97
|
+
</AppButton>
|
|
90
98
|
</v-col>
|
|
91
99
|
</v-row>
|
|
92
100
|
</v-row>
|
|
93
101
|
</v-form>
|
|
94
|
-
|
|
95
|
-
</v-card>
|
|
102
|
+
</AppCard>
|
|
96
103
|
<visitor-pass-key-q-r-scanner :dialog="dialog.scanQRCode" v-model:scannedValue="scannedPassValue"
|
|
97
104
|
@close-dialog="dialog.scanQRCode = false" />
|
|
98
105
|
<v-dialog v-model="dialog.memberAutofillOptions" max-width="430">
|
|
99
|
-
<v-card v-if="memberSelectedSearchResult" class="nric-options-card">
|
|
106
|
+
<v-card v-if="memberSelectedSearchResult" class="nric-options-card screen-modal">
|
|
100
107
|
<v-card-actions class="justify-end pa-1">
|
|
101
108
|
<v-btn icon="mdi-close" variant="text" size="small" @click="memberCloseAutofillOptions" />
|
|
102
109
|
</v-card-actions>
|
|
@@ -127,10 +134,10 @@
|
|
|
127
134
|
</v-card-text>
|
|
128
135
|
|
|
129
136
|
<v-card-actions class="justify-end px-4 pb-4">
|
|
130
|
-
<v-btn variant="
|
|
137
|
+
<v-btn variant="outlined" class="screen-btn-ghost" size="small" @click="memberCloseAutofillOptions">
|
|
131
138
|
Cancel
|
|
132
139
|
</v-btn>
|
|
133
|
-
<v-btn
|
|
140
|
+
<v-btn variant="flat" class="screen-btn-primary px-5" size="small"
|
|
134
141
|
@click="memberConfirmAutofillOptions">
|
|
135
142
|
Select
|
|
136
143
|
</v-btn>
|
|
@@ -626,13 +633,13 @@ function handleRemoveMember(index: number) {
|
|
|
626
633
|
}
|
|
627
634
|
|
|
628
635
|
.nric-options-title {
|
|
629
|
-
color:
|
|
636
|
+
color: var(--text);
|
|
630
637
|
font-size: 1.45rem;
|
|
631
638
|
line-height: 1.2;
|
|
632
639
|
}
|
|
633
640
|
|
|
634
641
|
.nric-options-section-title {
|
|
635
|
-
color:
|
|
642
|
+
color: var(--text);
|
|
636
643
|
font-size: 1.05rem;
|
|
637
644
|
line-height: 1.25;
|
|
638
645
|
}
|
|
@@ -640,7 +647,7 @@ function handleRemoveMember(index: number) {
|
|
|
640
647
|
.nric-selected-person {
|
|
641
648
|
border: 1px solid rgba(var(--v-border-color), var(--v-border-opacity));
|
|
642
649
|
border-radius: 12px;
|
|
643
|
-
color:
|
|
650
|
+
color: var(--text);
|
|
644
651
|
font-size: 0.95rem;
|
|
645
652
|
min-height: 52px;
|
|
646
653
|
padding: 10px 14px;
|