@7365admin1/layer-common 3.2.1-staging.72 → 3.2.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/components/EntryPassInformation.vue +4 -4
  3. package/components/FeedbackMain.vue +7 -7
  4. package/components/HidAccessLogDashboard.vue +44 -119
  5. package/components/HidIdentityMapping.vue +975 -0
  6. package/components/HidIntercomManagement.vue +201 -808
  7. package/components/HidQrCodeConfiguration.vue +95 -907
  8. package/components/HidServiceSettingsPanel.vue +1 -20
  9. package/components/HidUserEnrollment.vue +81 -392
  10. package/components/Layout/NavigationDrawer.vue +2 -43
  11. package/components/NavigationItem.vue +0 -9
  12. package/components/Nfc/NFCPatrolRouteMain.vue +7 -52
  13. package/components/OnlineFormConfigurationForm.vue +224 -620
  14. package/components/OnlineFormFill.vue +8 -36
  15. package/components/OnlineFormsConfiguration.vue +2 -6
  16. package/components/QrTemplate/CreditCardLandscape.vue +12 -19
  17. package/components/QrTemplate/PrintDialog.vue +196 -209
  18. package/components/SiteSettings.vue +2 -4
  19. package/components/VisitorForm.vue +78 -201
  20. package/components/VisitorManagement.vue +2 -1
  21. package/composables/useComment.ts +3 -3
  22. package/composables/useHidAmico.ts +0 -127
  23. package/composables/useHidNavigation.ts +7 -0
  24. package/composables/useOnlineFormPages.ts +0 -2
  25. package/composables/useSiteSettings.ts +0 -50
  26. package/composables/useWebUsb.ts +37 -127
  27. package/middleware/member.ts +4 -0
  28. package/package.json +1 -2
  29. package/pages/[org]/[site]/access-mgmt/identity-mapping/index.vue +23 -0
  30. package/pages/[org]/[site]/access-mgmt/intercom/index.vue +1 -1
  31. package/plugins/secure-member.client.ts +56 -21
  32. package/plugins/vuetify.ts +9 -37
  33. package/types/site.d.ts +0 -71
  34. package/.changeset/camera-wall-gated-endpoint.md +0 -47
  35. package/.changeset/camera-wall-plain-english.md +0 -60
  36. package/.changeset/camera-wall-selection-and-guidance.md +0 -65
  37. package/.changeset/dark-primary-contrast.md +0 -39
  38. package/components/CameraWall.vue +0 -1034
  39. package/components/CameraWallTile.vue +0 -818
  40. package/components/HidCameraCaptureDialog.vue +0 -199
  41. package/composables/useSipWebPhone.ts +0 -311
  42. package/utils/camera-wall.test.ts +0 -571
  43. package/utils/camera-wall.ts +0 -926
  44. package/utils/theme.test.ts +0 -201
  45. package/utils/theme.ts +0 -136
@@ -496,79 +496,10 @@
496
496
  </v-card-actions>
497
497
  </v-card>
498
498
  </v-dialog>
