@7365admin1/layer-common 1.8.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.
Files changed (198) hide show
  1. package/.changeset/README.md +8 -0
  2. package/.changeset/config.json +11 -0
  3. package/.editorconfig +12 -0
  4. package/.github/workflows/main.yml +17 -0
  5. package/.github/workflows/publish.yml +39 -0
  6. package/.nuxtrc +1 -0
  7. package/.playground/app.vue +41 -0
  8. package/.playground/eslint.config.mjs +6 -0
  9. package/.playground/nuxt.config.ts +22 -0
  10. package/.playground/pages/feedback.vue +30 -0
  11. package/CHANGELOG.md +263 -0
  12. package/README.md +73 -0
  13. package/app.vue +3 -0
  14. package/components/AccessCardAddForm.vue +363 -0
  15. package/components/AccessManagement.vue +420 -0
  16. package/components/Avatar/Main.vue +68 -0
  17. package/components/BillingMain.vue +66 -0
  18. package/components/BtnUploadFile.vue +139 -0
  19. package/components/BuildingForm.vue +303 -0
  20. package/components/BuildingManagement/buildings.vue +335 -0
  21. package/components/BuildingManagement/units.vue +350 -0
  22. package/components/BuildingUnitFormAdd.vue +441 -0
  23. package/components/BuildingUnitFormEdit.vue +429 -0
  24. package/components/CameraForm.vue +264 -0
  25. package/components/CameraMain.vue +352 -0
  26. package/components/Card/DeleteConfirmation.vue +51 -0
  27. package/components/Card/MemberInfoSummary.vue +44 -0
  28. package/components/Card/Toggle.vue +25 -0
  29. package/components/Chat/Bubbles.vue +53 -0
  30. package/components/Chat/Information.vue +416 -0
  31. package/components/Chat/ListCard.vue +62 -0
  32. package/components/Chat/Message.vue +158 -0
  33. package/components/Chat/Navigation.vue +150 -0
  34. package/components/ConfirmDialog.vue +66 -0
  35. package/components/Container/Standard.vue +33 -0
  36. package/components/DashboardPlaceholder.vue +1524 -0
  37. package/components/Dialog/DeleteConfirmation.vue +51 -0
  38. package/components/Dialog/ReplaceAutofillPrompt.vue +49 -0
  39. package/components/Dialog/UpdateMoreAction.vue +103 -0
  40. package/components/DocumentForm.vue +187 -0
  41. package/components/DocumentManagement.vue +376 -0
  42. package/components/Editor.vue +95 -0
  43. package/components/EntryPassMain.vue +518 -0
  44. package/components/Feedback/Form.vue +173 -0
  45. package/components/FeedbackDetail.vue +599 -0
  46. package/components/FeedbackMain.vue +588 -0
  47. package/components/FormDialog.vue +65 -0
  48. package/components/ImageCarousel.vue +138 -0
  49. package/components/Input/Date.vue +177 -0
  50. package/components/Input/DateTimePicker.vue +131 -0
  51. package/components/Input/File.vue +236 -0
  52. package/components/Input/FileV2.vue +234 -0
  53. package/components/Input/InputPhoneNumberV2.vue +164 -0
  54. package/components/Input/ListGroupSelection.vue +96 -0
  55. package/components/Input/NRICNumber.vue +53 -0
  56. package/components/Input/NewDate.vue +123 -0
  57. package/components/Input/Number.vue +124 -0
  58. package/components/Input/Password.vue +22 -0
  59. package/components/Input/PhoneNumber.vue +188 -0
  60. package/components/Input/VehicleNumber.vue +49 -0
  61. package/components/InputLabel.vue +22 -0
  62. package/components/InvitationForm.vue +359 -0
  63. package/components/InvitationMain.vue +310 -0
  64. package/components/Layout/Header.vue +129 -0
  65. package/components/Layout/NavigationDrawer.vue +44 -0
  66. package/components/ListItem.vue +35 -0
  67. package/components/ListView.vue +87 -0
  68. package/components/LocalPagination.vue +31 -0
  69. package/components/MemberMain.vue +459 -0
  70. package/components/NFC/NFCPatrolReportMain.vue +591 -0
  71. package/components/NFC/NFCPatrolRouteForm.vue +596 -0
  72. package/components/NFC/NFCPatrolRouteMain.vue +539 -0
  73. package/components/NFC/NFCTagForm.vue +236 -0
  74. package/components/NFC/NFCTagMain.vue +337 -0
  75. package/components/NFC/PatrolSettings.vue +130 -0
  76. package/components/NavigationItem.vue +83 -0
  77. package/components/NumberSettingField.vue +107 -0
  78. package/components/OnlineFormConfigurationForm.vue +290 -0
  79. package/components/OnlineFormsConfiguration.vue +429 -0
  80. package/components/PeopleForm.vue +452 -0
  81. package/components/PlaceholderComponent.vue +34 -0
  82. package/components/RolePermissionFormCreate.vue +161 -0
  83. package/components/RolePermissionFormPreviewUpdate.vue +183 -0
  84. package/components/RolePermissionMain.vue +361 -0
  85. package/components/SearchVehicleNumberUser.vue +91 -0
  86. package/components/ServiceProviderFormCreate.vue +154 -0
  87. package/components/ServiceProviderMain.vue +547 -0
  88. package/components/SignaturePad.vue +73 -0
  89. package/components/Snackbar.vue +23 -0
  90. package/components/SpecificAttr.vue +53 -0
  91. package/components/SupplyManagement.vue +292 -0
  92. package/components/SwitchContext.vue +108 -0
  93. package/components/TableList.vue +150 -0
  94. package/components/TableListSecondary.vue +164 -0
  95. package/components/TableMain.vue +142 -0
  96. package/components/TableWithButton.vue +94 -0
  97. package/components/VehicleUpdateMoreAction.vue +84 -0
  98. package/components/VideoPlayer.vue +125 -0
  99. package/components/VisitorForm.vue +659 -0
  100. package/components/VisitorFormSelection.vue +53 -0
  101. package/components/VisitorManagement.vue +490 -0
  102. package/components/WorkOrder/Create.vue +284 -0
  103. package/components/WorkOrder/Detail.vue +71 -0
  104. package/components/WorkOrder/ListView.vue +96 -0
  105. package/components/WorkOrder/Main.vue +489 -0
  106. package/components/Workorder.vue +1 -0
  107. package/composables/useAddress.ts +107 -0
  108. package/composables/useBuilding.ts +250 -0
  109. package/composables/useBuildingUnit.ts +116 -0
  110. package/composables/useCard.ts +46 -0
  111. package/composables/useCommonPermission.ts +207 -0
  112. package/composables/useCustomer.ts +113 -0
  113. package/composables/useCustomerSite.ts +56 -0
  114. package/composables/useDashboard.ts +31 -0
  115. package/composables/useDashboardData.ts +425 -0
  116. package/composables/useDocument.ts +57 -0
  117. package/composables/useFacility.ts +246 -0
  118. package/composables/useFeedback.ts +119 -0
  119. package/composables/useFile.ts +55 -0
  120. package/composables/useInvoice.ts +18 -0
  121. package/composables/useLocal.ts +131 -0
  122. package/composables/useLocalAuth.ts +137 -0
  123. package/composables/useLocalSetup.ts +13 -0
  124. package/composables/useMember.ts +111 -0
  125. package/composables/useNFCPatrolRoute.ts +77 -0
  126. package/composables/useNFCPatrolSettings.ts +19 -0
  127. package/composables/useNFCPatrolTag.ts +53 -0
  128. package/composables/useOnlineForm.ts +67 -0
  129. package/composables/useOrg.ts +129 -0
  130. package/composables/usePDFDownload.ts +25 -0
  131. package/composables/usePaymentMethod.ts +101 -0
  132. package/composables/usePeople.ts +81 -0
  133. package/composables/usePermission.ts +54 -0
  134. package/composables/usePhoneCountries.ts +561 -0
  135. package/composables/usePrice.ts +15 -0
  136. package/composables/usePromoCode.ts +36 -0
  137. package/composables/useRecapPermission.ts +26 -0
  138. package/composables/useRole.ts +104 -0
  139. package/composables/useSecurityUtils.ts +18 -0
  140. package/composables/useServiceProvider.ts +224 -0
  141. package/composables/useSite.ts +109 -0
  142. package/composables/useSiteEntryPassSettings.ts +46 -0
  143. package/composables/useSiteSettings.ts +123 -0
  144. package/composables/useSubscription.ts +150 -0
  145. package/composables/useUser.ts +132 -0
  146. package/composables/useUtils.ts +445 -0
  147. package/composables/useVerification.ts +34 -0
  148. package/composables/useVisitor.ts +120 -0
  149. package/composables/useWorkOrder.ts +85 -0
  150. package/error.vue +41 -0
  151. package/layouts/plain.vue +7 -0
  152. package/middleware/01.auth.ts +20 -0
  153. package/middleware/02.org.ts +21 -0
  154. package/middleware/03.customer.ts +13 -0
  155. package/middleware/member.ts +4 -0
  156. package/nuxt.config.ts +54 -0
  157. package/package.json +39 -0
  158. package/pages/index.vue +3 -0
  159. package/pages/payment-method-linked.vue +31 -0
  160. package/pages/require-customer.vue +56 -0
  161. package/pages/require-organization-membership.vue +47 -0
  162. package/pages/unauthorized.vue +29 -0
  163. package/plugins/API.ts +21 -0
  164. package/plugins/iconify.client.ts +5 -0
  165. package/plugins/secure-member.client.ts +86 -0
  166. package/plugins/vuetify.ts +62 -0
  167. package/public/bg-camera.jpg +0 -0
  168. package/public/bg-city.jpg +0 -0
  169. package/public/bg-condo.jpg +0 -0
  170. package/public/images/icons/delete-icon.png +0 -0
  171. package/public/sprite.svg +1 -0
  172. package/tsconfig.json +3 -0
  173. package/types/address.d.ts +13 -0
  174. package/types/building.d.ts +27 -0
  175. package/types/camera.d.ts +31 -0
  176. package/types/card.d.ts +22 -0
  177. package/types/customer.d.ts +27 -0
  178. package/types/document.d.ts +6 -0
  179. package/types/feedback.d.ts +68 -0
  180. package/types/local.d.ts +74 -0
  181. package/types/member.d.ts +21 -0
  182. package/types/online-form.d.ts +15 -0
  183. package/types/org.d.ts +13 -0
  184. package/types/people.d.ts +24 -0
  185. package/types/permission.d.ts +25 -0
  186. package/types/phone-number.d.ts +10 -0
  187. package/types/price.d.ts +17 -0
  188. package/types/promo-code.d.ts +19 -0
  189. package/types/role.d.ts +11 -0
  190. package/types/select.d.ts +4 -0
  191. package/types/service-provider.d.ts +15 -0
  192. package/types/site.d.ts +20 -0
  193. package/types/subscription.d.ts +23 -0
  194. package/types/user.d.ts +19 -0
  195. package/types/verification.d.ts +20 -0
  196. package/types/visitor.d.ts +42 -0
  197. package/types/work-order.d.ts +42 -0
  198. package/utils/phoneMasks.ts +1703 -0
