@argusoft/medplat-app-shell 1.0.6 → 1.0.7

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 (263) 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/utils/.gitkeep +0 -0
  161. package/src/utils/FormConstants.js +2629 -0
  162. package/src/utils/GujaratTopoChart.jsx +483 -0
  163. package/src/utils/UUIDgenerator.js +8 -0
  164. package/src/utils/appointment-utils/appointment-utils.js +123 -0
  165. package/src/utils/feature.js +42 -0
  166. package/src/utils/getThemeColor.js +12 -0
  167. package/src/utils/localStorageHelper.js +11 -0
  168. package/src/utils/notifications/enable-push-notifications.js +27 -0
  169. package/src/utils/resolveAppliedStyle.js +11 -0
  170. package/src/utils/themeConfigs.js +1483 -0
  171. package/src/views/custom-components/.gitkeep +0 -0
  172. package/src/views/custom-components/AgIconButton/RIf.jsx +14 -0
  173. package/src/views/custom-components/AgIconButton/button.jsx +108 -0
  174. package/src/views/custom-components/AgIconButton/waterDrop.jsx +95 -0
  175. package/src/views/custom-components/AgIconButton/waterDrop.scss +37 -0
  176. package/src/views/custom-components/AlertPlaceholder.jsx +32 -0
  177. package/src/views/custom-components/AllFaIconsSelector.jsx +56 -0
  178. package/src/views/custom-components/CkEditor/CkEditor.js +102 -0
  179. package/src/views/custom-components/CustomAccordion.jsx +72 -0
  180. package/src/views/custom-components/CustomActionIcons.jsx +118 -0
  181. package/src/views/custom-components/CustomAutoComplete.jsx +188 -0
  182. package/src/views/custom-components/CustomCheckBox.jsx +60 -0
  183. package/src/views/custom-components/CustomConfirmationModal.jsx +118 -0
  184. package/src/views/custom-components/CustomCountrySelect.jsx +129 -0
  185. package/src/views/custom-components/CustomDatePicker.jsx +122 -0
  186. package/src/views/custom-components/CustomDropdown.jsx +191 -0
  187. package/src/views/custom-components/CustomFileUpload.jsx +387 -0
  188. package/src/views/custom-components/CustomFullCalendar.jsx +514 -0
  189. package/src/views/custom-components/CustomInfiniteScroll.jsx +126 -0
  190. package/src/views/custom-components/CustomRadioComponent.jsx +65 -0
  191. package/src/views/custom-components/CustomStatsComponent.jsx +114 -0
  192. package/src/views/custom-components/CustomSvgUpload.jsx +170 -0
  193. package/src/views/custom-components/CustomSwitch.jsx +37 -0
  194. package/src/views/custom-components/CustomTabPanel.jsx +19 -0
  195. package/src/views/custom-components/CustomTextArea.jsx +62 -0
  196. package/src/views/custom-components/CustomTextArea.scss +27 -0
  197. package/src/views/custom-components/CustomTextField.jsx +116 -0
  198. package/src/views/custom-components/CustomToggleSwitch.jsx +138 -0
  199. package/src/views/custom-components/CustomTooltip.jsx +51 -0
  200. package/src/views/custom-components/CustomZoomImage.jsx +134 -0
  201. package/src/views/custom-components/CustomizedTable/CustomizedTableV2.jsx +1407 -0
  202. package/src/views/custom-components/CustomizedTable/VirtualizeTableBody.jsx +295 -0
  203. package/src/views/custom-components/CustomizedTable/helper.jsx +159 -0
  204. package/src/views/custom-components/CustomizedTable.jsx +532 -0
  205. package/src/views/custom-components/EditInputField.jsx +174 -0
  206. package/src/views/custom-components/FieldDescription.jsx +22 -0
  207. package/src/views/custom-components/FileDisplayComponent.jsx +138 -0
  208. package/src/views/custom-components/FormItem.jsx +53 -0
  209. package/src/views/custom-components/GenericChart.jsx +80 -0
  210. package/src/views/custom-components/InfoBadge.jsx +60 -0
  211. package/src/views/custom-components/PostgresEditor.jsx +801 -0
  212. package/src/views/custom-components/ResizableEditAutocompleteField.jsx +249 -0
  213. package/src/views/custom-components/ResizableEditInputField.jsx +215 -0
  214. package/src/views/custom-components/ResizeableEditSelectField.jsx +197 -0
  215. package/src/views/custom-components/SideOverlay.jsx +113 -0
  216. package/src/views/custom-components/SideOverlay.scss +42 -0
  217. package/src/views/custom-components/calendar.scss +571 -0
  218. package/src/views/feature-components/.gitkeep +0 -0
  219. package/src/views/feature-components/Dashboard/DashboardUI.jsx +1043 -0
  220. package/src/views/feature-components/Dashboard/DhnddModal/AshaDataQualityVerificationModal.jsx +278 -0
  221. package/src/views/feature-components/Dashboard/PinFeatureModal.jsx +143 -0
  222. package/src/views/feature-components/Dashboard/QuickLinks.jsx +163 -0
  223. package/src/views/feature-components/Dashboard/Taskbar.jsx +56 -0
  224. package/src/views/feature-components/Dashboard/WebtasksFilterForm.jsx +109 -0
  225. package/src/views/feature-components/Dashboard/WidgetCard.jsx +161 -0
  226. package/src/views/feature-components/Dashboard/actionModal.jsx +263 -0
  227. package/src/views/feature-components/Dashboard/ekavachModal/HealthWorkerIncorrectDetailsModal.jsx +332 -0
  228. package/src/views/feature-components/Dashboard/ekavachModal/MoMaternalDeathVerifcationModal.jsx +275 -0
  229. package/src/views/feature-components/Dashboard/ekavachModal/MoVerficationForChildScreeningMoadal.jsx +566 -0
  230. package/src/views/feature-components/FeatureUsageAnalytics/FeatureUsageAnalytics.jsx +989 -0
  231. package/src/views/feature-components/Features/NewServerManagement.jsx +217 -0
  232. package/src/views/feature-components/Features/ServerManagement.scss +120 -0
  233. package/src/views/feature-components/ForgotPassword/ForgotPassword.jsx +226 -0
  234. package/src/views/feature-components/LocationDirective/LocationDirective.jsx +992 -0
  235. package/src/views/feature-components/LocationDirective/LocationDirectiveV2.jsx +909 -0
  236. package/src/views/feature-components/NotFound.jsx +66 -0
  237. package/src/views/feature-components/Onboarding/Onboarding.jsx +1400 -0
  238. package/src/views/feature-components/Skeletons.js +115 -0
  239. package/src/views/feature-components/Unauthorized.jsx +48 -0
  240. package/src/views/feature-components/VerifyRoute.jsx +88 -0
  241. package/src/views/feature-components/YearlyRecap/YearlyRecap.jsx +357 -0
  242. package/src/views/feature-components/YearlyRecap/components/RecapSlide.jsx +183 -0
  243. package/src/views/feature-components/YearlyRecap/languageTranslator/TranslationContext.js +5 -0
  244. package/src/views/feature-components/YearlyRecap/languageTranslator/TranslationProvider.jsx +26 -0
  245. package/src/views/feature-components/YearlyRecap/languageTranslator/i18n.js +46 -0
  246. package/src/views/feature-components/YearlyRecap/languageTranslator/translations.json +167 -0
  247. package/src/views/feature-components/YearlyRecap/slides/IntroSlide.jsx +233 -0
  248. package/src/views/feature-components/YearlyRecap/slides/MaternalHealthSlide.jsx +146 -0
  249. package/src/views/feature-components/YearlyRecap/slides/MetricSlide.jsx +227 -0
  250. package/src/views/feature-components/YearlyRecap/slides/OutroSlide.jsx +701 -0
  251. package/src/views/feature-components/YearlyRecap/slides/ReachSlide.jsx +273 -0
  252. package/src/views/feature-components/login/Login.jsx +840 -0
  253. package/src/views/feature-components/login/Login.scss +154 -0
  254. package/src/views/feature-components/login/LoginConfigurator.jsx +1149 -0
  255. package/src/views/feature-components/login/TwoFactorSetupModal.jsx +411 -0
  256. package/src/views/feature-components/login/simplifyMenu.js +45 -0
  257. package/src/views/feature-components/system-config/ManageSystemConfigs.jsx +284 -0
  258. package/src/views/feature-components/system-config/SystemConfig.jsx +299 -0
  259. package/src/views/feature-components/users/ChangePasswordModal.jsx +243 -0
  260. package/src/views/feature-components/users/PasswordField.jsx +56 -0
  261. package/dist/index.css +0 -1
  262. package/dist/index.js +0 -32001
  263. package/dist/index.js.map +0 -1
