@iservice365/layer-common 1.3.0 → 1.3.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.
@@ -0,0 +1,441 @@
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"> Add Unit </span>
6
+ </v-row>
7
+ </v-toolbar>
8
+ <v-card-text style="max-height: 100vh; overflow-y: auto">
9
+ <v-form v-model="validForm" :disabled="disable">
10
+ <v-row no-gutters>
11
+ <v-col cols="12" class="mt-2">
12
+ <v-row no-gutters>
13
+ <InputLabel class="text-capitalize" title="Name" required />
14
+ <v-col cols="12">
15
+ <v-text-field
16
+ v-model="buildingUnit.name"
17
+ density="comfortable"
18
+ :rules="[requiredRule]"
19
+ ></v-text-field>
20
+ </v-col>
21
+ </v-row>
22
+ </v-col>
23
+
24
+ <v-col cols="12">
25
+ <v-row>
26
+ <v-col cols="12" class="mt-2">
27
+ <v-row no-gutters>
28
+ <InputLabel
29
+ class="text-capitalize"
30
+ title="Building"
31
+ required
32
+ />
33
+ <v-col cols="12">
34
+ <v-autocomplete
35
+ v-model="buildingUnit.building"
36
+ :items="buildings"
37
+ item-title="name"
38
+ item-value="_id"
39
+ v-model:search="searchBuilding"
40
+ :hide-no-data="false"
41
+ density="comfortable"
42
+ :rules="[requiredRule]"
43
+ variant="outlined"
44
+ ></v-autocomplete>
45
+ </v-col>
46
+ </v-row>
47
+ </v-col>
48
+ </v-row>
49
+ </v-col>
50
+
51
+ <v-col cols="12">
52
+ <v-row>
53
+ <v-col cols="12" class="mt-2">
54
+ <v-row no-gutters>
55
+ <InputLabel
56
+ class="text-capitalize"
57
+ title="Company Name"
58
+ required
59
+ />
60
+ <v-col cols="12">
61
+ <v-text-field
62
+ v-model="buildingUnit.companyName"
63
+ density="comfortable"
64
+ :rules="[requiredRule]"
65
+ ></v-text-field>
66
+ </v-col>
67
+ </v-row>
68
+ </v-col>
69
+ </v-row>
70
+ </v-col>
71
+
72
+ <v-col cols="12">
73
+ <v-row>
74
+ <v-col cols="12" class="mt-2">
75
+ <v-row no-gutters>
76
+ <InputLabel
77
+ class="text-capitalize"
78
+ title="Company Registration Number"
79
+ />
80
+ <v-col cols="12">
81
+ <v-text-field
82
+ v-model="buildingUnit.companyRegistrationNumber"
83
+ density="comfortable"
84
+ :rules="[]"
85
+ ></v-text-field>
86
+ </v-col>
87
+ </v-row>
88
+ </v-col>
89
+ </v-row>
90
+ </v-col>
91
+
92
+ <v-col cols="12">
93
+ <v-row>
94
+ <v-col cols="12" class="mt-2">
95
+ <v-row no-gutters>
96
+ <InputLabel
97
+ class="text-capitalize"
98
+ title="Lease Start"
99
+ required
100
+ />
101
+ <v-col cols="12">
102
+ <InputDateTimePicker
103
+ ref="startDateRef"
104
+ v-model="buildingUnit.leaseStart"
105
+ :rules="[requiredRule]"
106
+ />
107
+ </v-col>
108
+ </v-row>
109
+ </v-col>
110
+ </v-row>
111
+ </v-col>
112
+
113
+ <v-col cols="12">
114
+ <v-row>
115
+ <v-col cols="12" class="mt-2">
116
+ <v-row no-gutters>
117
+ <InputLabel
118
+ class="text-capitalize"
119
+ title="Lease End"
120
+ required
121
+ />
122
+ <v-col cols="12">
123
+ <InputDateTimePicker
124
+ ref="endDateRef"
125
+ v-model="buildingUnit.leaseEnd"
126
+ :rules="[requiredRule]"
127
+ />
128
+ </v-col>
129
+ </v-row>
130
+ </v-col>
131
+ </v-row>
132
+ </v-col>
133
+
134
+ <v-col cols="12" class="mt-2">
135
+ <v-row no-gutters>
136
+ <InputLabel class="text-capitalize" title="Category" required />
137
+ <v-col cols="12">
138
+ <v-autocomplete
139
+ v-model="buildingUnit.category"
140
+ :items="unitCategories"
141
+ density="comfortable"
142
+ :rules="[requiredRule]"
143
+ ></v-autocomplete>
144
+ </v-col>
145
+ </v-row>
146
+ </v-col>
147
+
148
+ <v-col cols="12">
149
+ <v-row>
150
+ <v-col cols="6" class="mt-2">
151
+ <v-row no-gutters>
152
+ <InputLabel class="text-capitalize" title="Level" required />
153
+ <v-col cols="12">
154
+ <v-select
155
+ v-model="buildingUnit.level"
156
+ :items="buildingLevels"
157
+ density="comfortable"
158
+ :rules="[requiredRule]"
159
+ ></v-select>
160
+ </v-col>
161
+ </v-row>
162
+ </v-col>
163
+
164
+ <v-col cols="6" class="mt-2">
165
+ <v-row no-gutters>
166
+ <InputLabel
167
+ class="text-capitalize"
168
+ title="No. of Units"
169
+ required
170
+ />
171
+ <v-col cols="12">
172
+ <v-text-field
173
+ v-model.number="buildingUnitQty"
174
+ density="comfortable"
175
+ :rules="[requiredRule]"
176
+ type="number"
177
+ @update:model-value="setBuildingLevels()"
178
+ ></v-text-field>
179
+ </v-col>
180
+ </v-row>
181
+ </v-col>
182
+ </v-row>
183
+ </v-col>
184
+
185
+ <v-col v-if="buildingLevels" cols="12">
186
+ <v-row justify="center">
187
+ <v-col cols="6">
188
+ <v-btn
189
+ block
190
+ color="primary"
191
+ variant="text"
192
+ class="text-none font-weight-bold"
193
+ text="Set unit labels"
194
+ @click="show = !show"
195
+ ></v-btn>
196
+ </v-col>
197
+ </v-row>
198
+ </v-col>
199
+
200
+ <v-expand-transition>
201
+ <v-row v-show="show" no-gutters>
202
+ <template
203
+ v-for="(unitLabel, unitLabelIndex) in unitLabels"
204
+ :key="levelIndex"
205
+ >
206
+ <v-col cols="12">
207
+ <v-row no-gutters>
208
+ <InputLabel
209
+ class="text-capitalize font-weight-bold"
210
+ :title="`Unit ${unitLabelIndex + 1}`"
211
+ />
212
+ <v-col cols="12">
213
+ <v-text-field
214
+ v-model.trim="unitLabels[unitLabelIndex]"
215
+ density="comfortable"
216
+ ></v-text-field>
217
+ </v-col>
218
+ </v-row>
219
+ </v-col>
220
+ </template>
221
+ </v-row>
222
+ </v-expand-transition>
223
+
224
+ <v-col cols="12" class="mt-5">
225
+ <InputLabel
226
+ class="text-capitalize"
227
+ title="Upload Files (Lease of Contract, Cert. of Occupancy)"
228
+ />
229
+ <InputFileV2
230
+ v-model="buildingUnit.buildingUnitFiles"
231
+ :multiple="false"
232
+ :max-length="10"
233
+ title="Upload PDF Files"
234
+ accept="application/pdf"
235
+ />
236
+ </v-col>
237
+
238
+ <v-col cols="12" class="mt-2">
239
+ <v-checkbox v-model="createMore" density="comfortable" hide-details>
240
+ <template #label>
241
+ <span class="text-subtitle-2 font-weight-bold">
242
+ Create more
243
+ </span>
244
+ </template>
245
+ </v-checkbox>
246
+ </v-col>
247
+
248
+ <v-col cols="12" class="my-2">
249
+ <v-row no-gutters>
250
+ <v-col cols="12" class="text-center">
251
+ <span
252
+ class="text-none text-subtitle-2 font-weight-medium text-error"
253
+ >
254
+ {{ message }}
255
+ </span>
256
+ </v-col>
257
+ </v-row>
258
+ </v-col>
259
+ </v-row>
260
+ </v-form>
261
+ </v-card-text>
262
+
263
+ <v-toolbar density="compact">
264
+ <v-row no-gutters>
265
+ <v-col cols="6">
266
+ <v-btn
267
+ tile
268
+ block
269
+ variant="text"
270
+ class="text-none"
271
+ size="48"
272
+ @click="cancel"
273
+ :disabled="disable"
274
+ >
275
+ Cancel
276
+ </v-btn>
277
+ </v-col>
278
+
279
+ <v-col cols="6">
280
+ <v-btn
281
+ tile
282
+ block
283
+ variant="flat"
284
+ color="black"
285
+ class="text-none"
286
+ size="48"
287
+ :disabled="!validForm || disable"
288
+ @click="submit"
289
+ :loading="disable"
290
+ >
291
+ Submit
292
+ </v-btn>
293
+ </v-col>
294
+ </v-row>
295
+ </v-toolbar>
296
+ </v-card>
297
+ </template>
298
+
299
+ <script setup lang="ts">
300
+ const prop = defineProps({
301
+ site: {
302
+ type: String,
303
+ default: "",
304
+ },
305
+ });
306
+
307
+ const searchBuilding = ref("");
308
+
309
+ const emit = defineEmits(["cancel", "success", "success:create-more"]);
310
+
311
+ const validForm = ref(false);
312
+
313
+ const { getAll } = useBuilding();
314
+
315
+ const buildings = ref<TBuilding[]>([]);
316
+
317
+ const { data: getBuildingReq } = useLazyAsyncData(
318
+ "get-all-buildings",
319
+ async () => getAll({ site: prop.site, status: "active" })
320
+ );
321
+
322
+ watchEffect(() => {
323
+ if (getBuildingReq.value) {
324
+ buildings.value = getBuildingReq.value.items;
325
+ }
326
+ });
327
+
328
+ const buildingUnitQty = ref(1);
329
+
330
+ const buildingUnit = ref<TBuildingUnit>({
331
+ site: "",
332
+ name: "Unit",
333
+ building: "",
334
+ buildingName: "",
335
+ block: 0,
336
+ level: "",
337
+ category: "",
338
+ status: "active",
339
+ buildingUnitFiles: [],
340
+ companyName: "",
341
+ companyRegistrationNumber: "",
342
+ leaseStart: "",
343
+ leaseEnd: "",
344
+ });
345
+
346
+ const startDateRef = ref<HTMLInputElement | null>(null);
347
+ const expiryDateRef = ref<HTMLInputElement | null>(null);
348
+
349
+ buildingUnit.value.site = prop.site;
350
+
351
+ const selectedBuilding = computed(() => {
352
+ return buildings.value.find((b) => b._id === buildingUnit.value.building);
353
+ });
354
+
355
+ watchEffect(() => {
356
+ if (buildingUnit.value.building) {
357
+ buildingUnit.value.buildingName = selectedBuilding.value?.name;
358
+ buildingUnit.value.block = selectedBuilding.value?.block || 0;
359
+ } else {
360
+ buildingUnit.value.buildingName = "";
361
+ buildingUnit.value.block = 0;
362
+ }
363
+ });
364
+
365
+ const buildingLevels = computed(() => {
366
+ return selectedBuilding.value?.levels || [];
367
+ });
368
+
369
+ const unitLabels = ref<string[]>([]);
370
+ unitLabels.value.push("Unit 1");
371
+
372
+ const show = ref(false);
373
+
374
+ function setBuildingLevels() {
375
+ unitLabels.value.length = 0;
376
+ for (let index = 0; index < buildingUnitQty.value; index++) {
377
+ unitLabels.value.push(`Unit ${index + 1}`);
378
+ }
379
+ }
380
+
381
+ const name = ref("");
382
+ const directorName = ref("");
383
+ const createMore = ref(false);
384
+ const disable = ref(false);
385
+
386
+ const { requiredRule, validateDate } = useUtils();
387
+
388
+ const message = ref("");
389
+
390
+ const { add, categories: unitCategories } = useBuildingUnit();
391
+
392
+ function setBuildingUnit() {
393
+ buildingUnit.value.site = prop.site ?? "";
394
+ buildingUnit.value.name = "Unit";
395
+ buildingUnit.value.building = "";
396
+ buildingUnit.value.buildingName = "";
397
+ buildingUnit.value.level = "";
398
+ buildingUnit.value.category = "";
399
+ buildingUnit.value.status = "active";
400
+ buildingUnit.value.buildingUnitFiles = [];
401
+ buildingUnitQty.value = 1;
402
+ message.value = "";
403
+ buildingUnit.value.companyName = "";
404
+ buildingUnit.value.companyRegistrationNumber = "";
405
+ buildingUnit.value.leaseStart = "";
406
+ buildingUnit.value.leaseEnd = "";
407
+ }
408
+
409
+ async function submit() {
410
+ disable.value = true;
411
+ try {
412
+ await add({
413
+ labels: unitLabels.value,
414
+ unit: buildingUnit.value,
415
+ qty: buildingUnitQty.value,
416
+ });
417
+
418
+ if (createMore.value) {
419
+ setBuildingUnit();
420
+ message.value = "";
421
+ emit("success:create-more");
422
+ return;
423
+ }
424
+
425
+ emit("success");
426
+ } catch (error: any) {
427
+ message.value =
428
+ error.response?._data?.message || "Failed to create building";
429
+ } finally {
430
+ disable.value = false;
431
+ }
432
+ }
433
+
434
+ function cancel() {
435
+ name.value = "";
436
+ directorName.value = "";
437
+ createMore.value = false;
438
+ message.value = "";
439
+ emit("cancel");
440
+ }
441
+ </script>