@7365admin1/layer-common 3.0.25 → 3.0.27

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.
@@ -151,8 +151,15 @@
151
151
  >
152
152
  </template>
153
153
 
154
- <template v-slot:item.email="{ value }">
155
- {{ value ?? "N/A" }}
154
+ <template v-slot:item.email-vehicleNumber="{ item }">
155
+ <span class="d-flex align-center ga-2">
156
+ <v-icon icon="mdi-email" size="15" />
157
+ <span class="text-capitalize">{{ item?.email || "N/A" }}</span>
158
+ </span>
159
+ <span class="d-flex align-center ga-2">
160
+ <v-icon icon="mdi-car-back" size="15" />
161
+ <span class="text-capitalize">{{ item?.plateNumber || "N/A" }}</span>
162
+ </span>
156
163
  </template>
157
164
 
158
165
  <template v-slot:item.invited-by="{ item }">
@@ -353,6 +360,54 @@
353
360
  />
354
361
  </v-list>
355
362
  </v-menu>
363
+
364
+ <!-- NFC Access Cards -->
365
+ <v-menu
366
+ v-if="item.accessCards?.type === 'NFC' && item.accessCards?.cardNo"
367
+ :close-on-content-click="false"
368
+ >
369
+ <template #activator="{ props: nfcMenuProps }">
370
+ <div
371
+ class="d-flex align-center ga-1 mt-1"
372
+ style="cursor: pointer"
373
+ v-bind="nfcMenuProps"
374
+ @click.stop
375
+ >
376
+ <v-icon
377
+ size="15"
378
+ icon="mdi-credit-card-outline"
379
+ color="purple"
380
+ />
381
+ <v-chip size="x-small" variant="tonal" color="purple">
382
+ {{ item.accessCards.cardNo }}
383
+ <template v-if="(item.cards?.flat().length ?? 0) > 1">
384
+ (+{{ item.cards.flat().length - 1 }})
385
+ </template>
386
+ </v-chip>
387
+ </div>
388
+ </template>
389
+ <v-list density="compact" min-width="200">
390
+ <v-list-subheader>NFC Cards</v-list-subheader>
391
+ <v-list-item
392
+ prepend-icon="mdi-credit-card-outline"
393
+ :title="item.accessCards.cardNo"
394
+ />
395
+ <template v-for="(cardGroup, gi) in item.cards" :key="gi">
396
+ <v-list-item
397
+ v-for="card in cardGroup.filter((c: any) => c._id !== item.accessCards._id)"
398
+ :key="card._id"
399
+ prepend-icon="mdi-credit-card-outline"
400
+ :title="card._id"
401
+ />
402
+ </template>
403
+ </v-list>
404
+ </v-menu>
405
+
406
+ <!-- QRCODE identifier -->
407
+ <div v-if="item.accessCards?.type === 'QRCODE' && item.accessCards?.cardNo" class="d-flex align-center ga-1 mt-1">
408
+ <v-icon size="15" icon="mdi-qrcode" color="teal" />
409
+ <v-chip size="x-small" variant="tonal" color="teal">QR · ({{ item.cards?.flat().length ?? 1 }})</v-chip>
410
+ </div>
356
411
  </v-row>
357
412
  </template>
358
413
 
@@ -852,6 +907,46 @@
852
907
  </v-card>
853
908
  </v-dialog>
854
909
 