499
-
500
- <v-dialog v-model="hidQrPreviewDialog" max-width="440" persistent>
501
- <v-card class="hid-qr-preview-card">
502
- <v-toolbar color="transparent" density="comfortable" class="px-2">
503
- <v-toolbar-title class="text-subtitle-1 font-weight-bold">
504
- Visitor QR Code
505
- </v-toolbar-title>
506
- <v-btn icon="mdi-close" variant="text" title="Close" @click="closeHidQrPreview" />
507
- </v-toolbar>
508
-
509
- <v-card-text class="px-8 pb-6 text-center">
510
- <div class="text-h6 font-weight-bold">
511
- {{ hidQrTemplate.header || "Visitor Access Pass" }}
512
- </div>
513
- <div class="text-body-2 text-medium-emphasis mt-1">
514
- {{ hidQrTemplate.subtext || "Scan at the HID reader for entry" }}
515
- </div>
516
-
517
- <div class="hid-qr-image-shell my-5">
518
- <v-img :src="hidQrPreview.imageUrl" width="280" height="280" alt="Visitor access QR code" />
519
- </div>
520
-
521
- <div class="text-h6 font-weight-bold">{{ visitor.name }}</div>
522
- <div v-if="hidQrPreview.expiresAt" class="text-caption text-medium-emphasis mt-1">
523
- Valid until {{ formatHidQrExpiry(hidQrPreview.expiresAt) }}
524
- </div>
525
-
526
- <v-alert v-if="hidQrPreviewError" type="error" variant="tonal" density="compact" class="mt-4 text-left">
527
- {{ hidQrPreviewError }}
528
- </v-alert>
529
- </v-card-text>
530
-
531
- <v-divider />
532
- <v-card-actions class="pa-0">
533
- <v-btn
534
- variant="text"
535
- height="52"
536
- class="flex-grow-1 text-none"
537
- prepend-icon="mdi-download"
538
- @click="downloadHidQrCode"
539
- >
540
- Download
541
- </v-btn>
542
- <v-btn
543
- v-if="hasHidQrPrinterConfig"
544
- variant="flat"
545
- color="primary-button"
546
- height="52"
547
- class="flex-grow-1 text-none"
548
- prepend-icon="mdi-printer"
549
- :loading="hidQrPrinting"
550
- @click="printHidQrCodePass"
551
- >
552
- Print
553
- </v-btn>
554
- <v-btn
555
- v-else
556
- variant="flat"
557
- color="primary-button"
558
- height="52"
559
- class="flex-grow-1 text-none"
560
- @click="closeHidQrPreview"
561
- >
562
- Close
563
- </v-btn>
564
- </v-card-actions>
565
- </v-card>
566
- </v-dialog>
567
499
  </v-card>
568
500
  </template>
569
501
 
570
502
  <script setup lang="ts">
571
- import QRCode from "qrcode";
572
503
  import { propsFactory } from "vuetify/lib/util/propsFactory.mjs";
573
504
  import useBuildingUnit from "../composables/useBuildingUnit";
574
505
  import useWebUsb from "../composables/useWebUsb";
@@ -580,7 +511,6 @@ import useVisitor from "../composables/useVisitor";
580
511
  import useSiteEntryPassSettings from "../composables/useSiteEntryPassSettings";
581
512
  import useAccessManagement from "../composables/useAccessManagement";
582
513
  import usePeople from "../composables/usePeople";
583
- import useHidAmico from "../composables/useHidAmico";
584
514
 
