@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,566 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import {
4
+ Modal,
5
+ Typography,
6
+ IconButton,
7
+ Button,
8
+ Divider,
9
+ MenuItem,
10
+ Select,
11
+ FormControl,
12
+ CircularProgress,
13
+ TextField,
14
+ FormHelperText,
15
+ } from '@mui/material';
16
+ import { useForm, FormProvider, Controller, useWatch } from 'react-hook-form';
17
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
18
+ import {
19
+ faXmark,
20
+ faUser,
21
+ faPhone,
22
+ faUserNurse,
23
+ faRulerVertical,
24
+ faWeightScale,
25
+ } from '@fortawesome/free-solid-svg-icons';
26
+ import * as Yup from 'yup';
27
+ import { yupResolver } from '@hookform/resolvers/yup';
28
+
29
+ // --- Mock Service Imports (Replace with your actual imports) ---
30
+
31
+ import { execute } from '@/common/services/GlobalApis';
32
+ import { showToast } from '@/common/toaster/toaster'; // Assuming a toaster exists
33
+ import { FormItem } from '@/views/custom-components/FormItem';
34
+ import CustomRadioGroup from '@/views/custom-components/CustomRadioComponent';
35
+
36
+ import SafeHtml from '@/common/SafeHtml.jsx';
37
+
38
+ // --- Validation Schema ---
39
+ const validationSchema = Yup.object().shape({
40
+ weight: Yup.number()
41
+ .typeError('Weight must be a number')
42
+ .required('Enter weight')
43
+ .min(0.1, 'Min 0.1')
44
+ .max(23, 'Max 23'),
45
+ height: Yup.number()
46
+ .typeError('Height must be a number')
47
+ .required('Enter height')
48
+ .min(45, 'Min 45')
49
+ .max(120, 'Max 120')
50
+ .test('is-decimal', 'Height not allowed in decimal value', (val) => Number.isInteger(val)),
51
+ midUpperArmCircumference: Yup.number()
52
+ .typeError('MUAC must be a number')
53
+ .required('Enter MUAC')
54
+ .min(6, 'Min 6')
55
+ .max(26, 'Max 26'),
56
+ bilateralPittingOedema: Yup.string().required('Select a value'),
57
+ // Conditional validation for apetiteTest and screeningCenter is handled in logic or via dynamic schema if strictly needed.
58
+ // For simplicity with RHF, we often make them nullable in schema and validate in onSubmit for complex business logic.
59
+ apetiteTest: Yup.string().nullable(),
60
+ screeningCenter: Yup.string().nullable(),
61
+ });
62
+
63
+ // --- Detail Item Component ---
64
+ const DetailItem = ({ label, value, icon, isHtml }) => {
65
+ if (value === null || value === undefined) return null;
66
+ return (
67
+ <div className="flex flex-col mb-3">
68
+ <Typography
69
+ variant="caption"
70
+ className="text-gray-500 uppercase tracking-wider mb-1 flex items-center gap-2 text-[11px] font-semibold"
71
+ >
72
+ {icon && <FontAwesomeIcon icon={icon} className="text-gray-400" />}
73
+ {label}
74
+ </Typography>
75
+ {isHtml ? (
76
+ <div className="font-medium text-gray-900 text-[14px]" dangerouslySetInnerHTML={{ __html: value }} />
77
+ ) : (
78
+ <Typography variant="body2" className="font-medium text-gray-900 text-[14px]">
79
+ {value}
80
+ </Typography>
81
+ )}
82
+ </div>
83
+ );
84
+ };
85
+ DetailItem.propTypes = {
86
+ label: PropTypes.string,
87
+ value: PropTypes.string,
88
+ icon: PropTypes.object,
89
+ isHtml: PropTypes.bool,
90
+ };
91
+ const MoVerficationForChildScreeningMoadal = ({ open, onClose, message, task, onSave }) => {
92
+ const [isLoading, setIsLoading] = useState(false);
93
+ const [screeningCenters, setScreeningCenters] = useState([]);
94
+ const [rchDetails, setRchDetails] = useState({});
95
+ const [sdScoreInfo, setSdScoreInfo] = useState({ score: 'NONE', display: '--' });
96
+ const [showApetiteTest, setShowApetiteTest] = useState(true);
97
+
98
+ // --- Form Setup ---
99
+ const methods = useForm({
100
+ mode: 'onChange',
101
+ resolver: yupResolver(validationSchema),
102
+ defaultValues: {
103
+ weight: '',
104
+ height: '',
105
+ midUpperArmCircumference: '',
106
+ bilateralPittingOedema: '',
107
+ apetiteTest: null,
108
+ screeningCenter: '',
109
+ },
110
+ });
111
+
112
+ const {
113
+ control,
114
+ handleSubmit,
115
+ reset,
116
+ setValue,
117
+ formState: { errors },
118
+ } = methods;
119
+
120
+ // Watch fields for calculations
121
+ const watchedValues = useWatch({
122
+ control,
123
+ name: ['weight', 'height', 'midUpperArmCircumference', 'bilateralPittingOedema', 'apetiteTest'],
124
+ });
125
+ const [weight, height, muac, oedema, apetiteTest] = watchedValues;
126
+
127
+ // --- Helpers ---
128
+ const formatSdScore = (score) => {
129
+ switch (score) {
130
+ case 'SD4':
131
+ return 'Less than -4';
132
+ case 'SD3':
133
+ return '-4 to -3';
134
+ case 'SD2':
135
+ return '-3 to -2';
136
+ case 'SD1':
137
+ return '-2 to -1';
138
+ case 'MEDIAN':
139
+ return 'MEDIAN';
140
+ default:
141
+ return 'NONE';
142
+ }
143
+ };
144
+
145
+ // --- 1. Init: Fetch Data ---
146
+ useEffect(() => {
147
+ if (open && task?.childId) {
148
+ reset(); // Clear form
149
+ setSdScoreInfo({ score: 'NONE', display: '--' });
150
+ setShowApetiteTest(true);
151
+
152
+ const initData = async () => {
153
+ try {
154
+ setIsLoading(true);
155
+
156
+ // 1. Fetch Screening Centers
157
+ // Note: Assuming logic to get userId exists, or passed in params.
158
+ // Using a generic code here based on your Angular snippet.
159
+ const centerRes = await execute({
160
+ code: 'retrieve_cmtc_nrc_centers_for_rbsk',
161
+ parameters: { userId: task.loggedInUserId },
162
+ });
163
+ if (centerRes?.data?.result) setScreeningCenters(centerRes.data.result);
164
+
165
+ // 2. Fetch RCH Child Service Details
166
+ // Use specific service if available, otherwise generic execute
167
+ const rchRes = await execute({
168
+ // Mapping "ChildScreeningService.retrieveRchChildServiceDetailsByMemberId"
169
+ // You might need to adjust this code to your actual API code string
170
+ code: 'retrieve_rch_child_service_details',
171
+ parameters: { memberId: task.childId },
172
+ });
173
+
174
+ let rchData = rchRes?.data || {};
175
+
176
+ // Format RCH SD Score
177
+ rchData.sdScoreDisplay = formatSdScore(rchData.sdScore);
178
+
179
+ // 3. Fetch Medical Complications
180
+ const medRes = await execute({
181
+ code: 'retrieve_medical_complications',
182
+ parameters: { childId: task.childId },
183
+ });
184
+ rchData.medicalComplications = medRes?.data?.medicalComplications;
185
+
186
+ setRchDetails(rchData);
187
+ } catch (error) {
188
+ console.error(error);
189
+ showToast({ message: 'Failed to fetch actions', type: 'error' });
190
+ } finally {
191
+ setIsLoading(false);
192
+ }
193
+ };
194
+
195
+ initData();
196
+ }
197
+ }, [open, task, reset]);
198
+
199
+ // --- 2. Calculate SD Score (Effect) ---
200
+ useEffect(() => {
201
+ const calculateScore = async () => {
202
+ if (weight && height && Number.isInteger(Number(height)) && task?.gender) {
203
+ try {
204
+ // Call API to get SD Score
205
+ const response = await execute({
206
+ code: 'retrieve_sd_score', // Adjust code
207
+ parameters: { gender: task.gender, height, weight },
208
+ });
209
+
210
+ const score = response?.data?.sdScore || 'NONE';
211
+ setSdScoreInfo({
212
+ score: score,
213
+ display: formatSdScore(score),
214
+ });
215
+ } catch (e) {
216
+ console.error(e);
217
+ }
218
+ } else {
219
+ setSdScoreInfo({ score: 'NONE', display: '--' });
220
+ }
221
+ };
222
+
223
+ const timer = setTimeout(() => {
224
+ if (weight && height) calculateScore();
225
+ }, 500); // Debounce
226
+
227
+ return () => clearTimeout(timer);
228
+ }, [weight, height, task?.gender]);
229
+
230
+ // --- 3. Validate SAM Child (Effect) ---
231
+ useEffect(() => {
232
+ // Logic: If NOT SAM, hide appetite test
233
+ // SAM Criteria: (MUAC <= 11.5) OR (SD Score is SD3 or SD4) OR (Oedema is present)
234
+ // The Angular logic was:
235
+ // if (MUAC > 11.5 && SD != SD3 && SD != SD4 && Oedema == NOTPRESENT) -> NOT SAM -> Hide Test
236
+
237
+ const isMuacSafe = muac ? Number(muac) > 11.5 : false;
238
+ const isSdSafe = sdScoreInfo.score !== 'SD3' && sdScoreInfo.score !== 'SD4';
239
+ const isOedemaSafe = oedema === 'NOTPRESENT';
240
+
241
+ if (muac && oedema && sdScoreInfo.score !== 'NONE') {
242
+ if (isMuacSafe && isSdSafe && isOedemaSafe) {
243
+ setShowApetiteTest(false);
244
+ setValue('apetiteTest', null); // Reset value
245
+ } else {
246
+ setShowApetiteTest(true);
247
+ }
248
+ }
249
+ }, [muac, oedema, sdScoreInfo.score, setValue]);
250
+
251
+ // --- 4. Submit Logic ---
252
+ const onSubmit = async (data) => {
253
+ // 1. Final SAM Check
254
+ const isMuacSafe = Number(data.midUpperArmCircumference) > 11.5;
255
+ const isSdSafe = sdScoreInfo.score !== 'SD3' && sdScoreInfo.score !== 'SD4';
256
+ const isOedemaSafe = data.bilateralPittingOedema === 'NOTPRESENT';
257
+ const isNotSAM = isMuacSafe && isSdSafe && isOedemaSafe;
258
+
259
+ if (isNotSAM) {
260
+ showToast('error', 'Child is not SAM. Entry will be removed');
261
+ onClose(); // Just close
262
+ return;
263
+ }
264
+
265
+ // 2. Validate Appetite Test Logic
266
+ // If Appetite Test is shown and is FALSE (Fail), Screening Center is required
267
+ if (showApetiteTest) {
268
+ if (data.apetiteTest === null || data.apetiteTest === undefined) {
269
+ showToast('error', 'Appetite Test is required');
270
+ return;
271
+ }
272
+ if (data.apetiteTest === 'false' && !data.screeningCenter) {
273
+ showToast('error', 'Screening Center is required when Appetite Test fails');
274
+ return;
275
+ }
276
+ }
277
+
278
+ setIsLoading(true);
279
+
280
+ // Prepare Payload
281
+ const payload = {
282
+ childId: task.childId,
283
+ childName: task.childName,
284
+ areaName: task.areaName,
285
+ villageName: task.villageName,
286
+ fhwName: task.fhwName,
287
+ fhwContactNumber: task.fhwContactNumber,
288
+ motherName: task.motherName,
289
+ motherContact: task.motherContact,
290
+ screenedOn: new Date(),
291
+ state: 'ACTIVE',
292
+ locationId: task.locationId,
293
+ gender: task.gender,
294
+ screeningCenter: data.screeningCenter,
295
+ apetiteTest: data.apetiteTest === 'true', // Convert string to boolean
296
+ childScreeningObject: {
297
+ childId: task.childId,
298
+ weight: data.weight,
299
+ height: data.height,
300
+ midUpperArmCircumference: data.midUpperArmCircumference,
301
+ bilateralPittingOedema: data.bilateralPittingOedema,
302
+ sdScore: sdScoreInfo.score,
303
+ sdScoreDisplay: sdScoreInfo.display,
304
+ },
305
+ };
306
+
307
+ try {
308
+ // 1. Create Child Screening
309
+ await execute({
310
+ code: 'create_child_screening', // Replace with actual API/Service call
311
+ parameters: payload,
312
+ });
313
+ showToast('success', 'Details saved successfully');
314
+
315
+ // 2. Create MO Verification
316
+ await execute({
317
+ code: 'create_mo_verification', // Replace with actual API/Service call
318
+ parameters: payload.childScreeningObject,
319
+ });
320
+ const updatedTask = {
321
+ ...task,
322
+ selectedAction: 'VERIFIED',
323
+ };
324
+ await onSave(updatedTask);
325
+ onClose();
326
+ } catch (error) {
327
+ if (error?.data?.errorcode === 101) {
328
+ showToast('error', 'Child is already added');
329
+ } else {
330
+ showToast({ message: 'Unable to save task actions', type: 'error' });
331
+ }
332
+ onClose();
333
+ } finally {
334
+ setIsLoading(false);
335
+ }
336
+ };
337
+
338
+ return (
339
+ <Modal open={open} onClose={() => onClose(null)} className="flex items-center justify-center">
340
+ <div className="bg-white shadow-2xl rounded-lg flex flex-col w-[90%] max-w-[800px] outline-none max-h-[90vh]">
341
+ {/* Header */}
342
+ <div className="flex justify-between items-center p-5 border-b border-gray-100 bg-gray-50 rounded-t-lg">
343
+ <Typography variant="h6" className="font-bold text-customBlue">
344
+ {message || 'Perform Action'}
345
+ </Typography>
346
+ <IconButton onClick={() => onClose(null)} size="small" disabled={isLoading}>
347
+ <FontAwesomeIcon icon={faXmark} className="text-gray-400 hover:text-gray-600" />
348
+ </IconButton>
349
+ </div>
350
+
351
+ <FormProvider {...methods}>
352
+ <form onSubmit={handleSubmit(onSubmit)} className="flex flex-col flex-1 overflow-hidden">
353
+ <div className="overflow-y-auto p-6">
354
+ {/* Child Info Header */}
355
+ <div className="mb-6">
356
+ <Typography variant="h6" className="font-bold text-primary-600 mb-2 text-customBlue">
357
+ {task?.childName || 'Child Name'}
358
+ </Typography>
359
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-x-4 gap-y-2 text-sm text-gray-600">
360
+ <DetailItem label="Area" value={task?.areaName} />
361
+ <DetailItem label="Village" value={task?.villageName} />
362
+ <DetailItem label="Mother" value={task?.motherName} icon={faUser} />
363
+ <DetailItem label="Mother Contact" value={task?.motherContact} icon={faPhone} />
364
+ <DetailItem label="FHW Name" value={task?.fhwName} icon={faUserNurse} />
365
+ <DetailItem label="FHW Contact" value={task?.fhwContactNumber} icon={faPhone} />
366
+ </div>
367
+ </div>
368
+
369
+ <Divider className="mb-6" />
370
+
371
+ {/* RCH Details (Read Only) */}
372
+ <Typography variant="subtitle2" className="text-gray-500 font-bold uppercase mb-3 text-xs tracking-wider">
373
+ Current RCH Details
374
+ </Typography>
375
+ <div className="grid grid-cols-1 md:grid-cols-3 gap-4 mb-6 bg-gray-50 p-4 rounded-md border border-gray-100">
376
+ <DetailItem
377
+ label="Weight"
378
+ value={rchDetails.weight ? `${rchDetails.weight} kgs` : 'Not available'}
379
+ icon={faWeightScale}
380
+ />
381
+ <DetailItem
382
+ label="Height"
383
+ value={rchDetails.height ? `${rchDetails.height} cms` : 'Not available'}
384
+ icon={faRulerVertical}
385
+ />
386
+ <DetailItem label="Oedema" value={rchDetails.havePedalEdema ? 'Yes' : 'No'} />
387
+ <DetailItem
388
+ label="MUAC"
389
+ value={rchDetails.midArmCircumference ? `${rchDetails.midArmCircumference} cms` : 'Not available'}
390
+ />
391
+ <DetailItem label="SD Score" value={rchDetails.sdScoreDisplay || 'N/A'} />
392
+ <DetailItem label="Medical Complications" value={rchDetails.medicalComplications} isHtml={true} />
393
+ </div>
394
+
395
+ <Divider className="mb-6" />
396
+
397
+ {/* Input Form */}
398
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
399
+ {/* Weight */}
400
+ <Controller
401
+ name="weight"
402
+ control={control}
403
+ render={({ field }) => (
404
+ <FormItem label="Weight (in Kg)" required>
405
+ <TextField
406
+ {...field}
407
+ type="number"
408
+ fullWidth
409
+ size="small"
410
+ error={!!errors.weight}
411
+ placeholder="Min 0.1 - Max 23"
412
+ />
413
+ <FormHelperText error>{errors.weight?.message}</FormHelperText>
414
+ </FormItem>
415
+ )}
416
+ />
417
+
418
+ {/* Height */}
419
+ <Controller
420
+ name="height"
421
+ control={control}
422
+ render={({ field }) => (
423
+ <FormItem label="Height (in cm)" required>
424
+ <TextField
425
+ {...field}
426
+ type="number"
427
+ fullWidth
428
+ size="small"
429
+ error={!!errors.height}
430
+ placeholder="Min 45 - Max 120"
431
+ />
432
+ <FormHelperText error>{errors.height?.message}</FormHelperText>
433
+ </FormItem>
434
+ )}
435
+ />
436
+
437
+ {/* MUAC */}
438
+ <Controller
439
+ name="midUpperArmCircumference"
440
+ control={control}
441
+ render={({ field }) => (
442
+ <FormItem label="MUAC (in cm)" required>
443
+ <TextField
444
+ {...field}
445
+ type="number"
446
+ fullWidth
447
+ size="small"
448
+ error={!!errors.midUpperArmCircumference}
449
+ placeholder="Min 6 - Max 26"
450
+ />
451
+ <FormHelperText error>{errors.midUpperArmCircumference?.message}</FormHelperText>
452
+ </FormItem>
453
+ )}
454
+ />
455
+
456
+ {/* Calculated SD Score Display */}
457
+ <FormItem label="Calculated SD Score">
458
+ <div className="p-2 bg-gray-100 rounded border border-gray-200 text-sm font-semibold h-[40px] flex items-center">
459
+ {sdScoreInfo.display}
460
+ </div>
461
+ </FormItem>
462
+
463
+ {/* Oedema */}
464
+ <Controller
465
+ name="bilateralPittingOedema"
466
+ control={control}
467
+ render={({ field }) => (
468
+ <FormItem label="Bilateral Pitting Oedema" required>
469
+ <FormControl fullWidth size="small" error={!!errors.bilateralPittingOedema}>
470
+ <Select {...field} displayEmpty value={field.value || ''}>
471
+ <MenuItem value="" disabled>
472
+ -- Select --
473
+ </MenuItem>
474
+ <MenuItem value="+">+</MenuItem>
475
+ <MenuItem value="++">++</MenuItem>
476
+ <MenuItem value="+++">+++</MenuItem>
477
+ <MenuItem value="NOTPRESENT">Not present</MenuItem>
478
+ </Select>
479
+ <FormHelperText>{errors.bilateralPittingOedema?.message}</FormHelperText>
480
+ </FormControl>
481
+ </FormItem>
482
+ )}
483
+ />
484
+
485
+ {/* Appetite Test (Conditional) */}
486
+ {showApetiteTest && (
487
+ <div className="md:col-span-2 grid grid-cols-1 md:grid-cols-2 gap-6 p-4 bg-orange-50 rounded border border-orange-100">
488
+ <FormItem label="Appetite Test" required>
489
+ <CustomRadioGroup
490
+ control={control}
491
+ name="apetiteTest"
492
+ errors={errors}
493
+ options={[
494
+ { label: 'Pass', value: 'true' },
495
+ { label: 'Fail', value: 'false' },
496
+ ]}
497
+ direction="row"
498
+ />
499
+ </FormItem>
500
+
501
+ {/* Screening Center (Only if Appetite Test Fail) */}
502
+ {!apetiteTest && (
503
+ <Controller
504
+ name="screeningCenter"
505
+ control={control}
506
+ render={({ field }) => (
507
+ <FormItem label="Screening Center" required>
508
+ <FormControl fullWidth size="small" error={!!errors.screeningCenter}>
509
+ <Select {...field} displayEmpty value={field.value || ''}>
510
+ <MenuItem value="" disabled>
511
+ -- Select --
512
+ </MenuItem>
513
+ {screeningCenters.map((center) => (
514
+ <MenuItem key={center.id} value={center.id}>
515
+ {center.name}
516
+ </MenuItem>
517
+ ))}
518
+ </Select>
519
+ </FormControl>
520
+ </FormItem>
521
+ )}
522
+ />
523
+ )}
524
+ </div>
525
+ )}
526
+ </div>
527
+ </div>
528
+
529
+ {/* Footer */}
530
+ <div className="p-4 px-6 bg-gray-50 border-t border-gray-100 flex justify-end gap-3 rounded-b-lg">
531
+ <Button
532
+ onClick={() => onClose(null)}
533
+ variant="outlined"
534
+ color="inherit"
535
+ disabled={isLoading}
536
+ className="border-gray-300 text-gray-600 normal-case"
537
+ >
538
+ Cancel
539
+ </Button>
540
+ <Button
541
+ type="submit"
542
+ variant="contained"
543
+ color="primary"
544
+ disabled={isLoading}
545
+ startIcon={isLoading ? <CircularProgress size={16} color="inherit" /> : null}
546
+ className="bg-blue-600 hover:bg-blue-700 normal-case shadow-none px-6"
547
+ >
548
+ {isLoading ? 'Saving...' : 'Save'}
549
+ </Button>
550
+ </div>
551
+ </form>
552
+ </FormProvider>
553
+ </div>
554
+ </Modal>
555
+ );
556
+ };
557
+
558
+ MoVerficationForChildScreeningMoadal.propTypes = {
559
+ open: PropTypes.bool,
560
+ onClose: PropTypes.func,
561
+ task: PropTypes.object,
562
+ message: PropTypes.string,
563
+ onSave: PropTypes.func,
564
+ };
565
+
566
+ export default MoVerficationForChildScreeningMoadal;