910
+ <v-dialog v-model="dialog.returnNfcCard" max-width="450" persistent>
911
+ <v-card>
912
+ <v-toolbar density="compact" color="">
913
+ <v-row no-gutters class="d-flex fill-height justify-space-between align-center px-4">
914
+ <span class="font-weight-bold">Return NFC Card</span>
915
+ <v-btn icon="mdi-close" variant="text" @click="dialog.returnNfcCard = false" />
916
+ </v-row>
917
+ </v-toolbar>
918
+ <v-card-text class="px-4 pb-2">
919
+ <p class="text-body-2 mb-3">Please indicate the status of the NFC card before checking out.</p>
920
+ <div>
921
+ <InputLabel class="text-capitalize" title="Full Name" />
922
+ <v-text-field v-model="selectedVisitorObject.name" density="comfortable" readonly />
923
+ </div>
924
+ <div>
925
+ <InputLabel class="text-capitalize" title="Location" />
926
+ <v-text-field v-model="selectedVisitorObject.location" density="comfortable" readonly />
927
+ </div>
928
+ <div v-for="(card, idx) in nfcCardReturnStatuses" :key="card.cardId" class="mb-4">
929
+ <div class="d-flex align-center ga-2 mb-2">
930
+ <v-icon size="18" icon="mdi-credit-card-outline" color="purple" />
931
+ <v-chip size="small" variant="tonal" color="purple">{{ card.cardNo }}</v-chip>
932
+ </div>
933
+ <v-select v-model="nfcCardReturnStatuses[idx].status" :items="nfcPassStatusOptions" item-title="label" item-value="value" density="comfortable" hide-details />
934
+ <v-textarea v-if="card.status === 'Lost' || card.status === 'Damage'" v-model="nfcCardReturnStatuses[idx].remarks" label="Remarks (required)" no-resize rows="3" class="mt-2" density="compact" />
935
+ </div>
936
+ </v-card-text>
937
+ <v-toolbar class="pa-0" density="compact">
938
+ <v-row no-gutters>
939
+ <v-col cols="6">
940
+ <v-btn variant="text" block @click="dialog.returnNfcCard = false">Close</v-btn>
941
+ </v-col>
942
+ <v-col cols="6">
943
+ <v-btn color="red" variant="flat" height="48" rounded="0" block :loading="loading.checkingOut" :disabled="!canConfirmNfcCheckout" @click="handleNfcCheckout">Confirm Checkout</v-btn>
944
+ </v-col>
945
+ </v-row>
946
+ </v-toolbar>
947
+ </v-card>
948
+ </v-dialog>
949
+
855
950
  <v-dialog v-model="dialog.addPassKey" width="450" persistent>
856
951
  <AddPassKeyToVisitor
857
952
  mode="add"
