@7365admin1/layer-common 1.10.3 → 1.10.4
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 +6 -0
- package/components/AccessCardPreviewDialog.vue +297 -0
- package/components/AccessCardReplaceForm.vue +179 -0
- package/components/AccessManagement.vue +44 -195
- package/components/AreaChecklistHistoryLogs.vue +1 -1
- package/components/BuildingManagement/units.vue +33 -2
- package/components/BuildingUnitFormAdd.vue +45 -99
- package/components/BuildingUnitFormEdit.vue +59 -148
- package/components/BulletinBoardView.vue +2 -2
- package/components/Button/Close.vue +3 -1
- package/components/CleaningScheduleMain.vue +2 -2
- package/components/IncidentReport/IncidentInformation.vue +45 -6
- package/components/PeopleForm.vue +1 -1
- package/components/ScheduleAreaMain.vue +2 -2
- package/components/ScheduleTaskForm.vue +59 -114
- package/components/ScheduleTaskMain.vue +19 -15
- package/components/VisitorForm.vue +1 -1
- package/composables/useAccessManagement.ts +8 -0
- package/composables/useBulletin.ts +5 -5
- package/composables/useCard.ts +14 -0
- package/composables/useScheduleTask.ts +4 -8
- package/package.json +1 -1
- package/types/bulletin-board.d.ts +1 -1
- package/types/checkout-item.d.ts +1 -0
- package/types/cleaner-schedule.d.ts +1 -1
- package/types/people.d.ts +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-dialog :model-value="modelValue" width="450" persistent>
|
|
3
|
+
<v-card width="100%">
|
|
4
|
+
<v-card-text style="max-height: 100vh; overflow-y: auto" class="pb-0">
|
|
5
|
+
<v-row no-gutters class="mb-4">
|
|
6
|
+
<v-col cols="12">
|
|
7
|
+
<strong>Building:</strong> {{ unit?.block?.name ?? "N/A" }}
|
|
8
|
+
</v-col>
|
|
9
|
+
<v-col cols="12">
|
|
10
|
+
<strong>Level:</strong> {{ unit?.level?.level ?? "N/A" }}
|
|
11
|
+
</v-col>
|
|
12
|
+
<v-col cols="12">
|
|
13
|
+
<strong>Unit:</strong> {{ unit?.name ?? "N/A" }}
|
|
14
|
+
</v-col>
|
|
15
|
+
|
|
16
|
+
<!-- Available Physical -->
|
|
17
|
+
<v-col cols="12" class="mt-3">
|
|
18
|
+
<strong>Available Physical</strong>
|
|
19
|
+
<div v-if="unit?.available?.physical?.length" class="mt-1">
|
|
20
|
+
<v-chip
|
|
21
|
+
v-for="card in unit.available.physical"
|
|
22
|
+
:key="card._id"
|
|
23
|
+
size="small"
|
|
24
|
+
class="mr-1 mb-1"
|
|
25
|
+
:color="selectedCardInUnit?._id === card._id ? 'primary' : undefined"
|
|
26
|
+
:variant="selectedCardInUnit?._id === card._id ? 'flat' : 'tonal'"
|
|
27
|
+
style="cursor: pointer"
|
|
28
|
+
@click="toggleCard(card)"
|
|
29
|
+
>
|
|
30
|
+
{{ card.cardNo }}
|
|
31
|
+
</v-chip>
|
|
32
|
+
</div>
|
|
33
|
+
<span v-else class="text-caption text-grey ml-1">None</span>
|
|
34
|
+
</v-col>
|
|
35
|
+
|
|
36
|
+
<!-- Available Non-Physical -->
|
|
37
|
+
<v-col cols="12" class="mt-2">
|
|
38
|
+
<strong>Available Non-Physical</strong>
|
|
39
|
+
<div v-if="unit?.available?.non_physical?.length" class="mt-1">
|
|
40
|
+
<v-chip
|
|
41
|
+
v-for="card in unit.available.non_physical"
|
|
42
|
+
:key="card._id"
|
|
43
|
+
size="small"
|
|
44
|
+
class="mr-1 mb-1"
|
|
45
|
+
:color="selectedCardInUnit?._id === card._id ? 'primary' : undefined"
|
|
46
|
+
:variant="selectedCardInUnit?._id === card._id ? 'flat' : 'tonal'"
|
|
47
|
+
style="cursor: pointer"
|
|
48
|
+
@click="toggleCard(card)"
|
|
49
|
+
>
|
|
50
|
+
{{ card.cardNo }}
|
|
51
|
+
</v-chip>
|
|
52
|
+
</div>
|
|
53
|
+
<span v-else class="text-caption text-grey ml-1">None</span>
|
|
54
|
+
</v-col>
|
|
55
|
+
|
|
56
|
+
<!-- Assigned Physical -->
|
|
57
|
+
<v-col cols="12" class="mt-2">
|
|
58
|
+
<strong>Assigned Physical</strong>
|
|
59
|
+
<div v-if="unit?.assigned?.physical?.length" class="mt-1">
|
|
60
|
+
<v-chip
|
|
61
|
+
v-for="card in unit.assigned.physical"
|
|
62
|
+
:key="card._id"
|
|
63
|
+
size="small"
|
|
64
|
+
class="mr-1 mb-1"
|
|
65
|
+
:color="selectedCardInUnit?._id === card._id ? 'primary' : undefined"
|
|
66
|
+
:variant="selectedCardInUnit?._id === card._id ? 'flat' : 'tonal'"
|
|
67
|
+
style="cursor: pointer"
|
|
68
|
+
@click="toggleCard(card)"
|
|
69
|
+
>
|
|
70
|
+
{{ card.cardNo }}
|
|
71
|
+
</v-chip>
|
|
72
|
+
</div>
|
|
73
|
+
<span v-else class="text-caption text-grey ml-1">None</span>
|
|
74
|
+
</v-col>
|
|
75
|
+
|
|
76
|
+
<!-- Assigned Non-Physical -->
|
|
77
|
+
<v-col cols="12" class="mt-2">
|
|
78
|
+
<strong>Assigned Non-Physical</strong>
|
|
79
|
+
<div v-if="unit?.assigned?.non_physical?.length" class="mt-1">
|
|
80
|
+
<v-chip
|
|
81
|
+
v-for="card in unit.assigned.non_physical"
|
|
82
|
+
:key="card._id"
|
|
83
|
+
size="small"
|
|
84
|
+
class="mr-1 mb-1"
|
|
85
|
+
:color="selectedCardInUnit?._id === card._id ? 'primary' : undefined"
|
|
86
|
+
:variant="selectedCardInUnit?._id === card._id ? 'flat' : 'tonal'"
|
|
87
|
+
style="cursor: pointer"
|
|
88
|
+
@click="toggleCard(card)"
|
|
89
|
+
>
|
|
90
|
+
{{ card.cardNo }}
|
|
91
|
+
</v-chip>
|
|
92
|
+
</div>
|
|
93
|
+
<span v-else class="text-caption text-grey ml-1">None</span>
|
|
94
|
+
</v-col>
|
|
95
|
+
|
|
96
|
+
<!-- Replaced Physical -->
|
|
97
|
+
<v-col cols="12" class="mt-2">
|
|
98
|
+
<strong>Replaced Physical</strong>
|
|
99
|
+
<div v-if="unit?.replaced?.physical?.length" class="mt-1">
|
|
100
|
+
<v-chip
|
|
101
|
+
v-for="card in unit.replaced.physical"
|
|
102
|
+
:key="card._id"
|
|
103
|
+
size="small"
|
|
104
|
+
class="mr-1 mb-1"
|
|
105
|
+
:color="selectedCardInUnit?._id === card._id ? 'orange' : 'orange'"
|
|
106
|
+
:variant="selectedCardInUnit?._id === card._id ? 'flat' : 'tonal'"
|
|
107
|
+
style="cursor: pointer"
|
|
108
|
+
@click="toggleCard(card)"
|
|
109
|
+
>
|
|
110
|
+
{{ card.cardNo }}
|
|
111
|
+
</v-chip>
|
|
112
|
+
</div>
|
|
113
|
+
<span v-else class="text-caption text-grey ml-1">None</span>
|
|
114
|
+
</v-col>
|
|
115
|
+
|
|
116
|
+
<!-- Replaced Non-Physical -->
|
|
117
|
+
<v-col cols="12" class="mt-2">
|
|
118
|
+
<strong>Replaced Non-Physical</strong>
|
|
119
|
+
<div v-if="unit?.replaced?.non_physical?.length" class="mt-1">
|
|
120
|
+
<v-chip
|
|
121
|
+
v-for="card in unit.replaced.non_physical"
|
|
122
|
+
:key="card._id"
|
|
123
|
+
size="small"
|
|
124
|
+
class="mr-1 mb-1"
|
|
125
|
+
:color="selectedCardInUnit?._id === card._id ? 'orange' : 'orange'"
|
|
126
|
+
:variant="selectedCardInUnit?._id === card._id ? 'flat' : 'tonal'"
|
|
127
|
+
style="cursor: pointer"
|
|
128
|
+
@click="toggleCard(card)"
|
|
129
|
+
>
|
|
130
|
+
{{ card.cardNo }}
|
|
131
|
+
</v-chip>
|
|
132
|
+
</div>
|
|
133
|
+
<span v-else class="text-caption text-grey ml-1">None</span>
|
|
134
|
+
</v-col>
|
|
135
|
+
|
|
136
|
+
<!-- Deleted Physical -->
|
|
137
|
+
<v-col cols="12" class="mt-2">
|
|
138
|
+
<strong>Deleted Physical</strong>
|
|
139
|
+
<div v-if="unit?.deleted?.physical?.length" class="mt-1">
|
|
140
|
+
<v-chip
|
|
141
|
+
v-for="card in unit.deleted.physical"
|
|
142
|
+
:key="card._id"
|
|
143
|
+
size="small"
|
|
144
|
+
class="mr-1 mb-1"
|
|
145
|
+
:color="selectedCardInUnit?._id === card._id ? 'red' : 'red'"
|
|
146
|
+
:variant="selectedCardInUnit?._id === card._id ? 'flat' : 'tonal'"
|
|
147
|
+
style="cursor: pointer"
|
|
148
|
+
@click="toggleCard(card)"
|
|
149
|
+
>
|
|
150
|
+
{{ card.cardNo }}
|
|
151
|
+
</v-chip>
|
|
152
|
+
</div>
|
|
153
|
+
<span v-else class="text-caption text-grey ml-1">None</span>
|
|
154
|
+
</v-col>
|
|
155
|
+
|
|
156
|
+
<!-- Deleted Non-Physical -->
|
|
157
|
+
<v-col cols="12" class="mt-2">
|
|
158
|
+
<strong>Deleted Non-Physical</strong>
|
|
159
|
+
<div v-if="unit?.deleted?.non_physical?.length" class="mt-1">
|
|
160
|
+
<v-chip
|
|
161
|
+
v-for="card in unit.deleted.non_physical"
|
|
162
|
+
:key="card._id"
|
|
163
|
+
size="small"
|
|
164
|
+
class="mr-1 mb-1"
|
|
165
|
+
:color="selectedCardInUnit?._id === card._id ? 'red' : 'red'"
|
|
166
|
+
:variant="selectedCardInUnit?._id === card._id ? 'flat' : 'tonal'"
|
|
167
|
+
style="cursor: pointer"
|
|
168
|
+
@click="toggleCard(card)"
|
|
169
|
+
>
|
|
170
|
+
{{ card.cardNo }}
|
|
171
|
+
</v-chip>
|
|
172
|
+
</div>
|
|
173
|
+
<span v-else class="text-caption text-grey ml-1">None</span>
|
|
174
|
+
</v-col>
|
|
175
|
+
</v-row>
|
|
176
|
+
</v-card-text>
|
|
177
|
+
|
|
178
|
+
<v-toolbar class="pa-0" density="compact">
|
|
179
|
+
<v-row no-gutters>
|
|
180
|
+
<v-col cols="6" class="pa-0">
|
|
181
|
+
<v-btn
|
|
182
|
+
block
|
|
183
|
+
variant="text"
|
|
184
|
+
class="text-none"
|
|
185
|
+
size="large"
|
|
186
|
+
height="48"
|
|
187
|
+
@click="emit('update:modelValue', false)"
|
|
188
|
+
>
|
|
189
|
+
Close
|
|
190
|
+
</v-btn>
|
|
191
|
+
</v-col>
|
|
192
|
+
<v-col cols="6" class="pa-0" v-if="canUpdate">
|
|
193
|
+
<v-menu>
|
|
194
|
+
<template #activator="{ props }">
|
|
195
|
+
<v-btn
|
|
196
|
+
block
|
|
197
|
+
variant="flat"
|
|
198
|
+
color="black"
|
|
199
|
+
class="text-none"
|
|
200
|
+
height="48"
|
|
201
|
+
v-bind="props"
|
|
202
|
+
tile
|
|
203
|
+
>
|
|
204
|
+
More actions
|
|
205
|
+
</v-btn>
|
|
206
|
+
</template>
|
|
207
|
+
<v-list class="pa-0">
|
|
208
|
+
<v-list-item
|
|
209
|
+
:disabled="!isSelectedCardAssignedPhysical"
|
|
210
|
+
@click="emit('replace')"
|
|
211
|
+
v-if="canReplaceAccessCard && isSelectedCardAssignedPhysical"
|
|
212
|
+
>
|
|
213
|
+
<v-list-item-title class="text-subtitle-2">
|
|
214
|
+
Replace Card
|
|
215
|
+
</v-list-item-title>
|
|
216
|
+
</v-list-item>
|
|
217
|
+
<v-list-item :disabled="selectedCardInUnit === null">
|
|
218
|
+
<v-list-item-title class="text-subtitle-2 cursor-pointer">
|
|
219
|
+
Card History
|
|
220
|
+
</v-list-item-title>
|
|
221
|
+
</v-list-item>
|
|
222
|
+
<v-list-item
|
|
223
|
+
@click="emit('delete')"
|
|
224
|
+
class="text-red"
|
|
225
|
+
:disabled="!isSelectedCardDeletable"
|
|
226
|
+
v-if="canDeleteAccessCard"
|
|
227
|
+
>
|
|
228
|
+
<v-list-item-title class="text-subtitle-2">
|
|
229
|
+
Delete Card
|
|
230
|
+
</v-list-item-title>
|
|
231
|
+
</v-list-item>
|
|
232
|
+
</v-list>
|
|
233
|
+
</v-menu>
|
|
234
|
+
</v-col>
|
|
235
|
+
</v-row>
|
|
236
|
+
</v-toolbar>
|
|
237
|
+
</v-card>
|
|
238
|
+
</v-dialog>
|
|
239
|
+
</template>
|
|
240
|
+
|
|
241
|
+
<script setup lang="ts">
|
|
242
|
+
const props = defineProps({
|
|
243
|
+
modelValue: {
|
|
244
|
+
type: Boolean,
|
|
245
|
+
default: false,
|
|
246
|
+
},
|
|
247
|
+
unit: {
|
|
248
|
+
type: Object as PropType<Record<string, any>>,
|
|
249
|
+
default: () => ({}),
|
|
250
|
+
},
|
|
251
|
+
selectedCardInUnit: {
|
|
252
|
+
type: Object as PropType<Record<string, any> | null>,
|
|
253
|
+
default: null,
|
|
254
|
+
},
|
|
255
|
+
canUpdate: {
|
|
256
|
+
type: Boolean,
|
|
257
|
+
default: true,
|
|
258
|
+
},
|
|
259
|
+
canReplaceAccessCard: {
|
|
260
|
+
type: Boolean,
|
|
261
|
+
default: true,
|
|
262
|
+
},
|
|
263
|
+
canDeleteAccessCard: {
|
|
264
|
+
type: Boolean,
|
|
265
|
+
default: true,
|
|
266
|
+
},
|
|
267
|
+
isSelectedCardAssignedPhysical: {
|
|
268
|
+
type: Boolean,
|
|
269
|
+
default: false,
|
|
270
|
+
},
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
const emit = defineEmits<{
|
|
274
|
+
"update:modelValue": [value: boolean];
|
|
275
|
+
"update:selectedCardInUnit": [value: Record<string, any> | null];
|
|
276
|
+
replace: [];
|
|
277
|
+
delete: [];
|
|
278
|
+
}>();
|
|
279
|
+
|
|
280
|
+
const isSelectedCardDeletable = computed(() => {
|
|
281
|
+
if (!props.selectedCardInUnit?._id) return false;
|
|
282
|
+
const id = props.selectedCardInUnit._id;
|
|
283
|
+
return [
|
|
284
|
+
...(props.unit?.available?.physical ?? []),
|
|
285
|
+
...(props.unit?.available?.non_physical ?? []),
|
|
286
|
+
...(props.unit?.assigned?.physical ?? []),
|
|
287
|
+
...(props.unit?.assigned?.non_physical ?? []),
|
|
288
|
+
].some((c) => c._id === id);
|
|
289
|
+
});
|
|
290
|
+
|
|
291
|
+
function toggleCard(card: Record<string, any>) {
|
|
292
|
+
emit(
|
|
293
|
+
"update:selectedCardInUnit",
|
|
294
|
+
props.selectedCardInUnit?._id === card._id ? null : card
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
</script>
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<v-card width="100%">
|
|
3
|
+
<v-toolbar>
|
|
4
|
+
<v-row no-gutters class="fill-height px-6" align="center">
|
|
5
|
+
<span class="font-weight-bold text-h5">Replace Access Card</span>
|
|
6
|
+
</v-row>
|
|
7
|
+
</v-toolbar>
|
|
8
|
+
<v-card-text style="max-height: 100vh; overflow-y: auto" class="pa-0">
|
|
9
|
+
<v-form v-model="validForm" :disabled="loading">
|
|
10
|
+
<v-row no-gutters class="px-6 pt-4 pb-6">
|
|
11
|
+
<!-- Card being replaced -->
|
|
12
|
+
<v-col cols="12" class="px-1 mb-4">
|
|
13
|
+
<div class="text-caption text-grey mb-1 font-weight-bold">
|
|
14
|
+
Card being replaced
|
|
15
|
+
</div>
|
|
16
|
+
<v-chip size="small" variant="tonal" color="warning">
|
|
17
|
+
{{ card.cardNo }}
|
|
18
|
+
</v-chip>
|
|
19
|
+
</v-col>
|
|
20
|
+
|
|
21
|
+
<!-- Replacement card -->
|
|
22
|
+
<v-col cols="12" class="px-1">
|
|
23
|
+
<InputLabel
|
|
24
|
+
class="text-capitalize font-weight-bold"
|
|
25
|
+
title="Replacement Card"
|
|
26
|
+
required
|
|
27
|
+
/>
|
|
28
|
+
<v-autocomplete
|
|
29
|
+
v-model="form.replacementCardId"
|
|
30
|
+
density="compact"
|
|
31
|
+
:items="replacementOptions"
|
|
32
|
+
hide-details="auto"
|
|
33
|
+
item-title="cardNo"
|
|
34
|
+
item-value="_id"
|
|
35
|
+
placeholder="Select replacement card..."
|
|
36
|
+
persistent-placeholder
|
|
37
|
+
:rules="[requiredRule]"
|
|
38
|
+
:no-data-text="noDataText"
|
|
39
|
+
/>
|
|
40
|
+
</v-col>
|
|
41
|
+
|
|
42
|
+
<!-- Remarks -->
|
|
43
|
+
<v-col cols="12" class="px-1 mt-2">
|
|
44
|
+
<InputLabel
|
|
45
|
+
class="text-capitalize font-weight-bold"
|
|
46
|
+
title="Remarks"
|
|
47
|
+
required
|
|
48
|
+
/>
|
|
49
|
+
<v-textarea
|
|
50
|
+
v-model="form.remarks"
|
|
51
|
+
density="compact"
|
|
52
|
+
hide-details="auto"
|
|
53
|
+
placeholder="Enter remarks..."
|
|
54
|
+
persistent-placeholder
|
|
55
|
+
rows="3"
|
|
56
|
+
auto-grow
|
|
57
|
+
:rules="[requiredRule]"
|
|
58
|
+
/>
|
|
59
|
+
</v-col>
|
|
60
|
+
</v-row>
|
|
61
|
+
</v-form>
|
|
62
|
+
</v-card-text>
|
|
63
|
+
|
|
64
|
+
<v-toolbar density="compact">
|
|
65
|
+
<v-row no-gutters>
|
|
66
|
+
<v-col cols="6">
|
|
67
|
+
<v-btn
|
|
68
|
+
tile
|
|
69
|
+
block
|
|
70
|
+
variant="text"
|
|
71
|
+
class="text-none"
|
|
72
|
+
size="48"
|
|
73
|
+
@click="cancel"
|
|
74
|
+
:disabled="loading"
|
|
75
|
+
>
|
|
76
|
+
Cancel
|
|
77
|
+
</v-btn>
|
|
78
|
+
</v-col>
|
|
79
|
+
<v-col cols="6">
|
|
80
|
+
<v-btn
|
|
81
|
+
tile
|
|
82
|
+
block
|
|
83
|
+
variant="flat"
|
|
84
|
+
color="black"
|
|
85
|
+
class="text-none"
|
|
86
|
+
size="48"
|
|
87
|
+
:disabled="!validForm || loading"
|
|
88
|
+
:loading="loading"
|
|
89
|
+
@click="submit"
|
|
90
|
+
>
|
|
91
|
+
Replace
|
|
92
|
+
</v-btn>
|
|
93
|
+
</v-col>
|
|
94
|
+
</v-row>
|
|
95
|
+
</v-toolbar>
|
|
96
|
+
</v-card>
|
|
97
|
+
</template>
|
|
98
|
+
<script setup lang="ts">
|
|
99
|
+
const props = defineProps({
|
|
100
|
+
card: {
|
|
101
|
+
type: Object as PropType<Record<string, any>>,
|
|
102
|
+
required: true,
|
|
103
|
+
},
|
|
104
|
+
unit: {
|
|
105
|
+
type: Object as PropType<Record<string, any>>,
|
|
106
|
+
required: true,
|
|
107
|
+
},
|
|
108
|
+
siteId: {
|
|
109
|
+
type: String,
|
|
110
|
+
default: "",
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
const emit = defineEmits(["cancel", "success", "error"]);
|
|
114
|
+
|
|
115
|
+
const { requiredRule } = useUtils();
|
|
116
|
+
|
|
117
|
+
const validForm = ref(false);
|
|
118
|
+
const loading = ref(false);
|
|
119
|
+
|
|
120
|
+
const form = ref({
|
|
121
|
+
replacementCardId: null as string | null,
|
|
122
|
+
remarks: "",
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
const cardType = computed(() => {
|
|
126
|
+
const id = props.card._id;
|
|
127
|
+
if (props.unit.available?.physical?.some((c: any) => c._id === id)) return "physical";
|
|
128
|
+
if (props.unit.assigned?.physical?.some((c: any) => c._id === id)) return "physical";
|
|
129
|
+
if (props.unit.available?.non_physical?.some((c: any) => c._id === id)) return "non_physical";
|
|
130
|
+
if (props.unit.assigned?.non_physical?.some((c: any) => c._id === id)) return "non_physical";
|
|
131
|
+
return null;
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
const replacementOptions = computed(() => {
|
|
135
|
+
const id = props.card._id;
|
|
136
|
+
if (cardType.value === "physical") {
|
|
137
|
+
return (props.unit.available?.physical ?? []).filter((c: any) => c._id !== id);
|
|
138
|
+
}
|
|
139
|
+
if (cardType.value === "non_physical") {
|
|
140
|
+
return (props.unit.available?.non_physical ?? []).filter((c: any) => c._id !== id);
|
|
141
|
+
}
|
|
142
|
+
return [];
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
const noDataText = computed(() => {
|
|
146
|
+
if (!cardType.value) return "Unable to determine card type";
|
|
147
|
+
const label = cardType.value === "physical" ? "physical" : "non-physical";
|
|
148
|
+
return `No available ${label} cards for replacement`;
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
function cancel() {
|
|
152
|
+
emit("cancel");
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async function submit() {
|
|
156
|
+
loading.value = true;
|
|
157
|
+
try {
|
|
158
|
+
const { replaceCard } = useCard();
|
|
159
|
+
const { currentUser } = useLocalAuth();
|
|
160
|
+
// @TODO: userId should be the ID of the unit owner, not the current user
|
|
161
|
+
await replaceCard({
|
|
162
|
+
cardId: props.card._id,
|
|
163
|
+
issuedCardId: form.value.replacementCardId!,
|
|
164
|
+
unitId: props.unit._id,
|
|
165
|
+
remarks: form.value.remarks,
|
|
166
|
+
userId: currentUser.value?._id ?? "",
|
|
167
|
+
});
|
|
168
|
+
emit("success");
|
|
169
|
+
} catch (error: any) {
|
|
170
|
+
const msg =
|
|
171
|
+
error?.response?._data?.message ||
|
|
172
|
+
error?.data?.message ||
|
|
173
|
+
"Failed to replace access card.";
|
|
174
|
+
emit("error", msg);
|
|
175
|
+
} finally {
|
|
176
|
+
loading.value = false;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
</script>
|