@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,1400 @@
1
+ import React, { useState } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import {
4
+ Box,
5
+ Typography,
6
+ Stack,
7
+ ButtonBase,
8
+ Stepper,
9
+ Step,
10
+ StepLabel,
11
+ StepConnector,
12
+ stepConnectorClasses,
13
+ useMediaQuery,
14
+ Modal,
15
+ TextField,
16
+ IconButton,
17
+ Tooltip,
18
+ Button,
19
+ } from '@mui/material';
20
+ import { styled } from '@mui/material/styles';
21
+ import { useNavigate, useSearchParams } from 'react-router-dom';
22
+ import { useTheme } from '@mui/system';
23
+ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
24
+ import {
25
+ faRocket,
26
+ faCheck,
27
+ faCogs,
28
+ faTimes,
29
+ faInfoCircle,
30
+ faThumbsUp,
31
+ faDownload,
32
+ faUpload,
33
+ faFileExcel,
34
+ } from '@fortawesome/free-solid-svg-icons';
35
+ import { useSelector } from 'react-redux';
36
+
37
+ // --- Custom Styled Connector ---
38
+ const QontoConnector = styled(StepConnector)(({ theme }) => ({
39
+ [`&.${stepConnectorClasses.alternativeLabel}`]: {
40
+ top: 10,
41
+ left: 'calc(-50% + 16px)',
42
+ right: 'calc(50% + 16px)',
43
+ },
44
+ [`&.${stepConnectorClasses.active}`]: {
45
+ [`& .${stepConnectorClasses.line}`]: {
46
+ borderColor: theme.palette.primary.main,
47
+ },
48
+ },
49
+ [`&.${stepConnectorClasses.completed}`]: {
50
+ [`& .${stepConnectorClasses.line}`]: {
51
+ borderColor: theme.palette.primary.main,
52
+ },
53
+ },
54
+ [`& .${stepConnectorClasses.line}`]: {
55
+ borderColor: theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.2)' : 'rgba(0,0,0,0.1)',
56
+ borderTopWidth: 3,
57
+ borderRadius: 1,
58
+ // Vertical styles
59
+ minHeight: 24,
60
+ borderLeftWidth: 3,
61
+ },
62
+ }));
63
+
64
+ // --- Custom Step Icon ---
65
+ const QontoStepIcon = (props) => {
66
+ const { active, completed, className } = props;
67
+ const theme = useTheme();
68
+
69
+ return (
70
+ <Box
71
+ className={className}
72
+ sx={{
73
+ zIndex: 1,
74
+ color: '#fff',
75
+ width: 24,
76
+ height: 24,
77
+ display: 'flex',
78
+ borderRadius: '50%',
79
+ justifyContent: 'center',
80
+ alignItems: 'center',
81
+ ...(active && {
82
+ bgcolor: 'primary.main',
83
+ boxShadow: `0 0 0 4px ${theme.palette.mode === 'dark' ? 'rgba(59, 130, 246, 0.2)' : 'rgba(25, 118, 210, 0.15)'}`,
84
+ transform: 'scale(1.1)',
85
+ }),
86
+ ...(completed && {
87
+ bgcolor: 'primary.main',
88
+ color: '#fff',
89
+ }),
90
+ ...(!active &&
91
+ !completed && {
92
+ bgcolor: theme.palette.mode === 'dark' ? 'rgba(255,255,255,0.15)' : 'rgba(0,0,0,0.1)',
93
+ }),
94
+ }}
95
+ >
96
+ {completed ? <FontAwesomeIcon icon={faCheck} style={{ fontSize: 10 }} /> : null}
97
+ {active && !completed ? <Box sx={{ width: 8, height: 8, borderRadius: '50%', bgcolor: '#fff' }} /> : null}
98
+ </Box>
99
+ );
100
+ };
101
+
102
+ QontoStepIcon.propTypes = {
103
+ active: PropTypes.bool,
104
+ completed: PropTypes.bool,
105
+ className: PropTypes.string,
106
+ };
107
+
108
+ export default function MedplatOnboardingSplit() {
109
+ const [searchParams, setSearchParams] = useSearchParams();
110
+ const step = searchParams.get('step') || 'intro';
111
+ const setStep = (value) => searchParams.get('step') !== value && setSearchParams({ step: value });
112
+
113
+ const theme = useTheme();
114
+ const navigate = useNavigate();
115
+ const { user } = useSelector((state) => state.Authenticate);
116
+ const isDark = theme.palette.mode === 'dark';
117
+ const isMobile = useMediaQuery(theme.breakpoints.down('md'));
118
+
119
+ // Location Hierarchy Modal State
120
+ const [locationModalOpen, setLocationModalOpen] = useState(false);
121
+ const [successModalOpen, setSuccessModalOpen] = useState(false);
122
+ const [downloadTemplateModalOpen, setDownloadTemplateModalOpen] = useState(false);
123
+ const [uploadDataModalOpen, setUploadDataModalOpen] = useState(false);
124
+ const [hierarchyLevels, setHierarchyLevels] = useState(1);
125
+ const [levelNames, setLevelNames] = useState({
126
+ 1: 'State',
127
+ });
128
+
129
+ // File upload states
130
+ const [locationsFile, setLocationsFile] = useState(null);
131
+ const [facilitiesFile, setFacilitiesFile] = useState(null);
132
+
133
+ // Track completed steps
134
+ const [completedSteps, setCompletedSteps] = useState(new Set());
135
+ const totalSteps = 7; // Total number of steps in the checklist
136
+ const progressPercentage = Math.round((completedSteps.size / totalSteps) * 100);
137
+
138
+ // Improved Steps Data
139
+ const steps = [
140
+ { id: 'intro', label: 'Welcome', description: 'Introduction' },
141
+ { id: 'select-setup-type', label: 'Method', description: 'Choose approach' },
142
+ { id: 'setup', label: 'Setup', description: 'Configuration' },
143
+ ];
144
+
145
+ // Map current URL step to index
146
+ const getActiveStep = (currentStep) => {
147
+ if (currentStep === 'intro') return 0;
148
+ if (currentStep === 'select-setup-type') return 1;
149
+ if (['quick-setup', 'advanced-setup'].includes(currentStep)) return 2;
150
+ return 0;
151
+ };
152
+
153
+ const activeStep = getActiveStep(step);
154
+
155
+ // Handle click on step
156
+ const handleStepClick = (index) => {
157
+ // Only allow clicking if we've "reached" that step logically or want to go back
158
+ // For this demo, we allow free navigation to previous steps or immediate next
159
+ if (index === 0) setStep('intro');
160
+ if (index === 1) setStep('select-setup-type');
161
+ if (index === 2) setStep('quick-setup'); // Default to quick setup if clicking the step manually
162
+ };
163
+
164
+ return (
165
+ <Box
166
+ sx={{
167
+ minHeight: { xs: '100%', md: '85vh', lg: '85vh' },
168
+ width: '100%',
169
+ minWidth: '60vw !important',
170
+ // position: 'fixed', // Fix to viewport
171
+ // top: 0,
172
+ // left: 0,
173
+ // bgcolor: isDark ? '#0F172A' : '#F4F5F7', // Professional background
174
+ display: 'flex',
175
+ alignItems: 'center',
176
+ justifyContent: 'center',
177
+ // overflow: 'hidden',
178
+ paddingTop: '1rem',
179
+ }}
180
+ >
181
+ <Box
182
+ sx={{
183
+ width: { xs: '100%', md: '85%', lg: '75%' },
184
+ // maxWidth: 1200,
185
+ height: { xs: '100%', md: '85vh', lg: '85vh' },
186
+ display: 'flex',
187
+ flexDirection: { xs: 'column', md: 'row' },
188
+ gap: 0,
189
+ bgcolor: isDark ? '#1E293B' : '#FFFFFF',
190
+ borderRadius: 2,
191
+ boxShadow: isDark ? '0 4px 20px rgba(0,0,0,0.4)' : '0 4px 20px rgba(0,0,0,0.08)',
192
+ overflow: 'hidden',
193
+ border: isDark ? '1px solid #334155' : '1px solid #E2E8F0',
194
+ }}
195
+ >
196
+ {/* Left Sidebar - Navigation & Context */}
197
+ <Box
198
+ sx={{
199
+ width: { xs: '100%', md: '320px', lg: '320px' },
200
+ flexShrink: 0,
201
+ bgcolor: isDark ? '#0F172A' : '#FAFBFC',
202
+ borderRight: isDark ? '1px solid #334155' : '1px solid #E2E8F0',
203
+ p: 4,
204
+ display: 'flex',
205
+ flexDirection: 'column',
206
+ }}
207
+ >
208
+ <Box sx={{ mb: 6 }}>
209
+ <Typography
210
+ variant="h6"
211
+ sx={{
212
+ fontWeight: 700,
213
+ color: theme.palette.primary.main,
214
+ mb: 1,
215
+ letterSpacing: '-0.01em',
216
+ }}
217
+ >
218
+ MEDplat
219
+ </Typography>
220
+ <Typography variant="body2" color="text.secondary">
221
+ Setup Wizard
222
+ </Typography>
223
+ </Box>
224
+
225
+ <Box sx={{ flex: 1, width: '100%' }}>
226
+ <Stepper
227
+ activeStep={activeStep}
228
+ orientation={isMobile ? 'horizontal' : 'vertical'}
229
+ connector={<QontoConnector />}
230
+ alternativeLabel={isMobile}
231
+ sx={{
232
+ '& .MuiStepLabel-root': {
233
+ padding: isMobile ? '8px 0' : '12px 0',
234
+ cursor: 'pointer',
235
+ },
236
+ '& .MuiStepLabel-label': {
237
+ fontWeight: 500,
238
+ color: 'text.secondary',
239
+ fontSize: isMobile ? 12 : 14,
240
+ '&.Mui-active': {
241
+ color: 'text.primary',
242
+ fontWeight: 600,
243
+ },
244
+ '&.Mui-completed': {
245
+ color: 'text.primary',
246
+ },
247
+ },
248
+ }}
249
+ >
250
+ {steps.map((s, index) => (
251
+ <Step key={s.id} onClick={() => handleStepClick(index)}>
252
+ <StepLabel StepIconComponent={QontoStepIcon}>{s.label}</StepLabel>
253
+ </Step>
254
+ ))}
255
+ </Stepper>
256
+ </Box>
257
+
258
+ <Box>
259
+ <Typography variant="caption" color="text.secondary" sx={{ display: 'block', mt: 2 }}>
260
+ Need help?{' '}
261
+ <Box component="span" sx={{ color: 'primary.main', cursor: 'pointer' }}>
262
+ Contact Support
263
+ </Box>
264
+ </Typography>
265
+ </Box>
266
+ </Box>
267
+
268
+ {/* Right Content Area */}
269
+ <Box
270
+ sx={{
271
+ flex: 1,
272
+ display: 'flex',
273
+ flexDirection: 'column',
274
+ overflow: 'hidden',
275
+ position: 'relative',
276
+ }}
277
+ >
278
+ <Box
279
+ sx={{
280
+ flex: 1,
281
+ overflowY: 'auto',
282
+ p: { xs: 3, md: 6 },
283
+ display: 'flex',
284
+ flexDirection: 'column',
285
+ justifyContent: step === 'quick-setup' || step === 'advanced-setup' ? 'flex-start' : 'center',
286
+ alignItems: 'center',
287
+ height: '100%',
288
+ }}
289
+ >
290
+ <Box sx={{ width: '100%', maxWidth: 600 }}>
291
+ {/* Intro */}
292
+ {step === 'intro' && (
293
+ <Box sx={{ animation: 'fadeIn 0.4s ease-out' }}>
294
+ <Typography variant="h4" sx={{ fontWeight: 700, mb: 2, color: 'text.primary' }}>
295
+ Welcome, {user?.name || 'User'}
296
+ </Typography>
297
+ <Typography variant="body1" color="text.secondary" sx={{ mb: 4, fontSize: 16, lineHeight: 1.6 }}>
298
+ Let&apos;s get your workspace ready. We&apos;ll guide you through setting up your organization
299
+ structure and permissions.
300
+ </Typography>
301
+
302
+ <ButtonBase
303
+ onClick={() => setStep('select-setup-type')}
304
+ sx={{
305
+ bgcolor: 'primary.main',
306
+ color: '#fff',
307
+ px: 4,
308
+ py: 1.5,
309
+ borderRadius: 1,
310
+ fontWeight: 600,
311
+ fontSize: 15,
312
+ transition: 'all 0.2s',
313
+ '&:hover': {
314
+ bgcolor: 'primary.dark',
315
+ transform: 'translateY(-1px)',
316
+ boxShadow: '0 4px 12px rgba(0,0,0,0.1)',
317
+ },
318
+ }}
319
+ >
320
+ Get Started
321
+ </ButtonBase>
322
+ </Box>
323
+ )}
324
+
325
+ {/* Select Setup */}
326
+ {step === 'select-setup-type' && (
327
+ <Box sx={{ animation: 'fadeIn 0.4s ease-out' }}>
328
+ <Typography variant="h5" sx={{ fontWeight: 700, mb: 1, color: 'text.primary' }}>
329
+ Choose your path
330
+ </Typography>
331
+ <Typography variant="body1" color="text.secondary" sx={{ mb: 4 }}>
332
+ Select how you want to configure your environment.
333
+ </Typography>
334
+
335
+ <Stack spacing={2}>
336
+ <ButtonBase
337
+ onClick={() => setStep('quick-setup')}
338
+ sx={{
339
+ width: '100%',
340
+ textAlign: 'left',
341
+ p: 3,
342
+ borderRadius: 2,
343
+ border: '1px solid',
344
+ borderColor: isDark ? 'rgba(255,255,255,0.1)' : 'divider',
345
+ bgcolor: isDark ? 'rgba(255,255,255,0.02)' : '#fff',
346
+ transition: 'all 0.2s',
347
+ '&:hover': {
348
+ borderColor: 'primary.main',
349
+ bgcolor: isDark ? 'rgba(59,130,246,0.05)' : '#F8FAFC',
350
+ boxShadow: '0 4px 12px rgba(0,0,0,0.05)',
351
+ },
352
+ }}
353
+ >
354
+ <Stack direction="row" spacing={2} alignItems="flex-start">
355
+ <Box
356
+ sx={{
357
+ mt: 0.5,
358
+ p: 1,
359
+ borderRadius: 1,
360
+ bgcolor: isDark ? 'rgba(59,130,246,0.2)' : '#EFF6FF',
361
+ color: 'primary.main',
362
+ }}
363
+ >
364
+ <FontAwesomeIcon icon={faRocket} />
365
+ </Box>
366
+ <Box>
367
+ <Typography variant="subtitle1" sx={{ fontWeight: 600, mb: 0.5 }}>
368
+ Quick Setup
369
+ </Typography>
370
+ <Typography variant="body2" color="text.secondary">
371
+ Use recommended defaults for a fast start. Perfect for new accounts.
372
+ </Typography>
373
+ </Box>
374
+ </Stack>
375
+ </ButtonBase>
376
+
377
+ <ButtonBase
378
+ disabled
379
+ onClick={() => setStep('advanced-setup')}
380
+ sx={{
381
+ width: '100%',
382
+ textAlign: 'left',
383
+ p: 3,
384
+ borderRadius: 2,
385
+ border: '1px solid',
386
+ borderColor: isDark ? 'rgba(255,255,255,0.1)' : 'divider',
387
+ bgcolor: isDark ? 'rgba(255,255,255,0.02)' : '#fff',
388
+ transition: 'all 0.2s',
389
+ '&:hover': {
390
+ borderColor: 'primary.main',
391
+ bgcolor: isDark ? 'rgba(59,130,246,0.05)' : '#F8FAFC',
392
+ boxShadow: '0 4px 12px rgba(0,0,0,0.05)',
393
+ },
394
+ }}
395
+ >
396
+ <Stack direction="row" spacing={2} alignItems="flex-start">
397
+ <Box
398
+ sx={{
399
+ mt: 0.5,
400
+ p: 1,
401
+ borderRadius: 1,
402
+ bgcolor: isDark ? 'rgba(100,116,139,0.2)' : '#F1F5F9',
403
+ color: 'text.secondary',
404
+ }}
405
+ >
406
+ <FontAwesomeIcon icon={faCogs} />
407
+ </Box>
408
+ <Box>
409
+ <Typography variant="subtitle1" sx={{ fontWeight: 600, mb: 0.5 }}>
410
+ Advanced Configuration
411
+ </Typography>
412
+ <Typography variant="body2" color="text.secondary">
413
+ Manually configure locations, roles, and granular permissions.
414
+ </Typography>
415
+ </Box>
416
+ </Stack>
417
+ </ButtonBase>
418
+ </Stack>
419
+ </Box>
420
+ )}
421
+
422
+ {/* Quick Setup Checklist */}
423
+ {step === 'quick-setup' && (
424
+ <Box sx={{ animation: 'fadeIn 0.4s ease-out' }}>
425
+ <Box sx={{ mb: 4 }}>
426
+ <ButtonBase
427
+ onClick={() => setStep('select-setup-type')}
428
+ sx={{ mb: 2, color: 'text.secondary', fontSize: 13, '&:hover': { color: 'primary.main' } }}
429
+ >
430
+ ← Back
431
+ </ButtonBase>
432
+ <Typography variant="h5" sx={{ fontWeight: 700, mb: 1, color: 'text.primary' }}>
433
+ Setup Checklist
434
+ </Typography>
435
+ <Typography variant="body1" color="text.secondary">
436
+ Complete these steps to finalize your account.
437
+ </Typography>
438
+ </Box>
439
+
440
+ <Stack spacing={1.5}>
441
+ {[
442
+ {
443
+ title: 'Define location hierarchy',
444
+ desc: 'Configure facilities, units, and departments.',
445
+ status: 'action',
446
+ action: () => setLocationModalOpen(true),
447
+ },
448
+ {
449
+ title: 'Download data template',
450
+ desc: 'Download Excel templates for locations and facilities.',
451
+ status: 'action',
452
+ action: () => setDownloadTemplateModalOpen(true),
453
+ },
454
+ {
455
+ title: 'Upload data',
456
+ desc: 'Upload completed Excel files for bulk data import.',
457
+ status: 'action',
458
+ action: () => setUploadDataModalOpen(true),
459
+ },
460
+ {
461
+ title: 'Add roles',
462
+ desc: 'Create role templates that match your team.',
463
+ status: 'action',
464
+ action: () => navigate('/ui/medplat/manage/role'),
465
+ },
466
+ {
467
+ title: 'Add users',
468
+ desc: 'Invite your team and assign them to locations.',
469
+ status: 'action',
470
+ action: () => navigate('/ui/medplat/manage/users'),
471
+ },
472
+ {
473
+ title: 'Define facility types',
474
+ desc: 'Set up different types of facilities.',
475
+ status: 'pending',
476
+ action: null,
477
+ },
478
+ {
479
+ title: 'Manage System Constraints',
480
+ desc: 'Configure system-wide constraints and limits.',
481
+ status: 'action',
482
+ action: () => navigate('/ui/medplat/form/SYSTEM_CONFIG_SEARCH'),
483
+ },
484
+ ].map((item, i) => (
485
+ <Box
486
+ key={i}
487
+ onClick={item.action}
488
+ sx={{
489
+ p: 2,
490
+ borderRadius: 1.5,
491
+ border: '1px solid',
492
+ borderColor: isDark ? 'rgba(255,255,255,0.1)' : 'divider',
493
+ bgcolor: isDark ? 'rgba(255,255,255,0.02)' : '#fff',
494
+ cursor: item.action ? 'pointer' : 'default',
495
+ transition: 'all 0.2s',
496
+ '&:hover': item.action
497
+ ? {
498
+ borderColor: 'primary.main',
499
+ bgcolor: isDark ? 'rgba(59,130,246,0.05)' : '#F8FAFC',
500
+ }
501
+ : {},
502
+ display: 'flex',
503
+ alignItems: 'center',
504
+ gap: 2,
505
+ }}
506
+ >
507
+ <Box
508
+ sx={{
509
+ width: 24,
510
+ height: 24,
511
+ borderRadius: '50%',
512
+ border: '2px solid',
513
+ borderColor: 'divider',
514
+ display: 'flex',
515
+ alignItems: 'center',
516
+ justifyContent: 'center',
517
+ }}
518
+ >
519
+ {/* Checkmark placeholder */}
520
+ </Box>
521
+ <Box sx={{ flex: 1 }}>
522
+ <Typography variant="subtitle2" sx={{ fontWeight: 600 }}>
523
+ {item.title}
524
+ </Typography>
525
+ <Typography variant="caption" color="text.secondary">
526
+ {item.desc}
527
+ </Typography>
528
+ </Box>
529
+ {item.action && (
530
+ <Typography variant="caption" sx={{ color: 'primary.main', fontWeight: 600 }}>
531
+ Start
532
+ </Typography>
533
+ )}
534
+ </Box>
535
+ ))}
536
+ </Stack>
537
+ </Box>
538
+ )}
539
+
540
+ {/* Advanced Setup Placeholder */}
541
+ {step === 'advanced-setup' && (
542
+ <Box sx={{ animation: 'fadeIn 0.4s ease-out' }}>
543
+ <ButtonBase
544
+ onClick={() => setStep('select-setup-type')}
545
+ sx={{ mb: 2, color: 'text.secondary', fontSize: 13, '&:hover': { color: 'primary.main' } }}
546
+ >
547
+ ← Back
548
+ </ButtonBase>
549
+ <Typography variant="h5" sx={{ fontWeight: 700, mb: 1, color: 'text.primary' }}>
550
+ Advanced Setup
551
+ </Typography>
552
+ <Box
553
+ sx={{
554
+ p: 8,
555
+ border: '1px dashed divider',
556
+ borderRadius: 2,
557
+ textAlign: 'center',
558
+ bgcolor: 'background.default',
559
+ }}
560
+ >
561
+ <Typography color="text.secondary">Form Configuration Area</Typography>
562
+ </Box>
563
+ </Box>
564
+ )}
565
+ </Box>
566
+ </Box>
567
+ </Box>
568
+ </Box>
569
+
570
+ {/* Location Hierarchy Modal */}
571
+ <Modal
572
+ open={locationModalOpen}
573
+ onClose={() => setLocationModalOpen(false)}
574
+ sx={{
575
+ display: 'flex',
576
+ alignItems: 'center',
577
+ justifyContent: 'center',
578
+ }}
579
+ >
580
+ <Box
581
+ sx={{
582
+ width: '90%',
583
+ maxWidth: '70%',
584
+ maxHeight: '90vh',
585
+ bgcolor: isDark ? '#1E293B' : '#FFFFFF',
586
+ borderRadius: 2,
587
+ boxShadow: 24,
588
+ overflow: 'hidden',
589
+ display: 'flex',
590
+ flexDirection: 'column',
591
+ }}
592
+ >
593
+ {/* Modal Header */}
594
+ <Box
595
+ sx={{
596
+ p: 3,
597
+ borderBottom: '1px solid',
598
+ borderColor: isDark ? '#334155' : '#E2E8F0',
599
+ display: 'flex',
600
+ justifyContent: 'space-between',
601
+ alignItems: 'center',
602
+ }}
603
+ >
604
+ <Typography variant="h6" sx={{ fontWeight: 600 }}>
605
+ Setting Up The System
606
+ </Typography>
607
+ <IconButton onClick={() => setLocationModalOpen(false)} size="small" sx={{ color: 'text.secondary' }}>
608
+ <FontAwesomeIcon icon={faTimes} />
609
+ </IconButton>
610
+ </Box>
611
+
612
+ {/* Modal Content */}
613
+ <Box
614
+ sx={{
615
+ flex: 1,
616
+ overflowY: 'auto',
617
+ p: 4,
618
+ }}
619
+ >
620
+ <Box sx={{ display: 'flex', gap: 4, flexDirection: { xs: 'column', md: 'row' } }}>
621
+ {/* Left Side - Form */}
622
+ <Box sx={{ flex: 1 }}>
623
+ <Typography variant="h6" sx={{ fontWeight: 600, mb: 3 }}>
624
+ Define Location Hierarchy
625
+ </Typography>
626
+
627
+ {/* Number of Levels */}
628
+ <Box sx={{ mb: 3 }}>
629
+ <Typography variant="body2" sx={{ mb: 1, fontWeight: 500 }}>
630
+ How many levels of location hierarchy do you have?
631
+ </Typography>
632
+ <TextField
633
+ type="number"
634
+ value={hierarchyLevels}
635
+ onChange={(e) => {
636
+ const value = Math.max(1, Math.min(10, parseInt(e.target.value) || 1));
637
+ setHierarchyLevels(value);
638
+ // Initialize level names for new levels
639
+ const newLevelNames = { ...levelNames };
640
+ for (let i = 1; i <= value; i++) {
641
+ if (!newLevelNames[i]) {
642
+ newLevelNames[i] = `Level ${i}`;
643
+ }
644
+ }
645
+ setLevelNames(newLevelNames);
646
+ }}
647
+ size="small"
648
+ fullWidth
649
+ inputProps={{ min: 1, max: 10 }}
650
+ sx={{
651
+ '& .MuiOutlinedInput-root': {
652
+ bgcolor: isDark ? 'rgba(255,255,255,0.05)' : '#F8FAFC',
653
+ },
654
+ }}
655
+ />
656
+ </Box>
657
+
658
+ {/* Dynamic Level Name Inputs */}
659
+ {Array.from({ length: hierarchyLevels }, (_, i) => i + 1).map((level) => {
660
+ // Tooltip messages for each level
661
+ const getTooltipMessage = (lvl) => {
662
+ if (lvl === 1) {
663
+ return 'This is the highest level in the location hierarchy, representing the broadest geographic subdivision. For example, "State" could be the top-level category, comprising of multiple "Regions" of Level 2. Each Level 1 location can contain multiple Level 2 locations.';
664
+ }
665
+ if (lvl === 2) {
666
+ return 'This is the second level in the location hierarchy. For example, "Region" could be Level 2, which falls under a "State" (Level 1). Each Level 2 location can contain multiple Level 3 locations.';
667
+ }
668
+ if (lvl === 3) {
669
+ return 'This is the third level in the location hierarchy. For example, "District" could be Level 3, which falls under a "Region" (Level 2). Each Level 3 location can contain multiple Level 4 locations if applicable.';
670
+ }
671
+ return 'Define the name for this level in your location hierarchy.';
672
+ };
673
+
674
+ return (
675
+ <Box key={level} sx={{ mb: 3 }}>
676
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 1, mb: 1 }}>
677
+ <Typography variant="body2" sx={{ fontWeight: 500 }}>
678
+ What do you call as &quot;Level {level}&quot;?
679
+ </Typography>
680
+ <Tooltip
681
+ title={getTooltipMessage(level)}
682
+ arrow
683
+ placement="right"
684
+ sx={{
685
+ '& .MuiTooltip-tooltip': {
686
+ maxWidth: 300,
687
+ fontSize: 12,
688
+ bgcolor: isDark ? '#1E293B' : '#334155',
689
+ },
690
+ }}
691
+ >
692
+ <Box sx={{ display: 'flex', alignItems: 'center', cursor: 'help' }}>
693
+ <FontAwesomeIcon
694
+ icon={faInfoCircle}
695
+ style={{ fontSize: 14, color: theme.palette.text.secondary }}
696
+ />
697
+ </Box>
698
+ </Tooltip>
699
+ </Box>
700
+ <TextField
701
+ value={levelNames[level] || ''}
702
+ onChange={(e) => setLevelNames({ ...levelNames, [level]: e.target.value })}
703
+ size="small"
704
+ fullWidth
705
+ placeholder={`Level ${level}`}
706
+ sx={{
707
+ '& .MuiOutlinedInput-root': {
708
+ bgcolor: isDark ? 'rgba(255,255,255,0.05)' : '#F8FAFC',
709
+ },
710
+ }}
711
+ />
712
+ </Box>
713
+ );
714
+ })}
715
+ </Box>
716
+
717
+ {/* Right Side - Preview */}
718
+ <Box
719
+ sx={{
720
+ width: { xs: '100%', md: 380 },
721
+ p: 3,
722
+ border: '1px solid',
723
+ borderColor: isDark ? '#334155' : '#E2E8F0',
724
+ borderRadius: 2,
725
+ bgcolor: isDark ? 'rgba(255,255,255,0.02)' : '#FAFBFC',
726
+ }}
727
+ >
728
+ <Typography variant="subtitle2" sx={{ fontWeight: 600, mb: 3 }}>
729
+ Preview
730
+ </Typography>
731
+
732
+ {/* Hierarchical Preview */}
733
+ <Box sx={{ pl: 2 }}>
734
+ {Array.from({ length: hierarchyLevels }, (_, i) => i + 1).map((level) => (
735
+ <Box
736
+ key={level}
737
+ sx={{
738
+ mb: 2,
739
+ ml: (level - 1) * 2,
740
+ position: 'relative',
741
+ }}
742
+ >
743
+ {/* Connecting Line */}
744
+ {level > 1 && (
745
+ <Box
746
+ sx={{
747
+ position: 'absolute',
748
+ left: -16,
749
+ top: -12,
750
+ width: 1,
751
+ height: 24,
752
+ borderLeft: '1px solid',
753
+ borderBottom: '1px solid',
754
+ borderColor: isDark ? '#475569' : '#CBD5E1',
755
+ }}
756
+ />
757
+ )}
758
+
759
+ {/* Level Box */}
760
+ <Box
761
+ sx={{
762
+ display: 'inline-flex',
763
+ alignItems: 'center',
764
+ gap: 1,
765
+ px: 2,
766
+ py: 1,
767
+ bgcolor: '#3B82F6',
768
+ color: '#fff',
769
+ borderRadius: 1,
770
+ fontSize: 13,
771
+ fontWeight: 500,
772
+ position: 'relative',
773
+ }}
774
+ >
775
+ {levelNames[level] || `Level ${level}`}
776
+ {level === 1 && (
777
+ <Typography
778
+ variant="caption"
779
+ sx={{
780
+ position: 'absolute',
781
+ right: -60,
782
+ top: -8,
783
+ fontSize: 10,
784
+ color: 'text.secondary',
785
+ }}
786
+ >
787
+ ↑ Highest
788
+ </Typography>
789
+ )}
790
+ {level === hierarchyLevels && (
791
+ <Typography
792
+ variant="caption"
793
+ sx={{
794
+ position: 'absolute',
795
+ right: -55,
796
+ bottom: -8,
797
+ fontSize: 10,
798
+ color: 'text.secondary',
799
+ }}
800
+ >
801
+ ↓ Lowest
802
+ </Typography>
803
+ )}
804
+ </Box>
805
+ </Box>
806
+ ))}
807
+ </Box>
808
+ </Box>
809
+ </Box>
810
+ </Box>
811
+
812
+ {/* Modal Footer */}
813
+ <Box
814
+ sx={{
815
+ p: 3,
816
+ borderTop: '1px solid',
817
+ borderColor: isDark ? '#334155' : '#E2E8F0',
818
+ display: 'flex',
819
+ justifyContent: 'space-between',
820
+ gap: 2,
821
+ }}
822
+ >
823
+ <ButtonBase
824
+ onClick={() => setLocationModalOpen(false)}
825
+ sx={{
826
+ px: 3,
827
+ py: 1.5,
828
+ borderRadius: 1,
829
+ border: '1px solid',
830
+ borderColor: isDark ? '#475569' : '#CBD5E1',
831
+ fontWeight: 500,
832
+ fontSize: 14,
833
+ transition: 'all 0.2s',
834
+ '&:hover': {
835
+ bgcolor: isDark ? 'rgba(255,255,255,0.05)' : '#F8FAFC',
836
+ },
837
+ }}
838
+ >
839
+ Back
840
+ </ButtonBase>
841
+ <ButtonBase
842
+ onClick={() => {
843
+ // Handle submit logic here
844
+ console.log('Hierarchy Levels:', hierarchyLevels);
845
+ console.log('Level Names:', levelNames);
846
+ setLocationModalOpen(false);
847
+ // Mark step as completed
848
+ setCompletedSteps((prev) => new Set(prev).add('location-hierarchy'));
849
+ // Show success modal
850
+ setSuccessModalOpen(true);
851
+ }}
852
+ sx={{
853
+ px: 3,
854
+ py: 1.5,
855
+ borderRadius: 1,
856
+ bgcolor: '#3B82F6',
857
+ color: '#fff',
858
+ fontWeight: 500,
859
+ fontSize: 14,
860
+ transition: 'all 0.2s',
861
+ '&:hover': {
862
+ bgcolor: '#2563EB',
863
+ },
864
+ }}
865
+ >
866
+ Submit
867
+ </ButtonBase>
868
+ </Box>
869
+ </Box>
870
+ </Modal>
871
+
872
+ {/* Success Modal */}
873
+ <Modal
874
+ open={successModalOpen}
875
+ onClose={() => setSuccessModalOpen(false)}
876
+ sx={{
877
+ display: 'flex',
878
+ alignItems: 'center',
879
+ justifyContent: 'center',
880
+ }}
881
+ >
882
+ <Box
883
+ sx={{
884
+ width: '90%',
885
+ maxWidth: 400,
886
+ bgcolor: isDark ? '#1E293B' : '#FFFFFF',
887
+ borderRadius: 3,
888
+ boxShadow: 24,
889
+ p: 5,
890
+ textAlign: 'center',
891
+ position: 'relative',
892
+ }}
893
+ >
894
+ {/* Thumbs Up Icon */}
895
+ <Box
896
+ sx={{
897
+ mb: 3,
898
+ display: 'flex',
899
+ justifyContent: 'center',
900
+ }}
901
+ >
902
+ <Box
903
+ sx={{
904
+ width: 100,
905
+ height: 100,
906
+ borderRadius: '50%',
907
+ bgcolor: '#60A5FA',
908
+ display: 'flex',
909
+ alignItems: 'center',
910
+ justifyContent: 'center',
911
+ boxShadow: '0 4px 20px rgba(96, 165, 250, 0.3)',
912
+ }}
913
+ >
914
+ <FontAwesomeIcon icon={faThumbsUp} style={{ fontSize: 50, color: '#FFFFFF' }} />
915
+ </Box>
916
+ </Box>
917
+
918
+ {/* Good Job! Heading */}
919
+ <Typography
920
+ variant="h5"
921
+ sx={{
922
+ fontWeight: 700,
923
+ color: '#60A5FA',
924
+ mb: 2,
925
+ }}
926
+ >
927
+ Good Job!
928
+ </Typography>
929
+
930
+ {/* Success Message */}
931
+ <Typography
932
+ variant="body2"
933
+ color="text.secondary"
934
+ sx={{
935
+ mb: 3,
936
+ lineHeight: 1.6,
937
+ }}
938
+ >
939
+ You have successfully completed your very first step towards system setup.
940
+ </Typography>
941
+
942
+ {/* Progress Bar */}
943
+ <Box sx={{ mb: 4 }}>
944
+ <Box
945
+ sx={{
946
+ width: '100%',
947
+ height: 8,
948
+ bgcolor: isDark ? '#334155' : '#E5E7EB',
949
+ borderRadius: 1,
950
+ overflow: 'hidden',
951
+ }}
952
+ >
953
+ <Box
954
+ sx={{
955
+ width: `${progressPercentage}%`,
956
+ height: '100%',
957
+ bgcolor: '#60A5FA',
958
+ borderRadius: 1,
959
+ transition: 'width 0.3s ease',
960
+ }}
961
+ />
962
+ </Box>
963
+ <Typography variant="caption" color="text.secondary" sx={{ display: 'block', mt: 1, textAlign: 'center' }}>
964
+ {progressPercentage}%
965
+ </Typography>
966
+ </Box>
967
+
968
+ {/* Action Buttons */}
969
+ <Stack direction="row" spacing={2} justifyContent="center">
970
+ <ButtonBase
971
+ onClick={() => {
972
+ setSuccessModalOpen(false);
973
+ // Logic to choose a step
974
+ }}
975
+ sx={{
976
+ px: 3,
977
+ py: 1.5,
978
+ borderRadius: 1,
979
+ border: '1px solid',
980
+ borderColor: isDark ? '#475569' : '#CBD5E1',
981
+ fontWeight: 500,
982
+ fontSize: 14,
983
+ transition: 'all 0.2s',
984
+ '&:hover': {
985
+ bgcolor: isDark ? 'rgba(255,255,255,0.05)' : '#F8FAFC',
986
+ },
987
+ }}
988
+ >
989
+ Choose a step
990
+ </ButtonBase>
991
+ <ButtonBase
992
+ onClick={() => {
993
+ setSuccessModalOpen(false);
994
+ // User can now choose next steps from the checklist
995
+ }}
996
+ sx={{
997
+ px: 3,
998
+ py: 1.5,
999
+ borderRadius: 1,
1000
+ bgcolor: '#60A5FA',
1001
+ color: '#fff',
1002
+ fontWeight: 500,
1003
+ fontSize: 14,
1004
+ transition: 'all 0.2s',
1005
+ '&:hover': {
1006
+ bgcolor: '#3B82F6',
1007
+ },
1008
+ }}
1009
+ >
1010
+ Go to next step
1011
+ </ButtonBase>
1012
+ </Stack>
1013
+ </Box>
1014
+ </Modal>
1015
+
1016
+ {/* Download Data Templates Modal */}
1017
+ <Modal
1018
+ open={downloadTemplateModalOpen}
1019
+ onClose={() => setDownloadTemplateModalOpen(false)}
1020
+ sx={{
1021
+ display: 'flex',
1022
+ alignItems: 'center',
1023
+ justifyContent: 'center',
1024
+ }}
1025
+ >
1026
+ <Box
1027
+ sx={{
1028
+ width: '90%',
1029
+ maxWidth: 600,
1030
+ bgcolor: isDark ? '#1E293B' : '#FFFFFF',
1031
+ borderRadius: 2,
1032
+ boxShadow: 24,
1033
+ overflow: 'hidden',
1034
+ display: 'flex',
1035
+ flexDirection: 'column',
1036
+ }}
1037
+ >
1038
+ {/* Modal Header */}
1039
+ <Box
1040
+ sx={{
1041
+ p: 3,
1042
+ borderBottom: '1px solid',
1043
+ borderColor: isDark ? '#334155' : '#E2E8F0',
1044
+ display: 'flex',
1045
+ justifyContent: 'space-between',
1046
+ alignItems: 'center',
1047
+ }}
1048
+ >
1049
+ <Typography variant="h6" sx={{ fontWeight: 600 }}>
1050
+ Setting Up The System
1051
+ </Typography>
1052
+ <IconButton
1053
+ onClick={() => setDownloadTemplateModalOpen(false)}
1054
+ size="small"
1055
+ sx={{ color: 'text.secondary' }}
1056
+ >
1057
+ <FontAwesomeIcon icon={faTimes} />
1058
+ </IconButton>
1059
+ </Box>
1060
+
1061
+ {/* Modal Content */}
1062
+ <Box sx={{ p: 4 }}>
1063
+ <Typography variant="h6" sx={{ fontWeight: 600, mb: 2 }}>
1064
+ Download Data Templates
1065
+ </Typography>
1066
+ <Typography variant="body2" color="text.secondary" sx={{ mb: 3, lineHeight: 1.6 }}>
1067
+ Please download the template excel file for locations and facilities generated based on your defined
1068
+ location hierarchy and facility types, fill the excel file with your data and go to &quot;Upload
1069
+ Data&quot; step to upload the filled excel file to bulk upload records.
1070
+ </Typography>
1071
+
1072
+ {/* Download Links */}
1073
+ <Stack spacing={2} sx={{ mb: 3 }}>
1074
+ <Box
1075
+ sx={{
1076
+ display: 'flex',
1077
+ alignItems: 'center',
1078
+ gap: 1,
1079
+ p: 2,
1080
+ borderRadius: 1,
1081
+ border: '1px solid',
1082
+ borderColor: isDark ? '#334155' : '#E2E8F0',
1083
+ bgcolor: isDark ? 'rgba(255,255,255,0.02)' : '#F8FAFC',
1084
+ }}
1085
+ >
1086
+ <FontAwesomeIcon icon={faFileExcel} style={{ fontSize: 20, color: '#10B981' }} />
1087
+ <Typography variant="body2" sx={{ flex: 1, fontWeight: 500 }}>
1088
+ Locations.xlsx
1089
+ </Typography>
1090
+ <Button
1091
+ size="small"
1092
+ startIcon={<FontAwesomeIcon icon={faDownload} />}
1093
+ onClick={() => {
1094
+ // Handle download logic
1095
+ console.log('Downloading Locations.xlsx');
1096
+ }}
1097
+ sx={{
1098
+ textTransform: 'none',
1099
+ color: 'primary.main',
1100
+ '&:hover': {
1101
+ bgcolor: isDark ? 'rgba(59,130,246,0.1)' : 'rgba(59,130,246,0.05)',
1102
+ },
1103
+ }}
1104
+ >
1105
+ Download
1106
+ </Button>
1107
+ </Box>
1108
+
1109
+ <Box
1110
+ sx={{
1111
+ display: 'flex',
1112
+ alignItems: 'center',
1113
+ gap: 1,
1114
+ p: 2,
1115
+ borderRadius: 1,
1116
+ border: '1px solid',
1117
+ borderColor: isDark ? '#334155' : '#E2E8F0',
1118
+ bgcolor: isDark ? 'rgba(255,255,255,0.02)' : '#F8FAFC',
1119
+ }}
1120
+ >
1121
+ <FontAwesomeIcon icon={faFileExcel} style={{ fontSize: 20, color: '#10B981' }} />
1122
+ <Typography variant="body2" sx={{ flex: 1, fontWeight: 500 }}>
1123
+ Facilities.xlsx
1124
+ </Typography>
1125
+ <Button
1126
+ size="small"
1127
+ startIcon={<FontAwesomeIcon icon={faDownload} />}
1128
+ onClick={() => {
1129
+ // Handle download logic
1130
+ console.log('Downloading Facilities.xlsx');
1131
+ }}
1132
+ sx={{
1133
+ textTransform: 'none',
1134
+ color: 'primary.main',
1135
+ '&:hover': {
1136
+ bgcolor: isDark ? 'rgba(59,130,246,0.1)' : 'rgba(59,130,246,0.05)',
1137
+ },
1138
+ }}
1139
+ >
1140
+ Download
1141
+ </Button>
1142
+ </Box>
1143
+ </Stack>
1144
+ </Box>
1145
+
1146
+ {/* Modal Footer */}
1147
+ <Box
1148
+ sx={{
1149
+ p: 3,
1150
+ borderTop: '1px solid',
1151
+ borderColor: isDark ? '#334155' : '#E2E8F0',
1152
+ display: 'flex',
1153
+ justifyContent: 'space-between',
1154
+ gap: 2,
1155
+ }}
1156
+ >
1157
+ <ButtonBase
1158
+ onClick={() => setDownloadTemplateModalOpen(false)}
1159
+ sx={{
1160
+ px: 3,
1161
+ py: 1.5,
1162
+ borderRadius: 1,
1163
+ border: '1px solid',
1164
+ borderColor: isDark ? '#475569' : '#CBD5E1',
1165
+ fontWeight: 500,
1166
+ fontSize: 14,
1167
+ transition: 'all 0.2s',
1168
+ '&:hover': {
1169
+ bgcolor: isDark ? 'rgba(255,255,255,0.05)' : '#F8FAFC',
1170
+ },
1171
+ }}
1172
+ >
1173
+ Back
1174
+ </ButtonBase>
1175
+ <ButtonBase
1176
+ onClick={() => {
1177
+ setDownloadTemplateModalOpen(false);
1178
+ // Mark step as completed
1179
+ setCompletedSteps((prev) => new Set(prev).add('download-template'));
1180
+ setSuccessModalOpen(true);
1181
+ }}
1182
+ sx={{
1183
+ px: 3,
1184
+ py: 1.5,
1185
+ borderRadius: 1,
1186
+ bgcolor: '#60A5FA',
1187
+ color: '#fff',
1188
+ fontWeight: 500,
1189
+ fontSize: 14,
1190
+ transition: 'all 0.2s',
1191
+ '&:hover': {
1192
+ bgcolor: '#3B82F6',
1193
+ },
1194
+ }}
1195
+ >
1196
+ Next
1197
+ </ButtonBase>
1198
+ </Box>
1199
+ </Box>
1200
+ </Modal>
1201
+
1202
+ {/* Upload Data Modal */}
1203
+ <Modal
1204
+ open={uploadDataModalOpen}
1205
+ onClose={() => setUploadDataModalOpen(false)}
1206
+ sx={{
1207
+ display: 'flex',
1208
+ alignItems: 'center',
1209
+ justifyContent: 'center',
1210
+ }}
1211
+ >
1212
+ <Box
1213
+ sx={{
1214
+ width: '90%',
1215
+ maxWidth: 600,
1216
+ bgcolor: isDark ? '#1E293B' : '#FFFFFF',
1217
+ borderRadius: 2,
1218
+ boxShadow: 24,
1219
+ overflow: 'hidden',
1220
+ display: 'flex',
1221
+ flexDirection: 'column',
1222
+ }}
1223
+ >
1224
+ {/* Modal Header */}
1225
+ <Box
1226
+ sx={{
1227
+ p: 3,
1228
+ borderBottom: '1px solid',
1229
+ borderColor: isDark ? '#334155' : '#E2E8F0',
1230
+ display: 'flex',
1231
+ justifyContent: 'space-between',
1232
+ alignItems: 'center',
1233
+ }}
1234
+ >
1235
+ <Typography variant="h6" sx={{ fontWeight: 600 }}>
1236
+ Setting Up The System
1237
+ </Typography>
1238
+ <IconButton onClick={() => setUploadDataModalOpen(false)} size="small" sx={{ color: 'text.secondary' }}>
1239
+ <FontAwesomeIcon icon={faTimes} />
1240
+ </IconButton>
1241
+ </Box>
1242
+
1243
+ {/* Modal Content */}
1244
+ <Box sx={{ p: 4 }}>
1245
+ <Typography variant="h6" sx={{ fontWeight: 600, mb: 2 }}>
1246
+ Upload Data
1247
+ </Typography>
1248
+ <Typography variant="body2" color="text.secondary" sx={{ mb: 3, lineHeight: 1.6 }}>
1249
+ Please upload the xlsx files containing the completed Excel templates for both Locations and Facilities
1250
+ data. This will enable a smooth bulk upload of records into the system.
1251
+ </Typography>
1252
+
1253
+ {/* Upload Sections */}
1254
+ <Stack spacing={3}>
1255
+ {/* Locations Upload */}
1256
+ <Box>
1257
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 2, mb: 1 }}>
1258
+ <FontAwesomeIcon icon={faFileExcel} style={{ fontSize: 18, color: '#10B981' }} />
1259
+ <Typography variant="body2" sx={{ fontWeight: 500 }}>
1260
+ Locations.xlsx
1261
+ </Typography>
1262
+ </Box>
1263
+ <Button
1264
+ component="label"
1265
+ variant="outlined"
1266
+ startIcon={<FontAwesomeIcon icon={faUpload} />}
1267
+ sx={{
1268
+ textTransform: 'none',
1269
+ borderColor: isDark ? '#475569' : '#CBD5E1',
1270
+ color: 'primary.main',
1271
+ '&:hover': {
1272
+ borderColor: 'primary.main',
1273
+ bgcolor: isDark ? 'rgba(59,130,246,0.05)' : 'rgba(59,130,246,0.05)',
1274
+ },
1275
+ }}
1276
+ >
1277
+ {locationsFile ? locationsFile.name : 'Upload File'}
1278
+ <input
1279
+ type="file"
1280
+ hidden
1281
+ accept=".xlsx,.xls"
1282
+ onChange={(e) => {
1283
+ if (e.target.files && e.target.files[0]) {
1284
+ setLocationsFile(e.target.files[0]);
1285
+ }
1286
+ }}
1287
+ />
1288
+ </Button>
1289
+ </Box>
1290
+
1291
+ {/* Facilities Upload */}
1292
+ <Box>
1293
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 2, mb: 1 }}>
1294
+ <FontAwesomeIcon icon={faFileExcel} style={{ fontSize: 18, color: '#10B981' }} />
1295
+ <Typography variant="body2" sx={{ fontWeight: 500 }}>
1296
+ Facilities.xlsx
1297
+ </Typography>
1298
+ </Box>
1299
+ <Button
1300
+ component="label"
1301
+ variant="outlined"
1302
+ startIcon={<FontAwesomeIcon icon={faUpload} />}
1303
+ sx={{
1304
+ textTransform: 'none',
1305
+ borderColor: isDark ? '#475569' : '#CBD5E1',
1306
+ color: 'primary.main',
1307
+ '&:hover': {
1308
+ borderColor: 'primary.main',
1309
+ bgcolor: isDark ? 'rgba(59,130,246,0.05)' : 'rgba(59,130,246,0.05)',
1310
+ },
1311
+ }}
1312
+ >
1313
+ {facilitiesFile ? facilitiesFile.name : 'Upload File'}
1314
+ <input
1315
+ type="file"
1316
+ hidden
1317
+ accept=".xlsx,.xls"
1318
+ onChange={(e) => {
1319
+ if (e.target.files && e.target.files[0]) {
1320
+ setFacilitiesFile(e.target.files[0]);
1321
+ }
1322
+ }}
1323
+ />
1324
+ </Button>
1325
+ </Box>
1326
+ </Stack>
1327
+ </Box>
1328
+
1329
+ {/* Modal Footer */}
1330
+ <Box
1331
+ sx={{
1332
+ p: 3,
1333
+ borderTop: '1px solid',
1334
+ borderColor: isDark ? '#334155' : '#E2E8F0',
1335
+ display: 'flex',
1336
+ justifyContent: 'space-between',
1337
+ gap: 2,
1338
+ }}
1339
+ >
1340
+ <ButtonBase
1341
+ onClick={() => {
1342
+ setUploadDataModalOpen(false);
1343
+ setDownloadTemplateModalOpen(true);
1344
+ }}
1345
+ sx={{
1346
+ px: 3,
1347
+ py: 1.5,
1348
+ borderRadius: 1,
1349
+ border: '1px solid',
1350
+ borderColor: isDark ? '#475569' : '#CBD5E1',
1351
+ fontWeight: 500,
1352
+ fontSize: 14,
1353
+ transition: 'all 0.2s',
1354
+ '&:hover': {
1355
+ bgcolor: isDark ? 'rgba(255,255,255,0.05)' : '#F8FAFC',
1356
+ },
1357
+ }}
1358
+ >
1359
+ Back
1360
+ </ButtonBase>
1361
+ <ButtonBase
1362
+ onClick={() => {
1363
+ // Handle file upload logic
1364
+ console.log('Uploading files:', { locationsFile, facilitiesFile });
1365
+ setUploadDataModalOpen(false);
1366
+ // Mark step as completed
1367
+ setCompletedSteps((prev) => new Set(prev).add('upload-data'));
1368
+ setSuccessModalOpen(true);
1369
+ }}
1370
+ sx={{
1371
+ px: 3,
1372
+ py: 1.5,
1373
+ borderRadius: 1,
1374
+ bgcolor: '#60A5FA',
1375
+ color: '#fff',
1376
+ fontWeight: 500,
1377
+ fontSize: 14,
1378
+ transition: 'all 0.2s',
1379
+ '&:hover': {
1380
+ bgcolor: '#3B82F6',
1381
+ },
1382
+ }}
1383
+ >
1384
+ Submit
1385
+ </ButtonBase>
1386
+ </Box>
1387
+ </Box>
1388
+ </Modal>
1389
+
1390
+ <style>
1391
+ {`
1392
+ @keyframes fadeIn {
1393
+ from { opacity: 0; transform: translateY(4px); }
1394
+ to { opacity: 1; transform: translateY(0); }
1395
+ }
1396
+ `}
1397
+ </style>
1398
+ </Box>
1399
+ );
1400
+ }