@7365admin1/layer-common 3.0.9 → 3.0.11

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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # @iservice365/layer-common
2
2
 
3
+ ## 3.0.11
4
+
5
+ ### Patch Changes
6
+
7
+ - fd1ebe1: Update Layer Version to 3.0.11
8
+
9
+ ## 3.0.10
10
+
11
+ ### Patch Changes
12
+
13
+ - 1919267: Update Layer Common Version to 3.0.10
14
+
3
15
  ## 3.0.9
4
16
 
5
17
  ### Patch Changes
@@ -1079,7 +1079,7 @@ const isHygieneMode = computed(
1079
1079
  const {
1080
1080
  getDashboard,
1081
1081
  getDashboardHygiene,
1082
- getDashboardHygieneWeeklyActivity,
1082
+ getDashboardWeeklyActivity,
1083
1083
  getDashboardHygieneTaskSchedule,
1084
1084
  getDashboardHygieneAttendance,
1085
1085
  getDashboardHygieneFeedbacks,
@@ -1169,13 +1169,13 @@ const { data: getDashboardAltReq, pending: loadingAltMetrics } =
1169
1169
  }
1170
1170
  );
1171
1171
 
1172
- // Weekly activity (hygiene mode only)
1172
+ // Weekly activity (all modes)
1173
1173
  const { data: weeklyActivityReq, pending: loadingWeeklyActivity } =