585
515
  const prop = defineProps({
586
516
  type: {
@@ -632,7 +562,6 @@ const {
632
562
  const { getBySiteId: getEntryPassSettingsBySiteId } =
633
563
  useSiteEntryPassSettings();
634
564
  const { createVisitorPass, signQr } = useAccessManagement();
635
- const { issueVisitorQr } = useHidAmico();
636
565
  const { testConnection } = useWebUsb();
637
566
  const {
638
567
  findPersonByNRIC,
@@ -681,15 +610,6 @@ const hidQrPrinted = ref(false);
681
610
  const isPhoneFieldFocused = ref(false);
682
611
  const isPlateNumberFieldFocused = ref(false);
683
612
  const isNricFieldFocused = ref(false);
684
- const hidQrPrinting = ref(false);
685
- const hidQrPreviewDialog = ref(false);
686
- const hidQrPreviewError = ref("");
687
- const hidQrPendingCompletion = ref<"done" | "done:more" | null>(null);
688
- const hidQrPreview = reactive({
689
- imageUrl: "",
690
- issuedAt: "",
691
- expiresAt: "",
692
- });
693
613
 
694
614
  const registeredUnitCompanyName = ref("N/A");
695
615
 
@@ -790,8 +710,7 @@ const requireNRIC = computed(() => {
790
710
  });
791
711
 
792
712
  const hidQrCodePassConfig = computed(() => {
793
- const site = siteData.value as TSite | null;
794
- return site?.metadata?.hidQrCodePass;
713
+ return (siteData.value as any)?.metadata?.hidQrCodePass || {};
795
714
  });
796
715
 
797
716
  const hidQrCodePassEnabled = computed(() => {
@@ -817,12 +736,6 @@ const hidQrValidityMinutes = computed(() => {
817
736
  return Number.isFinite(value) && value > 0 ? value : 60;
818
737
  });
819
738
 
820
- const hidQrReaderId = computed(() => String(hidQrCodePassConfig.value?.readerId || ""));
821
- const hidQrFormat = computed<"0" | "1" | "2">(() => {
822
- const value = String(hidQrCodePassConfig.value?.qrFormat || "0");
823
- return value === "1" || value === "2" ? value : "0";
824
- });
825
-
826
739
  const hidQrCodePassAllowed = computed(() => {
827
740
  return (
828
741
  hidQrCodePassEnabled.value &&
@@ -1797,7 +1710,7 @@ async function submit(options: { skipNonCheckedOutCheck?: boolean } = {}) {
1797
1710
  return;
1798
1711
  }
1799
1712
 
1800
- if (passType.value === "HID_QR" && !validateHidQrReaderConfig()) return;
1713
+ if (passType.value === "HID_QR" && !validateHidQrPrinterConfig()) return;
1801
1714
  if (
1802
1715
  prop.mode === "add" &&
1803
1716
  !options.skipNonCheckedOutCheck &&
@@ -1887,10 +1800,11 @@ async function submit(options: { skipNonCheckedOutCheck?: boolean } = {}) {
1887
1800
 
1888
1801
  if (res) {
1889
1802
  if (passType.value === "HID_QR") {
1890
- const previewReady = await prepareHidQrCodePreview(getVisitorIdFromResponse(res));
1891
- if (!previewReady) return;
1892
- hidQrPendingCompletion.value = createMore.value ? "done:more" : "done";
1893
- return;
1803
+ const printed = await printHidQrCodePass(
1804
+ getVisitorIdFromResponse(res),
1805
+ false
1806
+ );
1807
+ if (!printed) return;
1894
1808
  }
1895
1809
 
1896
1810
  if (
@@ -1923,9 +1837,12 @@ async function submit(options: { skipNonCheckedOutCheck?: boolean } = {}) {
1923
1837
  });
1924
1838
 
1925
1839
  if (passType.value === "QR") {
1840
+ console.log("[QR Print] passRes:", passRes);
1926
1841
  const accessCards: any[] =
1927
1842
  (passRes as any)?.data?.accessCards ?? [];
1843
+ console.log("[QR Print] accessCards:", accessCards);
1928
1844
  const printer = entryPassSettings.value?.data?.settings?.printer;
1845
+ console.log("[QR Print] printer config:", printer);
1929
1846
  if (!printer?.vendorId || !printer?.productId) {
1930
1847
  console.warn("[QR Print] Aborted: no printer configured.");
1931
1848
  } else if (!accessCards.length) {
@@ -1946,14 +1863,31 @@ async function submit(options: { skipNonCheckedOutCheck?: boolean } = {}) {
1946
1863
  const address = [blockLabel, levelLabel, unitLabel]
1947
1864
  .filter(Boolean)
1948
1865
  .join("/");
1866
+ console.log(
1867
+ "[QR Print] Printing",
1868
+ accessCards.length,
1869
+ "card(s). vendorId:",
1870
+ vendorId,
1871
+ "productId:",
1872
+ productId,
1873
+ "address:",
1874
+ address
1875
+ );
1949
1876
 
1950
1877
  await nextTick();
1951
1878
  for (const qrCode of accessCards) {
1879
+ console.log("[QR Print] Signing QR for card:", qrCode._id);
1952
1880
  const signed = await signQr({
1953
1881
  cardId: qrCode._id,
1954
1882
  purpose: "vms",
1955
1883
  });
1956
1884
  const qrData = signed?.data;
1885
+ console.log(
1886
+ "[QR Print] signQr result:",
1887
+ signed,
1888
+ "| qrData:",
1889
+ qrData
1890
+ );
1957
1891
  if (!qrData) {
1958
1892
  console.warn(
1959
1893
  "[QR Print] Skipping card",
@@ -2013,23 +1947,17 @@ function parseUsbId(value: unknown) {
2013
1947
  : parseInt(text, 10);
2014
1948
  }
2015
1949
 
2016
- function getVisitorIdFromResponse(response: unknown) {
1950
+ function getVisitorIdFromResponse(response: any) {
2017
1951
  if (typeof response === "string") return response;
2018
- if (!response || typeof response !== "object") return "";
2019
-
2020
- const result = response as Record<string, unknown>;
2021
- const nested = result.data && typeof result.data === "object"
2022
- ? result.data as Record<string, unknown>
2023
- : {};
2024
1952
  return (
2025
- result._id ||
2026
- result.id ||
2027
- nested._id ||
2028
- nested.id ||
2029
- result.insertedId ||
2030
- nested.insertedId ||
1953
+ response?._id ||
1954
+ response?.id ||
1955
+ response?.data?._id ||
1956
+ response?.data?.id ||
1957
+ response?.insertedId ||
1958
+ response?.data?.insertedId ||
2031
1959
  ""
2032
- ).toString();
1960
+ );
2033
1961
  }
2034
1962
 
2035
1963
  function getHidQrPrinterUsbIds() {
@@ -2038,19 +1966,7 @@ function getHidQrPrinterUsbIds() {
2038
1966
  return { vendorId, productId };
2039
1967
  }
2040
1968
 
2041
- function validateHidQrReaderConfig() {
2042
- if (!hidQrReaderId.value) {
2043
- errorMessage.value =
2044
- "No HID reader is configured for QR Code Pass. Please select a reader in Settings.";
2045
- return false;
2046
- }
2047
-
2048
- return true;
2049
- }
2050
-
2051
1969
  function validateHidQrPrinterConfig() {
2052
- if (!validateHidQrReaderConfig()) return false;
2053
-
2054
1970
  if (!hasHidQrPrinterConfig.value) {
2055
1971
  errorMessage.value =
2056
1972
  "No printer is configured on HID settings. Please configure the HID QR Code printer before continuing.";
@@ -2068,6 +1984,42 @@ function validateHidQrPrinterConfig() {
2068
1984
  return true;
2069
1985
  }
2070
1986
 
1987
+ function buildHidQrCodePayload(visitorId = "") {
1988
+ if (hidQrPrintPayload.value) return hidQrPrintPayload.value;
1989
+
1990
+ const issuedAt = new Date();
1991
+ const expiresAt = new Date(
1992
+ issuedAt.getTime() + hidQrValidityMinutes.value * 60 * 1000
1993
+ );
1994
+ const nonce =
1995
+ typeof crypto !== "undefined" && "randomUUID" in crypto
1996
+ ? crypto.randomUUID()
1997
+ : `${Date.now()}-${Math.random().toString(36).slice(2)}`;
1998
+
1999
+ hidQrPrintPayload.value = JSON.stringify({
2000
+ purpose: "hid-amico-visitor-access",
2001
+ visitorId,
2002
+ site: prop.site,
2003
+ org: prop.org,
2004
+ visitorType: prop.type,
2005
+ name: visitor.name || "",
2006
+ company: visitor.company || "",
2007
+ contact: visitor.contact || "",
2008
+ nric: visitor.nric || "",
2009
+ plateNumber: visitor.plateNumber || "",
2010
+ block: visitor.block || "",
2011
+ level: visitor.level || "",
2012
+ unit: visitor.unit || "",
2013
+ unitName: visitor.unitName || "",
2014
+ address: buildVisitorAddress(),
2015
+ issuedAt: issuedAt.toISOString(),
2016
+ expiresAt: expiresAt.toISOString(),
2017
+ nonce,
2018
+ });
2019
+
2020
+ return hidQrPrintPayload.value;
2021
+ }
2022
+
2071
2023
  function buildVisitorAddress() {
2072
2024
  const blockLabel =
2073
2025
  blocksArray.value.find((b: any) => b.value === visitor.block)?.title || "";
@@ -2080,58 +2032,20 @@ function buildVisitorAddress() {
2080
2032
  return [blockLabel, levelLabel, unitLabel].filter(Boolean).join("/");
2081
2033
  }
2082
2034
 
2083
- async function prepareHidQrCodePreview(visitorId: string) {
2084
- hidQrPreviewError.value = "";
2085
- if (!visitorId) {
2086
- errorMessage.value = "Unable to identify the visitor for HID QR Code enrollment.";
2087
- return false;
2088
- }
2089
-
2090
- try {
2091
- const response = await issueVisitorQr(hidQrReaderId.value, {
2092
- visitorId,
2093
- validityMinutes: hidQrValidityMinutes.value,
2094
- qrFormat: hidQrFormat.value,
2095
- });
2096
- const credential = "data" in response ? response.data : response;
2097
- hidQrPrintPayload.value = credential.qrValue;
2098
- if (!hidQrPrintPayload.value) {
2099
- errorMessage.value = "HID QR Code enrollment did not return a QR value.";
2100
- return false;
2101
- }
2102
-
2103
- hidQrPreview.imageUrl = await QRCode.toDataURL(hidQrPrintPayload.value, {
2104
- width: 360,
2105
- margin: 2,
2106
- errorCorrectionLevel: "M",
2107
- });
2108
- hidQrPreview.issuedAt = credential.issuedAt || "";
2109
- hidQrPreview.expiresAt = credential.expiresAt || "";
2110
- hidQrPreviewDialog.value = true;
2111
- return true;
2112
- } catch (error: unknown) {
2113
- errorMessage.value = errorConverter(error) || "Unable to generate HID QR Code.";
2114
- return false;
2115
- }
2116
- }
2117
-
2118
- async function printHidQrCodePass() {
2035
+ async function printHidQrCodePass(visitorId = "", manageProcessing = true) {
2119
2036
  if (hidQrPrinted.value) return true;
2120
2037
 
2121
2038
  if (!validateHidQrPrinterConfig()) return false;
2122
2039
 
2123
2040
  const { vendorId, productId } = getHidQrPrinterUsbIds();
2124
2041
 
2125
- hidQrPrinting.value = true;
2126
- hidQrPreviewError.value = "";
2042
+ if (manageProcessing) processing.value = true;
2127
2043
  try {
2128
- if (!hidQrPrintPayload.value) return false;
2129
-
2130
2044
  const printResult = await testConnection(
2131
2045
  vendorId,
2132
2046
  productId,
2133
2047
  true,
2134
- hidQrPrintPayload.value,
2048
+ buildHidQrCodePayload(visitorId),
2135
2049
  null,
2136
2050
  null,
2137
2051
  visitor.company || visitor.name || "",
@@ -2141,7 +2055,7 @@ async function printHidQrCodePass() {
2141
2055
  );
2142
2056
 
2143
2057
  if (!printResult?.success || printResult?.printTest?.success === false) {
2144
- hidQrPreviewError.value =
2058
+ errorMessage.value =
2145
2059
  printResult?.printTest?.error ||
2146
2060
  printResult?.error ||
2147
2061
  "Unable to print HID QR Code. Please check the printer connection.";
@@ -2150,40 +2064,14 @@ async function printHidQrCodePass() {
2150
2064
 
2151
2065
  hidQrPrinted.value = true;
2152
2066
  return true;
2153
- } catch (error: unknown) {
2154
- hidQrPreviewError.value = errorConverter(error) || "Unable to print HID QR Code.";
2067
+ } catch (error: any) {
2068
+ errorMessage.value = error?.message || "Unable to print HID QR Code.";
2155
2069
  return false;
2156
2070
  } finally {
2157
- hidQrPrinting.value = false;
2071
+ if (manageProcessing) processing.value = false;
2158
2072
  }
2159
2073
  }
2160
2074
 
2161
- function formatHidQrExpiry(value: string) {
2162
- const date = new Date(value);
2163
- return Number.isNaN(date.getTime()) ? value : date.toLocaleString();
2164
- }
2165
-
2166
- function downloadHidQrCode() {
2167
- if (!hidQrPreview.imageUrl) return;
2168
- const safeName = String(visitor.name || "visitor")
2169
- .trim()
2170
- .replace(/[^a-z0-9]+/gi, "-")
2171
- .replace(/^-|-$/g, "")
2172
- .toLowerCase();
2173
- const link = document.createElement("a");
2174
- link.href = hidQrPreview.imageUrl;
2175
- link.download = `hid-visitor-qr-${safeName || "visitor"}.png`;
2176
- link.click();
2177
- }
2178
-
2179
- function closeHidQrPreview() {
2180
- hidQrPreviewDialog.value = false;
2181
- const completion = hidQrPendingCompletion.value;
2182
- hidQrPendingCompletion.value = null;
2183
- if (completion === "done:more") emit("done:more");
2184
- else if (completion === "done") emit("done");
2185
- }
2186
-
2187
2075
  watch(
2188
2076
  () => visitor.plateNumber,
2189
2077
  (newVal) => {
@@ -2324,15 +2212,4 @@ onMounted(() => {
2324
2212
  font-size: 0.95rem;
2325
2213
  opacity: 1;
2326
2214
  }
2327
-
2328
- .hid-qr-preview-card {
2329
- border-radius: 6px;
2330
- }
2331
-
2332
- .hid-qr-image-shell {
2333
- display: inline-flex;
2334
- padding: 12px;
2335
- border: 1px solid #dce3e8;
2336
- background: #ffffff;
2337
- }
2338
2215
  </style>
@@ -1601,6 +1601,7 @@ const {
1601
1601
  watch(getVisitorReq, (newData: any) => {
1602
1602
  if (newData) {
1603
1603
  items.value = newData.items ?? [];
1604
+ // items.value = [{ _id: "testid", name: "John Doe", type: "Contractor", company: "ABC Corp", location: "Block A, Level 1, Unit 101", contact: "12345678", plateNumber: "SGX1234A", checkIn: new Date().toISOString(), checkOut: null, status: "registered", visitorPass: [{ _id: "1", keyId: "pass1", prefixAndName: "VIP Pass" }, { _id: "2", keyId: "pass2", prefixAndName: "VIP Pass 2" }], passKeys: [{ _id: "1", keyId: "key2", prefixAndName: "Master Key" }] }];
1604
1605
  pages.value = newData.pages ?? 0;
1605
1606
  pageRange.value = newData?.pageRange ?? "-- - -- of --";
1606
1607
  }
@@ -1707,7 +1708,7 @@ async function handleVisitorDataFromScannedQRCodeCheckInOut(
1707
1708
  site: visitorData.site ?? siteId,
1708
1709
  },
1709
1710
  update: {
1710
- updatedBy: currentUser.value?._id,
1711
+ updatedBy: currentUser.value._id,
1711
1712
  visitorPass: visitorPass.find(
1712
1713
  (i: Record<string, any>) => i.keyId === null
1713
1714
  )
@@ -89,13 +89,13 @@ export default function useComment() {
89
89
 
90
90
  comments.value = _comments.items
91
91
  .map((comment: any) => {
92
- if (comment.createdBy === currentUser.value?._id) {
92
+ if (comment.createdBy === currentUser.value._id) {
93
93
  comment.justify = "end";
94
94
  } else {
95
95
  comment.justify = "start";
96
96
  if (
97
97
  ((Array.isArray(comment.seenBy) &&
98
- !comment.seenBy.includes(currentUser.value?._id)) ||
98
+ !comment.seenBy.includes(currentUser.value._id)) ||
99
99
  !comment?.seenBy) &&
100
100
  comment?._id
101
101
  ) {
@@ -111,7 +111,7 @@ export default function useComment() {
111
111
  );
112
112
 
113
113
  if (Array.isArray(updateSeenIds) && updateSeenIds.length > 0) {
114
- const seenBy = await updateSeenBy(updateSeenIds, currentUser.value?._id);
114
+ const seenBy = await updateSeenBy(updateSeenIds, currentUser.value._id);
115
115
  }
116
116
  } catch (error) {
117
117
  console.log("error :", error);
@@ -28,46 +28,6 @@ type HidIdentityPayload = {
28
28
  metadata?: Record<string, any>;
29
29
  };
30
30
 
31
- type HidVisitorQrData = {
32
- visitorId: string;
33
- readerId: string;
34
- hidUserId: number;
35
- qrValue: string;
36
- qrFormat: "0" | "1" | "2";
37
- issuedAt: string;
38
- expiresAt: string;
39
- };
40
-
41
- type HidVisitorQrResponse = HidVisitorQrData | { data: HidVisitorQrData };
42
-
43
- type HidPermissionListResponse = {
44
- items: THidPermissionCandidate[];
45
- page: number;
46
- pages: number;
47
- pageRange: string;
48
- limit: number;
49
- };
50
-
51
- type HidFacialEnrollmentResult = {
52
- user_id?: number;
53
- success?: boolean;
54
- scores?: Record<string, unknown>;
55
- errors?: Array<{ code?: number; message?: string }>;
56
- };
57
-
58
- export type HidSipAccountData = {
59
- orgId: string;
60
- site: string;
61
- userId: string;
62
- extension: string;
63
- username: string;
64
- password: string;
65
- sipAddress: string;
66
- websocketUrl: string;
67
- status: "active";
68
- provisionedAt: string;
69
- };
70
-
71
31
  export default function useHidAmico() {
72
32
  const basePath = "/api/access-management/hid";
73
33
 
@@ -118,16 +78,6 @@ export default function useHidAmico() {
118
78
  });
119
79
  }
120
80
 
121
- function issueVisitorQr(
122
- readerId: string,
123
- payload: { visitorId: string; validityMinutes: number; qrFormat: "0" | "1" | "2" },
124
- ) {
125
- return useNuxtApp().$api<HidVisitorQrResponse>(`${basePath}/readers/${readerId}/visitor-qr`, {
126
- method: "POST",
127
- body: payload,
128
- });
129
- }
130
-
131
81
  function getReaderConfiguration(readerId: string, payload: Record<string, string[]> = {}) {
132
82
  return useNuxtApp().$api<Record<string, any>>(`${basePath}/readers/${readerId}/configuration`, {
133
83
  method: "POST",
@@ -162,33 +112,6 @@ export default function useHidAmico() {
162
112
  });
163
113
  }
164
114
 
165
- function setUserImage(
166
- readerId: string,
167
- hidUserId: string | number,
168
- image: Blob,
169
- options: { timestamp?: number; match?: boolean } = {},
170
- ) {
171
- return useNuxtApp().$api<{ data: HidFacialEnrollmentResult }>(
172
- `${basePath}/readers/${readerId}/users/${hidUserId}/image`,
173
- {
174
- method: "PUT",
175
- query: {
176
- ...(options.timestamp ? { timestamp: options.timestamp } : {}),
177
- match: options.match ?? true,
178
- },
179
- headers: { "Content-Type": "application/octet-stream" },
180
- body: image,
181
- },
182
- );
183
- }
184
-
185
- function deleteUserImage(readerId: string, hidUserId: string | number) {
186
- return useNuxtApp().$api<Record<string, unknown>>(
187
- `${basePath}/readers/${readerId}/users/${hidUserId}/image`,
188
- { method: "DELETE" },
189
- );
190
- }
191
-
192
115
  function createIdentity(readerId: string, payload: HidIdentityPayload) {
193
116
  return useNuxtApp().$api<Record<string, any>>(`${basePath}/readers/${readerId}/identities`, {
194
117
  method: "POST",
@@ -228,49 +151,6 @@ export default function useHidAmico() {
228
151
  });
229
152
  }
230
153
 
231
- function getSitePermissions(siteId: string, orgId: string, readerId: string) {
232
- return useNuxtApp().$api<{ data: THidSitePermissions }>(
233
- `${basePath}/sites/${siteId}/permissions`,
234
- { method: "GET", query: { orgId, readerId } },
235
- );
236
- }
237
-
238
- function ensureSipAccount(siteId: string, orgId: string) {
239
- return useNuxtApp().$api<{ data: HidSipAccountData }>(
240
- `${basePath}/sites/${siteId}/intercom/sip-account`,
241
- { method: "POST", body: { orgId } },
242
- );
243
- }
244
-
245
- function getPermissionCandidates(
246
- siteId: string,
247
- query: {
248
- orgId: string;
249
- readerId: string;
250
- category: THidPermissionCategory | "intercom";
251
- search?: string;
252
- page?: number;
253
- limit?: number;
254
- },
255
- ) {
256
- return useNuxtApp().$api<HidPermissionListResponse>(
257
- `${basePath}/sites/${siteId}/permission-candidates`,
258
- { method: "GET", query },
259
- );
260
- }
261
-
262
- function updateSitePermissions(
263
- siteId: string,
264
- orgId: string,
265
- readerId: string,
266
- assignments: Array<Pick<THidPermissionAssignment, "subjectId" | "category" | "intercom">>,
267
- ) {
268
- return useNuxtApp().$api<{ data: THidSitePermissions; message: string }>(
269
- `${basePath}/sites/${siteId}/permissions`,
270
- { method: "PUT", body: { orgId, readerId, assignments } },
271
- );
272
- }
273
-
274
154
  return {
275
155
  getReaders,
276
156
  createReader,
@@ -279,13 +159,10 @@ export default function useHidAmico() {
279
159
  testReader,
280
160
  syncReader,
281
161
  runObjectOperation,
282
- issueVisitorQr,
283
162
  getReaderConfiguration,
284
163
  setReaderConfiguration,
285
164
  getLogs,
286
165
  getUserImage,
287
- setUserImage,
288
- deleteUserImage,
289
166
  getIdentities,
290
167
  createIdentity,
291
168
  updateIdentity,
@@ -293,9 +170,5 @@ export default function useHidAmico() {
293
170
  getIntercomStatus,
294
171
  makeIntercomCall,
295
172
  finalizeIntercomCall,
296
- ensureSipAccount,
297
- getSitePermissions,
298
- getPermissionCandidates,
299
- updateSitePermissions,
300
173
  };
301
174
  }
@@ -41,6 +41,13 @@ export default function useHidNavigation() {
41
41
  params: { org, site },
42
42
  },
43
43
  },
44
+ {
45
+ title: "Identity Mapping",
46
+ route: {
47
+ name: "org-site-access-mgmt-identity-mapping",
48
+ params: { org, site },
49
+ },
50
+ },
44
51
  {
45
52
  title: "Access Logs",
46
53
  route: {
@@ -20,8 +20,6 @@ export type FormBlock =
20
20
  | { type: "checkbox-group"; title?: string; single?: boolean; items: CheckboxItemDef[] }
21
21
  | { type: "paragraph"; text: string }
22
22
  | { type: "section-header"; text: string }
23
- | { type: "ordered-list"; title?: string; items: string[] }
24
- | { type: "unordered-list"; title?: string; items: string[] }
25
23
  | { type: "divider" }
26
24
  | { type: "signature-row"; label: string; key: string }
27
25
  | { type: "acknowledgement"; text: string }