@@ -0,0 +1,684 @@
1
+ import React, { useCallback, useEffect, useState, useRef } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { Modal, Paper, Typography, Button, Card, CardHeader, CardContent } from '@mui/material';
4
+ import Grid from '@mui/material/Grid2';
5
+
6
+ import {
7
+ checkBankAccountNumberExist,
8
+ getBankNamesForPBI,
9
+ getPreferredLanguage,
10
+ getUserDetails,
11
+ updateUser,
12
+ uploadDoctorSignature,
13
+ getDoctorSignature,
14
+ } from '@/common/services/Users';
15
+ import { execute } from '@/common/services/GlobalApis';
16
+ import useTrackEvent from '@/hooks/useTrackEvent';
17
+ import { useForm } from 'react-hook-form';
18
+ import * as yup from 'yup';
19
+ import { yupResolver } from '@hookform/resolvers/yup';
20
+ import CustomDropdown from '@/views/custom-components/CustomDropdown';
21
+ import { useSelector } from 'react-redux';
22
+ import CustomTextField from '@/views/custom-components/CustomTextField';
23
+ import { getAssignedFeatures } from '@/utils/feature';
24
+ import { useTranslateProvider } from '@/common/languageTranslator/TranslationContext';
25
+ import { showToast } from '@/common/toaster/toaster';
26
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
27
+ import GeneralUtil from '@/common/services/util/GeneralUtil';
28
+ import { faXmark } from '@fortawesome/free-solid-svg-icons';
29
+
30
+ const UpdateUserModal = ({ open, onClose }) => {
31
+ const { user } = useSelector((state) => state.Authenticate);
32
+ const trackEvent = useTrackEvent();
33
+ const [formData, setFormData] = useState(null);
34
+ const [languages, setLanguages] = useState([]);
35
+ const [bankDetails, setBankDetails] = useState([]);
36
+ const { translate } = useTranslateProvider();
37
+
38
+ const [rights, setRights] = useState({});
39
+ const rightsRef = useRef(rights);
40
+
41
+ useEffect(() => {
42
+ rightsRef.current = rights;
43
+ }, [rights]);
44
+
45
+
46
+ const [signaturePreview, setSignaturePreview] = useState(null);
47
+ const [signatureFile, setSignatureFile] = useState(null);
48
+ const [isDoctor, setIsDoctor] = useState(false);
49
+
50
+ useEffect(() => {
51
+ if (isDoctor) {
52
+ getSpecAndAvgValues();
53
+ }
54
+ }, [isDoctor]);
55
+
56
+ const getSpecAndAvgValues = async () => {
57
+ try {
58
+ const res = await execute({
59
+ code: 'GET_SPECIALIZATION_BY_USERID',
60
+ parameters: {
61
+ id: formData?.id,
62
+ },
63
+ });
64
+ const res2 = await execute({
65
+ code: 'GET_SPECIALIZATION',
66
+ });
67
+ const specializationId = res.data.result[0].specialization_id;
68
+ const specialization = res2.data.result.find((item) => item.id === specializationId);
69
+ setFormData((prevData) => ({ ...prevData, specialization: specialization?.name }));
70
+ const res1 = await getDoctorSignature(parseInt(formData?.id));
71
+ const blob = new Blob([res1], { type: 'application/image' });
72
+ const url = URL.createObjectURL(blob);
73
+ setSignaturePreview(url);
74
+
75
+ // setValue('averageDuration', res.data.result[0].average_duration);
76
+ } catch (error) {
77
+ console.error(error);
78
+ }
79
+ };
80
+ const [isUpdate, setIsUpdate] = useState(false);
81
+ const handleFileChange = (e) => {
82
+ const file = e.target.files[0];
83
+ if (file) {
84
+ // Save file in parent state for submission
85
+ setSignatureFile(file);
86
+
87
+ // Generate preview
88
+ const reader = new FileReader();
89
+ reader.onloadend = () => {
90
+ setSignaturePreview(reader.result);
91
+ };
92
+ reader.readAsDataURL(file);
93
+ }
94
+ };
95
+
96
+ const validationSchema = yup.object().shape({
97
+ ifscCode: yup
98
+ .string()
99
+ .nullable()
100
+ .notRequired()
101
+ .test('ifsc-length', 'IFSC code must be exactly 11 characters', (value) => {
102
+ if (!value) return true; // Skip validation if the field is empty
103
+ return value.length === 11; // Validate length only if there's a value
104
+ }),
105
+
106
+ bankAccNo: yup
107
+ .string()
108
+ .nullable()
109
+ .notRequired()
110
+ .test('bankAccNo-length', 'Bank Account Number must be between 9 and 18 characters', (value) => {
111
+ if (!value) return true; // Skip validation if the field is empty
112
+ return value.length >= 9 && value.length <= 18; // Validate length only if there's a value
113
+ })
114
+ .test('is-unique', 'Bank account already exists', async (value) => {
115
+ if (!value) return true; // Skip uniqueness check if the field is empty
116
+ return await isBankAccountNumberUnique(value);
117
+ }),
118
+ });
119
+
120
+ const isBankAccountNumberUnique = async (value) => {
121
+ const lowerCaseValue = value?.toLowerCase();
122
+ if (formData.bankAccNo === lowerCaseValue) {
123
+ return true;
124
+ } else {
125
+ try {
126
+ const { data } = await checkBankAccountNumberExist({
127
+ code: 'check_bank_account_number_exists',
128
+ parameters: {
129
+ userId: user.id,
130
+ bankAccNo: lowerCaseValue,
131
+ },
132
+ });
133
+ return data;
134
+ } catch (error) {
135
+ console.error(error);
136
+ }
137
+ }
138
+ };
139
+
140
+ const {
141
+ control,
142
+ formState: { errors },
143
+ handleSubmit,
144
+ setValue,
145
+ } = useForm({ resolver: yupResolver(validationSchema), mode: 'onChange' });
146
+ const loadInitialData = useCallback(async () => {
147
+ try {
148
+ const { data: userData } = await getUserDetails(user.id);
149
+
150
+ setFormData(userData);
151
+ if (userData?.roleName == 'Doctor') {
152
+ setIsDoctor(true);
153
+ }
154
+
155
+ const { data: prefferedLanguage } = await getPreferredLanguage();
156
+ let bankDetailsRes = [];
157
+ if (!GeneralUtil.isTecho) {
158
+ const { data: bankDetailsData } = await getBankNamesForPBI({
159
+ code: 'get_bank_names_for_pbi',
160
+ });
161
+ bankDetailsRes = bankDetailsData?.result || [];
162
+ }
163
+ setBankDetails(bankDetailsRes);
164
+ if (userData.bankName) {
165
+ if (!GeneralUtil.isTecho) {
166
+ setValue('bankName', userData.bankName.id);
167
+ } else {
168
+ setValue('bankName', typeof userData.bankName === 'object' ? (userData.bankName.value || '') : userData.bankName);
169
+ }
170
+ }
171
+ if (userData.bankAccNo) {
172
+ setValue('bankAccNo', userData.bankAccNo);
173
+ }
174
+ if (userData.ifscCode) {
175
+ setValue('ifscCode', userData.ifscCode);
176
+ }
177
+ if (userData.prefferedLanguage) {
178
+ setValue('prefferedLanguage', userData.prefferedLanguage);
179
+ }
180
+ if (userData.reportPreferredLanguage) {
181
+ setValue('reportPreferredLanguage', userData.reportPreferredLanguage);
182
+ }
183
+ setLanguages(prefferedLanguage);
184
+ const { data: assignedFeatures } = await getAssignedFeatures('techo.manage.users');
185
+
186
+ let rightsObj = JSON.parse(assignedFeatures);
187
+ setRights(rightsObj);
188
+
189
+ const keysArray = [
190
+ 'update.manage.users.preferredLanguage',
191
+ 'update.manage.users.bankDetails',
192
+ 'update.manage.users.reportPreferredLanguage',
193
+ ];
194
+ const hasTrue = keysArray.some((key) => rightsObj[key] === true);
195
+ setIsUpdate(hasTrue);
196
+ } catch (error) {
197
+ console.error(error);
198
+ }
199
+ }, [setValue, user.id]);
200
+
201
+ useEffect(() => {
202
+ loadInitialData();
203
+ }, [open, loadInitialData]);
204
+
205
+ const handleChange = (e) => {
206
+ const { name, value } = e.target;
207
+ setFormData((prevData) => ({ ...prevData, [name]: value }));
208
+ };
209
+ const handleBankChange = (e) => {
210
+ const { name, value } = e.target;
211
+ setFormData((prevData) => ({
212
+ ...prevData,
213
+ [name]: bankDetails.find((item) => item.id === value),
214
+ }));
215
+ };
216
+
217
+ const handleUpdateUser = async (values) => {
218
+ try {
219
+ const { bankAccNo, ifscCode, reportPreferredLanguage, prefferedLanguage, bankName } = values;
220
+ trackEvent('button_click', {
221
+ button_name: 'update_profile_update_button',
222
+ button_type: 'submit',
223
+ button_id: 'updateprofilemodal-button-update',
224
+ });
225
+ const payload = {
226
+ ...formData,
227
+ bankAccNo,
228
+ ifscCode,
229
+ reportPreferredLanguage,
230
+ prefferedLanguage,
231
+ };
232
+ if (GeneralUtil.isTecho) {
233
+ payload.bankName = bankName;
234
+ payload.bankNameId = null;
235
+ }
236
+ await updateUser(payload);
237
+
238
+ if (formData.roleName.toLowerCase() === 'doctor') {
239
+ // if (formData.id) {
240
+ // await execute({
241
+ // code: 'UPDATE_DOCTOR_DETAILS',
242
+ // parameters: {
243
+ // userId: parseInt(formData.id),
244
+ // specializationId: parseInt(formValues?.specialization),
245
+ // // averageDuration: parseInt(formValues?.averageDuration),
246
+ // },
247
+ // });
248
+ // } else {
249
+ // await execute({
250
+ // code: 'SET_DOCTOR_DETAILS',
251
+ // parameters: {
252
+ // userName: formValues?.userName,
253
+ // specializationId: parseInt(formValues?.specialization),
254
+ // // averageDuration: parseInt(formValues?.averageDuration),
255
+ // },
256
+ // });
257
+ // }
258
+ if (signatureFile) {
259
+ await uploadDoctorSignature(formData?.userName, signatureFile);
260
+ }
261
+ }
262
+ showToast({ message: 'Profile Updated Successfully', type: 'success' });
263
+ } catch (error) {
264
+ console.error(error);
265
+ showToast({ message: 'Failed to update profile', type: 'error' });
266
+ return;
267
+ }
268
+
269
+ // Handle form submission
270
+ onClose();
271
+ };
272
+
273
+ const renderItem = ({ label, name, disabled = false, value }) => (
274
+ <>
275
+ <Grid size={{ xs: 3 }} className="my-1 font-bold">
276
+ <Typography variant="body"> {translate(label)}</Typography>
277
+ </Grid>
278
+ <Grid size={{ xs: 1 }} className="my-1">
279
+ :
280
+ </Grid>
281
+ <Grid size={{ xs: 7 }} className="my-1">
282
+ {disabled ? (
283
+ <Typography variant="body2" size={{ xs: 3 }} item="true" className="my-1">
284
+ {value || 'Not Available'}
285
+ </Typography>
286
+ ) : (
287
+ <CustomTextField
288
+ control={control}
289
+ // id={name}
290
+ name={name}
291
+ size="small"
292
+ placeholder={label}
293
+ errors={errors}
294
+ disabled={disabled}
295
+ />
296
+ )}
297
+ </Grid>
298
+ </>
299
+ );
300
+
301
+ return (
302
+ <Modal open={open} onClose={onClose} data-testid="updateprofilemodal-modal">
303
+ <Paper className="absolute top-[10%] left-[10%] w-[80%]">
304
+ <Card className="m-0" elevation={5} component="form" onSubmit={handleSubmit(handleUpdateUser)} noValidate>
305
+ <CardHeader
306
+ className="manage-user-type-header"
307
+ subheader={isUpdate || formData?.roleName === 'Doctor' ? 'Update Profile' : 'View Profile'}
308
+ slotProps={{ subheader: { className: 'subheader-style text-customBlue text-lg' } }}
309
+ action={
310
+ <button
311
+ onClick={onClose}
312
+ className="flex items-center justify-center w-10 h-10 rounded-full bg-slate-100 hover:bg-red-100 text-slate-500 hover:text-red-600 transition-all duration-200 shadow-sm mr-4"
313
+ >
314
+ <FontAwesomeIcon icon={faXmark} className="text-xl" />
315
+ </button>
316
+ }
317
+ />
318
+ <CardContent className="overflow-auto max-h-[75vh]">
319
+ <Grid container spacing={2} alignItems="space-between">
320
+ <Grid
321
+ container
322
+ size={{ xs: 12, sm: 12 }}
323
+ className="my-1"
324
+ alignItems="center"
325
+ data-testid="updateprofilemodal-grid"
326
+ >
327
+ <Grid
328
+ container
329
+ size={{ xs: 12, sm: 6 }}
330
+ className="my-1"
331
+ alignItems="center"
332
+ data-testid="updateprofilemodal-grid-fullname"
333
+ >
334
+ {renderItem({
335
+ label: 'Full Name',
336
+ name: 'fullName',
337
+ value: `${formData?.title} ${formData?.fullName}`,
338
+ disabled: true,
339
+ })}
340
+ </Grid>
341
+
342
+ <Grid
343
+ container
344
+ size={{ xs: 12, sm: 6 }}
345
+ className="my-1"
346
+ alignItems="center"
347
+ data-testid="updateprofilemodal-grid-rolename"
348
+ >
349
+ {renderItem({
350
+ label: 'Role',
351
+ name: 'roleName',
352
+ value: formData?.roleName,
353
+ disabled: true,
354
+ })}
355
+ </Grid>
356
+
357
+ {rights?.['update.manage.users.bankDetails'] && (
358
+ <Grid
359
+ container
360
+ size={{ xs: 12, sm: 6 }}
361
+ className="my-1"
362
+ alignItems="center"
363
+ data-testid="updateprofilemodal-grid-bankname"
364
+ >
365
+ <>
366
+ <Grid size={{ xs: 3 }}>
367
+ {' '}
368
+ <Typography variant="body2">{translate('Bank Name')}</Typography>
369
+ </Grid>
370
+ <Grid size={{ xs: 1 }} className="my-1">
371
+ :
372
+ </Grid>
373
+ <Grid size={{ xs: 7 }}>
374
+ {!GeneralUtil.isTecho ? (
375
+ <CustomDropdown
376
+ control={control}
377
+ name="bankName"
378
+ options={bankDetails}
379
+ displayName="value"
380
+ optionValue="id"
381
+ onChange={handleBankChange}
382
+ dataTestId="updateprofilemodal-customdropdown-bankname"
383
+ />
384
+ ) : (
385
+ <CustomTextField
386
+ control={control}
387
+ name="bankName"
388
+ size="small"
389
+ placeholder="Bank Name"
390
+ errors={errors}
391
+ dataTestId="updateprofilemodal-customtextfield-bankname"
392
+ />
393
+ )}
394
+ </Grid>
395
+ {renderItem({
396
+ label: 'Bank Account Number',
397
+ name: 'bankAccNo',
398
+ value: formData?.bankAccNo,
399
+ })}
400
+ </>
401
+ </Grid>
402
+ )}
403
+ <Grid
404
+ container
405
+ size={{ xs: 12, sm: 6 }}
406
+ className="my-1"
407
+ alignItems="center"
408
+ data-testid="updateprofilemodal-grid-emailid"
409
+ >
410
+ {renderItem({
411
+ label: 'Email',
412
+ name: 'emailId',
413
+ value: formData?.emailId,
414
+ disabled: true,
415
+ })}
416
+ </Grid>
417
+
418
+ {rights?.['update.manage.users.preferredLanguage'] && (
419
+ <Grid
420
+ container
421
+ size={{ xs: 12, sm: 6 }}
422
+ className="my-1"
423
+ alignItems="center"
424
+ data-testid="updateprofilemodal-grid-preferredlanguage"
425
+ >
426
+ <>
427
+ <Grid size={{ xs: 3 }} className="font-bold">
428
+ <Typography variant="body">{translate('Preferred Language')}</Typography>
429
+ </Grid>
430
+ <Grid size={{ xs: 1 }} className="my-1">
431
+ :
432
+ </Grid>
433
+ <Grid size={{ xs: 7 }}>
434
+ <CustomDropdown
435
+ control={control}
436
+ name="prefferedLanguage"
437
+ options={languages}
438
+ displayName="languageValue"
439
+ optionValue="languageKey"
440
+ onChange={handleChange}
441
+ dataTestId="updateprofilemodal-customdropdown-prefferedLanguage"
442
+ />
443
+ </Grid>
444
+ </>
445
+ </Grid>
446
+ )}
447
+
448
+ <Grid
449
+ container
450
+ size={{ xs: 12, sm: 6 }}
451
+ className="my-1"
452
+ alignItems="center"
453
+ data-testid="updateprofilemodal-grid-gender"
454
+ >
455
+ {renderItem({
456
+ label: 'Gender',
457
+ name: 'gender',
458
+ value:
459
+ formData?.gender === 'M'
460
+ ? 'male'
461
+ : formData?.gender === 'F'
462
+ ? 'female'
463
+ : formData?.gender === 'O'
464
+ ? 'other'
465
+ : '',
466
+ disabled: true,
467
+ })}
468
+ </Grid>
469
+
470
+ <Grid
471
+ container
472
+ size={{ xs: 12, sm: 6 }}
473
+ className="my-1"
474
+ alignItems="center"
475
+ data-testid="updateprofilemodal-grid-username"
476
+ >
477
+ {/* <Grid container size={{ xs: 12, sm: 6 }} className="my-1" alignItems="center"> */}
478
+ {renderItem({
479
+ label: 'User name',
480
+ name: 'userName',
481
+ value: formData?.userName,
482
+ disabled: true,
483
+ })}
484
+ </Grid>
485
+
486
+ {rights?.['view.manage.users.CUGPhoneNumber'] && (
487
+ <Grid
488
+ container
489
+ size={{ xs: 12, sm: 6 }}
490
+ className="my-1"
491
+ alignItems="center"
492
+ data-testid="updateprofilemodal-grid-contactnumber"
493
+ >
494
+ {renderItem({
495
+ label: 'CUG Phone Number',
496
+ name: 'contactNumber',
497
+ value: formData?.contactNumber,
498
+ disabled: true,
499
+ })}
500
+ </Grid>
501
+ )}
502
+
503
+ {rights?.['update.manage.users.bankDetails'] && (
504
+ <Grid
505
+ container
506
+ size={{ xs: 12, sm: 6 }}
507
+ className="my-1"
508
+ alignItems="center"
509
+ data-testid="updateprofilemodal-grid-ifsccode"
510
+ >
511
+ {renderItem({
512
+ label: 'IFSC Code',
513
+ name: 'ifscCode',
514
+ value: formData?.ifscCode,
515
+ })}
516
+ </Grid>
517
+ )}
518
+
519
+ {rights?.['view.manage.users.aadhar'] && (
520
+ <Grid
521
+ container
522
+ size={{ xs: 12, sm: 6 }}
523
+ className="my-1"
524
+ alignItems="center"
525
+ data-testid="updateprofilemodal-grid-aadharnumber"
526
+ >
527
+ {renderItem({
528
+ label: 'Aadhar Number',
529
+ name: 'aadharNumber',
530
+ value: formData?.aadharNumber,
531
+ disabled: true,
532
+ })}
533
+ </Grid>
534
+ )}
535
+
536
+ {rights?.['update.manage.users.reportPreferredLanguage'] && (
537
+ <Grid
538
+ container
539
+ size={{ xs: 12, sm: 6 }}
540
+ className="my-1"
541
+ alignItems="center"
542
+ data-testid="updateprofilemodal-grid-reportpreferredlanguage"
543
+ >
544
+ <>
545
+ <Grid size={{ xs: 3 }} className="font-bold">
546
+ {' '}
547
+ <Typography variant="body">{translate('Report Preferred Language')}</Typography>
548
+ </Grid>
549
+ <Grid size={{ xs: 1 }} className="my-1">
550
+ :
551
+ </Grid>
552
+ <Grid size={{ xs: 7 }}>
553
+ <CustomDropdown
554
+ control={control}
555
+ name="reportPreferredLanguage"
556
+ options={[
557
+ { id: 'GU', value: 'Gujarati' },
558
+ { id: 'EN', value: 'English' },
559
+ { id: 'HI', value: 'Hindi' },
560
+ ]}
561
+ displayName="value"
562
+ optionValue="id"
563
+ onChange={handleChange}
564
+ dataTestId="updateprofilemodal-customdropdown-reportpreferredlanguage"
565
+ />
566
+ </Grid>
567
+ </>
568
+ </Grid>
569
+ )}
570
+
571
+ {rights?.['view.manage.users.loginCode'] && (
572
+ <Grid
573
+ container
574
+ size={{ xs: 12, sm: 6 }}
575
+ className="my-1"
576
+ alignItems="center"
577
+ data-testid="updateprofilemodal-grid-logincode"
578
+ >
579
+ {renderItem({
580
+ label: 'Login Code',
581
+ name: 'loginCode',
582
+ value: formData?.loginCode,
583
+ disabled: true,
584
+ })}
585
+ </Grid>
586
+ )}
587
+
588
+ {formData?.roleName === 'Doctor' && (
589
+ <Grid
590
+ container
591
+ size={{ xs: 12, sm: 6 }}
592
+ className="my-1"
593
+ alignItems="center"
594
+ data-testid="updateprofilemodal-grid-specialization"
595
+ >
596
+ {renderItem({
597
+ label: 'Specialization',
598
+ name: 'specialization',
599
+ value: formData?.specialization,
600
+ disabled: true,
601
+ })}
602
+ </Grid>
603
+ )}
604
+ {formData?.roleName === 'Doctor' && (
605
+ <Grid
606
+ container
607
+ size={{ xs: 12 }}
608
+ className="my-1"
609
+ alignItems="center"
610
+ data-testid="updateprofilemodal-grid-uploadsignature"
611
+ >
612
+ <Grid size={{ xs: 3 }} className="font-bold">
613
+ <Typography variant="body">{translate('Upload Signature')}</Typography>
614
+ </Grid>
615
+ <Grid size={{ xs: 1 }} className="my-1">
616
+ :
617
+ </Grid>
618
+ <Grid item size={{ xs: 7 }} className="flex items-center gap-4">
619
+ <input
620
+ type="file"
621
+ accept="image/*"
622
+ id="signatureUpload"
623
+ name="signatureUpload"
624
+ className="block w-full text-sm text-gray-700 border border-gray-300 rounded-md cursor-pointer
625
+ file:mr-4 file:py-2 file:px-4 file:rounded-md file:border-0
626
+ file:text-sm file:font-semibold file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100"
627
+ data-testid="user-signature-upload"
628
+ onChange={handleFileChange}
629
+ />
630
+
631
+ {/* Show preview only if signature is uploaded */}
632
+ {signaturePreview && (
633
+ <div className="mt-3 w-full flex justify-center">
634
+ <img
635
+ src={signaturePreview}
636
+ alt="Signature Preview"
637
+ className="h-15 w-[80%] object-fit border border-gray-300 rounded-md p-2 bg-white"
638
+ />
639
+ </div>
640
+ )}
641
+ </Grid>
642
+ </Grid>
643
+ )}
644
+ </Grid>
645
+ </Grid>
646
+
647
+ {/* </Grid> */}
648
+
649
+ {(isUpdate || formData?.roleName === 'Doctor') && (
650
+ <Grid container justifyContent="flex-end">
651
+ <Button
652
+ variant="contained"
653
+ onClick={onClose}
654
+ className="mt-[1rem] mr-2.5"
655
+ color="secondary"
656
+ size="small"
657
+ data-testid="updateprofilemodal-button-cancel"
658
+ >
659
+ {translate('Cancel')}
660
+ </Button>
661
+ <Button
662
+ type="submit"
663
+ variant="contained"
664
+ size="small"
665
+ color="primary"
666
+ className="mt-[1rem]"
667
+ data-testid="updateprofilemodal-button-update"
668
+ >
669
+ {translate('Update')}
670
+ </Button>
671
+ </Grid>
672
+ )}
673
+ </CardContent>
674
+ </Card>
675
+ </Paper>
676
+ </Modal>
677
+ );
678
+ };
679
+ UpdateUserModal.propTypes = {
680
+ open: PropTypes.any,
681
+ onClose: PropTypes.any,
682
+ };
683
+
684
+ export default UpdateUserModal;