@7365admin1/layer-common 3.2.7 → 3.2.8-staging.201

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 (283) hide show
  1. package/assets/css/primitives.css +1113 -0
  2. package/assets/css/screens.css +1097 -0
  3. package/assets/css/shell.css +258 -0
  4. package/assets/css/tokens.css +236 -0
  5. package/components/AcceptDialog.vue +17 -18
  6. package/components/AccessCard/AvailableStats.vue +24 -16
  7. package/components/AccessCardAddForm.vue +42 -42
  8. package/components/AccessCardAssignToUnitForm.vue +13 -21
  9. package/components/AccessCardDeleteDialog.vue +41 -39
  10. package/components/AccessCardDetailsDialog.vue +125 -79
  11. package/components/AccessCardPreviewDialog.vue +58 -84
  12. package/components/AccessCardQrTagging.vue +60 -63
  13. package/components/AccessCardReplaceForm.vue +27 -23
  14. package/components/AccessManagement.vue +86 -85
  15. package/components/AddEqupmentForm.vue +18 -22
  16. package/components/AddPassKeyToVisitor.vue +95 -73
  17. package/components/AppButton.vue +62 -0
  18. package/components/AppCard.vue +20 -0
  19. package/components/AppDateField.vue +49 -0
  20. package/components/AppField.vue +76 -0
  21. package/components/AppKpiTile.vue +65 -0
  22. package/components/AppSegmented.vue +38 -0
  23. package/components/AppSelect.vue +247 -0
  24. package/components/AreaChecklistHistoryLogs.vue +51 -44
  25. package/components/AreaChecklistHistoryMain.vue +14 -7
  26. package/components/AreaFormDialog.vue +71 -59
  27. package/components/AreaMain.vue +73 -107
  28. package/components/AttachmentsViewer.vue +84 -22
  29. package/components/AttendanceCheckInOutDialog.vue +85 -88
  30. package/components/AttendanceDetailsDialog.vue +57 -63
  31. package/components/AttendanceMain.vue +4 -3
  32. package/components/AttendanceMapSearchDialog.vue +42 -44
  33. package/components/AttendanceSettingsDialog.vue +79 -63
  34. package/components/Avatar/Main.vue +54 -2
  35. package/components/BillingMain.vue +26 -30
  36. package/components/BtnUploadFile.vue +53 -11
  37. package/components/BuildingForm.vue +34 -27
  38. package/components/BuildingManagement/buildings.vue +39 -39
  39. package/components/BuildingManagement/units.vue +26 -42
  40. package/components/BuildingUnitFormAdd.vue +20 -23
  41. package/components/BuildingUnitFormEdit.vue +8 -4
  42. package/components/BulletinBoardForm.vue +19 -24
  43. package/components/BulletinBoardManagement.vue +49 -57
  44. package/components/BulletinBoardView.vue +9 -6
  45. package/components/BulletinExpirationChip.vue +13 -4
  46. package/components/Button/Close.vue +2 -2
  47. package/components/CameraForm.vue +21 -22
  48. package/components/CameraMain.vue +50 -49
  49. package/components/Card/DeleteConfirmation.vue +24 -22
  50. package/components/Card/MemberInfoSummary.vue +28 -3
  51. package/components/Card/Toggle.vue +15 -3
  52. package/components/CardToolbar.vue +37 -0
  53. package/components/Carousel.vue +56 -36
  54. package/components/Chat/Bubbles.vue +43 -14
  55. package/components/Chat/Information.vue +49 -32
  56. package/components/Chat/ListCard.vue +38 -9
  57. package/components/Chat/Message.vue +41 -15
  58. package/components/Chat/Navigation.vue +27 -15
  59. package/components/Chat/SkeletonLoader.vue +9 -2
  60. package/components/ChecklistItemRow.vue +25 -1
  61. package/components/CleaningScheduleMain.vue +44 -49
  62. package/components/ClientDetailForm.vue +81 -56
  63. package/components/ClientMain.vue +92 -82
  64. package/components/ConfirmDialog.vue +14 -8
  65. package/components/Container/Standard.vue +9 -7
  66. package/components/CreateSubsciptionPlan.vue +148 -89
  67. package/components/DashboardEmptyState.vue +48 -3
  68. package/components/DashboardMain.vue +924 -676
  69. package/components/DashboardPanel.vue +84 -21
  70. package/components/DeliveryCompany.vue +34 -20
  71. package/components/Dialog/DeleteConfirmation.vue +20 -21
  72. package/components/Dialog/ReplaceAutofillPrompt.vue +19 -26
  73. package/components/Dialog/ReusablePrompt.vue +30 -29
  74. package/components/Dialog/UpdateMoreAction.vue +62 -59
  75. package/components/DocumentForm.vue +14 -21
  76. package/components/DocumentManagement.vue +162 -108
  77. package/components/DocumentViewer.vue +29 -12
  78. package/components/DrawImage.vue +29 -21
  79. package/components/EntryPass/QrTemplatePreview.vue +27 -16
  80. package/components/EntryPassInformation.vue +40 -10
  81. package/components/EntryPassMain.vue +49 -27
  82. package/components/EquipmentItemMain.vue +84 -97
  83. package/components/EquipmentManagementMain.vue +81 -103
  84. package/components/Facility/BookingSetup.vue +43 -52
  85. package/components/Feedback/Form.vue +26 -12
  86. package/components/FeedbackMain.vue +35 -49
  87. package/components/FileInput.vue +75 -58
  88. package/components/FileInputWithList.vue +59 -12
  89. package/components/FormDialog.vue +60 -21
  90. package/components/HidAccessLogDashboard.vue +512 -490
  91. package/components/HidCameraCaptureDialog.vue +216 -0
  92. package/components/HidEnabledGate.vue +67 -9
  93. package/components/HidIntercomManagement.vue +1322 -653
  94. package/components/HidQrCodeConfiguration.vue +1030 -258
  95. package/components/HidReaderForm.vue +142 -59
  96. package/components/HidReaderManagement.vue +211 -323
  97. package/components/HidServiceSettingsPanel.vue +44 -13
  98. package/components/HidUserEnrollment.vue +1185 -412
  99. package/components/HygieneUpdateMoreAction.vue +44 -44
  100. package/components/IncidentReport/Authorities.vue +30 -18
  101. package/components/IncidentReport/IncidentInformation.vue +10 -10
  102. package/components/IncidentReport/IncidentInformationDownload.vue +3 -4
  103. package/components/IncidentReport/affectedEntities.vue +41 -20
  104. package/components/Input/Date.vue +3 -0
  105. package/components/Input/DatePicker.vue +1 -2
  106. package/components/Input/DateTimePicker.vue +1 -1
  107. package/components/Input/File.vue +55 -10
  108. package/components/Input/FileV2.vue +39 -6
  109. package/components/Input/InputPhoneNumberV2.vue +2 -1
  110. package/components/Input/ListGroupSelection.vue +56 -8
  111. package/components/Input/NRICNumber.vue +1 -0
  112. package/components/Input/NewDate.vue +1 -0
  113. package/components/Input/Number.vue +1 -0
  114. package/components/Input/Password.vue +1 -0
  115. package/components/Input/PhoneNumber.vue +21 -1
  116. package/components/Input/VehicleNumber.vue +1 -0
  117. package/components/InputLabel.vue +2 -2
  118. package/components/InvitationClientForm.vue +21 -19
  119. package/components/InvitationForm.vue +15 -21
  120. package/components/InvitationMain.vue +46 -61
  121. package/components/Layout/Header.vue +263 -36
  122. package/components/Layout/NavigationDrawer.vue +300 -30
  123. package/components/ListItem.vue +33 -3
  124. package/components/LocalPagination.vue +27 -3
  125. package/components/ManageChecklistMain.vue +136 -86
  126. package/components/MemberInformation.vue +32 -16
  127. package/components/MemberMain.vue +113 -93
  128. package/components/MyAttendanceMain.vue +3 -5
  129. package/components/NavigationItem.vue +83 -3
  130. package/components/Nfc/NFCPatrolReportMain.vue +47 -33
  131. package/components/Nfc/NFCPatrolRouteForm.vue +18 -20
  132. package/components/Nfc/NFCPatrolRouteMain.vue +116 -103
  133. package/components/Nfc/NFCPatrolSettings.vue +14 -4
  134. package/components/Nfc/NFCTagForm.vue +22 -8
  135. package/components/Nfc/NFCTagMain.vue +41 -43
  136. package/components/Nfc/PatrolReport/DailyReportTab.vue +8 -1
  137. package/components/Nfc/PatrolReport/MonthlyReportTab.vue +8 -1
  138. package/components/Nfc/PatrolReport/MonthlyReportTable.vue +5 -3
  139. package/components/Nfc/PatrolReport/PatrolActivityTable.vue +26 -6
  140. package/components/Nfc/PatrolReport/PatrolReportTab.vue +8 -0
  141. package/components/Nfc/PatrolReport/PatrolRouteSummary.vue +41 -9
  142. package/components/Nfc/PatrolReport/RemarksDialog.vue +39 -9
  143. package/components/Nfc/PatrolReport/ReportEmptyState.vue +29 -9
  144. package/components/Nfc/PatrolReport/ReportFilters.vue +19 -10
  145. package/components/Nfc/PatrolReport/ReportLocationHeader.vue +32 -6
  146. package/components/Nfc/PatrolReport/SummaryReportTable.vue +28 -6
  147. package/components/NotificationSettings.vue +373 -0
  148. package/components/NumberSettingField.vue +9 -2
  149. package/components/OnlineFormConfigurationForm.vue +725 -237
  150. package/components/OnlineFormFill.vue +213 -106
  151. package/components/OnlineFormRenderPreview.vue +25 -30
  152. package/components/OnlineFormsConfiguration.vue +113 -109
  153. package/components/OrgViewDialog.vue +34 -16
  154. package/components/OvernightParkingAvailability.vue +49 -26
  155. package/components/OvernightParkingManagement.vue +78 -18
  156. package/components/PageHeader.vue +43 -0
  157. package/components/PassInformation.vue +109 -53
  158. package/components/PasswordConfirmation.vue +44 -26
  159. package/components/PeopleForm.vue +41 -20
  160. package/components/PhotoUpload.vue +110 -48
  161. package/components/PlaceholderComponent.vue +35 -19
  162. package/components/PlanActionsMenu.vue +12 -2
  163. package/components/PlanStatusBadge.vue +7 -8
  164. package/components/PlateNumberDisplay.vue +9 -6
  165. package/components/QrTemplate/PrintDialog.vue +66 -43
  166. package/components/RolePermissionFormCreate.vue +104 -79
  167. package/components/RolePermissionFormPreviewUpdate.vue +111 -109
  168. package/components/RolePermissionMain.vue +183 -81
  169. package/components/ScanVisitorQRCode.vue +99 -35
  170. package/components/ScheduleAreaMain.vue +34 -59
  171. package/components/ScheduleTaskForm.vue +61 -42
  172. package/components/ScheduleTaskMain.vue +56 -69
  173. package/components/SearchVehicleNumberUser.vue +39 -37
  174. package/components/ServiceProviderFormCreate.vue +29 -20
  175. package/components/ServiceProviderInvitationPrompt.vue +155 -0
  176. package/components/ServiceProviderMain.vue +601 -432
  177. package/components/Signature.vue +40 -34
  178. package/components/SignaturePad.vue +5 -29
  179. package/components/SiteSettings.vue +41 -11
  180. package/components/SiteSettingsWorkOrder.vue +61 -30
  181. package/components/SlideCardGroup.vue +35 -11
  182. package/components/Snackbar.vue +36 -3
  183. package/components/SpecificAttr.vue +18 -8
  184. package/components/StatusChip.vue +156 -0
  185. package/components/StockCard.vue +17 -12
  186. package/components/SubscriptionPlanTable.vue +207 -140
  187. package/components/SwitchContext.vue +201 -9
  188. package/components/TableHygiene.vue +36 -46
  189. package/components/TableList.vue +10 -10
  190. package/components/TableListSecondary.vue +105 -54
  191. package/components/TableMain.vue +251 -78
  192. package/components/TableV3.vue +61 -70
  193. package/components/TiptapEditor.vue +33 -40
  194. package/components/TiptapEditorQr.vue +5 -2
  195. package/components/Tooltip/Info.vue +69 -24
  196. package/components/UnitMain.vue +40 -60
  197. package/components/UnitPersonCard.vue +42 -13
  198. package/components/VehicleAddSelection.vue +48 -32
  199. package/components/VehicleForm.vue +112 -129
  200. package/components/VehicleManagement.vue +26 -12
  201. package/components/VehicleUpdateMoreAction.vue +59 -46
  202. package/components/VisitorDataFromScannedQRCodeForm.vue +90 -65
  203. package/components/VisitorForm.vue +774 -210
  204. package/components/VisitorFormSelection.vue +40 -37
  205. package/components/VisitorManagement.vue +239 -82
  206. package/components/VisitorPassKeyQRScanner.vue +65 -18
  207. package/components/VisitorSearchResultSummary.vue +60 -16
  208. package/components/VisitorSocketPopUp.vue +22 -14
  209. package/components/VisitorsReportPreview.vue +44 -29
  210. package/components/WorkOrder/Create.vue +26 -17
  211. package/components/WorkOrder/ListView.vue +38 -7
  212. package/components/WorkOrder/Main.vue +62 -59
  213. package/composables/useFeedback.ts +3 -3
  214. package/composables/useHidAmico.ts +269 -0
  215. package/composables/useHidNavigation.ts +2 -9
  216. package/composables/useMember.ts +3 -3
  217. package/composables/useNFCPatrolDailyReport.ts +13 -0
  218. package/composables/useNFCPatrolMonthlyReport.ts +22 -56
  219. package/composables/useNFCPatrolReport.ts +13 -0
  220. package/composables/useNotificationPreference.ts +87 -0
  221. package/composables/useOnlineFormPages.ts +2 -0
  222. package/composables/useRole.ts +22 -0
  223. package/composables/useServiceProvider.ts +3 -3
  224. package/composables/useServiceProviderInvitation.ts +145 -0
  225. package/composables/useSipWebPhone.ts +336 -0
  226. package/composables/useSubscriptionPlan.ts +62 -0
  227. package/composables/useThemePreference.ts +63 -0
  228. package/composables/useVisitor.ts +6 -1
  229. package/composables/useWebUsb.ts +127 -37
  230. package/composables/useWorkOrder.ts +17 -3
  231. package/error.vue +30 -6
  232. package/nuxt.config.ts +36 -0
  233. package/package.json +25 -4
  234. package/pages/[org]/[site]/access-mgmt/administrator/index.vue +2 -2
  235. package/pages/[org]/[site]/access-mgmt/{identity-mapping → hid-cards}/index.vue +2 -2
  236. package/pages/[org]/[site]/access-mgmt/intercom/index.vue +1 -1
  237. package/pages/notification-settings.vue +19 -0
  238. package/pages/payment-method-linked.vue +34 -10
  239. package/pages/require-customer.vue +48 -10
  240. package/pages/require-organization-membership.vue +32 -8
  241. package/pages/unauthorized.vue +29 -4
  242. package/plugins/secure-member.client.ts +21 -56
  243. package/plugins/vuetify.ts +69 -2
  244. package/types/nfc-patrol-report.ts +3 -2
  245. package/types/site.d.ts +71 -0
  246. package/types/subscription.ts +18 -11
  247. package/utils/breadcrumb.test.ts +108 -0
  248. package/utils/breadcrumb.ts +82 -0
  249. package/utils/dashboard.test.ts +118 -0
  250. package/utils/dashboard.ts +53 -0
  251. package/utils/data.test.ts +95 -0
  252. package/utils/data.ts +40 -2
  253. package/utils/hid-discover.test.ts +102 -0
  254. package/utils/list-page.test.ts +60 -0
  255. package/utils/list-page.ts +38 -0
  256. package/utils/materialSymbols.ts +363 -0
  257. package/utils/nav-sections.test.ts +190 -0
  258. package/utils/nav-sections.ts +151 -0
  259. package/utils/nfc-patrol-report.test.ts +130 -0
  260. package/utils/nfc-patrol-report.ts +101 -0
  261. package/utils/role.test.ts +69 -0
  262. package/utils/role.ts +10 -0
  263. package/utils/route-name.test.ts +85 -0
  264. package/utils/route-name.ts +24 -0
  265. package/utils/status.test.ts +110 -0
  266. package/utils/status.ts +135 -0
  267. package/utils/table-card.test.ts +84 -0
  268. package/utils/theme-aa-ledger.ts +148 -0
  269. package/utils/theme.test.ts +485 -7
  270. package/utils/theme.ts +295 -110
  271. package/.changeset/README.md +0 -8
  272. package/.changeset/config.json +0 -11
  273. package/.editorconfig +0 -12
  274. package/.github/workflows/main.yml +0 -17
  275. package/.github/workflows/publish-staging.yml +0 -47
  276. package/.github/workflows/publish.yml +0 -39
  277. package/PUBLISHING.md +0 -269
  278. package/components/HidIdentityMapping.vue +0 -975
  279. package/components/ScheduleTaskAreaFormDialog.vue +0 -144
  280. package/components/ScheduleTaskAreaUpdateMoreAction.vue +0 -109
  281. package/components/ScheduleTastTicketMain.vue +0 -182
  282. package/components/TableWithButton.vue +0 -94
  283. package/test/visitor-socket.test.mjs +0 -36