@@ -1039,6 +1134,16 @@ const props = defineProps({
1039
1134
  const { authenticate, currentUser } = useLocalAuth();
1040
1135
  authenticate();
1041
1136
 
1137
+ const route = useRoute();
1138
+ const router = useRouter();
1139
+ const { org: orgId, site: siteId } = route.params as {
1140
+ org: string;
1141
+ site: string;
1142
+ };
1143
+
1144
+ const { enableUnregistered } = useANPRSettings(siteId);
1145
+ const enableUnregisteredTab = computed(() => enableUnregistered.value);
1146
+
1042
1147
  const {
1043
1148
  getVisitors,
1044
1149
  visitorSelection,
@@ -1046,6 +1151,7 @@ const {
1046
1151
  updateVisitor,
1047
1152
  visitorDataFromScannedQRCodeCheckIn,
1048
1153
  } = useVisitor();
1154
+ const { visitorCheckout } = useAccessManagement();
1049
1155
  const {
1050
1156
  debounce,
1051
1157
  formatCamelCaseToWords,
@@ -1058,12 +1164,6 @@ const { formatLocation } = useSecurityUtils();
1058
1164
  const { getFileUrlAnpr } = useFile();
1059
1165
  // const { status: visitorStatus, search } = useRoute().query as { status: string, search: string};
1060
1166
 
1061
- const route = useRoute();
1062
- const router = useRouter();
1063
- const { org: orgId, site: siteId } = route.params as {
1064
- org: string;
1065
- site: string;
1066
- };
1067
1167
  const routeName = route.name;
1068
1168
 
1069
1169
  const items = ref<Array<Record<string, any>>>([]);
@@ -1112,6 +1212,7 @@ const dialog = reactive({
1112
1212
  scanVisitorQRCode: false,
1113
1213
  showVisitorDataFromScannedQRCode: false,
1114
1214
  approveRejectOvernightParkingRequestDialog: false,
1215
+ returnNfcCard: false,
1115
1216
  });
1116
1217
 
1117
1218
  const snapshotImageUrl = ref("");
@@ -1126,7 +1227,7 @@ const headers = computed(() => {
1126
1227
  if (tab === "overnight-parking") {
1127
1228
  return [
1128
1229
  { title: "Name", value: "name" },
1129
- { title: "Email", value: "email" },
1230
+ { title: "Email/Vehicle No.", value: "email-vehicleNumber" },
1130
1231
  { title: "Invited By", value: "invited-by" },
1131
1232
  { title: "Arrival Date/Time", value: "arrival-date-time" },
1132
1233
  { title: "Check In/Out", value: "checkin-out" },
@@ -1167,13 +1268,19 @@ const headers = computed(() => {
1167
1268
  return list;
1168
1269
  });
1169
1270
 
1170
- const tabOptions = [
1171
- { name: "Registered", value: "registered" },
1172
- { name: "Unregistered", value: "unregistered" },
1173
- { name: "Guests", value: "guests" },
1174
- { name: "Resident Transactions", value: "resident-transactions" },
1175
- { name: "Overnight Parking", value: "overnight-parking" },
1176
- ];
1271
+ const tabOptions = computed(() => {
1272
+ const baseTabs = [
1273
+ { name: "Registered", value: "registered" },
1274
+ ...(enableUnregisteredTab.value
1275
+ ? [{ name: "Unregistered", value: "unregistered" }]
1276
+ : []),
1277
+ { name: "Guests", value: "guests" },
1278
+ { name: "Resident Transactions", value: "resident-transactions" },
1279
+ { name: "Overnight Parking", value: "overnight-parking" },
1280
+ ];
1281
+
1282
+ return baseTabs;
1283
+ });
1177
1284
 
1178
1285
  function getOvernightParkingRequestStatusColor(status: string) {
1179
1286
  switch (status) {
@@ -1319,10 +1426,17 @@ const passStatusOptions = [
1319
1426
  { label: "Lost", value: "Lost" },
1320
1427
  ];
1321
1428
 
1429
+ const nfcPassStatusOptions = [
1430
+ { label: "Returned", value: "Returned" },
1431
+ { label: "Not Returned", value: "In Use" },
1432
+ { label: "Damaged", value: "Damage" },
1433
+ { label: "Lost", value: "Lost" },
1434
+ ];
1435
+
1322
1436
  function toRoute(tab: any) {
1323
1437
  items.value = [];
1324
1438
 
1325
- const obj = tabOptions.find((x) => x.value === tab);
1439
+ const obj = tabOptions.value.find((x) => x.value === tab);
1326
1440
  if (!obj) return;
1327
1441
  page.value = 1;
1328
1442
  getVisitorRefresh();
@@ -1605,7 +1719,7 @@ function handleRegistrationUnregisteredVisitor(item: Partial<TVisitor>) {
1605
1719
  dialog.showSelection = true;
1606
1720
  mode.value = "register";
1607
1721
 
1608
- if(!selectedVisitorDataObject.value){
1722
+ if (!selectedVisitorDataObject.value) {
1609
1723
  getVisitorRefresh();
1610
1724
  }
1611
1725
  }
@@ -1703,6 +1817,9 @@ const passReturnStatuses = ref<
1703
1817
  const keyReturnStatuses = ref<
1704
1818
  { keyId: string; status: string; prefixAndName: string; remarks: string }[]
1705
1819
  >([]);
1820
+ const nfcCardReturnStatuses = ref<
1821
+ { cardId: string; cardNo: string; status: string; remarks: string }[]
1822
+ >([]);
1706
1823
 
1707
1824
  const canConfirmCheckout = computed(() => {
1708
1825
  const allEntries = [...passReturnStatuses.value, ...keyReturnStatuses.value];
@@ -1717,6 +1834,15 @@ const canConfirmCheckout = computed(() => {
1717
1834
  });
1718
1835
  });
1719
1836
 
1837
+ const canConfirmNfcCheckout = computed(() => {
1838
+ if (nfcCardReturnStatuses.value.length === 0) return false;
1839
+ return nfcCardReturnStatuses.value.every(({ status, remarks }) => {
1840
+ if (!status || status === "In Use") return false;
1841
+ if ((status === "Lost" || status === "Damage") && !remarks.trim()) return false;
1842
+ return true;
1843
+ });
1844
+ });
1845
+
1720
1846
  function handleCheckin(user: Record<string, any>) {
1721
1847
  visitorDataFromScannedQRCode.value = user;
1722
1848
  dialog.showVisitorDataFromScannedQRCode = true;
@@ -1755,6 +1881,22 @@ function handleCheckout(userId: string) {
1755
1881
  return;
1756
1882
  }
1757
1883
 
1884
+ const hasNfc = visitor?.accessCards?.type === "NFC" && !!visitor?.accessCards?.cardNo;
1885
+ if (hasNfc) {
1886
+ const allCards: any[] = visitor.cards?.flat() ?? [];
1887
+ nfcCardReturnStatuses.value = allCards.map((card: any) => ({
1888
+ cardId: card._id,
1889
+ cardNo: card._id === visitor.accessCards._id ? visitor.accessCards.cardNo : card._id,
1890
+ status: "In Use",
1891
+ remarks: "",
1892
+ }));
1893
+ if (nfcCardReturnStatuses.value.length === 0) {
1894
+ nfcCardReturnStatuses.value = [{ cardId: visitor.accessCards._id, cardNo: visitor.accessCards.cardNo, status: "In Use", remarks: "" }];
1895
+ }
1896
+ dialog.returnNfcCard = true;
1897
+ return;
1898
+ }
1899
+
1758
1900
  proceedCheckout();
1759
1901
  }
1760
1902
 
@@ -1803,6 +1945,34 @@ async function proceedCheckout() {
1803
1945
  }
1804
1946
  }
1805
1947
 
1948
+ async function handleNfcCheckout() {
1949
+ const userId = selectedVisitorId.value;
1950
+ if (!userId) return;
1951
+ try {
1952
+ loading.checkingOut = true;
1953
+ const res = await visitorCheckout({
1954
+ cards: nfcCardReturnStatuses.value.map(({ cardId, status, remarks }) => ({
1955
+ cardId,
1956
+ userId,
1957
+ status,
1958
+ remarks: remarks ?? "",
1959
+ })),
1960
+ });
1961
+ if (res) {
1962
+ await updateVisitor(userId as string, { checkOut: new Date().toISOString() });
1963
+ showMessage("Visitor successfully checked-out!", "info");
1964
+ await getVisitorRefresh();
1965
+ dialog.returnNfcCard = false;
1966
+ dialog.viewVisitor = false;
1967
+ }
1968
+ } catch (error: any) {
1969
+ const errorMessage = error?.response?._data?.message;
1970
+ showMessage(errorMessage || "Something went wrong. Please try again later.", "error");
1971
+ } finally {
1972
+ loading.checkingOut = false;
1973
+ }
1974
+ }
1975
+
1806
1976
  function buildReportParams(): any {
1807
1977
  const params: any = {
1808
1978
  site: siteId,
@@ -2021,7 +2191,12 @@ watch([searchInput, dateFrom, dateTo, filterTypes, activeTab], () => {
2021
2191
  });
2022
2192
 
2023
2193
  onMounted(() => {
2024
- activeTab.value = (route.query.tab as string) || "unregistered";
2194
+ const requestedTab = (route.query.tab as string) || "registered";
2195
+ activeTab.value = enableUnregisteredTab.value
2196
+ ? requestedTab
2197
+ : requestedTab === "unregistered"
2198
+ ? "registered"
2199
+ : requestedTab;
2025
2200
  searchInput.value = (route.query.search as string) || "";
2026
2201
  if (route.query.dateFrom) {
2027
2202
  dateFrom.value = normalizeDateOnly(route.query.dateFrom as string);
@@ -2042,29 +2217,48 @@ onMounted(() => {
2042
2217
  const { socketUnregisteredVisitorTrigger, visitorSocketData } =
2043
2218
  useVisitorSocket();
2044
2219
 
2045
- watchEffect(async () => {
2046
- if (visitorSocketData.value && visitorSocketData.value.reload && activeTab.value === "unregistered") {
2047
- await getVisitorRefresh();
2048
- visitorSocketData.value = null;
2049
- socketUnregisteredVisitorTrigger.value = false;
2220
+ watch(
2221
+ enableUnregisteredTab,
2222
+ (enabled) => {
2223
+ if (!enabled && activeTab.value === "unregistered") {
2224
+ activeTab.value = "registered";
2050
2225
  }
2226
+ },
2227
+ { immediate: true }
2228
+ );
2051
2229
 
2052
- if(visitorSocketData.value && visitorSocketData.value.plateNumber && socketUnregisteredVisitorTrigger.value && activeTab.value === "unregistered" && dialog.showSelection === false) {
2053
- // await getVisitorRefresh();
2054
- // visitorSocketData.value = null;
2055
- // socketUnregisteredVisitorTrigger.value = false;
2056
- setTimeout(async() => {
2057
- const { _id } = visitorSocketData.value;
2058
- await handleRegistrationUnregisteredVisitor({ _id });
2059
- socketUnregisteredVisitorTrigger.value = false;
2060
-
2061
- setTimeout(() => {
2062
- visitorSocketData.value = null;
2063
- }, 1000)
2064
- }, 1000)
2065
- }
2066
- })
2230
+ watchEffect(async () => {
2231
+ if (
2232
+ visitorSocketData.value &&
2233
+ visitorSocketData.value.reload &&
2234
+ activeTab.value === "unregistered"
2235
+ ) {
2236
+ await getVisitorRefresh();
2237
+ visitorSocketData.value = null;
2238
+ socketUnregisteredVisitorTrigger.value = false;
2239
+ }
2240
+
2241
+ if (
2242
+ visitorSocketData.value &&
2243
+ visitorSocketData.value.plateNumber &&
2244
+ socketUnregisteredVisitorTrigger.value &&
2245
+ activeTab.value === "unregistered" &&
2246
+ dialog.showSelection === false
2247
+ ) {
2248
+ // await getVisitorRefresh();
2249
+ // visitorSocketData.value = null;
2250
+ // socketUnregisteredVisitorTrigger.value = false;
2251
+ setTimeout(async () => {
2252
+ const { _id } = visitorSocketData.value;
2253
+ await handleRegistrationUnregisteredVisitor({ _id });
2254
+ socketUnregisteredVisitorTrigger.value = false;
2067
2255
 
2256
+ setTimeout(() => {
2257
+ visitorSocketData.value = null;
2258
+ }, 1000);
2259
+ }, 1000);
2260
+ }
2261
+ });
2068
2262
  </script>
2069
2263
 
2070
2264
  <style scoped></style>
@@ -32,7 +32,7 @@
32
32
  </section> -->
33
33
 
34
34
  <v-snackbar
35
- v-if="!isUnregisteredVisitorRoute"
35
+ v-if="!isUnregisteredVisitorRoute && enableUnregisteredSnackbar && canViewVisitor"
36
36
  v-model="snackBarMessage.modal"
37
37
  :color="snackBarMessage.color"
38
38
  :timeout="snackBarMessage.timeout"
@@ -94,12 +94,20 @@ const props = defineProps({
94
94
  type: String,
95
95
  default: "",
96
96
  },
97
+ canViewVisitor: {
98
+ type: Boolean,
99
+ default: false,
100
+ },
97
101
  });
98
102
 
99
103
  const config = useRuntimeConfig();
100
104
  const publicConfig = config.public as Record<string, string | undefined>;
101
105
  const route = useRoute();
102
106
  const { tab } = useVisitor();
107
+ const { enableUnregistered, ensureANPRSettings } = useANPRSettings(
108
+ props.siteId
109
+ );
110
+ const enableUnregisteredSnackbar = computed(() => enableUnregistered.value);
103
111
  const { socketUnregisteredVisitorTrigger, visitorSocketData } =
104
112
  useVisitorSocket();
105
113
 
@@ -124,6 +132,16 @@ const permanentMessageDialog = reactive({
124
132
  text: "",
125
133
  });
126
134
 
135
+ watch(
136
+ () => props.siteId,
137
+ async (siteId) => {
138
+ if (siteId && !route.path.includes("/settings")) {
139
+ await ensureANPRSettings();
140
+ }
141
+ },
142
+ { immediate: true }
143
+ );
144
+
127
145
  const path = computed(() => route.path);
128
146
  const isVisitorManagementPath = (path: string) =>
129
147
  path.includes("/visitor-management");
@@ -166,6 +184,10 @@ const showTransientMessage = (
166
184
  color: string,
167
185
  isUnregistered = false
168
186
  ) => {
187
+ if (!enableUnregisteredSnackbar.value) {
188
+ return;
189
+ }
190
+
169
191
  snackBarMessage.text = text;
170
192
  snackBarMessage.color = color;
171
193
  snackBarMessage.modal = true;
@@ -283,6 +305,12 @@ watch(
283
305
  { immediate: true }
284
306
  );
285
307
 
308
+ watch(enableUnregisteredSnackbar, (enabled) => {
309
+ if (!enabled) {
310
+ snackBarMessage.modal = false;
311
+ }
312
+ });
313
+
286
314
  onUnmounted(() => {
287
315
  disconnectSocket();
288
316
  });
@@ -1,26 +1,75 @@
1
- export default function () {
2
- async function getANPRSettingBySite(data: any) {
3
- return await useNuxtApp().$api<Record<string, any>>(
1
+ export default function (siteId?: string) {
2
+ const stateKey = computed(() =>
3
+ siteId ? `anpr-settings-${siteId}` : "anpr-settings"
4
+ );
5
+
6
+ const anprSettings = useState<Record<string, any> | null>(
7
+ stateKey.value,
8
+ () => null
9
+ );
10
+
11
+ const enableUnregistered = computed(
12
+ () => anprSettings.value?.ANPRSwitches?.enableUnregistered === true
13
+ );
14
+
15
+ async function fetchANPRSettings(data?: any) {
16
+ const payload = data ?? (siteId ? { site: siteId, userType: "site" } : undefined);
17
+
18
+ if (!payload) {
19
+ return anprSettings.value;
20
+ }
21
+
22
+ const response = await useNuxtApp().$api<Record<string, any>>(
4
23
  `/api/anpr-settings/get/v1`,
5
24
  {
6
25
  method: "POST",
7
- body: data,
26
+ body: payload,
8
27
  }
9
28
  );
29
+
30
+ if (response) {
31
+ anprSettings.value = response;
32
+ }
33
+
34
+ return response;
10
35
  }
11
- async function createUpdateANPRSettings(
12
- data: any
13
- ) {
14
- return await useNuxtApp().$api<Record<string, any>>(
36
+
37
+ async function ensureANPRSettings(force = false) {
38
+ if (!siteId) {
39
+ return anprSettings.value;
40
+ }
41
+
42
+ if (!force && anprSettings.value) {
43
+ return anprSettings.value;
44
+ }
45
+
46
+ return await fetchANPRSettings({ site: siteId, userType: "site" });
47
+ }
48
+
49
+ async function getANPRSettingBySite(data: any) {
50
+ return await fetchANPRSettings(data);
51
+ }
52
+
53
+ async function createUpdateANPRSettings(data: any) {
54
+ const response = await useNuxtApp().$api<Record<string, any>>(
15
55
  `/api/anpr-settings/v1`,
16
56
  {
17
57
  method: "POST",
18
58
  body: data,
19
59
  }
20
60
  );
61
+
62
+ if (response) {
63
+ anprSettings.value = response;
64
+ }
65
+
66
+ return response;
21
67
  }
22
68
 
23
69
  return {
70
+ anprSettings,
71
+ enableUnregistered,
72
+ ensureANPRSettings,
24
73
  getANPRSettingBySite,
25
74
  createUpdateANPRSettings,
26
75
  };
@@ -268,7 +268,15 @@ export default function useAccessManagement() {
268
268
  type: string;
269
269
  nfcCards: { _id: string; cardNo: string }[];
270
270
  acm_url: string;
271
- visitorId: string;
271
+ user: {
272
+ visitorId: string;
273
+ name?: string;
274
+ nric?: string;
275
+ contact?: string;
276
+ company?: string;
277
+ type?: string;
278
+ plateNumber?: string;
279
+ };
272
280
  }) {
273
281
  return useNuxtApp().$api<Record<string, any>>(
274
282
  `/api/access-management/visitor`,
@@ -313,6 +321,13 @@ export default function useAccessManagement() {
313
321
  );
314
322
  }
315
323
 
324
+ function visitorCheckout(payload: { cards: { cardId: string; userId: string; status: string; remarks: string }[] }) {
325
+ return useNuxtApp().$api<Record<string, any>>(
326
+ `/api/access-management/visitor-checkout`,
327
+ { method: "PATCH", body: payload }
328
+ );
329
+ }
330
+
316
331
  return {
317
332
  getResidents,
318
333
  assignUser,
@@ -337,5 +352,6 @@ export default function useAccessManagement() {
337
352
  createVisitorPass,
338
353
  signQr,
339
354
  getBlockLevelUnitList,
355
+ visitorCheckout,
340
356
  };
341
357
  }
@@ -6,7 +6,7 @@ export default function useCleaningPermission() {
6
6
  workOrderPermissions,
7
7
  invitationPermissions,
8
8
  bulletinBoardPermissions,
9
- dashboardPermissions,
9
+
10
10
  } = useCommonPermissions();
11
11
  const permissions: TPermissions = {
12
12
  members: memberPermissions,
@@ -15,7 +15,7 @@ export default function useCleaningPermission() {
15
15
  roles: rolePermissions,
16
16
  invitations: invitationPermissions,
17
17
  "bulletin-board": bulletinBoardPermissions,
18
- dashboard: dashboardPermissions,
18
+
19
19
  inventory: {
20
20
  "view-inventory": {
21
21
  check: true,
@@ -279,44 +279,7 @@ export function useCommonPermissions() {
279
279
 
280
280
  }
281
281
 
282
- const dashboardPermissions: Record<string, TPermission> = {
283
- "view-activity": {
284
- check: true,
285
- description: "Allows the user to view the activity chart widget.",
286
- },
287
- "view-task-schedule": {
288
- check: true,
289
- description: "Allows the user to view the task schedule widget.",
290
- },
291
- "view-attendance-widget": {
292
- check: true,
293
- description: "Allows the user to view the attendance/staff status widget.",
294
- },
295
- "view-feedbacks-widget": {
296
- check: true,
297
- description: "Allows the user to view the feedbacks widget.",
298
- },
299
- "view-upcoming-events": {
300
- check: true,
301
- description: "Allows the user to view the upcoming events widget.",
302
- },
303
- "view-today-reminders": {
304
- check: true,
305
- description: "Allows the user to view the today's reminders widget.",
306
- },
307
- "view-today-attentions": {
308
- check: true,
309
- description: "Allows the user to view the today's attentions widget.",
310
- },
311
- "view-work-order-status": {
312
- check: true,
313
- description: "Allows the user to view the work order status widget.",
314
- },
315
- "view-active-patrol": {
316
- check: true,
317
- description: "Allows the user to view the active patrol widget.",
318
- },
319
- }
282
+
320
283
 
321
284
  return {
322
285
  invitationPermissions,
@@ -329,6 +292,6 @@ export function useCommonPermissions() {
329
292
  buildingUnitManagementPermissions,
330
293
  bulletinBoardPermissions,
331
294
  siteSettingsPermissions,
332
- dashboardPermissions
295
+
333
296
  };
334
297
  }
@@ -76,6 +76,25 @@ export default function useDocument() {
76
76
  return add({ ...value, type: "folder" });
77
77
  }
78
78
 
79
+ function updateFolderById(id: string, value: any) {
80
+ return useNuxtApp().$api<Record<string, any>>(
81
+ `/api/documents/folder/${id}`,
82
+ {
83
+ method: "PUT",
84
+ body: value,
85
+ }
86
+ );
87
+ }
88
+
89
+ function deleteFolderById(id: string) {
90
+ return useNuxtApp().$api<Record<string, any>>(
91
+ `/api/documents/folder/${id}`,
92
+ {
93
+ method: "DELETE",
94
+ }
95
+ );
96
+ }
97
+
79
98
  return {
80
99
  getAll,
81
100
  getById,
@@ -85,5 +104,7 @@ export default function useDocument() {
85
104
  getDocumentsBySiteId,
86
105
  create,
87
106
  createFolder,
107
+ updateFolderById,
108
+ deleteFolderById,
88
109
  };
89
110
  }