@@ -0,0 +1,352 @@
1
+ <template>
2
+ <v-row no-gutters>
3
+ <v-col cols="12">
4
+ <v-card width="100%" variant="outlined" border="thin" rounded="lg">
5
+ <v-toolbar density="compact" color="grey-lighten-4 pl-2 pr-4">
6
+ <template #prepend>
7
+ <v-btn fab icon density="comfortable" @click="getCameraRefresh()">
8
+ <v-icon>mdi-refresh</v-icon>
9
+ </v-btn>
10
+ </template>
11
+
12
+ <template #append>
13
+ <v-btn
14
+ variant="flat"
15
+ color="primary"
16
+ class="text-none"
17
+ @click="dialogAdd = true"
18
+ >
19
+ Add
20
+ </v-btn>
21
+ </template>
22
+ </v-toolbar>
23
+
24
+ <v-card-text class="pa-0 bg-red">
25
+ <v-data-table
26
+ :headers="prop.headers"
27
+ :items="items"
28
+ fixed-header
29
+ hide-default-footer
30
+ hide-default-header
31
+ @click:row="handleRowClick"
32
+ style="max-height: 300px"
33
+ >
34
+ </v-data-table>
35
+ </v-card-text>
36
+
37
+ <v-toolbar density="compact" color="grey-lighten-4">
38
+ <template #append>
39
+ <v-row no-gutters justify="end" align="center">
40
+ <span class="mr-2 text-caption text-font gray">
41
+ {{ pageRange }}
42
+ </span>
43
+ <local-pagination
44
+ v-model="page"
45
+ :length="pages"
46
+ @update:value="$emit('update:value', $event)"
47
+ />
48
+ </v-row>
49
+ </template>
50
+ </v-toolbar>
51
+ </v-card>
52
+ </v-col>
53
+
54
+ <!-- dialog -->
55
+ <v-dialog v-model="dialogAdd" persistent width="450">
56
+ <CameraForm
57
+ title="Add Camera"
58
+ :site="prop.site"
59
+ :guard-posts="prop.guardPosts"
60
+ :type="prop.type"
61
+ @cancel="dialogAdd = false"
62
+ @success="handleSuccess"
63
+ />
64
+ </v-dialog>
65
+
66
+ <v-dialog v-model="dialogEdit" persistent width="450">
67
+ <CameraForm
68
+ title="Edit Camera"
69
+ :site="prop.site"
70
+ :guard-posts="prop.guardPosts"
71
+ :type="prop.type"
72
+ @cancel="dialogEdit = false"
73
+ @success="handleSuccess"
74
+ mode="edit"
75
+ :camera="camera"
76
+ />
77
+ </v-dialog>
78
+
79
+ <v-dialog v-model="dialogPreview" persistent width="540">
80
+ <v-card width="100%">
81
+ <v-toolbar>
82
+ <v-row no-gutters class="fill-height px-6" align="center">
83
+ <span class="font-weight-bold text-h5 text-capitalize">
84
+ Preview
85
+ </span>
86
+ </v-row>
87
+ </v-toolbar>
88
+
89
+ <v-card-text
90
+ style="max-height: 100vh; overflow-y: auto"
91
+ class="pa-5 my-5 px-7"
92
+ >
93
+ <v-row no-gutters>
94
+ <v-col cols="12" class="mb-2">
95
+ Host:
96
+ <span class="font-weight-bold">
97
+ {{ camera.host }}
98
+ </span>
99
+ </v-col>
100
+
101
+ <v-col cols="12" class="mb-2">
102
+ Username:
103
+ <span class="font-weight-bold">
104
+ {{ camera.username }}
105
+ </span>
106
+ </v-col>
107
+
108
+ <v-col cols="12" class="mb-2">
109
+ Password:
110
+ <span class="font-weight-bold">
111
+ {{ camera.password }}
112
+ </span>
113
+ </v-col>
114
+
115
+ <v-col cols="12" class="mb-2">
116
+ Type:
117
+ <span class="font-weight-bold">
118
+ {{ camera.type }}
119
+ </span>
120
+ </v-col>
121
+
122
+ <v-col cols="12" class="mb-2">
123
+ Category:
124
+ <span class="font-weight-bold">
125
+ {{ camera.category }}
126
+ </span>
127
+ </v-col>
128
+
129
+ <v-col v-if="camera.type === 'anpr'" cols="12" class="mb-2">
130
+ Direction:
131
+ <span class="font-weight-bold">
132
+ {{ camera.direction }}
133
+ </span>
134
+ </v-col>
135
+
136
+ <v-col v-if="camera.type === 'anpr'" cols="12">
137
+ Guard House:
138
+ <span class="font-weight-bold">
139
+ {{ camera.guardPost }}
140
+ </span>
141
+ </v-col>
142
+ </v-row>
143
+ </v-card-text>
144
+
145
+ <v-toolbar class="pa-0" density="compact">
146
+ <v-row no-gutters>
147
+ <v-col cols="6" class="pa-0">
148
+ <v-btn
149
+ block
150
+ variant="text"
151
+ class="text-none"
152
+ size="large"
153
+ @click="dialogPreview = false"
154
+ height="48"
155
+ >
156
+ Close
157
+ </v-btn>
158
+ </v-col>
159
+
160
+ <v-col cols="6" class="pa-0">
161
+ <v-menu>
162
+ <template #activator="{ props }">
163
+ <v-btn
164
+ block
165
+ variant="flat"
166
+ color="black"
167
+ class="text-none"
168
+ height="48"
169
+ v-bind="props"
170
+ tile
171
+ >
172
+ More actions
173
+ </v-btn>
174
+ </template>
175
+
176
+ <v-list class="pa-0">
177
+ <v-list-item @click="openDialogEdit()">
178
+ <v-list-item-title class="text-subtitle-2">
179
+ Edit Building
180
+ </v-list-item-title>
181
+ </v-list-item>
182
+
183
+ <v-list-item @click="openDialogDelete()" class="text-red">
184
+ <v-list-item-title class="text-subtitle-2">
185
+ Delete Building
186
+ </v-list-item-title>
187
+ </v-list-item>
188
+ </v-list>
189
+ </v-menu>
190
+ </v-col>
191
+ </v-row>
192
+ </v-toolbar>
193
+ </v-card>
194
+ </v-dialog>
195
+
196
+ <v-dialog v-model="dialogDelete" persistent width="540">
197
+ <v-card width="100%">
198
+ <v-card-text
199
+ style="max-height: 100vh; overflow-y: auto"
200
+ class="pa-5 my-5 px-7 text-center"
201
+ >
202
+ Are you sure want to delete this {{ camera.type }} camera?
203
+ </v-card-text>
204
+
205
+ <v-toolbar class="pa-0" density="compact">
206
+ <v-row no-gutters>
207
+ <v-col cols="6" class="pa-0">
208
+ <v-btn
209
+ block
210
+ variant="text"
211
+ class="text-none"
212
+ size="large"
213
+ tile
214
+ @click="dialogDelete = false"
215
+ height="48"
216
+ >
217
+ Cancel
218
+ </v-btn>
219
+ </v-col>
220
+
221
+ <v-col cols="6" class="pa-0">
222
+ <v-btn
223
+ block
224
+ tile
225
+ variant="flat"
226
+ class="text-none"
227
+ size="large"
228
+ height="48"
229
+ color="black"
230
+ @click="submitDelete()"
231
+ >
232
+ Delete
233
+ </v-btn>
234
+ </v-col>
235
+ </v-row>
236
+ </v-toolbar>
237
+ </v-card>
238
+ </v-dialog>
239
+ </v-row>
240
+ </template>
241
+
242
+ <script setup lang="ts">
243
+ import type { PropType } from "vue";
244
+ import useSiteSettings from "../composables/useSiteSettings";
245
+
246
+ const events = defineEmits(["update:value", "row-click"]);
247
+
248
+ const prop = defineProps({
249
+ site: {
250
+ type: String,
251
+ required: true,
252
+ default: "site",
253
+ },
254
+ type: {
255
+ type: String as PropType<TSiteCamera["type"]>,
256
+ default: "anpr",
257
+ },
258
+ guardPosts: {
259
+ type: Number,
260
+ default: 0,
261
+ },
262
+ headers: {
263
+ type: Array as PropType<Array<any>>,
264
+ default: () => [
265
+ { text: "Host", value: "host" },
266
+ { text: "Category", value: "category" },
267
+ { text: "Guard House", value: "guardPost" },
268
+ { text: "Actions", value: "action", sortable: false },
269
+ ],
270
+ },
271
+ });
272
+
273
+ const items = ref<Array<TCamera>>([]);
274
+ const page = ref(1);
275
+ const pages = ref(0);
276
+ const pageRange = ref("-- - -- of --");
277
+
278
+ const { getAllSiteCameras, deleteSiteCameraById } = useSiteSettings();
279
+ const { data: getCameraReq, refresh: getCameraRefresh } =
280
+ await useLazyAsyncData(
281
+ `get-site-${prop.site}-${prop.type}-cameras`,
282
+ () =>
283
+ getAllSiteCameras({ site: prop.site, type: prop.type, page: page.value }),
284
+ {
285
+ watch: [page],
286
+ }
287
+ );
288
+
289
+ watchEffect(() => {
290
+ if (getCameraReq.value) {
291
+ items.value = getCameraReq.value.items;
292
+ pageRange.value = getCameraReq.value.pageRange;
293
+ pages.value = getCameraReq.value.pages;
294
+ }
295
+ });
296
+
297
+ const dialogAdd = ref(false);
298
+ const dialogEdit = ref(false);
299
+ const dialogPreview = ref(false);
300
+ const dialogDelete = ref(false);
301
+
302
+ function openDialogEdit() {
303
+ dialogEdit.value = true;
304
+
305
+ if (dialogPreview.value) dialogPreview.value = false;
306
+ }
307
+
308
+ function openDialogDelete() {
309
+ dialogDelete.value = true;
310
+
311
+ if (dialogPreview.value) dialogPreview.value = false;
312
+ }
313
+
314
+ function handleSuccess() {
315
+ if (dialogAdd.value) dialogAdd.value = false;
316
+
317
+ if (dialogEdit.value) dialogEdit.value = false;
318
+
319
+ if (dialogPreview.value) dialogPreview.value = false;
320
+
321
+ if (dialogDelete.value) dialogDelete.value = false;
322
+
323
+ getCameraRefresh();
324
+ }
325
+
326
+ const camera = ref<TSiteCamera>({
327
+ site: "",
328
+ host: "",
329
+ username: "",
330
+ password: "",
331
+ type: "ip",
332
+ category: "standard",
333
+ direction: "none",
334
+ guardPost: null,
335
+ status: "active",
336
+ });
337
+
338
+ function handleRowClick(_: any, data: any) {
339
+ dialogPreview.value = true;
340
+ camera.value = JSON.parse(JSON.stringify(data.item));
341
+ }
342
+
343
+ async function submitDelete() {
344
+ try {
345
+ await deleteSiteCameraById(camera.value._id ?? "");
346
+ await getCameraRefresh();
347
+ dialogDelete.value = false;
348
+ } catch (error) {
349
+ console.error("Error deleting camera:", error);
350
+ }
351
+ }
352
+ </script>
@@ -0,0 +1,51 @@
1
+ <template>
2
+ <v-card width="100%" :disabled="loading" :loading="loading">
3
+ <v-card-text style="max-height: 100vh; overflow-y: auto" class="pa-5 my-5 px-7 text-center">
4
+ <span> {{ promptTitle }}</span>
5
+
6
+ <span v-if="message" class="text-error mt-2">
7
+ {{ message }} Do you want to delete anyway?
8
+ </span>
9
+ </v-card-text>
10
+
11
+ <v-toolbar class="pa-0" density="compact">
12
+ <v-row no-gutters>
13
+ <v-col cols="6" class="pa-0">
14
+ <v-btn block variant="text" class="text-none" size="large" tile @click="emit('close')"
15
+ height="48">
16
+ Cancel
17
+ </v-btn>
18
+ </v-col>
19
+
20
+ <v-col cols="6" class="pa-0">
21
+ <v-btn block tile variant="flat" class="text-none" size="large" height="48" color="black"
22
+ @click="emit('delete')">
23
+ Delete
24
+ </v-btn>
25
+ </v-col>
26
+ </v-row>
27
+ </v-toolbar>
28
+ </v-card>
29
+ </template>
30
+
31
+ <script setup lang="ts">
32
+ const props = defineProps({
33
+ message: {
34
+ type: String,
35
+ default: ""
36
+ },
37
+ promptTitle: {
38
+ type: String,
39
+ default: "Are you sure want to delete this? "
40
+ },
41
+ loading: {
42
+ type: Boolean,
43
+ default: false
44
+ }
45
+ })
46
+
47
+ const emit = defineEmits(["close", "delete"])
48
+
49
+ </script>
50
+
51
+ <style scoped></style>
@@ -0,0 +1,44 @@
1
+ <template>
2
+ <v-card flat border="sm grey-lighten-2" color="grey-lighten-3" class="w-100">
3
+ <v-card-text>
4
+ <v-row no-gutters>
5
+ <v-col cols="10" no-gutters>
6
+ <v-row no-gutters class="ga-1">
7
+ <template v-for="(label, key) in displayFields" :key="key">
8
+ <v-col v-if="member[key]" cols="12">
9
+ <span class="d-flex ga-3 align-center"><strong>{{ label }}:</strong> {{ member[key]
10
+ }}</span>
11
+ </v-col>
12
+ </template>
13
+ </v-row>
14
+ </v-col>
15
+ <v-col cols="2" class="d-flex align-center justify-center">
16
+ <v-btn icon="mdi-trash-outline" size="small" color="red" @click="emit('remove')" />
17
+ </v-col>
18
+ </v-row>
19
+ </v-card-text>
20
+ </v-card>
21
+ </template>
22
+
23
+ <script setup lang="ts">
24
+
25
+ const prop = defineProps({
26
+ member: {
27
+ type: Object as PropType<TMemberInfo>,
28
+ required: true
29
+ }
30
+ })
31
+
32
+ const emit = defineEmits(['remove'])
33
+
34
+
35
+ const displayFields: Record<keyof TMemberInfo, string> = {
36
+ name: "Name",
37
+ nric: "NRIC",
38
+ visitorPass: "Pass",
39
+ contact: "Contact"
40
+ } as const
41
+
42
+ </script>
43
+
44
+ <style scoped></style>
@@ -0,0 +1,25 @@
1
+ <template>
2
+ <v-card flat border="md black">
3
+ <v-card-text class="d-flex justify-space-between align-center py-0">
4
+ <p>{{ label }}</p>
5
+ <v-switch v-model="toggle" :color="toggleColor" hide-details />
6
+ </v-card-text>
7
+ </v-card>
8
+ </template>
9
+
10
+ <script setup lang="ts">
11
+ defineProps({
12
+ label: {
13
+ type: String,
14
+ default: "Enable"
15
+ },
16
+ toggleColor: {
17
+ type: String,
18
+ default: 'primary'
19
+ }
20
+ })
21
+
22
+ const toggle = defineModel({default: false})
23
+ </script>
24
+
25
+ <style scoped></style>
@@ -0,0 +1,53 @@
1
+ <template>
2
+ <v-card class="mb-2 pa-4 rounded-lg" width="400" elevation="2">
3
+ <v-row no-gutters align="center">
4
+ <v-col cols="auto" class="mr-3">
5
+ <v-avatar color="surface-variant" size="35">
6
+ <v-img v-if="currentUser?.profile" width="15" height="15" />
7
+ <span v-else class="text-h5">{{ getNameInitials(senderName) }}</span>
8
+ </v-avatar>
9
+ </v-col>
10
+
11
+ <v-col class="d-flex flex-column">
12
+ <span class="text-body-2 font-weight-medium">{{ senderName }}</span>
13
+ <span class="text-caption text-grey">{{ role }}</span>
14
+ </v-col>
15
+ </v-row>
16
+
17
+ <v-row no-gutters class="mt-1">
18
+ <v-col>
19
+ <span class="py-2">{{ message }}</span>
20
+
21
+ <v-row no-gutters justify="space-between" align="center" class="mt-1">
22
+ <v-col cols="auto">
23
+ <span class="text-caption">{{ timestamp }}</span>
24
+ </v-col>
25
+ <v-col
26
+ v-if="isCurrentUser"
27
+ cols="auto"
28
+ class="d-flex align-center bg-grey-200"
29
+ >
30
+ <v-icon size="16" class="mr-1 text--secondary"
31
+ >mdi-eye-outline</v-icon
32
+ >
33
+ <span class="text-caption text--secondary">{{ seenLabel }}</span>
34
+ </v-col>
35
+ </v-row>
36
+ </v-col>
37
+ </v-row>
38
+ </v-card>
39
+ </template>
40
+
41
+ <script setup lang="ts">
42
+ defineProps<{
43
+ isCurrentUser: boolean;
44
+ message: string;
45
+ timestamp: string;
46
+ seenLabel?: string;
47
+ senderName: string;
48
+ role?: string;
49
+ }>();
50
+
51
+ const { currentUser } = useLocalAuth();
52
+ const { getNameInitials } = useUtils();
53
+ </script>