@@ -9,36 +9,27 @@
9
9
  >
10
10
  <v-container class="d-flex justify-center" max-height="90vh">
11
11
  <!-- QR code reader container -->
12
- <v-card
13
- elevation="2"
14
- class="d-flex flex-column align-center pa-2 w-100 h-100"
15
- >
16
- <v-toolbar>
17
- <v-card-title class="text-h5"> Scan QR Code </v-card-title>
18
- <v-spacer />
19
- <v-btn
20
- color="grey-darken-1"
21
- icon="mdi-close"
22
- @click="closeDialog()"
23
- />
24
- </v-toolbar>
25
-
26
- <div
27
- id="reader"
28
- class="d-flex justify-center align-center w-100 h-100"
29
- style="height: calc(100vh - 64px)"
30
- >
31
- <!-- The QR code scanner box -->
32
- <!-- This is where the QR code scanner will be displayed -->
12
+ <v-card class="screen-modal qr-scanner">
13
+ <div class="qr-scanner__head">
14
+ <v-card-title>Scan QR Code</v-card-title>
15
+ <AppButton variant="icon" icon="mdi-close" @click="closeDialog()" />
33
16
  </div>
34
- <!-- Show Error Messages -->
35
- <div v-if="showNotFoundMessage" class="text-error mt-4 text-h5">
36
- <p>{{ errorMessage }}</p>
17
+
18
+ <div class="screen-modal__body qr-scanner__body">
19
+ <div id="reader" class="qr-scanner__reader">
20
+ <!-- The QR code scanner box -->
21
+ <!-- This is where the QR code scanner will be displayed -->
22
+ </div>
23
+ <!-- Show Error Messages -->
24
+ <p v-if="showNotFoundMessage" class="qr-scanner__error">{{ errorMessage }}</p>
25
+ <!-- Switch camera button inside the reader box -->
26
+ <AppButton
27
+ icon="mdi-camera-switch"
28
+ class="qr-scanner__switch"
29
+ aria-label="Switch camera"
30
+ @click="switchCamera()"
31
+ />
37
32
  </div>
