@argusoft/medplat-app-shell 1.0.6 → 1.0.8

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 (264) hide show
  1. package/package.json +139 -141
  2. package/src/GlobalErrorBoundary.jsx +31 -0
  3. package/src/SilentErrorFallback.jsx +68 -0
  4. package/src/TrackingProviderWrapper.jsx +40 -0
  5. package/src/_tests_/__mocks__/MockTranslationProvider.jsx +21 -0
  6. package/src/_tests_/__mocks__/ckeditor.js +45 -0
  7. package/src/_tests_/__mocks__/fileMock.js +1 -0
  8. package/src/_tests_/__mocks__/useranalytics.js +5 -0
  9. package/src/_tests_/views/components/Dashboard/DashboardUI.test.jsx +137 -0
  10. package/src/_tests_/views/components/Dashboard/DashboardUIMock.js +877 -0
  11. package/src/_tests_/views/components/ForgotPassword/ForgotPassword.test.jsx +314 -0
  12. package/src/_tests_/views/components/LocationDirective/LocationDirective.test.jsx.disable +229 -0
  13. package/src/_tests_/views/components/LocationDirective/mockLocationDirective.js +810 -0
  14. package/src/_tests_/views/components/LocationType/MockLocationType.js +42259 -0
  15. package/src/_tests_/views/components/LocationType/addlocationtype.test.jsx.disable +276 -0
  16. package/src/_tests_/views/components/LocationType/editlocationtype.test.jsx.disable +262 -0
  17. package/src/_tests_/views/components/LocationType/locationtype.test.jsx.disable +148 -0
  18. package/src/_tests_/views/components/Profile/UpdateProfileModalData.js +4396 -0
  19. package/src/_tests_/views/components/Profile/updateprofilemodal.test.jsx +282 -0
  20. package/src/_tests_/views/components/SideBar/MockSideBar.js +1379 -0
  21. package/src/_tests_/views/components/SideBar/SideBar.test.jsx +98 -0
  22. package/src/_tests_/views/components/SystemConfig/ManageSystemConfig/AddManageSystemConfig.test.jsx.disable +164 -0
  23. package/src/_tests_/views/components/SystemConfig/ManageSystemConfig/UpdateManageSystemConfig.test.jsx.disable +157 -0
  24. package/src/_tests_/views/components/SystemConfig/MockSystemConfig.js +1280 -0
  25. package/src/_tests_/views/components/SystemConfig/SystemConfig.test.jsx.disable +165 -0
  26. package/src/_tests_/views/components/login/Login.test.jsx +276 -0
  27. package/src/_tests_/views/components/login/MockAuthorise.js +2414 -0
  28. package/src/_tests_/views/components/login/ServiceResponse.js +595 -0
  29. package/src/_tests_/views/components/user/MockManageUser.js +7965 -0
  30. package/src/_tests_/views/components/user/manageuser.test.jsx.disable +989 -0
  31. package/src/_tests_/views/components/user/mockUsersData.js +582 -0
  32. package/src/assets/img/OASISLogin.png +0 -0
  33. package/src/assets/img/bahaarNew.png +0 -0
  34. package/src/assets/img/dnhdd4K.png +0 -0
  35. package/src/assets/img/govtofup.png +0 -0
  36. package/src/assets/img/sewarural4K.png +0 -0
  37. package/src/assets/img/techo4K.png +0 -0
  38. package/src/assets/img/up4K.png +0 -0
  39. package/src/common/HolidayList.jsx +573 -0
  40. package/src/common/MalaciaousInputUtil.js +23 -0
  41. package/src/common/SafeHtml.jsx +17 -0
  42. package/src/common/VersionManager.jsx +109 -0
  43. package/src/common/constants/PerformanceDashboard.js +514 -0
  44. package/src/common/constants/app.constant.js +781 -0
  45. package/src/common/constants/cccVerificationConstants.js +18 -0
  46. package/src/common/constants/fhsrConstant.js +33 -0
  47. package/src/common/constants/gvk-verification.constant.js +76 -0
  48. package/src/common/constants/search.constant.js +23 -0
  49. package/src/common/constants/teleconsulatationConstant.jsx +1339 -0
  50. package/src/common/directives/SearchTemplate.jsx +784 -0
  51. package/src/common/directives/SearchTemplate.scss +14 -0
  52. package/src/common/dynamicView/DynamicView.jsx +353 -0
  53. package/src/common/dynamicView/InputFieldComponent.jsx +1501 -0
  54. package/src/common/dynamicView/InputViewComponent.jsx +298 -0
  55. package/src/common/dynamicView/InputViewComponent.scss +15 -0
  56. package/src/common/env.js +5 -0
  57. package/src/common/filters/locationNameFilter.js +26 -0
  58. package/src/common/fontAwesomeIcons/FontAwesomeIcons.jsx +27 -0
  59. package/src/common/fontAwesomeIcons/FontAwesomeIconsNames.js +1968 -0
  60. package/src/common/fontPreferences/fontSizeProvider.jsx +34 -0
  61. package/src/common/fontPreferences/fontSizeSelector.jsx +116 -0
  62. package/src/common/getAssignedFeature/getAssignedFeature.js +32 -0
  63. package/src/common/interceptors/AxiosInterceptor.js +216 -0
  64. package/src/common/languageTranslator/TranslationContext.js +5 -0
  65. package/src/common/languageTranslator/TranslationProvider.jsx +24 -0
  66. package/src/common/languageTranslator/i18n.js +49 -0
  67. package/src/common/services/AuthenticateService.js +116 -0
  68. package/src/common/services/DownloadFile.js +35 -0
  69. package/src/common/services/ForgotPassword.js +18 -0
  70. package/src/common/services/FormConfiguratorService.js +195 -0
  71. package/src/common/services/GlobalApis.js +84 -0
  72. package/src/common/services/InterceptorNavigationService.js +17 -0
  73. package/src/common/services/LocationService.js +65 -0
  74. package/src/common/services/LocationType.js +11 -0
  75. package/src/common/services/QueryBuilder.js +36 -0
  76. package/src/common/services/Roles.js +28 -0
  77. package/src/common/services/SyncWithServer.js +15 -0
  78. package/src/common/services/SystemConfig.js +15 -0
  79. package/src/common/services/TranslationService.js +70 -0
  80. package/src/common/services/TwoFactorService.js +7 -0
  81. package/src/common/services/Users.js +91 -0
  82. package/src/common/services/Webtasks.js +27 -0
  83. package/src/common/services/util/Convert-pad-data-to-API-format.jsx +167 -0
  84. package/src/common/services/util/Convert-to-UI-format.jsx +82 -0
  85. package/src/common/services/util/EmptyPrescriptionPadData.jsx +11 -0
  86. package/src/common/services/util/GeneralUtil.js +456 -0
  87. package/src/common/services/util/Prescription-pad-util.js +339 -0
  88. package/src/common/services/util/PrescriptionPadData.js +67 -0
  89. package/src/common/services/util/PrescriptionpadCommonUtil.js +96 -0
  90. package/src/common/services/util/ReportFieldUtil.jsx +398 -0
  91. package/src/common/services/util/WebSocketContext.jsx +261 -0
  92. package/src/common/syncWithServer/SyncWithServerDialog.jsx +170 -0
  93. package/src/common/syncWithServer/SyncWithServerDialogSkeleton.jsx +67 -0
  94. package/src/common/tests/CustomWrapper.jsx +49 -0
  95. package/src/common/tests/TranslationWrapper.jsx +38 -0
  96. package/src/common/themeProvider/ColorInputs.jsx +97 -0
  97. package/src/common/themeProvider/EditableColorInput.jsx +128 -0
  98. package/src/common/themeProvider/ThemeEditor.jsx +319 -0
  99. package/src/common/themeProvider/ThemeProvider.jsx +210 -0
  100. package/src/common/themeProvider/themeConfig.js +558 -0
  101. package/src/common/toaster/toaster.jsx +30 -0
  102. package/src/firebaseConfig.js +24 -0
  103. package/src/global.scss +221 -0
  104. package/src/hooks/.gitkeep +0 -0
  105. package/src/hooks/useAESEncryption.js +56 -0
  106. package/src/hooks/useCaching.js +43 -0
  107. package/src/hooks/useDebounce.js +34 -0
  108. package/src/hooks/useDebounceFn.js +50 -0
  109. package/src/hooks/useDownloadPdf.js +358 -0
  110. package/src/hooks/useDownloadXlsx.js +55 -0
  111. package/src/hooks/useListValueFieldValues.js +30 -0
  112. package/src/hooks/useLocationHierarchies.js +63 -0
  113. package/src/hooks/useLocationHierarchyTranslate.js +16 -0
  114. package/src/hooks/useOnline.js +27 -0
  115. package/src/hooks/usePagination.js +63 -0
  116. package/src/hooks/useRefreshToken.js +87 -0
  117. package/src/hooks/useScript.js +25 -0
  118. package/src/hooks/useStopwatch.js +75 -0
  119. package/src/hooks/useTrackEvent.js +22 -0
  120. package/src/hooks/useWebAudioRecorder.js +115 -0
  121. package/src/layout/LoaderComponet.jsx +22 -0
  122. package/src/layout/LoaderContext.jsx +29 -0
  123. package/src/layout/mainLayout/AdaptiveZoom.jsx +27 -0
  124. package/src/layout/mainLayout/Chatbot.jsx +243 -0
  125. package/src/layout/mainLayout/Layout.jsx +445 -0
  126. package/src/layout/mainLayout/Profile/UpdateProfileModal.jsx +684 -0
  127. package/src/layout/mainLayout/header/LogoutModal.jsx +131 -0
  128. package/src/layout/mainLayout/header/Navbar.jsx +1677 -0
  129. package/src/layout/mainLayout/header/Navbar.scss +4 -0
  130. package/src/layout/mainLayout/header/index.js +0 -0
  131. package/src/layout/mainLayout/sidebar/SideBar.jsx +1402 -0
  132. package/src/layout/mainLayout/sidebar/Sidebar.css +159 -0
  133. package/src/layout/mainLayout/sidebar/index.js +0 -0
  134. package/src/logo.svg +1 -0
  135. package/src/reportWebVitals.js +13 -0
  136. package/src/setupFirebaseMessaging.js +28 -0
  137. package/src/setupTests.js +8 -0
  138. package/src/store/actions/AuthenticationActions.js +0 -0
  139. package/src/store/actions/ReportsActions.js +0 -0
  140. package/src/store/actions/TranslationAction.js +0 -0
  141. package/src/store/index.js +8 -0
  142. package/src/store/reducer.js +46 -0
  143. package/src/store/reducers/AuthenticationReducer.js +50 -0
  144. package/src/store/reducers/CalendarEventReducer.js +41 -0
  145. package/src/store/reducers/ConditionClipboardReducer.js +45 -0
  146. package/src/store/reducers/FeatureReducer.js +27 -0
  147. package/src/store/reducers/FormConfiguratorReducer.js +38 -0
  148. package/src/store/reducers/LoadingReducer.js +20 -0
  149. package/src/store/reducers/MembersAuthenticationReducer.js +28 -0
  150. package/src/store/reducers/PrescriptionPadReducer.js +329 -0
  151. package/src/store/reducers/QuestionaireReducer.js +29 -0
  152. package/src/store/reducers/ReportsReducer.js +24 -0
  153. package/src/store/reducers/SkeletonReducer.js +20 -0
  154. package/src/store/reducers/ThemeReducer.js +106 -0
  155. package/src/store/reducers/TranslationReducer.js +126 -0
  156. package/src/store/reducers/dashboardEditorSlice.js +77 -0
  157. package/src/store/reducers/districtHealthDashboardSlice.js +58 -0
  158. package/src/store/reducers/immunizationSlice.js +234 -0
  159. package/src/store/slices/dashboardPagesSlice.js +51 -0
  160. package/src/store/slices/dashboardSlice.js +14 -0
  161. package/src/utils/.gitkeep +0 -0
  162. package/src/utils/FormConstants.js +2629 -0
  163. package/src/utils/GujaratTopoChart.jsx +483 -0
  164. package/src/utils/UUIDgenerator.js +8 -0
  165. package/src/utils/appointment-utils/appointment-utils.js +123 -0
  166. package/src/utils/feature.js +42 -0
  167. package/src/utils/getThemeColor.js +12 -0
  168. package/src/utils/localStorageHelper.js +11 -0
  169. package/src/utils/notifications/enable-push-notifications.js +27 -0
  170. package/src/utils/resolveAppliedStyle.js +11 -0
  171. package/src/utils/themeConfigs.js +1483 -0
  172. package/src/views/custom-components/.gitkeep +0 -0
  173. package/src/views/custom-components/AgIconButton/RIf.jsx +14 -0
  174. package/src/views/custom-components/AgIconButton/button.jsx +108 -0
  175. package/src/views/custom-components/AgIconButton/waterDrop.jsx +95 -0
  176. package/src/views/custom-components/AgIconButton/waterDrop.scss +37 -0
  177. package/src/views/custom-components/AlertPlaceholder.jsx +32 -0
  178. package/src/views/custom-components/AllFaIconsSelector.jsx +56 -0
  179. package/src/views/custom-components/CkEditor/CkEditor.js +102 -0
  180. package/src/views/custom-components/CustomAccordion.jsx +72 -0
  181. package/src/views/custom-components/CustomActionIcons.jsx +118 -0
  182. package/src/views/custom-components/CustomAutoComplete.jsx +188 -0
  183. package/src/views/custom-components/CustomCheckBox.jsx +60 -0
  184. package/src/views/custom-components/CustomConfirmationModal.jsx +118 -0
  185. package/src/views/custom-components/CustomCountrySelect.jsx +129 -0
  186. package/src/views/custom-components/CustomDatePicker.jsx +122 -0
  187. package/src/views/custom-components/CustomDropdown.jsx +191 -0
  188. package/src/views/custom-components/CustomFileUpload.jsx +387 -0
  189. package/src/views/custom-components/CustomFullCalendar.jsx +514 -0
  190. package/src/views/custom-components/CustomInfiniteScroll.jsx +126 -0
  191. package/src/views/custom-components/CustomRadioComponent.jsx +65 -0
  192. package/src/views/custom-components/CustomStatsComponent.jsx +114 -0
  193. package/src/views/custom-components/CustomSvgUpload.jsx +170 -0
  194. package/src/views/custom-components/CustomSwitch.jsx +37 -0
  195. package/src/views/custom-components/CustomTabPanel.jsx +19 -0
  196. package/src/views/custom-components/CustomTextArea.jsx +62 -0
  197. package/src/views/custom-components/CustomTextArea.scss +27 -0
  198. package/src/views/custom-components/CustomTextField.jsx +116 -0
  199. package/src/views/custom-components/CustomToggleSwitch.jsx +138 -0
  200. package/src/views/custom-components/CustomTooltip.jsx +51 -0
  201. package/src/views/custom-components/CustomZoomImage.jsx +134 -0
  202. package/src/views/custom-components/CustomizedTable/CustomizedTableV2.jsx +1407 -0
  203. package/src/views/custom-components/CustomizedTable/VirtualizeTableBody.jsx +295 -0
  204. package/src/views/custom-components/CustomizedTable/helper.jsx +159 -0
  205. package/src/views/custom-components/CustomizedTable.jsx +532 -0
  206. package/src/views/custom-components/EditInputField.jsx +174 -0
  207. package/src/views/custom-components/FieldDescription.jsx +22 -0
  208. package/src/views/custom-components/FileDisplayComponent.jsx +138 -0
  209. package/src/views/custom-components/FormItem.jsx +53 -0
  210. package/src/views/custom-components/GenericChart.jsx +80 -0
  211. package/src/views/custom-components/InfoBadge.jsx +60 -0
  212. package/src/views/custom-components/PostgresEditor.jsx +801 -0
  213. package/src/views/custom-components/ResizableEditAutocompleteField.jsx +249 -0
  214. package/src/views/custom-components/ResizableEditInputField.jsx +215 -0
  215. package/src/views/custom-components/ResizeableEditSelectField.jsx +197 -0
  216. package/src/views/custom-components/SideOverlay.jsx +113 -0
  217. package/src/views/custom-components/SideOverlay.scss +42 -0
  218. package/src/views/custom-components/calendar.scss +571 -0
  219. package/src/views/feature-components/.gitkeep +0 -0
  220. package/src/views/feature-components/Dashboard/DashboardUI.jsx +1043 -0
  221. package/src/views/feature-components/Dashboard/DhnddModal/AshaDataQualityVerificationModal.jsx +278 -0
  222. package/src/views/feature-components/Dashboard/PinFeatureModal.jsx +143 -0
  223. package/src/views/feature-components/Dashboard/QuickLinks.jsx +163 -0
  224. package/src/views/feature-components/Dashboard/Taskbar.jsx +56 -0
  225. package/src/views/feature-components/Dashboard/WebtasksFilterForm.jsx +109 -0
  226. package/src/views/feature-components/Dashboard/WidgetCard.jsx +161 -0
  227. package/src/views/feature-components/Dashboard/actionModal.jsx +263 -0
  228. package/src/views/feature-components/Dashboard/ekavachModal/HealthWorkerIncorrectDetailsModal.jsx +332 -0
  229. package/src/views/feature-components/Dashboard/ekavachModal/MoMaternalDeathVerifcationModal.jsx +275 -0
  230. package/src/views/feature-components/Dashboard/ekavachModal/MoVerficationForChildScreeningMoadal.jsx +566 -0
  231. package/src/views/feature-components/FeatureUsageAnalytics/FeatureUsageAnalytics.jsx +989 -0
  232. package/src/views/feature-components/Features/NewServerManagement.jsx +217 -0
  233. package/src/views/feature-components/Features/ServerManagement.scss +120 -0
  234. package/src/views/feature-components/ForgotPassword/ForgotPassword.jsx +226 -0
  235. package/src/views/feature-components/LocationDirective/LocationDirective.jsx +992 -0
  236. package/src/views/feature-components/LocationDirective/LocationDirectiveV2.jsx +909 -0
  237. package/src/views/feature-components/NotFound.jsx +66 -0
  238. package/src/views/feature-components/Onboarding/Onboarding.jsx +1400 -0
  239. package/src/views/feature-components/Skeletons.js +115 -0
  240. package/src/views/feature-components/Unauthorized.jsx +48 -0
  241. package/src/views/feature-components/VerifyRoute.jsx +88 -0
  242. package/src/views/feature-components/YearlyRecap/YearlyRecap.jsx +357 -0
  243. package/src/views/feature-components/YearlyRecap/components/RecapSlide.jsx +183 -0
  244. package/src/views/feature-components/YearlyRecap/languageTranslator/TranslationContext.js +5 -0
  245. package/src/views/feature-components/YearlyRecap/languageTranslator/TranslationProvider.jsx +26 -0
  246. package/src/views/feature-components/YearlyRecap/languageTranslator/i18n.js +46 -0
  247. package/src/views/feature-components/YearlyRecap/languageTranslator/translations.json +167 -0
  248. package/src/views/feature-components/YearlyRecap/slides/IntroSlide.jsx +233 -0
  249. package/src/views/feature-components/YearlyRecap/slides/MaternalHealthSlide.jsx +146 -0
  250. package/src/views/feature-components/YearlyRecap/slides/MetricSlide.jsx +227 -0
  251. package/src/views/feature-components/YearlyRecap/slides/OutroSlide.jsx +701 -0
  252. package/src/views/feature-components/YearlyRecap/slides/ReachSlide.jsx +273 -0
  253. package/src/views/feature-components/login/Login.jsx +840 -0
  254. package/src/views/feature-components/login/Login.scss +154 -0
  255. package/src/views/feature-components/login/LoginConfigurator.jsx +1149 -0
  256. package/src/views/feature-components/login/TwoFactorSetupModal.jsx +411 -0
  257. package/src/views/feature-components/login/simplifyMenu.js +45 -0
  258. package/src/views/feature-components/system-config/ManageSystemConfigs.jsx +284 -0
  259. package/src/views/feature-components/system-config/SystemConfig.jsx +299 -0
  260. package/src/views/feature-components/users/ChangePasswordModal.jsx +243 -0
  261. package/src/views/feature-components/users/PasswordField.jsx +56 -0
  262. package/dist/index.css +0 -1
  263. package/dist/index.js +0 -32001
  264. package/dist/index.js.map +0 -1