1174
1174
  await useLazyAsyncData(
1175
1175
  `get-dashboard-weekly-activity-${props.site}-${props.serviceType}`,
1176
1176
  () =>
1177
- props.serviceType && isHygieneMode.value
1178
- ? getDashboardHygieneWeeklyActivity(
1177
+ props.serviceType
1178
+ ? getDashboardWeeklyActivity(
1179
1179
  props.site,
1180
1180
  props.serviceType as TServiceType,
1181
1181
  currentPeriod.value
@@ -1251,10 +1251,10 @@ const finalLoading = computed(() => {
1251
1251
  );
1252
1252
  }
1253
1253
  if (isPropertyMode.value) {
1254
- return loadingAltMetrics.value || loadingFeedbacks.value;
1254
+ return loadingAltMetrics.value || loadingWeeklyActivity.value || loadingFeedbacks.value;
1255
1255
  }
1256
1256
  // security
1257
- return loadingAltMetrics.value || loadingAttendance.value || loadingFeedbacks.value;
1257
+ return loadingAltMetrics.value || loadingWeeklyActivity.value || loadingAttendance.value || loadingFeedbacks.value;
1258
1258
  });
1259
1259
 
1260
1260
  // ─── Merged Dashboard Data ────────────────────────────────────────────────────
@@ -1262,45 +1262,49 @@ const finalLoading = computed(() => {
1262
1262
  const finalDashboardData = computed<Record<string, any>>(() => {
1263
1263
  if (!props.serviceType) return props.dashboardData || {};
1264
1264
 
1265
+ let weeklyActivity = weeklyActivityReq.value ?? [];
1266
+ const hasNoActivity =
1267
+ !weeklyActivity.length ||
1268
+ weeklyActivity.every(
1269
+ (item: any) =>
1270
+ !item.workOrder &&
1271
+ !item.taskCompleted &&
1272
+ !item.openWorkOrder &&
1273
+ !item.closedWorkOrder &&
1274
+ !item.incidents &&
1275
+ !item.visitors
1276
+ );
1277
+
1278
+ if (hasNoActivity && currentPeriod.value === "thisWeek") {
1279
+ weeklyActivity = [
1280
+ { day: "Mon", workOrder: 800, taskCompleted: 1400 },
1281
+ { day: "Tue", workOrder: 450, taskCompleted: 900 },
1282
+ { day: "Wed", workOrder: 950, taskCompleted: 1640 },
1283
+ { day: "Thu", workOrder: 2000, taskCompleted: 2100 },
1284
+ { day: "Fri", workOrder: 2000, taskCompleted: 2700 },
1285
+ { day: "Sat", workOrder: 2200, taskCompleted: 3100 },
1286
+ { day: "Sun", workOrder: 2800, taskCompleted: 3200 },
1287
+ ];
1288
+ }
1289
+
1290
+ const activityChart = {
1291
+ labels: weeklyActivity.map((item: any) => item.day || item.label),
1292
+ workOrders: weeklyActivity.map(
1293
+ (item: any) => item.workOrder ?? item.openWorkOrder
1294
+ ),
1295
+ taskCompleted: weeklyActivity.map(
1296
+ (item: any) => item.taskCompleted ?? item.closedWorkOrder
1297
+ ),
1298
+ };
1299
+
1265
1300
  if (isHygieneMode.value) {
1266
1301
  const data = getDashboardReq.value ?? {};
1267
- let weeklyActivity = weeklyActivityReq.value ?? [];
1268
- const hasNoActivity =
1269
- !weeklyActivity.length ||
1270
- weeklyActivity.every(
1271
- (item: any) =>
1272
- !item.workOrder &&
1273
- !item.taskCompleted &&
1274
- !item.openWorkOrder &&
1275
- !item.closedWorkOrder
1276
- );
1277
-
1278
- if (hasNoActivity && currentPeriod.value === "thisWeek") {
1279
- weeklyActivity = [
1280
- { day: "Mon", workOrder: 800, taskCompleted: 1400 },
1281
- { day: "Tue", workOrder: 450, taskCompleted: 900 },
1282
- { day: "Wed", workOrder: 950, taskCompleted: 1640 },
1283
- { day: "Thu", workOrder: 2000, taskCompleted: 2100 },
1284
- { day: "Fri", workOrder: 2000, taskCompleted: 2700 },
1285
- { day: "Sat", workOrder: 2200, taskCompleted: 3100 },
1286
- { day: "Sun", workOrder: 2800, taskCompleted: 3200 },
1287
- ];
1288
- }
1289
-
1290
1302
  return {
1291
1303
  ...data,
1292
1304
  openWorkOrder: data.openWorkOrder ?? { count: 0, percentage: 0 },
1293
1305
  supplyAlert: data.supplyAlert ?? { count: 0, percentage: 0 },
1294
1306
  taskCompleted: data.taskCompleted ?? { count: 0, percentage: 0 },
1295
- activityChart: {
1296
- labels: weeklyActivity.map((item: any) => item.day || item.label),
1297
- workOrders: weeklyActivity.map(
1298
- (item: any) => item.workOrder ?? item.openWorkOrder
1299
- ),
1300
- taskCompleted: weeklyActivity.map(
1301
- (item: any) => item.taskCompleted ?? item.closedWorkOrder
1302
- ),
1303
- },
1307
+ activityChart,
1304
1308
  taskScheduleItems: taskScheduleReq.value?.items ?? [],
1305
1309
  attendanceItems: attendanceReq.value?.items ?? [],
1306
1310
  feedbackItems: feedbacksReq.value?.items ?? [],
@@ -1311,6 +1315,7 @@ const finalDashboardData = computed<Record<string, any>>(() => {
1311
1315
  const data = getDashboardAltReq.value ?? {};
1312
1316
  return {
1313
1317
  ...data,
1318
+ activityChart,
1314
1319
  feedbackItems: feedbacksReq.value?.items ?? [],
1315
1320
  openWorkOrder: data.openWorkOrder ?? { count: 0, inProgress: 0, percentage: 0 },
1316
1321
  openIncidents: data.openIncidents ?? { count: 0, highSeverity: 0, percentage: 0 },
@@ -1328,6 +1333,7 @@ const finalDashboardData = computed<Record<string, any>>(() => {
1328
1333
  const data = getDashboardAltReq.value ?? {};
1329
1334
  return {
1330
1335
  ...data,
1336
+ activityChart,
1331
1337
  feedbackItems: feedbacksReq.value?.items ?? [],
1332
1338
  attendanceItems: attendanceReq.value?.items ?? [],
1333
1339
  openWorkOrder: data.openWorkOrder ?? {
@@ -1397,14 +1403,14 @@ const propertyCardValues: TDashboardCardValue[] = [
1397
1403
  key: "visitors",
1398
1404
  periodKey: "period",
1399
1405
  title: "Visitors",
1400
- icon: "mdi-account-group",
1406
+ icon: "mdi-account-multiple",
1401
1407
  color: "#d28722",
1402
1408
  },
1403
1409
  {
1404
1410
  key: "facilityBookings",
1405
1411
  periodKey: "period",
1406
1412
  title: "Facility Booking",
1407
- icon: "mdi-domain",
1413
+ icon: "mdi-office-building",
1408
1414
  color: "#23824f",
1409
1415
  },
1410
1416
  ];
@@ -1428,14 +1434,14 @@ const securityCardValues: TDashboardCardValue[] = [
1428
1434
  key: "visitors",
1429
1435
  periodKey: "period",
1430
1436
  title: "Visitors",
1431
- icon: "mdi-account-group",
1437
+ icon: "mdi-account-multiple",
1432
1438
  color: "#d28722",
1433
1439
  },
1434
1440
  {
1435
1441
  key: "patrolCompliance",
1436
1442
  periodKey: "period",
1437
1443
  title: "Patrol Compliance",
1438
- icon: "mdi-calculator-variant",
1444
+ icon: "mdi-office-building",
1439
1445
  color: "#23824f",
1440
1446
  },
1441
1447
  ];
@@ -1603,7 +1609,7 @@ const facilityOptions = computed(() =>
1603
1609
  function getPropertyKpiCards() {
1604
1610
  const workOrderMetric = getMetric(["openWorkOrder", "workOrders", "openWorkOrders", "workOrder"]);
1605
1611
  const incidentMetric = getMetric(["openIncidents", "incidents", "incidentReports"]);
1606
- const visitorMetric = getMetric(["visitors", "visitorTransactions"]);
1612
+ const visitorMetric = getFilteredVisitorMetric();
1607
1613
  const facilityMetric = computeFacilityMetric();
1608
1614
 
1609
1615
  return [
@@ -1615,7 +1621,7 @@ function getPropertyKpiCards() {
1615
1621
  tint: "#d7ecff",
1616
1622
  value: formatNumber(toNumber(workOrderMetric?.count)),
1617
1623
  percentage: toNumber(workOrderMetric?.percentage),
1618
- meta: `${toNumber(workOrderMetric?.inProgress)} in progress`,
1624
+ meta: getMetricMeta(workOrderMetric),
1619
1625
  raw: workOrderMetric,
1620
1626
  filter: undefined,
1621
1627
  },
@@ -1627,19 +1633,19 @@ function getPropertyKpiCards() {
1627
1633
  tint: "#ffdede",
1628
1634
  value: formatNumber(toNumber(incidentMetric?.count)),
1629
1635
  percentage: toNumber(incidentMetric?.percentage),
1630
- meta: `${toNumber(incidentMetric?.highSeverity)} high severity`,
1636
+ meta: getMetricMeta(incidentMetric),
1631
1637
  raw: incidentMetric,
1632
1638
  filter: undefined,
1633
1639
  },
1634
1640
  {
1635
1641
  key: "visitors",
1636
1642
  title: "Visitors",
1637
- icon: "mdi-account-group",
1643
+ icon: "mdi-account-multiple",
1638
1644
  color: "#d28722",
1639
1645
  tint: "#ffe4bd",
1640
1646
  value: formatNumber(toNumber(visitorMetric?.count)),
1641
1647
  percentage: toNumber(visitorMetric?.percentage),
1642
- meta: `${toNumber(visitorMetric?.currentlyOnSite)} currently on site`,
1648
+ meta: getMetricMeta(visitorMetric),
1643
1649
  raw: visitorMetric,
1644
1650
  filter: {
1645
1651
  model: visitorType.value,
@@ -1653,12 +1659,12 @@ function getPropertyKpiCards() {
1653
1659
  {
1654
1660
  key: "facilityBookings",
1655
1661
  title: "Facility Booking",
1656
- icon: "mdi-domain",
1662
+ icon: "mdi-office-building",
1657
1663
  color: "#23824f",
1658
1664
  tint: "#c8f3da",
1659
1665
  value: formatNumber(toNumber(facilityMetric?.count)),
1660
1666
  percentage: toNumber(facilityMetric?.percentage),
1661
- meta: `${toNumber(facilityMetric?.ongoing)} ongoing - ${toNumber(facilityMetric?.waitingApproval)} waiting approval`,
1667
+ meta: getMetricMeta(facilityMetric),
1662
1668
  raw: facilityMetric,
1663
1669
  filter: {
1664
1670
  model: facilityType.value,
@@ -1700,6 +1706,7 @@ function getSecurityKpiCards() {
1700
1706
  const workOrderMetric = getMetric(["openWorkOrder", "workOrders", "openWorkOrders", "workOrder"]);
1701
1707
  const incidentMetric = getMetric(["openIncidents", "incidents", "incidentReports"]);
1702
1708
  const patrolMetric = getMetric(["patrolCompliance", "patrol"]);
1709
+ const visitorMetric = getFilteredVisitorMetric();
1703
1710
 
1704
1711
  return [
1705
1712
  {
@@ -1710,7 +1717,7 @@ function getSecurityKpiCards() {
1710
1717
  tint: "#d7ecff",
1711
1718
  value: formatNumber(toNumber(workOrderMetric?.count)),
1712
1719
  percentage: toNumber(workOrderMetric?.percentage),
1713
- meta: `${toNumber(workOrderMetric?.overdue)} overdue · ${toNumber(workOrderMetric?.inProgress)} in progress`,
1720
+ meta: getMetricMeta(workOrderMetric),
1714
1721
  raw: workOrderMetric,
1715
1722
  filter: undefined,
1716
1723
  },
@@ -1722,20 +1729,20 @@ function getSecurityKpiCards() {
1722
1729
  tint: "#ffdede",
1723
1730
  value: formatNumber(toNumber(incidentMetric?.count)),
1724
1731
  percentage: toNumber(incidentMetric?.percentage),
1725
- meta: `${toNumber(incidentMetric?.highSeverity)} high severity`,
1732
+ meta: getMetricMeta(incidentMetric),
1726
1733
  raw: incidentMetric,
1727
1734
  filter: undefined,
1728
1735
  },
1729
1736
  {
1730
1737
  key: "visitors",
1731
1738
  title: "Visitors",
1732
- icon: "mdi-account-group",
1739
+ icon: "mdi-account-multiple",
1733
1740
  color: "#d28722",
1734
1741
  tint: "#ffe4bd",
1735
- value: formatNumber(toNumber(getFilteredVisitorMetric()?.count)),
1736
- percentage: toNumber(getFilteredVisitorMetric()?.percentage),
1737
- meta: `${toNumber(getFilteredVisitorMetric()?.currentlyOnSite)} currently on site`,
1738
- raw: getFilteredVisitorMetric(),
1742
+ value: formatNumber(toNumber(visitorMetric?.count)),
1743
+ percentage: toNumber(visitorMetric?.percentage),
1744
+ meta: getMetricMeta(visitorMetric),
1745
+ raw: visitorMetric,
1739
1746
  filter: {
1740
1747
  model: visitorType.value,
1741
1748
  options: visitorOptions.value,
@@ -1748,12 +1755,12 @@ function getSecurityKpiCards() {
1748
1755
  {
1749
1756
  key: "patrolCompliance",
1750
1757
  title: "Patrol Compliance",
1751
- icon: "mdi-calculator-variant",
1758
+ icon: "mdi-office-building",
1752
1759
  color: "#23824f",
1753
1760
  tint: "#c8f3da",
1754
1761
  value: `${toNumber(patrolMetric?.count)}%`,
1755
1762
  percentage: toNumber(patrolMetric?.percentage),
1756
- meta: `${toNumber(patrolMetric?.missed ?? patrolMetric?.missedCheckpoints)} checkpoint missed · ${toNumber(patrolMetric?.ongoing)} ongoing`,
1763
+ meta: getMetricMeta(patrolMetric),
1757
1764
  raw: patrolMetric,
1758
1765
  filter: undefined,
1759
1766
  },
@@ -2022,6 +2029,10 @@ function getMetricMeta(metric: DashboardMetric) {
2022
2029
  `${formatNumber(toNumber((metric as any).missedCheckpoints ?? (metric as any).missed))} checkpoint missed`
2023
2030
  );
2024
2031
  }
2032
+ if (typeof metric.ongoing !== "undefined")
2033
+ parts.push(`${formatNumber(toNumber(metric.ongoing))} ongoing`);
2034
+ if (typeof metric.waitingApproval !== "undefined")
2035
+ parts.push(`${formatNumber(toNumber(metric.waitingApproval))} waiting approval`);
2025
2036
  if (typeof metric.lowStock !== "undefined")
2026
2037
  parts.push(`${formatNumber(toNumber(metric.lowStock))} low stock`);
2027
2038
  if (typeof metric.outOfStock !== "undefined")
@@ -2032,7 +2043,7 @@ function getMetricMeta(metric: DashboardMetric) {
2032
2043
  ) {
2033
2044
  parts.push(`${formatNumber(toNumber(metric.completed))} completed`);
2034
2045
  }
2035
- return parts.join(" - ");
2046
+ return parts.join(" ");
2036
2047
  }
2037
2048
 
2038
2049
  function getFilteredVisitorMetric(): DashboardMetric {
@@ -62,15 +62,18 @@ const { menuItem: hidFaceReaderMenu } = useHidFaceReaderMenu({
62
62
  cacheKey: "layout-navigation-hid-site",
63
63
  });
64
64
 
65
+ const { canManageEntryPass } = useSettingsPermission();
66
+
65
67
  const navigationItems = computed(() => {
66
68
  const items = [...(props.navigationItems as TNavigationItem[])];
67
69
 
68
70
  if (
71
+ canManageEntryPass.value &&
69
72
  hidFaceReaderMenu.value &&
70
73
  !items.some((item) => item.title === hidFaceReaderMenu.value?.title)
71
74
  ) {
72
75
  const insertAfterIndex = items.findIndex(
73
- (item) => item.title === "Pass & Key Mgmt",
76
+ (item) => item.title === "Pass & Key Mgmt"
74
77
  );
75
78
 
76
79
  if (insertAfterIndex >= 0) {
@@ -204,7 +204,7 @@ function handleScanQRPass() {
204
204
  }
205
205
 
206
206
  watch(selectedPass, (newVal) => {
207
- memberForm.visitorPass = [{ keyId: newVal }]
207
+ memberForm.visitorPass = [...(newVal ? [{ keyId: newVal }] : [])]
208
208
  })
209
209
 
210
210
  watch(scannedPassValue, (newVal) => {
@@ -258,13 +258,14 @@
258
258
  <span class="text-caption text-medium-emphasis d-block mb-1">{{ block.label }}</span>
259
259
  <div
260
260
  v-if="initialValues[block.key]"
261
- style="
262
- display: inline-block;
263
- border-radius: 8px;
264
- background: #111111;
265
- padding: 8px;
266
- max-width: 100%;
267
- "
261
+ :style="{
262
+ display: 'inline-block',
263
+ borderRadius: '8px',
264
+ background: sigBgLight[block.key] === false ? '#1e1e1e' : '#ffffff',
265
+ border: sigBgLight[block.key] === false ? '1px solid #334155' : '1px solid #e0e0e0',
266
+ padding: '8px',
267
+ maxWidth: '100%',
268
+ }"
268
269
  >
269
270
  <img
270
271
  :src="initialValues[block.key]"
@@ -443,6 +444,68 @@ const { currentUser } = useLocalAuth();
443
444
  const validForm = ref(false);
444
445
  const submitting = ref(false);
445
446
  const message = ref("");
447
+
448
+ // Detect signature background: true = light (black ink), false = dark (white ink)
449
+ const sigBgLight = ref<Record<string, boolean>>({});
450
+
451
+ function detectSigBackground(key: string, dataUrl: string) {
452
+ if (!dataUrl?.startsWith("data:image")) return;
453
+ const img = new Image();
454
+ img.onload = () => {
455
+ const SIZE = 32;
456
+ const canvas = document.createElement("canvas");
457
+ canvas.width = SIZE;
458
+ canvas.height = SIZE;
459
+ const ctx = canvas.getContext("2d");
460
+ if (!ctx) return;
461
+ ctx.drawImage(img, 0, 0, SIZE, SIZE);
462
+ const d = ctx.getImageData(0, 0, SIZE, SIZE).data;
463
+
464
+ let opaqueTotal = 0, opaqueCount = 0;
465
+ let inkTotal = 0, inkCount = 0;
466
+ for (let i = 0; i < d.length; i += 4) {
467
+ const alpha = d[i + 3];
468
+ const lum = (d[i] + d[i + 1] + d[i + 2]) / 3;
469
+ if (alpha > 128) {
470
+ opaqueTotal += lum;
471
+ opaqueCount++;
472
+ // Ink pixels are the non-background strokes (not very transparent)
473
+ inkTotal += lum;
474
+ inkCount++;
475
+ }
476
+ }
477
+
478
+ if (opaqueCount === 0) {
479
+ // Fully transparent PNG — can't detect, default to white bg
480
+ sigBgLight.value[key] = true;
481
+ return;
482
+ }
483
+
484
+ const opaqueRatio = opaqueCount / (d.length / 4);
485
+ if (opaqueRatio > 0.5) {
486
+ // Mostly opaque PNG — has a solid background; use overall brightness
487
+ sigBgLight.value[key] = opaqueTotal / opaqueCount > 128;
488
+ } else {
489
+ // Mostly transparent — ink-only PNG; check ink color
490
+ // Dark ink (< 128) = black strokes = was light mode → show white bg
491
+ // Light ink (≥ 128) = white strokes = was dark mode → show dark bg
492
+ sigBgLight.value[key] = inkTotal / inkCount < 128;
493
+ }
494
+ };
495
+ img.src = dataUrl;
496
+ }
497
+
498
+ watch(
499
+ () => props.initialValues,
500
+ (vals) => {
501
+ for (const [key, val] of Object.entries(vals)) {
502
+ if (typeof val === "string" && val.startsWith("data:image")) {
503
+ detectSigBackground(key, val);
504
+ }
505
+ }
506
+ },
507
+ { immediate: true, deep: true }
508
+ );
446
509
  const values = ref<Record<string, any>>({});
447
510
 
448
511
  const selectedAction = ref("");
@@ -101,7 +101,7 @@
101
101
  <v-text-field v-model="location" density="comfortable" readonly />
102
102
  </v-col>
103
103
 
104
- <v-col v-if="!visitorInfo.checkIn" cols="12">
104
+ <v-col cols="12">
105
105
  <InputLabel class="text-capitalize" title="Purpose" />
106
106
  <v-textarea
107
107
  v-model="visitorInfo.purpose"
@@ -253,7 +253,20 @@ const emit = defineEmits(["check-in-out", "close"]);
253
253
 
254
254
  const { standardFormatDateTime } = useUtils();
255
255
 
256
- const visitorInfo = ref(prop.visitorData);
256
+ const visitorInfo = ref<Partial<TVisitor>>({});
257
+
258
+ watch(
259
+ () => prop.visitorData,
260
+ (visitorData) => {
261
+ visitorInfo.value = {
262
+ ...visitorData,
263
+ visitorPass: Array.isArray(visitorData?.visitorPass)
264
+ ? [...visitorData.visitorPass]
265
+ : [],
266
+ };
267
+ },
268
+ { immediate: true }
269
+ );
257
270
 
258
271
  const visitorNric = computed({
259
272
  get: () =>
@@ -557,7 +557,7 @@
557
557
  color="success"
558
558
  text="Checkin"
559
559
  :disabled="isVisitorDataFromScannedQRCodeCheckingInOut"
560
- @click="handleCheckin(selectedVisitorObject)"
560
+ @click="handleCheckin(selectedVisitorDataObject)"
561
561
  :loading="isVisitorDataFromScannedQRCodeCheckingInOut"
562
562
  />
563
563
  </span>
@@ -1298,6 +1298,7 @@ const formattedFields = {
1298
1298
  block: "Block",
1299
1299
  level: "Level",
1300
1300
  unit: "Unit",
1301
+ purpose: "Purpose",
1301
1302
  checkIn: "Check In",
1302
1303
  snapshotEntryImage: "Entry Image",
1303
1304
  checkOut: "Check Out",
@@ -1481,18 +1482,32 @@ async function handleVisitorDataFromScannedQRCodeCheckInOut(
1481
1482
  try {
1482
1483
  isVisitorDataFromScannedQRCodeCheckingInOut.value = true;
1483
1484
  if (type != "checkOut") {
1485
+ const visitorId =
1486
+ visitorData._id ??
1487
+ visitorDataFromScannedQRCode.value._id ??
1488
+ selectedVisitorId.value;
1489
+
1490
+ if (!visitorId) {
1491
+ showMessage("Unable to check in visitor: missing visitor ID.", "error");
1492
+ return;
1493
+ }
1494
+
1495
+ const visitorPass = Array.isArray(visitorData.visitorPass)
1496
+ ? visitorData.visitorPass
1497
+ : [];
1498
+
1484
1499
  await visitorDataFromScannedQRCodeCheckIn({
1485
1500
  type,
1486
1501
  filter: {
1487
- _id: visitorData._id,
1502
+ _id: visitorId,
1488
1503
  },
1489
1504
  update: {
1490
1505
  updatedBy: currentUser.value._id,
1491
- visitorPass: visitorData.visitorPass.find(
1506
+ visitorPass: visitorPass.find(
1492
1507
  (i: Record<string, any>) => i.keyId === null
1493
1508
  )
1494
1509
  ? undefined
1495
- : visitorData.visitorPass,
1510
+ : visitorPass,
1496
1511
  nric: visitorData.nric ?? "",
1497
1512
  plateNumber: visitorData.plateNumber ?? "",
1498
1513
  },
@@ -33,7 +33,7 @@ export default function () {
33
33
  );
34
34
  }
35
35
 
36
- function getDashboardHygieneWeeklyActivity(
36
+ function getDashboardWeeklyActivity(
37
37
  site = "",
38
38
  serviceType: TServiceType = "cleaning_services",
39
39
  period?: TDashboardValues
@@ -149,7 +149,7 @@ export default function () {
149
149
  return {
150
150
  getDashboard,
151
151
  getDashboardHygiene,
152
- getDashboardHygieneWeeklyActivity,
152
+ getDashboardWeeklyActivity,
153
153
  getDashboardHygieneTaskSchedule,
154
154
  getDashboardHygieneAttendance,
155
155
  getDashboardHygieneFeedbacks,
@@ -58,7 +58,7 @@ export default function useMember() {
58
58
  if (search) query.search = search;
59
59
  if (user) query.user = user;
60
60
  if (org) query.org = org;
61
-
61
+ if (siteId) query.siteId = siteId;
62
62
  return useNuxtApp().$api<Record<string, any>>("/api/members", {
63
63
  method: "GET",
64
64
  query,
@@ -120,10 +120,9 @@ export default function useMember() {
120
120
  return useNuxtApp().$api<TMember>("/api/members/direct", {
121
121
  method: "POST",
122
122
  body: payload,
123
- })
123
+ });
124
124
  }
125
125
 
126
-
127
126
  function updateMemberSite(id: string, siteId: string, siteName: string) {
128
127
  return useNuxtApp().$api(`/api/members/site`, {
129
128
  method: "PUT",
@@ -26,6 +26,7 @@ export default function () {
26
26
  "level",
27
27
  "unit",
28
28
  "unitName",
29
+ "purpose",
29
30
  "remarks",
30
31
  ],
31
32
  contractor: [
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@7365admin1/layer-common",
3
3
  "license": "MIT",
4
4
  "type": "module",
5
- "version": "3.0.9",
5
+ "version": "3.0.11",
6
6
  "author": "7365admin1",
7
7
  "main": "./nuxt.config.ts",
8
8
  "publishConfig": {
@@ -58,6 +58,7 @@ declare type TVisitorPayload = Pick<
58
58
  | "deliveryType"
59
59
  | "nric"
60
60
  | "contact"
61
+ | "purpose"
61
62
  | "remarks"
62
63
  | "attachments"
63
64
  | "org"