38
- <!-- Switch camera button inside the reader box -->
39
- <v-btn color="primary" icon class="mt-4" @click="switchCamera()">
40
- <v-icon icon="mdi-camera-switch" large />
41
- </v-btn>
42
33
  </v-card>
43
34
  </v-container>
44
35
  </v-dialog>
@@ -60,7 +51,9 @@ const props = defineProps({
60
51
 
61
52
  const { standardFormatDate } = useUtils();
62
53
 
63
- const { validateVisitorQrCode } = useVisitor();
54
+ const { validateVisitorQrCode, getVisitors } = useVisitor();
55
+
56
+ const { getPassKeysByPageSearch } = usePassKey();
64
57
 
65
58
  const emits = defineEmits([
66
59
  "closeDialog",
@@ -97,8 +90,6 @@ const handleScanVisitorQRCode = async () => {
97
90
  showNotFoundMessage.value = false;
98
91
  // Automatically navigate to the scanned URL if it's a valid link
99
92
  if (isValidUrl(qrCodeMessage)) {
100
- console.log("QR Code value", qrCodeMessage);
101
- console.log("Last _id", qrCodeMessage.split("/").pop());
102
93
  // get the last _id in the url
103
94
  const id = qrCodeMessage.split("/").pop();
104
95
  // check if it's a valid mongodb _id
@@ -108,7 +99,6 @@ const handleScanVisitorQRCode = async () => {
108
99
  props.site as string,
109
100
  id as string
110
101
  );
111
- console.log("validateVisitorQrCode", response);
112
102
  if (response.errorMessage) {
113
103
  showNotFoundMessage.value = true;
114
104
  errorMessage.value =
@@ -122,9 +112,38 @@ const handleScanVisitorQRCode = async () => {
122
112
  emits("openVisitorDataFromScannedQrCodeDialog", response);
123
113
  }
124
114
  } else {
125
- showNotFoundMessage.value = true;
126
- errorMessage.value = "Invalid mongodb _id.";
127
- showMessage(errorMessage.value, "error");
115
+ const result: any = await getPassKeysByPageSearch({
116
+ sites: [props.site as string],
117
+ search: qrCodeMessage,
118
+ });
119
+
120
+ if (result.items?.length < 1) {
121
+ showMessage(`Pass or Key ${qrCodeMessage} not found.`, "error");
122
+ return;
123
+ }
124
+
125
+ const data: any = await getVisitors({
126
+ site: props.site as string,
127
+ passOrKey: {
128
+ keyId: result.items[0]._id,
129
+ type: result.items[0].passType == "pass-key" ? "key" : "pass",
130
+ },
131
+ checkedOut: false,
132
+ });
133
+
134
+ if (data.items?.length < 1) {
135
+ showMessage(
136
+ `There are no unchecked-out visitor transactions for the scanned ${
137
+ result.items[0].passType == "pass-key" ? "Key" : "Pass"
138
+ } ${qrCodeMessage}.`,
139
+ "error"
140
+ );
141
+
142
+ return;
143
+ }
144
+
145
+ closeDialog();
146
+ emits("openVisitorDataFromScannedQrCodeDialog", data.items[0]);
128
147
  }
129
148
 
130
149
  // window.location.href = qrCodeMessage;
@@ -197,3 +216,48 @@ const stopScanner = () => {
197
216
  });
198
217
  };
199
218
  </script>
219
+
220
+ <style scoped>
221
+ /* Same scanner frame as the pass-key scanner: the card used to be `w-100`
222
+ inside the centring container, so keep that width. */
223
+ .qr-scanner {
224
+ width: 100%;
225
+ }
226
+
227
+ .qr-scanner__head {
228
+ display: flex;
229
+ align-items: center;
230
+ justify-content: space-between;
231
+ padding-right: 12px;
232
+ }
233
+
234
+ .qr-scanner__body {
235
+ display: flex;
236
+ flex-direction: column;
237
+ align-items: center;
238
+ gap: 16px;
239
+ padding: 4px 20px 20px;
240
+ }
241
+
242
+ .qr-scanner__reader {
243
+ display: flex;
244
+ align-items: center;
245
+ justify-content: center;
246
+ width: 100%;
247
+ min-height: 320px;
248
+ border: 1px solid var(--border);
249
+ border-radius: var(--r-inner);
250
+ background: var(--thead);
251
+ }
252
+
253
+ .qr-scanner__error {
254
+ margin: 0;
255
+ font-size: var(--fs-cell);
256
+ color: var(--err);
257
+ }
258
+
259
+ .qr-scanner__switch {
260
+ width: var(--btn-h);
261
+ padding: 0;
262
+ }
263
+ </style>
@@ -20,17 +20,18 @@
20
20
 
21
21
  <template #extension>
22
22
  <v-row no-gutters class="w-100 d-flex flex-column">
23
- <v-card
24
- class="w-100 px-3 d-flex align-center ga-5 py-2"
25
- flat
26
- :height="60"
27
- >
23
+ <!--
24
+ A bare `v-card` here paints Vuetify's own `surface`, a shade off
25
+ the table card it sits inside. A plain row on the card's own
26
+ background, with both filters on the design's field.
27
+ -->
28
+ <div class="w-100 filter-bar d-flex align-center ga-5">
28
29
  <v-select
29
30
  v-model="statusFilter"
30
31
  :items="statusOptions"
31
32
  density="compact"
32
33
  hide-details
33
- class="mx-2"
34
+ class="mx-2 filter-field"
34
35
  style="max-width: 160px"
35
36
  item-title="title"
36
37
  item-value="value"
@@ -42,13 +43,13 @@
42
43
  :items="typeOptions"
43
44
  density="compact"
44
45
  hide-details
45
- class="mx-2"
46
+ class="mx-2 filter-field"
46
47
  style="max-width: 160px"
47
48
  item-title="title"
48
49
  item-value="value"
49
50
  label="Type"
50
51
  />
51
- </v-card>
52
+ </div>
52
53
  </v-row>
53
54
  </template>
54
55
  <template #actions>
@@ -68,20 +69,18 @@
68
69
  <v-spacer />
69
70
 
70
71
  <v-col cols="auto">
71
- <v-chip
72
+ <StatusChip
72
73
  v-if="isScheduleClosed"
73
- color="error"
74
- variant="tonal"
74
+ status="Closed"
75
75
  class="text-capitalize mr-2"
76
76
  >
77
- <v-icon start>mdi-lock</v-icon>
77
+ <v-icon size="14">mdi-lock</v-icon>
78
78
  Closed – View Only
79
- </v-chip>
79
+ </StatusChip>
80
80
  <v-btn
81
81
  v-if="canViewHistory"
82
- class="text-none mr-2"
83
- size="large"
84
- color="primary"
82
+ class="text-none mr-2 screen-btn-primary"
83
+ variant="flat"
85
84
  aria-label="History"
86
85
  @click="openHistory"
87
86
  >
@@ -89,9 +88,8 @@
89
88
  </v-btn>
90
89
  <v-btn
91
90
  v-if="canGenerateChecklist"
92
- class="text-none"
93
- size="large"
94
- color="primary"
91
+ class="text-none screen-btn-primary"
92
+ variant="flat"
95
93
  aria-label="Generate"
96
94
  @click="_generateChecklist"
97
95
  :loading="submitting"
@@ -109,25 +107,26 @@
109
107
  (item.status && String(item.status).toLowerCase() === 'accepted')
110
108
  "
111
109
  >
112
- <span class="text-capitalize" color="success" variant="tonal">
113
- {{ item.acceptedByName || item.acceptedBy || "Accepted" }}
114
- </span>
110
+ <!--
111
+ `color`/`variant` on a plain `<span>` do nothing - Vuetify only
112
+ reads them on its own components, so this drew as bare cell text
113
+ while reading as a tonal green chip. It is the accepted chip the
114
+ sibling branches already use.
115
+ -->
116
+ <StatusChip
117
+ status="Accepted"
118
+ class="text-capitalize"
119
+ :label="item.acceptedByName || item.acceptedBy || 'Accepted'"
120
+ />
115
121
  </div>
116
122
  <div v-else-if="isScheduleClosed">
117
- <v-chip
118
- size="small"
119
- color="error"
120
- variant="tonal"
121
- class="text-capitalize"
122
- >Closed</v-chip
123
- >
123
+ <StatusChip status="Closed" class="text-capitalize" />
124
124
  </div>
125
125
  <div v-else>
126
126
  <v-btn
127
127
  v-if="canManageScheduleTasks"
128
128
  variant="outlined"
129
- size="medium"
130
- class="text-capitalize px-4 py-2"
129
+ class="text-capitalize screen-btn-ghost"
131
130
  @click.stop="() => _acceptAreaChecklist(item._id)"
132
131
  >
133
132
  Accept
@@ -146,14 +145,11 @@
146
145
  </template>
147
146
 
148
147
  <template #item.status="{ value }">
149
- <v-chip
148
+ <StatusChip
150
149
  class="text-capitalize"
151
- :color="getStatusColor(value)"
152
- variant="flat"
153
- pill
154
- >
155
- {{ value || "No Status" }}
156
- </v-chip>
150
+ :status="value"
151
+ :label="value || 'No Status'"
152
+ />
157
153
  </template>
158
154
  </TableMain></v-col
159
155
  >
@@ -262,27 +258,6 @@ watchEffect(() => {
262
258
  }
263
259
  });
264
260
 
265
- const getStatusColor = (status: unknown): string => {
266
- if (!status) return "grey";
267
-
268
- const normalized = String(status).toLowerCase();
269
-
270
- switch (normalized) {
271
- case "open":
272
- return "grey";
273
- case "ongoing":
274
- return "primary";
275
- case "completed":
276
- case "accepted":
277
- return "success";
278
- case "closed":
279
- case "rejected":
280
- return "error";
281
- default:
282
- return "secondary";
283
- }
284
- };
285
-
286
261
  function showMessage(msg: string, color: string = "error") {
287
262
  message.value = msg;
288
263
  messageColor.value = color;
@@ -1,26 +1,24 @@
1
1
  <template>
2
2
  <v-dialog v-model="show" max-width="680" persistent>
3
- <v-card class="d-flex flex-column" max-height="90vh">
4
- <v-toolbar flat color="grey-lighten-4">
5
- <v-row no-gutters class="fill-height px-6" align="center">
6
- <v-toolbar-title class="text-h6 font-weight-bold">
7
- {{
8
- props.mode === "edit"
9
- ? "Edit Schedule Task"
10
- : "Create Schedule Task"
11
- }}
12
- </v-toolbar-title>
13
- <v-spacer />
14
- <v-btn
15
- icon="mdi-close"
16
- variant="text"
17
- @click="close"
18
- :disabled="submitting"
19
- />
20
- </v-row>
21
- </v-toolbar>
22
-
23
- <v-card-text class="pa-4 flex-grow-1" style="overflow-y: auto">
3
+ <v-card class="screen-modal">
4
+ <v-card-title class="d-flex align-center">
5
+ {{
6
+ props.mode === "edit"
7
+ ? "Edit Schedule Task"
8
+ : "Create Schedule Task"
9
+ }}
10
+ <v-spacer />
11
+ <v-btn
12
+ icon="mdi-close"
13
+ variant="text"
14
+ class="screen-modal__close"
15
+ aria-label="Close"
16
+ @click="close"
17
+ :disabled="submitting"
18
+ />
19
+ </v-card-title>
20
+
21
+ <v-card-text class="screen-modal__body">
24
22
  <v-form ref="formRef" v-model="valid">
25
23
  <v-row dense>
26
24
  <v-col cols="12">
@@ -30,15 +28,15 @@
30
28
  v-model="subject"
31
29
  variant="outlined"
32
30
  density="comfortable"
31
+ class="filter-field mb-4"
33
32
  placeholder="Enter task title"
34
33
  hide-details="auto"
35
- class="mb-4"
36
34
  />
37
35
  </v-col>
38
36
 
39
37
  <v-col cols="12">
40
38
  <InputLabel for="date-range" title="Select Dates" required />
41
- <v-sheet border rounded class="pa-4 mb-4" color="grey-lighten-5">
39
+ <div class="task-form__panel mb-4">
42
40
  <v-date-picker
43
41
  v-model="pickerDates"
44
42
  multiple
@@ -49,7 +47,7 @@
49
47
  class="ma-0"
50
48
  />
51
49
  <v-divider class="my-3" />
52
- <div class="text-caption text-medium-emphasis mb-2">
50
+ <div class="task-form__hint mb-2">
53
51
  {{ selectedDates.length }} date(s) selected
54
52
  </div>
55
53
  <div
@@ -66,10 +64,10 @@
66
64
  {{ date }}
67
65
  </v-chip>
68
66
  </div>
69
- <div v-else class="text-caption text-disabled">
67
+ <div v-else class="task-form__hint">
70
68
  No dates selected. Click on the calendar to select dates.
71
69
  </div>
72
- </v-sheet>
70
+ </div>
73
71
  </v-col>
74
72
 
75
73
  <v-col cols="12">
@@ -80,9 +78,9 @@
80
78
  type="time"
81
79
  variant="outlined"
82
80
  density="comfortable"
81
+ class="filter-field mb-4"
83
82
  hide-details="auto"
84
83
  prepend-inner-icon="mdi-clock-outline"
85
- class="mb-4"
86
84
  />
87
85
  </v-col>
88
86
 
@@ -98,10 +96,10 @@
98
96
  multiple
99
97
  variant="outlined"
100
98
  density="comfortable"
99
+ class="filter-field mb-4"
101
100
  :loading="loadingAreas"
102
101
  placeholder="Choose one or more areas"
103
102
  hide-details="auto"
104
- class="mb-4"
105
103
  chips
106
104
  closable-chips
107
105
  >
@@ -116,7 +114,7 @@
116
114
  </v-chip>
117
115
  <span
118
116
  v-if="index === 3"
119
- class="text-grey text-caption align-self-center"
117
+ class="task-form__hint align-self-center"
120
118
  >
121
119
  (+{{ selectedAreas.length - 3 }} others)
122
120
  </span>
@@ -215,7 +213,7 @@
215
213
  </v-chip>
216
214
  </div>
217
215
 
218
- <span v-else class="text-caption text-disabled">
216
+ <span v-else class="task-form__hint">
219
217
  No units configured
220
218
  </span>
221
219
  </v-card-text>
@@ -233,38 +231,34 @@
233
231
  v-model="description"
234
232
  variant="outlined"
235
233
  density="comfortable"
234
+ class="filter-field mb-2"
236
235
  rows="4"
237
236
  placeholder="Add additional details about this task..."
238
237
  hide-details="auto"
239
- class="mb-2"
240
238
  />
241
239
  </v-col>
242
240
  </v-row>
243
241
  </v-form>
244
242
  </v-card-text>
245
243
 
246
- <v-toolbar class="pa-0" density="compact">
244
+ <v-card-actions class="screen-modal__footer">
247
245
  <v-row no-gutters>
248
- <v-col cols="6" class="pa-0">
246
+ <v-col cols="6" class="pr-2">
249
247
  <v-btn
250
248
  block
251
- variant="text"
252
- class="text-none"
253
- size="large"
249
+ variant="outlined"
250
+ class="text-none screen-btn-ghost"
254
251
  @click="close"
255
- height="48"
256
252
  :disabled="submitting"
257
253
  >
258
254
  Cancel
259
255
  </v-btn>
260
256
  </v-col>
261
- <v-col cols="6" class="pa-0">
257
+ <v-col cols="6" class="pl-2">
262
258
  <v-btn
263
259
  block
264
260
  variant="flat"
265
- color="primary"
266
- class="text-none font-weight-bold rounded-0"
267
- height="48"
261
+ class="text-none screen-btn-primary"
268
262
  @click="submitTask"
269
263
  :loading="submitting"
270
264
  >
@@ -272,7 +266,7 @@
272
266
  </v-btn>
273
267
  </v-col>
274
268
  </v-row>
275
- </v-toolbar>
269
+ </v-card-actions>
276
270
  </v-card>
277
271
  </v-dialog>
278
272
 
@@ -568,3 +562,28 @@ watch(
568
562
  { immediate: false }
569
563
  );
570
564
  </script>
565
+
566
+ <style scoped>
567
+ /* Was `<v-sheet border rounded color="grey-lighten-5">` - a fixed light grey
568
+ that stayed light on the dark theme. The design has no calendar panel, so
569
+ this is the estate's own card surface and border, nothing invented. */
570
+ .task-form__panel {
571
+ padding: 16px;
572
+ border: 1px solid var(--border);
573
+ border-radius: var(--r-inner);
574
+ background: var(--card);
575
+ }
576
+
577
+ /* Replaces `text-caption text-disabled` / `text-medium-emphasis` / `text-grey`,
578
+ three different Vuetify greys doing the same job.
579
+
580
+ `--text2`, not `--muted`: the design is silent on this hint line, and `--muted`
581
+ at 12px measured 3.24:1 on the light card. That pairing would have been OURS,
582
+ not the design's, so it is fixed here with an existing token rather than
583
+ recorded. `--text2` measures 8.2:1. */
584
+ .task-form__hint {
585
+ font-size: var(--fs-chip-lg);
586
+ font-weight: 600;
587
+ color: var(--text2);
588
+ }
589
+ </style>