@@ -0,0 +1,278 @@
1
+ import React, { useState, useEffect, useCallback } from 'react';
2
+ import {
3
+ Modal,
4
+ Typography,
5
+ IconButton,
6
+ Button,
7
+ Divider,
8
+ Paper,
9
+ Table,
10
+ TableBody,
11
+ TableCell,
12
+ TableContainer,
13
+ TableHead,
14
+ TableRow,
15
+ Collapse,
16
+ Box,
17
+ CircularProgress,
18
+ } from '@mui/material';
19
+ import Grid from '@mui/material/Grid2';
20
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
21
+ import { faXmark, faPlus, faMinus } from '@fortawesome/free-solid-svg-icons';
22
+ import PropTypes from 'prop-types';
23
+ import { showToast } from '@/common/toaster/toaster';
24
+ import { execute, executeAll } from '@/common/services/GlobalApis';
25
+ import { getLoggedInUser } from '@/common/services/AuthenticateService'; // Adjust path based on your project
26
+
27
+ const AshaScreenedMembersModal = ({ open, onClose, task, onSave }) => {
28
+ const [members, setMembers] = useState([]);
29
+ const [expandedId, setExpandedId] = useState(null);
30
+ const [isLoading, setIsLoading] = useState(false);
31
+ const [userId, setUserId] = useState(null);
32
+
33
+ // --- 1. INIT Logic: Fetch User and Members ---
34
+ const init = useCallback(async () => {
35
+ setIsLoading(true);
36
+ try {
37
+ // Get Logged In User
38
+ const userRes = await getLoggedInUser();
39
+ setUserId(userRes?.data?.id);
40
+
41
+ // Fetch Screened Members
42
+ const response = await execute({
43
+ code: 'retrieve_cbac_done_member_by_asha_id',
44
+ parameters: {
45
+ ashaName: task?.details?.UserName,
46
+ taskId: task?.taskId,
47
+ },
48
+ });
49
+
50
+ if (response?.data?.result) {
51
+ const formattedMembers = response.data.result.map((m) => ({
52
+ ...m,
53
+ pending: m.status === 'PENDING',
54
+ currentStatus: m.status, // Track changes locally
55
+ }));
56
+ setMembers(formattedMembers);
57
+ }
58
+ } catch (error) {
59
+ console.error(error);
60
+ showToast({ message: 'Error loading initial data', type: 'error' });
61
+ } finally {
62
+ setIsLoading(false);
63
+ }
64
+ }, [task]);
65
+
66
+ useEffect(() => {
67
+ if (open) init();
68
+ }, [open, init]);
69
+
70
+ // --- 2. Action Handlers (Local State Only) ---
71
+ const handleMemberAction = (memberId, newStatus) => {
72
+ setMembers((prev) => prev.map((m) => (m.member_id === memberId ? { ...m, currentStatus: newStatus } : m)));
73
+ setExpandedId(null); // Close details after action
74
+ };
75
+
76
+ // --- 3. SAVE Logic: Batch Execute Queries ---
77
+ const saveChanges = async () => {
78
+ const nonPendingMembers = members.filter((m) => m.currentStatus !== 'PENDING');
79
+
80
+ if (nonPendingMembers.length === 0) {
81
+ onClose();
82
+ return;
83
+ }
84
+
85
+ setIsLoading(true);
86
+ try {
87
+ // Map member updates to query DTOs
88
+ const queryDtos = nonPendingMembers.map((member, index) => ({
89
+ code: 'update_member_status',
90
+ parameters: {
91
+ memberId: member.member_id,
92
+ status: member.currentStatus,
93
+ taskId: task.taskId,
94
+ userId: userId,
95
+ },
96
+ sequence: index + 1,
97
+ }));
98
+
99
+ // If all (or 5) are processed, mark notification complete
100
+ if (nonPendingMembers.length === members.length || nonPendingMembers.length === 5) {
101
+ queryDtos.push({
102
+ code: 'mark_techo_web_notification_as_complete',
103
+ parameters: {
104
+ notification_id: task.taskId,
105
+ action_by: userId,
106
+ },
107
+ sequence: queryDtos.length + 1,
108
+ });
109
+ }
110
+
111
+ await executeAll(queryDtos);
112
+ showToast({ message: 'Changes saved successfully', type: 'success' });
113
+ await onSave;
114
+ await onClose();
115
+ } catch (error) {
116
+ console.error(error);
117
+ showToast({ message: 'Error saving changes', type: 'error' });
118
+ } finally {
119
+ setIsLoading(false);
120
+ }
121
+ };
122
+
123
+ return (
124
+ <Modal open={open} onClose={onClose} className="flex items-center justify-center">
125
+ <Grid container className="bg-white shadow-2xl rounded-lg flex flex-col w-[95%] max-w-[1100px] outline-none">
126
+ {/* Header */}
127
+ <div className="flex justify-between items-center p-4 border-b">
128
+ <Typography variant="h6" className="font-bold text-customBlue">
129
+ List of members screened by asha
130
+ </Typography>
131
+ <IconButton onClick={onClose} size="small" disabled={isLoading}>
132
+ <FontAwesomeIcon icon={faXmark} className="text-gray-400" />
133
+ </IconButton>
134
+ </div>
135
+
136
+ {/* Body */}
137
+ <div className="p-4 max-h-[70vh] overflow-y-auto relative">
138
+ {isLoading && members.length === 0 ? (
139
+ <Box className="flex justify-center p-10">
140
+ <CircularProgress />
141
+ </Box>
142
+ ) : (
143
+ <TableContainer component={Paper} variant="outlined">
144
+ <Table stickyHeader size="small">
145
+ <TableHead>
146
+ <TableRow>
147
+ <TableCell className="bg-gray-50 font-bold">Sr. No.</TableCell>
148
+ <TableCell className="bg-gray-50 font-bold">Member ID</TableCell>
149
+ <TableCell className="bg-gray-50 font-bold">Name</TableCell>
150
+ <TableCell className="bg-gray-50 font-bold">Contact</TableCell>
151
+ <TableCell className="bg-gray-50 font-bold">Location</TableCell>
152
+ <TableCell className="bg-gray-50 font-bold">CBAC Date</TableCell>
153
+ <TableCell className="bg-gray-50 font-bold">Status</TableCell>
154
+ <TableCell className="bg-gray-50 font-bold" align="center">
155
+ Details
156
+ </TableCell>
157
+ </TableRow>
158
+ </TableHead>
159
+ <TableBody>
160
+ {members.map((member, index) => (
161
+ <React.Fragment key={member.member_id}>
162
+ <TableRow hover selected={expandedId === member.member_id}>
163
+ <TableCell>{index + 1}</TableCell>
164
+ <TableCell>{member?.unique_health_id || 'N/A'}</TableCell>
165
+ <TableCell>{member?.member_name || 'N/A'}</TableCell>
166
+ <TableCell>{member?.contact_number || 'N/A'}</TableCell>
167
+ <TableCell>{member?.location || 'N/A'}</TableCell>
168
+ <TableCell>{member?.done_on || 'N/A'}</TableCell>
169
+ <TableCell>
170
+ <Typography
171
+ variant="body2"
172
+ sx={{
173
+ color:
174
+ member?.currentStatus === 'Approved'
175
+ ? 'success.main'
176
+ : member?.currentStatus === 'Disapproved'
177
+ ? 'error.main'
178
+ : 'inherit',
179
+ fontWeight: member?.currentStatus !== 'PENDING' ? 600 : 400,
180
+ }}
181
+ >
182
+ {member?.currentStatus || 'N/A'}
183
+ </Typography>
184
+ </TableCell>
185
+ <TableCell align="center">
186
+ <IconButton
187
+ size="small"
188
+ onClick={() => setExpandedId(expandedId === member?.member_id ? null : member?.member_id)}
189
+ >
190
+ <FontAwesomeIcon icon={expandedId === member?.member_id ? faMinus : faPlus} />
191
+ </IconButton>
192
+ </TableCell>
193
+ </TableRow>
194
+
195
+ <TableRow>
196
+ <TableCell style={{ paddingBottom: 0, paddingTop: 0 }} colSpan={8}>
197
+ <Collapse in={expandedId === member.member_id} timeout="auto" unmountOnExit>
198
+ <Box className="m-4 p-4 bg-gray-50 border border-gray-200 rounded-md">
199
+ <Grid container spacing={2}>
200
+ <Grid size={{ xs: 12, md: 6 }}>
201
+ <Typography variant="body2">
202
+ <strong>Suspected for:</strong> {member?.suspected || 'N.A.'}
203
+ </Typography>
204
+ <Typography variant="body2">
205
+ <strong>Smoke:</strong> {member?.smoke || 'N.A.'}
206
+ </Typography>
207
+ <Typography variant="body2">
208
+ <strong>Alcohol:</strong> {member?.alchohol || 'N.A.'}
209
+ </Typography>
210
+ </Grid>
211
+ <Grid size={{ xs: 12, md: 6 }}>
212
+ <Typography variant="body2">
213
+ <strong>Waist:</strong> {member?.waist || 'N.A.'}
214
+ </Typography>
215
+ <Typography variant="body2">
216
+ <strong>Score:</strong> {member?.score || 'N.A.'}
217
+ </Typography>
218
+ </Grid>
219
+ </Grid>
220
+ <Divider className="my-3" />
221
+ <div className="flex justify-center gap-2">
222
+ <Button
223
+ variant="contained"
224
+ size="small"
225
+ onClick={() => handleMemberAction(member?.member_id, 'Approved')}
226
+ disabled={!member?.pending}
227
+ >
228
+ Approve
229
+ </Button>
230
+ <Button
231
+ variant="contained"
232
+ size="small"
233
+ color="error"
234
+ onClick={() => handleMemberAction(member?.member_id, 'Disapproved')}
235
+ disabled={!member?.pending}
236
+ >
237
+ Disapprove
238
+ </Button>
239
+ </div>
240
+ </Box>
241
+ </Collapse>
242
+ </TableCell>
243
+ </TableRow>
244
+ </React.Fragment>
245
+ ))}
246
+ </TableBody>
247
+ </Table>
248
+ </TableContainer>
249
+ )}
250
+ </div>
251
+
252
+ {/* Footer */}
253
+ <div className="p-4 px-6 bg-gray-50 border-t flex justify-end gap-3 rounded-b-lg">
254
+ <Button variant="contained" color="secondary" onClick={onClose} disabled={isLoading}>
255
+ Close
256
+ </Button>
257
+ <Button
258
+ variant="contained"
259
+ color="primary"
260
+ onClick={saveChanges}
261
+ disabled={isLoading || members.length === 0}
262
+ >
263
+ {isLoading ? <CircularProgress size={24} color="inherit" /> : 'Save Changes'}
264
+ </Button>
265
+ </div>
266
+ </Grid>
267
+ </Modal>
268
+ );
269
+ };
270
+
271
+ AshaScreenedMembersModal.propTypes = {
272
+ open: PropTypes.bool,
273
+ onClose: PropTypes.func,
274
+ task: PropTypes.object,
275
+ onSave: PropTypes.any,
276
+ };
277
+
278
+ export default AshaScreenedMembersModal;
@@ -0,0 +1,143 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import {
3
+ Dialog,
4
+ DialogTitle,
5
+ DialogContent,
6
+ DialogActions,
7
+ Button,
8
+ List,
9
+ ListItem,
10
+ ListItemText,
11
+ ListItemIcon,
12
+ Checkbox,
13
+ TextField,
14
+ InputAdornment,
15
+ } from '@mui/material';
16
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
17
+ import { faSearch } from '@fortawesome/free-solid-svg-icons';
18
+ import { showToast } from '@/common/toaster/toaster';
19
+
20
+ const PinFeatureModal = ({ open, onClose, linearMenuItems, pinnedFeatures, onSave }) => {
21
+ const [selected, setSelected] = useState([]);
22
+ const [search, setSearch] = useState('');
23
+
24
+ useEffect(() => {
25
+ if (open) {
26
+ setSelected(pinnedFeatures || []);
27
+ setSearch('');
28
+ }
29
+ }, [open, pinnedFeatures]);
30
+
31
+ const handleToggle = (navState) => {
32
+ const currentIndex = selected.indexOf(navState);
33
+ const newSelected = [...selected];
34
+
35
+ if (currentIndex === -1) {
36
+ if (selected.length >= 5) {
37
+ // Enforce maximum 5 pins
38
+ return;
39
+ }
40
+ newSelected.push(navState);
41
+ } else {
42
+ newSelected.splice(currentIndex, 1);
43
+ }
44
+ setSelected(newSelected);
45
+ };
46
+
47
+ const handleSave = () => {
48
+ onSave(selected);
49
+ onClose();
50
+ };
51
+
52
+ // Convert dictionary back to array and filter out nulls or parents without actual routing
53
+ const availableItems = Object.values(linearMenuItems || {})
54
+ .filter((item) => item?.displayName || item?.name)
55
+ .sort((a, b) => (a.displayName || a.name || '').localeCompare(b.displayName || b.name || ''));
56
+
57
+ const filteredItems = availableItems.filter((item) => {
58
+ const name = (item.displayName || item.name || '').toLowerCase();
59
+ return name.includes(search.toLowerCase());
60
+ });
61
+
62
+ return (
63
+ <Dialog open={open} onClose={onClose} fullWidth maxWidth="sm">
64
+ <DialogTitle>
65
+ Pin Menu Shortcuts
66
+ <div className="text-sm font-normal text-slate-500 mt-1">
67
+ Select up to 5 quick access features for your Dashboard. ({selected.length}/5)
68
+ </div>
69
+ </DialogTitle>
70
+
71
+ <div className="px-6 pb-2">
72
+ <TextField
73
+ fullWidth
74
+ size="small"
75
+ placeholder="Search features..."
76
+ value={search}
77
+ onChange={(e) => setSearch(e.target.value)}
78
+ InputProps={{
79
+ startAdornment: (
80
+ <InputAdornment position="start">
81
+ <FontAwesomeIcon icon={faSearch} className="text-slate-400" />
82
+ </InputAdornment>
83
+ ),
84
+ }}
85
+ />
86
+ </div>
87
+
88
+ <DialogContent dividers sx={{ p: 0, minHeight: 300 }}>
89
+ <List sx={{ pt: 0 }}>
90
+ {filteredItems.map((item) => {
91
+ const isChecked = selected.includes(item.navigationState);
92
+ const isDisabled = !isChecked && selected.length >= 5;
93
+
94
+ return (
95
+ <ListItem
96
+ className='cursor-pointer'
97
+ key={item.navigationState}
98
+ button
99
+ onClick={() => {
100
+ if (!isDisabled) {
101
+ handleToggle(item.navigationState);
102
+ } else {
103
+ showToast({
104
+ message: 'You can only pin up to 5 features.',
105
+ type: 'info'
106
+ });
107
+ }
108
+ }}
109
+ disabled={isDisabled}
110
+ >
111
+ <ListItemIcon>
112
+ <Checkbox
113
+ edge="start"
114
+ checked={isChecked}
115
+ tabIndex={-1}
116
+ disableRipple
117
+ disabled={isDisabled}
118
+ />
119
+ </ListItemIcon>
120
+ <ListItemText primary={item.displayName || item.name} secondary={item.navigationState} />
121
+ </ListItem>
122
+ );
123
+ })}
124
+ {filteredItems.length === 0 && (
125
+ <div className="text-center text-slate-500 py-8">
126
+ No matching features found.
127
+ </div>
128
+ )}
129
+ </List>
130
+ </DialogContent>
131
+ <DialogActions sx={{ p: '1rem 1.5rem' }}>
132
+ <Button onClick={onClose} color="inherit">
133
+ Cancel
134
+ </Button>
135
+ <Button onClick={handleSave} variant="contained" color="primary">
136
+ Save Pins
137
+ </Button>
138
+ </DialogActions>
139
+ </Dialog>
140
+ );
141
+ };
142
+
143
+ export default PinFeatureModal;
@@ -0,0 +1,163 @@
1
+ import React, { useState } from 'react';
2
+ import { useSelector, useDispatch } from 'react-redux';
3
+ import { useNavigate } from 'react-router-dom';
4
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
5
+ import {
6
+ faPlus,
7
+ faUsers,
8
+ faUserTie,
9
+ faChartBar,
10
+ faHeartbeat,
11
+ faHome,
12
+ faCog,
13
+ faFileAlt,
14
+ faStar,
15
+ faCubes,
16
+ faLayerGroup,
17
+ faTimes,
18
+ } from '@fortawesome/free-solid-svg-icons';
19
+ import { getPinnedFeatures, setPinnedFeatures } from '@/store/reducers/AuthenticationReducer';
20
+ import PinFeatureModal from './PinFeatureModal';
21
+ import GeneralUtil from '@/common/services/util/GeneralUtil';
22
+ import { Tooltip, useTheme, alpha } from '@mui/material';
23
+
24
+ const QuickLinks = () => {
25
+ const dispatch = useDispatch();
26
+ const navigate = useNavigate();
27
+ const theme = useTheme();
28
+ const isDark = theme.palette.mode === 'dark';
29
+ const pinnedStates = useSelector(getPinnedFeatures) || [];
30
+ const { linearMenuItems } = useSelector((state) => state.Authenticate);
31
+ const [modalOpen, setModalOpen] = useState(false);
32
+
33
+ // Handler to remove a shortcut
34
+ const handleRemove = (navState) => {
35
+ const updated = pinnedStates.filter((ns) => ns !== navState);
36
+ dispatch(setPinnedFeatures(updated));
37
+ };
38
+
39
+ // Derive full objects based on navigationState matches
40
+ const pinnedItems = pinnedStates.map((navState) => linearMenuItems?.[navState]).filter(Boolean);
41
+
42
+ const getFeatureIcon = (name) => {
43
+ const n = (name || '').toLowerCase();
44
+ if (n.includes('user')) return faUsers;
45
+ if (n.includes('role')) return faUserTie;
46
+ if (n.includes('report')) return faChartBar;
47
+ if (n.includes('patient') || n.includes('health') || n.includes('disease')) return faHeartbeat;
48
+ if (n.includes('dashboard') || n.includes('home')) return faHome;
49
+ if (n.includes('setting') || n.includes('config')) return faCog;
50
+ if (n.includes('form') || n.includes('data')) return faFileAlt;
51
+ if (n.includes('location')) return faLayerGroup;
52
+ if (n.includes('feature') || n.includes('app')) return faCubes;
53
+ return faStar; // Default placeholder
54
+ };
55
+
56
+ const handleShortcutClick = (item) => {
57
+ let path = GeneralUtil.naviagationFunc(item);
58
+ if (path) {
59
+ if (!path.startsWith('/ui/')) {
60
+ path = `/ui/${path}`;
61
+ }
62
+ // is ekavach then only open in new tab
63
+ if (path.includes('report/view/')) {
64
+ if (GeneralUtil.isEkavach) {
65
+ window.open(`/ui/${path}`, '_blank');
66
+ } else {
67
+ navigate(path);
68
+ }
69
+ } else {
70
+ navigate(path);
71
+ }
72
+ }
73
+ };
74
+
75
+ const handleSavePins = (selectedNavStates) => {
76
+ dispatch(setPinnedFeatures(selectedNavStates));
77
+ };
78
+
79
+ // Skip showing anything if the component renders before menu items load
80
+ if (!linearMenuItems || Object.keys(linearMenuItems).length === 0) {
81
+ return null;
82
+ }
83
+
84
+ return (
85
+ <div className="w-full mt-4 mb-2 flex justify-center">
86
+ <div className="flex flex-wrap items-center justify-center gap-6 max-w-4xl px-4 py-4">
87
+ {pinnedItems.map((item, idx) => {
88
+ const name = item.displayName || item.name;
89
+ const icon = getFeatureIcon(name);
90
+ return (
91
+ <div className="relative" key={item.navigationState || idx}>
92
+ <Tooltip title={name} arrow placement="bottom">
93
+ <button
94
+ onClick={() => handleShortcutClick(item)}
95
+ className="flex flex-col items-center group w-[100px] hover:-translate-y-1 transition-transform duration-200 focus:outline-none cursor-pointer"
96
+ >
97
+ <div
98
+ className={`w-[56px] h-[56px] rounded-full shadow-sm flex items-center justify-center border transition-colors mb-2 ${
99
+ isDark
100
+ ? 'bg-slate-800 border-slate-700 group-hover:bg-slate-700 group-hover:border-blue-500/50'
101
+ : 'bg-slate-100 border-slate-200 group-hover:bg-blue-50 group-hover:border-blue-200'
102
+ }`}
103
+ >
104
+ <FontAwesomeIcon
105
+ icon={icon}
106
+ className={`text-xl transition-colors ${
107
+ isDark ? 'text-slate-300 group-hover:text-blue-400' : 'text-slate-600 group-hover:text-blue-600'
108
+ }`}
109
+ />
110
+ </div>
111
+ <span
112
+ className={`text-[13px] font-medium text-center line-clamp-1 leading-tight transition-colors ${
113
+ isDark ? 'text-slate-200 group-hover:text-blue-400' : 'text-slate-700 group-hover:text-blue-700'
114
+ }`}
115
+ >
116
+ {name}
117
+ </span>
118
+ </button>
119
+ </Tooltip>
120
+ </div>
121
+ );
122
+ })}
123
+
124
+ <button
125
+ onClick={() => setModalOpen(true)}
126
+ className="flex flex-col items-center group w-[100px] hover:-translate-y-1 transition-transform duration-200 focus:outline-none cursor-pointer"
127
+ >
128
+ <div
129
+ className={`w-[56px] h-[56px] rounded-full flex items-center justify-center border border-dashed transition-colors ${
130
+ isDark
131
+ ? 'bg-slate-800/40 border-slate-700 group-hover:bg-slate-800/60 group-hover:border-slate-500'
132
+ : 'bg-slate-50 border-slate-300 group-hover:bg-slate-100 group-hover:border-slate-400'
133
+ }`}
134
+ >
135
+ <FontAwesomeIcon
136
+ icon={faPlus}
137
+ className={`transition-colors ${
138
+ isDark ? 'text-slate-500 group-hover:text-slate-300' : 'text-slate-400 group-hover:text-slate-600'
139
+ }`}
140
+ />
141
+ </div>
142
+ <span
143
+ className={`text-[13px] font-medium text-center transition-colors ${
144
+ isDark ? 'text-slate-400 group-hover:text-slate-200' : 'text-slate-500 group-hover:text-slate-700'
145
+ }`}
146
+ >
147
+ Add Shortcut
148
+ </span>
149
+ </button>
150
+ </div>
151
+
152
+ <PinFeatureModal
153
+ open={modalOpen}
154
+ onClose={() => setModalOpen(false)}
155
+ linearMenuItems={linearMenuItems}
156
+ pinnedFeatures={pinnedStates}
157
+ onSave={handleSavePins}
158
+ />
159
+ </div>
160
+ );
161
+ };
162
+
163
+ export default QuickLinks;
@@ -0,0 +1,56 @@
1
+ import React, { lazy, Suspense } from 'react';
2
+ const WidgetCard = lazy(() => import('@/views/feature-components/Dashboard/WidgetCard'));
3
+ import { Button } from '@mui/material';
4
+ import Grid from '@mui/material/Grid2';
5
+ import { Box } from '@mui/system';
6
+ import PropTypes from 'prop-types';
7
+
8
+ import { useTranslateProvider } from '@/common/languageTranslator/TranslationContext';
9
+ const Taskbar = ({
10
+ hiddenWidgets,
11
+ handleHideTaskbar,
12
+ handleUnhideWidget,
13
+ onWidgetClick,
14
+ dataTestId = 'Dashboard-Taskbar',
15
+ }) => {
16
+ const { translate } = useTranslateProvider();
17
+ return (
18
+ <Box className="border border-gray-300 p-4 mt-4" data-testid={dataTestId}>
19
+ <Grid container spacing={2}>
20
+ {hiddenWidgets
21
+ .sort((a, b) => {
22
+ if (a.orderNo === null) return 1;
23
+ if (b.orderNo === null) return -1;
24
+ return a.orderNo - b.orderNo;
25
+ })
26
+ .map((widget) => {
27
+ return (
28
+ <Grid item key={widget.id} size={{ xs: 12, sm: 6 }}>
29
+ <Suspense>
30
+ <WidgetCard
31
+ onClick={() => onWidgetClick(widget)}
32
+ widgetData={widget}
33
+ hidden={true}
34
+ onArrowClick={() => handleUnhideWidget(widget)}
35
+ dataTestId={`${dataTestId}-Widget-Card`}
36
+ />
37
+ </Suspense>
38
+ </Grid>
39
+ );
40
+ })}
41
+ </Grid>
42
+ <Button data-testid={`taskbar-hide-button`} variant="contained" className=" mt-4" onClick={handleHideTaskbar}>
43
+ {translate('Hide Taskbar')}
44
+ </Button>
45
+ </Box>
46
+ );
47
+ };
48
+
49
+ export default Taskbar;
50
+ Taskbar.propTypes = {
51
+ hiddenWidgets: PropTypes.any,
52
+ handleHideTaskbar: PropTypes.any,
53
+ handleUnhideWidget: PropTypes.any,
54
+ onWidgetClick: PropTypes.any,
55
+ dataTestId: PropTypes.any,
56
+ };