@argusoft/medplat-app-shell 1.0.5 → 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,87 @@
1
+ import { useState, useCallback, useRef } from 'react';
2
+ import { useDispatch } from 'react-redux';
3
+ import { setLoggedIn, setToken } from '@/store/reducers/AuthenticationReducer';
4
+ import { refreshAccessToken } from '@/common/services/AuthenticateService';
5
+ import { navigate } from '@/common/services/InterceptorNavigationService';
6
+ import { clearAllExceptPinned } from '@/utils/localStorageHelper';
7
+
8
+ const useRefreshToken = (initialToken) => {
9
+ const [accessToken] = useState(initialToken);
10
+ const dispatch = useDispatch();
11
+ const refreshPromiseRef = useRef(null);
12
+
13
+ const executeActualRefresh = useCallback(async (token) => {
14
+ // 1. If a refresh is already in progress, return the existing promise
15
+ if (refreshPromiseRef.current) {
16
+ return refreshPromiseRef.current;
17
+ }
18
+
19
+ // 2. Check if the token has already been refreshed by someone else
20
+ const tokenString = localStorage.getItem('token');
21
+ const storedToken = tokenString ? JSON.parse(tokenString) : null;
22
+ if (storedToken && token && storedToken.access_token !== token.access_token) {
23
+ // Token was already refreshed, no need to do it again
24
+ return storedToken;
25
+ }
26
+
27
+ // 3. Start the refresh process and store the promise
28
+ refreshPromiseRef.current = (async () => {
29
+ try {
30
+ const response = await refreshAccessToken(token);
31
+
32
+ if (response) {
33
+ const loginTime = new Date();
34
+ localStorage.setItem('loginTime', JSON.stringify(loginTime));
35
+ dispatch(setToken(response));
36
+ dispatch(setLoggedIn());
37
+ return response;
38
+ }
39
+ return null;
40
+ } catch (error) {
41
+ console.error('DEBUG: executeActualRefresh - ERROR', error);
42
+ clearAllExceptPinned();
43
+ const isTecho = sessionStorage.getItem('isTecho');
44
+ if (isTecho === null || isTecho === undefined || isTecho === 'true') {
45
+ sessionStorage.clear();
46
+ navigate('/ui/login');
47
+ } else {
48
+ sessionStorage.clear();
49
+ navigate('/ui/medplat/manage/members/verify-otp');
50
+ }
51
+ throw error;
52
+ } finally {
53
+ // Clear the promise ref when done
54
+ refreshPromiseRef.current = null;
55
+ }
56
+ })();
57
+
58
+ return refreshPromiseRef.current;
59
+ }, [dispatch]);
60
+
61
+ const manualRefresh = useCallback(async (token) => {
62
+ if (!token || !token.access_token) return;
63
+
64
+ const loginTimeString = localStorage.getItem('loginTime');
65
+ const loginTime = loginTimeString ? new Date(JSON.parse(loginTimeString)) : new Date();
66
+ const currentTime = new Date();
67
+ const timeDifferenceMillis = currentTime - loginTime;
68
+
69
+ const expiresIn = token.expires_in || 900;
70
+
71
+ if (timeDifferenceMillis > (expiresIn - 1) * 1000) {
72
+ await executeActualRefresh(token);
73
+ } else {
74
+ dispatch(setLoggedIn());
75
+ }
76
+ }, [executeActualRefresh, dispatch]);
77
+
78
+ const refreshToken = useCallback(async (token) => {
79
+ await executeActualRefresh(token);
80
+ }, [executeActualRefresh]);
81
+
82
+ const newToken = refreshToken;
83
+
84
+ return { accessToken, manualRefresh, refreshToken, newToken };
85
+ };
86
+
87
+ export default useRefreshToken;
@@ -0,0 +1,25 @@
1
+ import { useEffect } from "react";
2
+
3
+ const useScript = (src, id, disabled = false, persist = false) => {
4
+ useEffect(() => {
5
+ if (disabled) return;
6
+ if (document.getElementById(id)) return;
7
+
8
+ const script = document.createElement("script");
9
+ script.src = src;
10
+ script.async = true;
11
+ script.id = id;
12
+
13
+ document.body.appendChild(script);
14
+ if (persist) return;
15
+
16
+ return () => {
17
+ const existingScript = document.getElementById(id);
18
+ if (existingScript) {
19
+ existingScript.remove();
20
+ }
21
+ };
22
+ }, [src, id, disabled, persist]);
23
+ };
24
+
25
+ export default useScript;
@@ -0,0 +1,75 @@
1
+ import { useState, useRef, useEffect } from 'react';
2
+
3
+ const useStopwatch = () => {
4
+ const [elapsedTime, setElapsedTime] = useState(0);
5
+ const [isRunning, setIsRunning] = useState(false);
6
+ const timerIntervalRef = useRef(null);
7
+ const startTimeRef = useRef(null);
8
+ const accumulatedTimeRef = useRef(0);
9
+
10
+ const start = () => {
11
+ if (isRunning) return;
12
+
13
+ setIsRunning(true);
14
+ startTimeRef.current = Date.now();
15
+
16
+ timerIntervalRef.current = setInterval(() => {
17
+ const now = Date.now();
18
+ const currentRunTime = now - startTimeRef.current;
19
+ setElapsedTime(accumulatedTimeRef.current + currentRunTime);
20
+ }, 100);
21
+ };
22
+
23
+ const stop = () => {
24
+ if (!isRunning) return;
25
+
26
+ if (timerIntervalRef.current) {
27
+ clearInterval(timerIntervalRef.current);
28
+ timerIntervalRef.current = null;
29
+ }
30
+
31
+ // Final update to ensure precision
32
+ const now = Date.now();
33
+ accumulatedTimeRef.current += (now - startTimeRef.current);
34
+ setElapsedTime(accumulatedTimeRef.current);
35
+ setIsRunning(false);
36
+ };
37
+
38
+ const pause = () => {
39
+ stop();
40
+ };
41
+
42
+ const reset = () => {
43
+ stop();
44
+ setElapsedTime(0);
45
+ accumulatedTimeRef.current = 0;
46
+ };
47
+
48
+ const formatTime = (ms) => {
49
+ const totalSeconds = Math.floor(ms / 1000);
50
+ const h = Math.floor(totalSeconds / 3600);
51
+ const m = Math.floor((totalSeconds % 3600) / 60);
52
+ const s = totalSeconds % 60;
53
+ return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}`;
54
+ };
55
+
56
+ useEffect(() => {
57
+ return () => {
58
+ if (timerIntervalRef.current) {
59
+ clearInterval(timerIntervalRef.current);
60
+ }
61
+ };
62
+ }, []);
63
+
64
+ return {
65
+ elapsedTime,
66
+ isRunning,
67
+ start,
68
+ stop,
69
+ pause,
70
+ reset,
71
+ formatTime
72
+ };
73
+ };
74
+
75
+ export default useStopwatch;
@@ -0,0 +1,22 @@
1
+ // hooks/useTrackEvent.js
2
+ import GeneralUtil from '@/common/services/util/GeneralUtil';
3
+ import { useTracking } from 'useranalytics';
4
+
5
+ const useTrackEvent = () => {
6
+ const { trackEvent } = GeneralUtil.isEkavach ? useTracking() :{trackEvent:()=>{}} ;
7
+
8
+ const trackEvent2 = async (event, data) => {
9
+ // const { trackEvent } = useTracking();
10
+ if (event === 'button_click') {
11
+ await trackEvent(event, data);
12
+ }
13
+ //
14
+ };
15
+ if (GeneralUtil.isEkavach){
16
+ return trackEvent2;
17
+ }
18
+ else{ return ()=>{}
19
+ }
20
+ };
21
+
22
+ export default useTrackEvent;
@@ -0,0 +1,115 @@
1
+ import { useState, useRef } from 'react';
2
+ import { showToast } from '@/common/toaster/toaster';
3
+
4
+ const useWebAudioRecorder = () => {
5
+ const [isRecording, setIsRecording] = useState(false);
6
+ const mediaRecorderRef = useRef(null);
7
+ const audioChunksRef = useRef([]);
8
+ const streamRef = useRef(null); // Added streamRef
9
+
10
+ const startRecording = async () => {
11
+ try {
12
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
13
+ streamRef.current = stream; // Store the stream
14
+ mediaRecorderRef.current = new MediaRecorder(stream);
15
+ audioChunksRef.current = [];
16
+
17
+ mediaRecorderRef.current.ondataavailable = (event) => {
18
+ if (event.data.size > 0) {
19
+ audioChunksRef.current.push(event.data);
20
+ }
21
+ };
22
+
23
+ mediaRecorderRef.current.start();
24
+ setIsRecording(true);
25
+ return true;
26
+ } catch (err) {
27
+ console.error('Web Recording Error:', err);
28
+ showToast({ type: 'error', message: 'Microphone access denied or error occurred.' });
29
+ return false;
30
+ }
31
+ };
32
+
33
+ const stopRecording = () => {
34
+ return new Promise((resolve, reject) => {
35
+ // Safety check: if not recording or not initialized
36
+ if (!mediaRecorderRef.current || mediaRecorderRef.current.state === 'inactive') {
37
+ // Try to cleanup anyway if stream exists
38
+ if (streamRef.current) {
39
+ streamRef.current.getTracks().forEach(track => track.stop());
40
+ streamRef.current = null;
41
+ }
42
+ setIsRecording(false);
43
+ resolve(null);
44
+ return;
45
+ }
46
+
47
+ mediaRecorderRef.current.onstop = () => {
48
+ try {
49
+ const audioBlob = new Blob(audioChunksRef.current, { type: 'audio/wav' });
50
+ const reader = new FileReader();
51
+ reader.readAsDataURL(audioBlob);
52
+
53
+ reader.onloadend = () => {
54
+ const base64String = reader.result;
55
+
56
+ // Stop all tracks from the stored stream reference
57
+ if (streamRef.current) {
58
+ streamRef.current.getTracks().forEach(track => track.stop());
59
+ streamRef.current = null;
60
+ }
61
+
62
+ setIsRecording(false);
63
+ resolve({ blob: audioBlob, base64: base64String });
64
+ };
65
+
66
+ reader.onerror = (error) => {
67
+ console.error("FileReader error", error);
68
+
69
+ // Ensure we cleanup even on error
70
+ if (streamRef.current) {
71
+ streamRef.current.getTracks().forEach(track => track.stop());
72
+ streamRef.current = null;
73
+ }
74
+ setIsRecording(false);
75
+ reject(error);
76
+ };
77
+ } catch (e) {
78
+ // Catch potential Blob/Reader errors
79
+ reject(e);
80
+ }
81
+ };
82
+
83
+ try {
84
+ mediaRecorderRef.current.stop();
85
+ } catch (e) {
86
+ console.error("MediaRecorder stop error", e);
87
+ reject(e);
88
+ }
89
+ });
90
+ };
91
+
92
+ const pauseRecording = () => {
93
+ if (mediaRecorderRef.current && mediaRecorderRef.current.state === 'recording') {
94
+ mediaRecorderRef.current.pause();
95
+ setIsRecording(false); // Visually paused
96
+ }
97
+ };
98
+
99
+ const resumeRecording = () => {
100
+ if (mediaRecorderRef.current && mediaRecorderRef.current.state === 'paused') {
101
+ mediaRecorderRef.current.resume();
102
+ setIsRecording(true);
103
+ }
104
+ };
105
+
106
+ return {
107
+ isRecording,
108
+ startRecording,
109
+ stopRecording,
110
+ pauseRecording,
111
+ resumeRecording
112
+ };
113
+ };
114
+
115
+ export default useWebAudioRecorder;
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ import { useLoader } from '@/layout/LoaderContext';
3
+
4
+ import MEDplatLoader from '@/assets/img/medplat-loader.gif';
5
+
6
+ import { useSelector } from 'react-redux';
7
+ import { getUseSkeleton } from '@/store/reducers/SkeletonReducer';
8
+ const LoaderComponent = () => {
9
+ const { loading } = useLoader();
10
+ const useSkeleton = useSelector(getUseSkeleton);
11
+ if (useSkeleton) {
12
+ return null;
13
+ }
14
+ return loading ? (
15
+ <div className="loader-overlay">
16
+ {/* <div className="loader-spinner"></div> */}
17
+ <img src={MEDplatLoader} alt="Loading..." className="loader" />
18
+ </div>
19
+ ) : null;
20
+ };
21
+
22
+ export default LoaderComponent;
@@ -0,0 +1,29 @@
1
+ import React, { createContext, useContext, useState } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { startLoading, stopLoading } from '@/store/reducers/LoadingReducer';
4
+
5
+ const LoaderContext = createContext();
6
+
7
+ export const LoaderProvider = ({ children }) => {
8
+ const [loading, setLoading] = useState(false);
9
+
10
+ const showLoader = () => {
11
+ startLoading();
12
+ setLoading(true);
13
+ };
14
+ const hideLoader = () => {
15
+ stopLoading();
16
+ setLoading(false);
17
+ };
18
+
19
+ const contextValue = React.useMemo(() => ({ loading, showLoader, hideLoader }), [loading]);
20
+
21
+ return <LoaderContext.Provider value={contextValue}>{children}</LoaderContext.Provider>;
22
+ };
23
+
24
+ export const useLoader = () =>
25
+ useContext(LoaderContext) || { loading: false, showLoader: () => {}, hideLoader: () => {} };
26
+
27
+ LoaderProvider.propTypes = {
28
+ children: PropTypes.any,
29
+ };
@@ -0,0 +1,27 @@
1
+ import { useEffect, useState } from "react";
2
+
3
+ const useAdaptiveZoom = () => {
4
+ const [zoom, setZoom] = useState(1);
5
+
6
+ const calculateZoom = () => {
7
+ const width = window.innerWidth;
8
+
9
+ if (width <= 1500) {
10
+ const scale = Math.max(0.88, width / 1520);
11
+ setZoom(scale);
12
+ } else {
13
+ setZoom(1);
14
+ }
15
+ };
16
+
17
+ useEffect(() => {
18
+ calculateZoom();
19
+
20
+ window.addEventListener("resize", calculateZoom);
21
+ return () => window.removeEventListener("resize", calculateZoom);
22
+ }, []);
23
+
24
+ return zoom;
25
+ };
26
+
27
+ export default useAdaptiveZoom;
@@ -0,0 +1,243 @@
1
+ import React, { useState } from 'react';
2
+ import { Fab, Tooltip } from '@mui/material';
3
+ import ChatIcon from '@mui/icons-material/Chat';
4
+
5
+ const Chatbot = () => {
6
+ const [isLoaded, setIsLoaded] = useState(false);
7
+
8
+ const loadChatbot = () => {
9
+ if (isLoaded || window.__ANYTHINGLLM_EMBED_LOADED__) return;
10
+ window.__ANYTHINGLLM_EMBED_LOADED__ = true;
11
+
12
+ /* Load AnythingLLM Script */
13
+ const script = document.createElement("script");
14
+ script.src = "https://aiservices.duckdns.org/embed/anythingllm-chat-widget.min.js";
15
+ script.async = true;
16
+
17
+ /* Required Core Params */
18
+ script.setAttribute("data-embed-id", "f8adc5e8-9143-4b9b-8e29-07db2fbf80d7");
19
+ script.setAttribute("data-base-api-url", "https://aiservices.duckdns.org/api/embed");
20
+
21
+ /* Position & Behavior */
22
+ script.setAttribute("data-position", "bottom-right");
23
+ script.setAttribute("data-open-on-load", "on");
24
+ script.setAttribute("data-chat-icon", "support");
25
+
26
+ /* Identity */
27
+ script.setAttribute("data-assistant-name", "AI Assistant");
28
+ script.setAttribute(
29
+ "data-assistant-icon",
30
+ "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS7tJKQ1KOQvWJQdx57kzZjdtTlkBvzSOXs2A&s"
31
+ );
32
+ script.setAttribute(
33
+ "data-brand-image-url",
34
+ "https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcS7tJKQ1KOQvWJQdx57kzZjdtTlkBvzSOXs2A&s"
35
+ );
36
+
37
+ /* Text */
38
+ script.setAttribute("data-greeting", "👋 Hi! How can I help you today?");
39
+ script.setAttribute("data-send-message-text", "Type your message…");
40
+ script.setAttribute("data-reset-chat-text", "New / Reset chat");
41
+
42
+ /* Disclaimer */
43
+ script.setAttribute(
44
+ "data-sponsor-text",
45
+ "This is an AI chatbot. Responses may vary based on available data. Though all efforts have been made to ensure the accuracy and currency of the content on this website, the same should not be construed as a statement of law or used for any legal purposes. Kindly contact office in case of any discrepancy and/or clarification."
46
+ );
47
+ script.setAttribute("data-sponsor-link", "#");
48
+
49
+ /* Styling */
50
+ script.setAttribute("data-button-color", "#2563EB");
51
+ script.setAttribute("data-user-bg-color", "#2563EB");
52
+ script.setAttribute("data-assistant-bg-color", "#F1F5F9");
53
+
54
+ /* Size */
55
+ script.setAttribute("data-window-width", "440px");
56
+ script.setAttribute("data-window-height", "580px");
57
+ script.setAttribute("data-text-size", "15px");
58
+
59
+ document.body.appendChild(script);
60
+
61
+ /* Custom Styles */
62
+ const style = document.createElement("style");
63
+ style.id = "anythingllm-custom-style";
64
+ style.textContent = `
65
+ /* Always on top */
66
+ #anythingllm-chat-widget,
67
+ #anythingllm-chat-widget-launcher {
68
+ z-index: 2147483647 !important;
69
+ }
70
+ #anything-llm-embed-chat-container {
71
+ z-index: 2147483647;
72
+ }
73
+ #anythingllm-chat-widget {
74
+ background: #ffffff !important;
75
+ color: #0f172a !important;
76
+ border-radius: 16px !important;
77
+ box-shadow: 0 18px 40px rgba(0,0,0,0.18) !important;
78
+ font-family: Inter, Segoe UI, system-ui, sans-serif !important;
79
+ }
80
+
81
+ #anythingllm-chat-widget .chat-header {
82
+ background: linear-gradient(135deg, #2563eb, #1d4ed8) !important;
83
+ color: #ffffff !important;
84
+ position: relative !important;
85
+ }
86
+
87
+ /* Header controls */
88
+ .anythingllm-window-controls {
89
+ position: absolute;
90
+ right: 14px;
91
+ top: 50%;
92
+ transform: translateY(-50%);
93
+ display: flex;
94
+ gap: 8px;
95
+ }
96
+
97
+ .anythingllm-window-controls button {
98
+ background: rgba(255,255,255,0.2);
99
+ border: none;
100
+ color: #ffffff;
101
+ width: 26px;
102
+ height: 26px;
103
+ border-radius: 6px;
104
+ cursor: pointer;
105
+ font-size: 13px;
106
+ line-height: 1;
107
+ }
108
+
109
+ .anythingllm-window-controls button:hover {
110
+ background: rgba(255,255,255,0.3);
111
+ }
112
+
113
+ /* Maximized state */
114
+ #anythingllm-chat-widget.anythingllm-maximized {
115
+ top: 0 !important;
116
+ left: 0 !important;
117
+ right: 0 !important;
118
+ bottom: 0 !important;
119
+ width: 100% !important;
120
+ height: 100% !important;
121
+ border-radius: 0 !important;
122
+ }
123
+
124
+ #anythingllm-chat-widget .chat-body {
125
+ background: #f8fafc !important;
126
+ }
127
+
128
+ #anythingllm-chat-widget .chat-message.assistant {
129
+ background: #f1f5f9 !important;
130
+ color: #0f172a !important;
131
+ border-radius: 14px !important;
132
+ }
133
+
134
+ #anythingllm-chat-widget .chat-message.user {
135
+ background: linear-gradient(135deg, #2563eb, #1d4ed8) !important;
136
+ color: #ffffff !important;
137
+ border-radius: 14px !important;
138
+ margin-left: auto !important;
139
+ }
140
+
141
+ #anythingllm-chat-widget .branding,
142
+ #anythingllm-chat-widget .powered-by {
143
+ display: none !important;
144
+ }
145
+
146
+ .allm-text-xs {
147
+ margin: 0 5px !important;
148
+ display: inline-block !important;
149
+ }
150
+
151
+ #anythingllm-chat-widget .chat-footer::after {
152
+ content: "Secure • Private • AI Assistant";
153
+ font-size: 12px;
154
+ color: #64748b;
155
+ display: block;
156
+ text-align: center;
157
+ margin-top: 6px;
158
+ }
159
+
160
+ @media (max-width: 480px) {
161
+ #anythingllm-chat-widget {
162
+ width: 100% !important;
163
+ height: 100% !important;
164
+ border-radius: 0 !important;
165
+ left: 0 !important;
166
+ bottom: 0 !important;
167
+ }
168
+ }
169
+ `;
170
+ document.head.appendChild(style);
171
+
172
+ /* Inject Maximize / Minimize Controls */
173
+ function injectControls() {
174
+ const widget = document.getElementById("anythingllm-chat-widget");
175
+ if (!widget) return false;
176
+
177
+ const header = widget.querySelector(".chat-header");
178
+ if (!header || header.querySelector(".anythingllm-window-controls")) {
179
+ return true;
180
+ }
181
+
182
+ const controls = document.createElement("div");
183
+ controls.className = "anythingllm-window-controls";
184
+
185
+ const maximizeBtn = document.createElement("button");
186
+ maximizeBtn.innerHTML = "⛶";
187
+ maximizeBtn.title = "Maximize";
188
+
189
+ const minimizeBtn = document.createElement("button");
190
+ minimizeBtn.innerHTML = "🗗";
191
+ minimizeBtn.title = "Restore";
192
+
193
+ maximizeBtn.onclick = () => {
194
+ widget.classList.add("anythingllm-maximized");
195
+ };
196
+
197
+ minimizeBtn.onclick = () => {
198
+ widget.classList.remove("anythingllm-maximized");
199
+ };
200
+
201
+ controls.appendChild(maximizeBtn);
202
+ controls.appendChild(minimizeBtn);
203
+ header.appendChild(controls);
204
+
205
+ return true;
206
+ }
207
+
208
+ const controlInterval = setInterval(() => {
209
+ if (injectControls()) {
210
+ clearInterval(controlInterval);
211
+ }
212
+ }, 300);
213
+
214
+ setIsLoaded(true);
215
+ };
216
+
217
+ if (isLoaded) return null; // Hide our icon once loaded, the widget has its own.
218
+
219
+ return (
220
+ <Tooltip title="TeCHO AI Assistant" placement="left">
221
+ <Fab
222
+ color="primary"
223
+ aria-label="chat"
224
+ onClick={loadChatbot}
225
+ sx={{
226
+ position: 'fixed',
227
+ bottom: 100,
228
+ right: 20,
229
+ zIndex: 1000,
230
+ boxShadow: '0 4px 12px rgba(0,0,0,0.15)',
231
+ transition: 'transform 0.2s',
232
+ '&:hover': {
233
+ transform: 'scale(1.1)',
234
+ }
235
+ }}
236
+ >
237
+ <ChatIcon />
238
+ </Fab>
239
+ </Tooltip>
240
+ );
241
+ };
242
+
243
+ export default Chatbot;