@iservice365/layer-common 1.1.0 → 1.3.0
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 +21 -0
- package/components/CameraForm.vue +264 -0
- package/components/CameraMain.vue +352 -0
- package/components/Card/DeleteConfirmation.vue +51 -0
- package/components/Card/MemberInfoSummary.vue +44 -0
- package/components/Chat/Information.vue +28 -11
- package/components/Dialog/DeleteConfirmation.vue +51 -0
- package/components/Dialog/UpdateMoreAction.vue +99 -0
- package/components/Feedback/Form.vue +17 -3
- package/components/FeedbackDetail.vue +0 -11
- package/components/FeedbackMain.vue +21 -11
- package/components/Input/DateTimePicker.vue +10 -5
- package/components/Input/File.vue +1 -1
- package/components/Input/FileV2.vue +106 -63
- package/components/Input/InputPhoneNumberV2.vue +114 -0
- package/components/Input/NRICNumber.vue +41 -0
- package/components/Input/PhoneNumber.vue +1 -0
- package/components/Input/VehicleNumber.vue +49 -0
- package/components/NumberSettingField.vue +107 -0
- package/components/PeopleForm.vue +452 -0
- package/components/TableMain.vue +2 -1
- package/components/VehicleUpdateMoreAction.vue +84 -0
- package/components/VisitorForm.vue +712 -0
- package/components/VisitorFormSelection.vue +53 -0
- package/components/VisitorManagement.vue +569 -0
- package/components/WorkOrder/Create.vue +87 -49
- package/components/WorkOrder/Main.vue +17 -12
- package/composables/useBuilding.ts +250 -0
- package/composables/useBuildingUnit.ts +116 -0
- package/composables/useFeedback.ts +3 -3
- package/composables/useFile.ts +7 -9
- package/composables/useLocal.ts +67 -0
- package/composables/usePeople.ts +48 -0
- package/composables/useSecurityUtils.ts +18 -0
- package/composables/useSiteSettings.ts +111 -0
- package/composables/useUtils.ts +30 -1
- package/composables/useVisitor.ts +80 -0
- package/composables/useWorkOrder.ts +3 -3
- package/package.json +1 -1
- package/plugins/vuetify.ts +6 -1
- package/types/building.d.ts +19 -0
- package/types/camera.d.ts +31 -0
- package/types/people.d.ts +22 -0
- package/types/select.d.ts +4 -0
- package/types/site.d.ts +10 -7
- package/types/visitor.d.ts +42 -0
- package/utils/phoneMasks.ts +1703 -0
|
@@ -34,19 +34,19 @@ export default function useFeedback() {
|
|
|
34
34
|
|
|
35
35
|
async function getFeedbacks({
|
|
36
36
|
page = 1,
|
|
37
|
-
organization = "",
|
|
38
37
|
site = "",
|
|
39
38
|
status = "to-do",
|
|
40
39
|
search = "",
|
|
41
40
|
limit = 10,
|
|
42
41
|
from = "",
|
|
42
|
+
category = "",
|
|
43
43
|
} = {}) {
|
|
44
44
|
try {
|
|
45
45
|
return useNuxtApp().$api<Record<string, any>>(
|
|
46
|
-
`/api/feedbacks/
|
|
46
|
+
`/api/feedbacks/site/${site}/status/${status}`,
|
|
47
47
|
{
|
|
48
48
|
method: "GET",
|
|
49
|
-
query: { page, search, limit, from },
|
|
49
|
+
query: { page, search, limit, from, category },
|
|
50
50
|
}
|
|
51
51
|
);
|
|
52
52
|
} catch (err) {
|
package/composables/useFile.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export default function useFile() {
|
|
2
|
-
const baseUrl =
|
|
3
|
-
"https://iservice365-dev.sgp1.cdn.digitaloceanspaces.com/default";
|
|
2
|
+
const baseUrl = useRuntimeConfig().public.API_DO_STORAGE_ENDPOINT;
|
|
4
3
|
|
|
5
4
|
function addFile(file: File | null) {
|
|
6
5
|
if (!file) {
|
|
@@ -10,13 +9,10 @@ export default function useFile() {
|
|
|
10
9
|
const formData = new FormData();
|
|
11
10
|
formData.append("file", file);
|
|
12
11
|
|
|
13
|
-
return $fetch<Record<string, any>>(
|
|
14
|
-
"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
body: formData,
|
|
18
|
-
}
|
|
19
|
-
);
|
|
12
|
+
return $fetch<Record<string, any>>("/api/files", {
|
|
13
|
+
method: "POST",
|
|
14
|
+
body: formData,
|
|
15
|
+
});
|
|
20
16
|
}
|
|
21
17
|
|
|
22
18
|
function getFileUrl(id: string) {
|
|
@@ -41,8 +37,10 @@ export default function useFile() {
|
|
|
41
37
|
}
|
|
42
38
|
);
|
|
43
39
|
}
|
|
40
|
+
|
|
44
41
|
|
|
45
42
|
return {
|
|
43
|
+
baseUrl,
|
|
46
44
|
addFile,
|
|
47
45
|
deleteFile,
|
|
48
46
|
urlToFile,
|
package/composables/useLocal.ts
CHANGED
|
@@ -49,6 +49,72 @@ export default function useLocal() {
|
|
|
49
49
|
|
|
50
50
|
const landingPage = useCookie("landing-page", cookieConfig);
|
|
51
51
|
|
|
52
|
+
const subjects = [
|
|
53
|
+
{
|
|
54
|
+
title: "Facilities",
|
|
55
|
+
value: "Facilities",
|
|
56
|
+
subtitle:
|
|
57
|
+
"Shared amenities like gym, pool, BBQ pits, and function rooms.",
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
title: "Building Facade",
|
|
61
|
+
value: "Building Facade",
|
|
62
|
+
subtitle:
|
|
63
|
+
"Exterior walls, paint, cladding, signage, and overall appearance.",
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
title: "Security",
|
|
67
|
+
value: "Security",
|
|
68
|
+
subtitle:
|
|
69
|
+
"Guard services, access control, patrols, and visitor management.",
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
title: "Cleaning",
|
|
73
|
+
value: "Cleaning",
|
|
74
|
+
subtitle:
|
|
75
|
+
"Cleanliness of lobbies, corridors, lifts, bins, and common areas.",
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
title: "Landscape",
|
|
79
|
+
value: "Landscape",
|
|
80
|
+
subtitle: "Condition of plants, lawns, trees, and garden maintenance.",
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
title: "Pest Control",
|
|
84
|
+
value: "Pest Control",
|
|
85
|
+
subtitle:
|
|
86
|
+
"Effectiveness of measures against insects, rodents, and pests.",
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
title: "Water Features",
|
|
90
|
+
value: "Water Features",
|
|
91
|
+
subtitle:
|
|
92
|
+
"Operation and cleanliness of fountains, ponds, and pools (non-swimming).",
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
title: "Car Park",
|
|
96
|
+
value: "Car Park",
|
|
97
|
+
subtitle:
|
|
98
|
+
"Parking availability, markings, lighting, and barrier systems.",
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
title: "Lift",
|
|
102
|
+
value: "Lift",
|
|
103
|
+
subtitle:
|
|
104
|
+
"Lift reliability, speed, cleanliness, ventilation, and downtime.",
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
title: "Security Systems",
|
|
108
|
+
value: "Security Systems",
|
|
109
|
+
subtitle: "CCTV, intercoms, access cards, and gate/door sensors.",
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
title: "Others",
|
|
113
|
+
value: "Others",
|
|
114
|
+
subtitle: "Any issues or feedback not covered by the categories above.",
|
|
115
|
+
},
|
|
116
|
+
];
|
|
117
|
+
|
|
52
118
|
return {
|
|
53
119
|
cookieConfig,
|
|
54
120
|
getUserFromCookie,
|
|
@@ -57,5 +123,6 @@ export default function useLocal() {
|
|
|
57
123
|
headerSearch,
|
|
58
124
|
natureOfBusiness,
|
|
59
125
|
landingPage,
|
|
126
|
+
subjects,
|
|
60
127
|
};
|
|
61
128
|
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export default function(){
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
async function getAll({
|
|
5
|
+
page = 1,
|
|
6
|
+
limit = 10,
|
|
7
|
+
sort = "asc",
|
|
8
|
+
search = "",
|
|
9
|
+
org = "",
|
|
10
|
+
site = "",
|
|
11
|
+
dateTo = "",
|
|
12
|
+
dateFrom = "",
|
|
13
|
+
type="",
|
|
14
|
+
displayNoCheckOut=false
|
|
15
|
+
} = {}) {
|
|
16
|
+
return await $fetch<Record<string, any>>("/api/people", {
|
|
17
|
+
method: "GET",
|
|
18
|
+
query: { page, limit, sort, search, org, site, dateTo, dateFrom, type }
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async function create(payload: Partial<TPeoplePayload>){
|
|
23
|
+
return await $fetch<Record<string, any>>("/api/people", {
|
|
24
|
+
method: "POST",
|
|
25
|
+
body: payload,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async function updateById(_id: string, payload: Partial<TPeoplePayload>){
|
|
30
|
+
return await $fetch<Record<string, any>>(`/api/people/id/${_id}`, {
|
|
31
|
+
method: "PUT",
|
|
32
|
+
body: payload,
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async function deleteById(_id: string){
|
|
37
|
+
return await $fetch<Record<string, any>>(`/api/people/id/${_id}`, {
|
|
38
|
+
method: "DELETE",
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return {
|
|
43
|
+
create,
|
|
44
|
+
getAll,
|
|
45
|
+
updateById,
|
|
46
|
+
deleteById
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export default function(){
|
|
2
|
+
|
|
3
|
+
const formatLocation = ({block, level, unit}: {block: number, level: string, unit: string | TBuildingUnit}) => {
|
|
4
|
+
const parts = [];
|
|
5
|
+
|
|
6
|
+
if (block) parts.push(`Block ${block}`);
|
|
7
|
+
if (level) parts.push(level);
|
|
8
|
+
if (unit) parts.push(unit);
|
|
9
|
+
|
|
10
|
+
return parts.join(" / ");
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
formatLocation
|
|
16
|
+
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
export default function () {
|
|
2
|
+
async function getSiteById(siteId: string) {
|
|
3
|
+
return await useNuxtApp().$api<Record<string, any>>(
|
|
4
|
+
`/api/sites/${siteId}`,
|
|
5
|
+
{
|
|
6
|
+
method: "GET",
|
|
7
|
+
}
|
|
8
|
+
);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
async function getSiteLevels(siteId: string, query: { block: number }) {
|
|
12
|
+
return await useNuxtApp().$api<Record<string, any>>(
|
|
13
|
+
`/api/buildings/site/${siteId}`,
|
|
14
|
+
{
|
|
15
|
+
method: "GET",
|
|
16
|
+
query: query,
|
|
17
|
+
}
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function getSiteUnits(siteId: string, block: number, level: string) {
|
|
22
|
+
return await useNuxtApp().$api<Record<string, any>>(
|
|
23
|
+
`/api/building-units/site/${siteId}/block/${block}/level/${level}`,
|
|
24
|
+
{
|
|
25
|
+
method: "GET",
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function updateSite(siteId: string, payload: { block: number }) {
|
|
31
|
+
return await useNuxtApp().$api<Record<string, any>>(
|
|
32
|
+
`/api/sites/${siteId}/block`,
|
|
33
|
+
{
|
|
34
|
+
method: "PUT",
|
|
35
|
+
body: payload,
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function addCamera(camera: TSiteCamera) {
|
|
41
|
+
return await useNuxtApp().$api<Record<string, any>>(`/api/site-cameras`, {
|
|
42
|
+
method: "POST",
|
|
43
|
+
body: camera,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function updateSiteCamera(
|
|
48
|
+
id: string,
|
|
49
|
+
value: Partial<
|
|
50
|
+
Pick<
|
|
51
|
+
TSiteCamera,
|
|
52
|
+
| "host"
|
|
53
|
+
| "category"
|
|
54
|
+
| "guardPost"
|
|
55
|
+
| "password"
|
|
56
|
+
| "username"
|
|
57
|
+
| "direction"
|
|
58
|
+
>
|
|
59
|
+
>
|
|
60
|
+
) {
|
|
61
|
+
return await useNuxtApp().$api<Record<string, any>>(
|
|
62
|
+
`/api/site-cameras/id/${id}`,
|
|
63
|
+
{
|
|
64
|
+
method: "PATCH",
|
|
65
|
+
body: value,
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
async function deleteSiteCameraById(id: string) {
|
|
71
|
+
return await useNuxtApp().$api<Record<string, any>>(
|
|
72
|
+
`/api/site-cameras/id/${id}`,
|
|
73
|
+
{
|
|
74
|
+
method: "DELETE",
|
|
75
|
+
}
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
async function getAllSiteCameras(payload: {
|
|
80
|
+
site: string;
|
|
81
|
+
type?: string;
|
|
82
|
+
page?: number;
|
|
83
|
+
}) {
|
|
84
|
+
return await useNuxtApp().$api<Record<string, any>>(`/api/site-cameras`, {
|
|
85
|
+
method: "GET",
|
|
86
|
+
query: payload,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
async function setSiteGuardPosts(siteId: string, value: number) {
|
|
91
|
+
return await useNuxtApp().$api<Record<string, any>>(
|
|
92
|
+
`/api/sites/guard-post/id/${siteId}`,
|
|
93
|
+
{
|
|
94
|
+
method: "PATCH",
|
|
95
|
+
body: { guardPost: value },
|
|
96
|
+
}
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
getSiteById,
|
|
102
|
+
getSiteLevels,
|
|
103
|
+
getSiteUnits,
|
|
104
|
+
updateSite,
|
|
105
|
+
addCamera,
|
|
106
|
+
getAllSiteCameras,
|
|
107
|
+
setSiteGuardPosts,
|
|
108
|
+
updateSiteCamera,
|
|
109
|
+
deleteSiteCameraById,
|
|
110
|
+
};
|
|
111
|
+
}
|
package/composables/useUtils.ts
CHANGED
|
@@ -365,6 +365,33 @@ export default function useUtils() {
|
|
|
365
365
|
.replace(/^./, str => str.toUpperCase());
|
|
366
366
|
}
|
|
367
367
|
|
|
368
|
+
|
|
369
|
+
function calculateRemainingTime(
|
|
370
|
+
item: Date | string | number | null | undefined
|
|
371
|
+
) {
|
|
372
|
+
if (!item) return -1;
|
|
373
|
+
const _date = new Date(item);
|
|
374
|
+
if (isNaN(_date.getTime())) return -1;
|
|
375
|
+
const creationTime = _date.getTime();
|
|
376
|
+
const currentTime = Date.now();
|
|
377
|
+
const differenceInMillis = currentTime - creationTime;
|
|
378
|
+
const differenceInSeconds = Math.floor(differenceInMillis / 1000);
|
|
379
|
+
const desiredDurationInSeconds = 24 * 60 * 60;
|
|
380
|
+
const remainingTimeInSeconds = desiredDurationInSeconds - differenceInSeconds;
|
|
381
|
+
console.log(remainingTimeInSeconds);
|
|
382
|
+
return remainingTimeInSeconds;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
const formatTime = (seconds: number) => {
|
|
386
|
+
if (seconds <= 0 || isNaN(seconds)) return "00h 00m";
|
|
387
|
+
const hours = Math.floor(seconds / 3600);
|
|
388
|
+
const minutes = Math.floor((seconds % 3600) / 60);
|
|
389
|
+
return `${String(hours).padStart(2, "0")}h ${String(minutes).padStart(
|
|
390
|
+
2,
|
|
391
|
+
"0"
|
|
392
|
+
)}m`;
|
|
393
|
+
};
|
|
394
|
+
|
|
368
395
|
return {
|
|
369
396
|
requiredRule,
|
|
370
397
|
emailRule,
|
|
@@ -398,6 +425,8 @@ export default function useUtils() {
|
|
|
398
425
|
toOrdinal,
|
|
399
426
|
formatDateISO8601,
|
|
400
427
|
isValidBaseURL,
|
|
401
|
-
formatCamelCaseToWords
|
|
428
|
+
formatCamelCaseToWords,
|
|
429
|
+
calculateRemainingTime,
|
|
430
|
+
formatTime
|
|
402
431
|
};
|
|
403
432
|
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
export default function(){
|
|
2
|
+
|
|
3
|
+
type TVisitorSelection = {
|
|
4
|
+
label: string;
|
|
5
|
+
value: TVisitorType
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const visitorSelection: TVisitorSelection[] =[
|
|
9
|
+
{ label: "Contractor", value: "contractor" },
|
|
10
|
+
{ label: "Delivery", value: "delivery" },
|
|
11
|
+
{ label: "Walk-In", value: "walk-in"},
|
|
12
|
+
{ label: "Pick-Up", value: "pick-up"},
|
|
13
|
+
{ label: "Drop-Off", value: "drop-off"}
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
const typeFieldMap: Record<TVisitorType, (keyof TVisitorPayload)[]> = {
|
|
17
|
+
contractor: ['contractorType', 'name', 'nric', 'company', 'contact', 'plateNumber', 'block', 'level', 'unit', 'unitName', 'remarks'],
|
|
18
|
+
delivery: ['attachments', 'name', 'deliveryType', 'company', 'nric', 'contact', 'plateNumber', 'block', 'level', 'unit' , 'unitName', 'remarks'],
|
|
19
|
+
'walk-in': ['name', 'company', 'nric', 'contact', 'block', 'level', 'unit' , 'unitName', 'remarks'],
|
|
20
|
+
'pick-up': ['plateNumber', 'block', 'remarks'],
|
|
21
|
+
'drop-off': ['plateNumber', 'block', 'remarks'],
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const contractorTypes = [
|
|
25
|
+
{ title: "Estate Contractor", value: "estate-contractor" },
|
|
26
|
+
{ title: "Home Contractor", value: "home-contractor" },
|
|
27
|
+
{ title: "Property Agent", value: "property-agent" },
|
|
28
|
+
{ title: "House Mover", value: "house-mover" },
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
async function getVisitors({
|
|
33
|
+
page = 1,
|
|
34
|
+
limit = 10,
|
|
35
|
+
sort = "asc",
|
|
36
|
+
search = "",
|
|
37
|
+
org = "",
|
|
38
|
+
site = "",
|
|
39
|
+
dateTo = "",
|
|
40
|
+
dateFrom = "",
|
|
41
|
+
type="",
|
|
42
|
+
displayNoCheckOut=false,
|
|
43
|
+
// status = "registered"
|
|
44
|
+
} = {}) {
|
|
45
|
+
return await useNuxtApp().$api<Record<string, any>>("/api/visitor-transactions", {
|
|
46
|
+
method: "GET",
|
|
47
|
+
query: { page, limit, sort, search, org, site, dateTo, dateFrom, ...(type.length > 0 && {type}), ...(displayNoCheckOut === true && {checkedOut: false}) },
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
async function createVisitor(payload: Partial<TVisitorPayload>){
|
|
52
|
+
return await useNuxtApp().$api<Record<string, any>>("/api/visitor-transactions", {
|
|
53
|
+
method: "POST",
|
|
54
|
+
body: payload,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
async function updateVisitor(_id: string, payload: Partial<TVisitorPayload>){
|
|
59
|
+
return await useNuxtApp().$api<Record<string, any>>(`/api/visitor-transactions/id/${_id}`, {
|
|
60
|
+
method: "PUT",
|
|
61
|
+
body: payload,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
async function deleteVisitor(_id: string){
|
|
66
|
+
return await useNuxtApp().$api<Record<string, any>>(`/api/visitor-transactions/id/${_id}`, {
|
|
67
|
+
method: "DELETE",
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
typeFieldMap,
|
|
73
|
+
visitorSelection,
|
|
74
|
+
contractorTypes,
|
|
75
|
+
createVisitor,
|
|
76
|
+
getVisitors,
|
|
77
|
+
updateVisitor,
|
|
78
|
+
deleteVisitor
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -32,18 +32,18 @@ export default function useWorkOrder() {
|
|
|
32
32
|
|
|
33
33
|
async function getWorkOrders({
|
|
34
34
|
page = 1,
|
|
35
|
-
organization = "",
|
|
36
35
|
site = "",
|
|
37
36
|
status = "to-do",
|
|
38
37
|
search = "",
|
|
39
38
|
limit = 10,
|
|
39
|
+
category = "",
|
|
40
40
|
} = {}) {
|
|
41
41
|
try {
|
|
42
42
|
return useNuxtApp().$api<Record<string, any>>(
|
|
43
|
-
`/api/work-orders/
|
|
43
|
+
`/api/work-orders/site/${site}/status/${status}`,
|
|
44
44
|
{
|
|
45
45
|
method: "GET",
|
|
46
|
-
query: { page, search, limit },
|
|
46
|
+
query: { page, search, limit, category },
|
|
47
47
|
}
|
|
48
48
|
);
|
|
49
49
|
} catch (err) {
|
package/package.json
CHANGED
package/plugins/vuetify.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// import this after install `@mdi/font` package
|
|
2
2
|
import "@mdi/font/css/materialdesignicons.css";
|
|
3
3
|
import { VFileUpload, VFileUploadItem } from 'vuetify/labs/VFileUpload'
|
|
4
|
+
import { VMaskInput } from 'vuetify/labs/VMaskInput'
|
|
5
|
+
|
|
4
6
|
|
|
5
7
|
import "vuetify/styles";
|
|
6
8
|
import { createVuetify } from "vuetify";
|
|
@@ -16,10 +18,12 @@ export default defineNuxtPlugin((app) => {
|
|
|
16
18
|
VAutocomplete: {
|
|
17
19
|
variant: "outlined",
|
|
18
20
|
density: "comfortable",
|
|
21
|
+
menuProps: { attach: document.body, zIndex: 3000, }
|
|
19
22
|
},
|
|
20
23
|
VSelect: {
|
|
21
24
|
variant: "outlined",
|
|
22
25
|
density: "comfortable",
|
|
26
|
+
menuProps: { attach: document.body, zIndex: 3000}
|
|
23
27
|
},
|
|
24
28
|
VTextarea: {
|
|
25
29
|
variant: "outlined",
|
|
@@ -49,7 +53,8 @@ export default defineNuxtPlugin((app) => {
|
|
|
49
53
|
},
|
|
50
54
|
components: {
|
|
51
55
|
VFileUpload,
|
|
52
|
-
VFileUploadItem
|
|
56
|
+
VFileUploadItem,
|
|
57
|
+
VMaskInput
|
|
53
58
|
}
|
|
54
59
|
});
|
|
55
60
|
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
declare type TBuilding = {
|
|
2
|
+
_id?: string;
|
|
3
|
+
site: string;
|
|
4
|
+
name: string;
|
|
5
|
+
block: number | null;
|
|
6
|
+
levels: string[];
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
declare type TBuildingUnit = {
|
|
10
|
+
_id?: string;
|
|
11
|
+
site: string;
|
|
12
|
+
name?: string;
|
|
13
|
+
building: string;
|
|
14
|
+
buildingName?: string;
|
|
15
|
+
block: number | null;
|
|
16
|
+
level: string | null;
|
|
17
|
+
category: string;
|
|
18
|
+
status: string;
|
|
19
|
+
};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
declare type TCamera = {
|
|
2
|
+
site: string;
|
|
3
|
+
cameras: {
|
|
4
|
+
host: string;
|
|
5
|
+
username: string;
|
|
6
|
+
password: string;
|
|
7
|
+
type: TCameraTypes;
|
|
8
|
+
}[];
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
declare type TCameraConfig = {
|
|
12
|
+
host: string;
|
|
13
|
+
username: string;
|
|
14
|
+
password: string;
|
|
15
|
+
type: TCameraTypes;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
declare type TCameraTypes = "ip" | "exit" | "entry" | "both";
|
|
19
|
+
|
|
20
|
+
declare type TSiteCamera = {
|
|
21
|
+
_id?: string;
|
|
22
|
+
site: string;
|
|
23
|
+
host: string;
|
|
24
|
+
username: string;
|
|
25
|
+
password: string;
|
|
26
|
+
type: "ip" | "anpr";
|
|
27
|
+
category: "standard" | "resident" | "visitor";
|
|
28
|
+
direction: "entry" | "exit" | "both" | "none";
|
|
29
|
+
guardPost: number | null;
|
|
30
|
+
status: string;
|
|
31
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
declare type TPeople = {
|
|
2
|
+
name?: string;
|
|
3
|
+
block?: number | string;
|
|
4
|
+
level?: string;
|
|
5
|
+
unit?: string | Partial<TBuildingUnit>;
|
|
6
|
+
unitName?: string;
|
|
7
|
+
contact?: string;
|
|
8
|
+
plateNumber?: string;
|
|
9
|
+
nric?: string;
|
|
10
|
+
contact?: string;
|
|
11
|
+
remarks?: string;
|
|
12
|
+
start?: string;
|
|
13
|
+
end?: string;
|
|
14
|
+
org?: string;
|
|
15
|
+
site?: string,
|
|
16
|
+
type?: TPeoplePayload;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
declare type TPeoplePayload = Pick<TGuest, "name" | "block" | "level" | "unit" | "unitName" | "contact" | "plateNumber" | "nric" | "contact" | "remarks" | "org" | "site" | "start" | "end" | "type">
|
|
21
|
+
|
|
22
|
+
declare type TPeopleType = "visitor" | "resident" | "tenant"
|
package/types/site.d.ts
CHANGED
|
@@ -1,17 +1,20 @@
|
|
|
1
|
+
declare type TSiteCreate = Pick<TSite, "name" | "description" | "orgId">;
|
|
2
|
+
|
|
3
|
+
|
|
1
4
|
declare type TSite = {
|
|
2
5
|
_id?: string;
|
|
3
6
|
name: string;
|
|
4
7
|
description?: string;
|
|
5
8
|
orgId: string;
|
|
9
|
+
metadata?: TSiteMetadata;
|
|
10
|
+
status?: string;
|
|
11
|
+
createdAt?: string;
|
|
12
|
+
updatedAt?: string | string;
|
|
13
|
+
deletedAt?: string | string;
|
|
6
14
|
blocks?: number;
|
|
7
|
-
customerOrgId
|
|
8
|
-
customerSiteId
|
|
15
|
+
customerOrgId?: string;
|
|
16
|
+
customerSiteId?: string;
|
|
9
17
|
createdAt?: string;
|
|
10
18
|
updatedAt?: string;
|
|
11
19
|
deletedAt?: string;
|
|
12
|
-
metadata?: {
|
|
13
|
-
block?: number; // Number of blocks in the site
|
|
14
|
-
};
|
|
15
20
|
};
|
|
16
|
-
|
|
17
|
-
declare type TSiteCreate = Pick<TSite, "name" | "description" | "orgId">;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
declare type TVisitor = {
|
|
2
|
+
name?: string;
|
|
3
|
+
type: TVisitorType;
|
|
4
|
+
company?: string | "";
|
|
5
|
+
block?: number | string;
|
|
6
|
+
level?: string;
|
|
7
|
+
unit?: string;
|
|
8
|
+
unitName?: string; // only for display purpose
|
|
9
|
+
contact: string;
|
|
10
|
+
plateNumber: string;
|
|
11
|
+
checkIn?: string;
|
|
12
|
+
checkOut?: string | null;
|
|
13
|
+
contractorType?: string;
|
|
14
|
+
deliveryType?: string;
|
|
15
|
+
nric?: string;
|
|
16
|
+
contact?: string;
|
|
17
|
+
remarks?: string;
|
|
18
|
+
attachments: string[];
|
|
19
|
+
org: string;
|
|
20
|
+
site: string,
|
|
21
|
+
manualCheckout?: boolean;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
declare type TVisitorType = "contractor" | "delivery" | "walk-in" | "pick-up" | "drop-off";
|
|
25
|
+
|
|
26
|
+
declare type TVisitorPayload = Pick<TVisitor, "name" | "type" | "company" | "block" | "level" | "unit" | "unitName" | "contact" | "plateNumber" | "checkOut" | "contractorType" | "deliveryType" | "nric" | "contact" | "remarks" | "attachments" | "org" | "site"> & {
|
|
27
|
+
members?: TMemberInfo[]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
declare type TDefaultOptionObj = {
|
|
33
|
+
title: string;
|
|
34
|
+
value: any;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
declare type TMemberInfo = {
|
|
38
|
+
name: string;
|
|
39
|
+
nric: string;
|
|
40
|
+
visitorPass: string;
|
|
41
|
+
contact: string
|
|
42
|
+
}
|