@campxdev/shared 1.10.39 → 1.10.41

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 (280) hide show
  1. package/antd.customize.less +73 -73
  2. package/exports.ts +19 -19
  3. package/package.json +87 -87
  4. package/src/assets/fonts/avenir/index.ts +13 -13
  5. package/src/assets/fonts/poppins/index.ts +18 -18
  6. package/src/assets/images/index.ts +17 -17
  7. package/src/assets/images/unauth.svg +92 -92
  8. package/src/components/ActionButton.tsx +20 -20
  9. package/src/components/ApplicationProfile/ApplicationProfile.tsx +334 -334
  10. package/src/components/ApplicationProfile/DepartmentFilter.tsx +77 -77
  11. package/src/components/ApplicationProfile/UserProfileRelation.tsx +140 -140
  12. package/src/components/ApplicationProfile/index.tsx +1 -1
  13. package/src/components/ApplicationProfile/services.ts +83 -83
  14. package/src/components/Attachment.tsx +26 -26
  15. package/src/components/AutocompleteSearch/AutocompleteSearch.tsx +57 -57
  16. package/src/components/AutocompleteSearch/index.tsx +1 -1
  17. package/src/components/Breadcrumbs.tsx +72 -72
  18. package/src/components/Card.tsx +98 -98
  19. package/src/components/CardsGrid.tsx +28 -28
  20. package/src/components/ChangePassword.tsx +123 -123
  21. package/src/components/Chips.tsx +81 -81
  22. package/src/components/Detail.tsx +15 -15
  23. package/src/components/DetailsGrid.tsx +52 -52
  24. package/src/components/DividerHeading.tsx +41 -41
  25. package/src/components/DrawerWrapper/DialogWrapper.tsx +67 -67
  26. package/src/components/DrawerWrapper/DrawerTemplate.tsx +53 -53
  27. package/src/components/DrawerWrapper/DrawerWrapper.tsx +53 -53
  28. package/src/components/DropDownButton/AnchorElement.tsx +44 -44
  29. package/src/components/DropDownButton/DropDownButton.tsx +184 -184
  30. package/src/components/DropDownButton/DropdownMenuItem.tsx +122 -122
  31. package/src/components/DropDownButton/index.tsx +1 -1
  32. package/src/components/DropDownButton/styles.tsx +59 -59
  33. package/src/components/ErrorBoundary/ErrorBoundary.tsx +33 -33
  34. package/src/components/ErrorBoundary/ErrorFallback.tsx +240 -240
  35. package/src/components/ErrorBoundary/GlobalNetworkLoadingIndicator.tsx +13 -13
  36. package/src/components/ErrorBoundary/index.tsx +1 -1
  37. package/src/components/ErrorBox.tsx +42 -42
  38. package/src/components/ExcelToJsonInput/ExcelJsonUpload.tsx +50 -50
  39. package/src/components/ExcelToJsonInput/ExcelToJsonInput.tsx +57 -57
  40. package/src/components/ExcelToJsonInput/index.tsx +1 -1
  41. package/src/components/FilterComponents/FilterButton.tsx +56 -56
  42. package/src/components/FilterComponents/SearchBar.tsx +45 -45
  43. package/src/components/FloatingContainer.tsx +33 -33
  44. package/src/components/Form/Form.tsx +147 -147
  45. package/src/components/Form/RenderForm.tsx +189 -189
  46. package/src/components/FullScreenLoader.tsx +19 -19
  47. package/src/components/HookForm/AutoCompleteSearch.tsx +113 -113
  48. package/src/components/HookForm/DatePicker.tsx +40 -40
  49. package/src/components/HookForm/DateTimePicker.tsx +47 -47
  50. package/src/components/HookForm/FormLabel.tsx +14 -14
  51. package/src/components/HookForm/MultiCheckbox.tsx +69 -69
  52. package/src/components/HookForm/MultiSelect.tsx +61 -61
  53. package/src/components/HookForm/RadioGroup.tsx +47 -47
  54. package/src/components/HookForm/SingleCheckbox.tsx +34 -34
  55. package/src/components/HookForm/SingleSelect.tsx +46 -46
  56. package/src/components/HookForm/TextField.tsx +40 -40
  57. package/src/components/HookForm/TimePicker.tsx +40 -40
  58. package/src/components/HookForm/index.ts +23 -23
  59. package/src/components/IconButtons/IconButtons.tsx +137 -137
  60. package/src/components/IconButtons/Icons.tsx +299 -299
  61. package/src/components/IconButtons/assets/edit.svg +4 -4
  62. package/src/components/IconButtons/assets/eye.svg +6 -6
  63. package/src/components/IconButtons/assets/trash.svg +7 -7
  64. package/src/components/IconButtons/index.tsx +8 -8
  65. package/src/components/IconLabel.tsx +37 -37
  66. package/src/components/Image/Image.tsx +45 -45
  67. package/src/components/Image/index.tsx +1 -1
  68. package/src/components/ImageUpload.tsx +105 -98
  69. package/src/components/Input/AsyncSearchSelect/AsyncSearchSelect.tsx +216 -216
  70. package/src/components/Input/AsyncSearchSelect/index.tsx +1 -1
  71. package/src/components/Input/AsyncSearchSelect/styles.tsx +105 -105
  72. package/src/components/Input/AutoCompleteSearch.tsx +121 -121
  73. package/src/components/Input/DatePicker.tsx +94 -94
  74. package/src/components/Input/DateRangePicker.tsx +105 -105
  75. package/src/components/Input/DateTimePicker.tsx +87 -87
  76. package/src/components/Input/FormLabel.tsx +21 -21
  77. package/src/components/Input/MultiCheckbox.tsx +64 -64
  78. package/src/components/Input/MultiSelect.tsx +161 -161
  79. package/src/components/Input/RadioGroup.tsx +110 -110
  80. package/src/components/Input/SingleCheckbox.tsx +78 -78
  81. package/src/components/Input/SingleSelect.tsx +104 -104
  82. package/src/components/Input/TextField.tsx +46 -46
  83. package/src/components/Input/TimePicker.tsx +77 -77
  84. package/src/components/Input/index.ts +26 -26
  85. package/src/components/Input/types.ts +3 -3
  86. package/src/components/Institutions/InsititutionsDialog.tsx +78 -78
  87. package/src/components/Institutions/InsititutionsNotAssignedDialog .tsx +12 -12
  88. package/src/components/Institutions/InstitutionsDropdown.tsx +33 -33
  89. package/src/components/Institutions/index.tsx +1 -1
  90. package/src/components/Institutions/services.ts +12 -12
  91. package/src/components/JsonPreview.tsx +7 -7
  92. package/src/components/LabelValue.tsx +21 -21
  93. package/src/components/Layout/ChangePassword.tsx +49 -49
  94. package/src/components/Layout/Header/AppHeader.tsx +109 -109
  95. package/src/components/Layout/Header/AppsMenu.tsx +132 -132
  96. package/src/components/Layout/Header/HeaderActions/CogWheelMenu.tsx +33 -33
  97. package/src/components/Layout/Header/HeaderActions/FreshChatButton.tsx +61 -61
  98. package/src/components/Layout/Header/HeaderActions/FreshDeskHelpButton.tsx +53 -53
  99. package/src/components/Layout/Header/HeaderActions/HeaderActions.tsx +29 -29
  100. package/src/components/Layout/Header/HeaderActions/UserBox.tsx +74 -74
  101. package/src/components/Layout/Header/Notification.tsx +13 -13
  102. package/src/components/Layout/Header/Search/SearchButton.tsx +69 -69
  103. package/src/components/Layout/Header/Search/SearchDialog.tsx +178 -178
  104. package/src/components/Layout/Header/applications.ts +101 -101
  105. package/src/components/Layout/Header/assets/campx_square_small.svg +8 -8
  106. package/src/components/Layout/Header/assets/commuteX.png +0 -0
  107. package/src/components/Layout/Header/assets/commutex.svg +14 -14
  108. package/src/components/Layout/Header/assets/commutexSmall.svg +11 -11
  109. package/src/components/Layout/Header/assets/enroll.svg +14 -14
  110. package/src/components/Layout/Header/assets/enrollx.svg +14 -14
  111. package/src/components/Layout/Header/assets/exams_small.svg +11 -11
  112. package/src/components/Layout/Header/assets/examsx.svg +14 -14
  113. package/src/components/Layout/Header/assets/hostel_small.svg +13 -13
  114. package/src/components/Layout/Header/assets/hostelx.svg +13 -13
  115. package/src/components/Layout/Header/assets/index.ts +37 -37
  116. package/src/components/Layout/Header/assets/libraryx.svg +12 -12
  117. package/src/components/Layout/Header/assets/pay_small.svg +15 -15
  118. package/src/components/Layout/Header/assets/payx.svg +19 -19
  119. package/src/components/Layout/Header/assets/people_small.svg +9 -9
  120. package/src/components/Layout/Header/assets/peoplex.svg +12 -12
  121. package/src/components/Layout/Header/assets/squarex.svg +12 -12
  122. package/src/components/Layout/Header/icons.tsx +57 -57
  123. package/src/components/Layout/Header/index.tsx +1 -1
  124. package/src/components/Layout/Header/styles.tsx +133 -133
  125. package/src/components/Layout/Helmet.tsx +129 -129
  126. package/src/components/Layout/LayoutWrapper.tsx +28 -28
  127. package/src/components/Layout/SideMenuHeader.tsx +29 -29
  128. package/src/components/Layout/SideNav.tsx +168 -168
  129. package/src/components/Layout/Tickets/HelpWidget/HelpWidget.tsx +273 -273
  130. package/src/components/Layout/Tickets/HelpWidget/styles.tsx +94 -94
  131. package/src/components/Layout/Tickets/MyTickets.tsx +72 -72
  132. package/src/components/Layout/Tickets/TicketDetails.tsx +65 -65
  133. package/src/components/Layout/Tickets/TimeLine.tsx +64 -64
  134. package/src/components/Layout/Tickets/index.tsx +1 -1
  135. package/src/components/Layout/Tickets/services.ts +11 -11
  136. package/src/components/Layout/Tickets/styles.tsx +136 -136
  137. package/src/components/LinearProgress.tsx +19 -19
  138. package/src/components/ListItemButton.tsx +95 -95
  139. package/src/components/LoginForm.tsx +274 -274
  140. package/src/components/MediaRow/MediaRow.tsx +67 -67
  141. package/src/components/MediaRow/index.tsx +1 -1
  142. package/src/components/ModalButtons/DialogButton.tsx +133 -133
  143. package/src/components/ModalButtons/DrawerButton.tsx +118 -118
  144. package/src/components/ModalButtons/PopoverButton.tsx +99 -99
  145. package/src/components/ModalButtons/index.tsx +4 -4
  146. package/src/components/MyProfile/Education/Education.tsx +47 -47
  147. package/src/components/MyProfile/Education/EducationCard.tsx +62 -62
  148. package/src/components/MyProfile/Education/EducationForm.tsx +117 -117
  149. package/src/components/MyProfile/Education/Styles.tsx +27 -27
  150. package/src/components/MyProfile/Experience/Experience.tsx +47 -47
  151. package/src/components/MyProfile/Experience/ExperienceCard.tsx +65 -65
  152. package/src/components/MyProfile/Experience/ExperienceForm.tsx +134 -134
  153. package/src/components/MyProfile/Experience/Styles.tsx +27 -27
  154. package/src/components/MyProfile/FileUpload.tsx +69 -69
  155. package/src/components/MyProfile/MyProfile.tsx +161 -152
  156. package/src/components/MyProfile/NoDataSection.tsx +27 -27
  157. package/src/components/MyProfile/PaperPublication/Authors.tsx +88 -88
  158. package/src/components/MyProfile/PaperPublication/PaperPublications.tsx +52 -52
  159. package/src/components/MyProfile/PaperPublication/PublicationCard.tsx +80 -80
  160. package/src/components/MyProfile/PaperPublication/PublicationsForm.tsx +286 -286
  161. package/src/components/MyProfile/PaperPublication/Styles.tsx +51 -51
  162. package/src/components/MyProfile/ResearchProjects/FileRender.tsx +53 -0
  163. package/src/components/MyProfile/ResearchProjects/ResearchProjectCard.tsx +69 -0
  164. package/src/components/MyProfile/ResearchProjects/ResearchProjectData.tsx +36 -0
  165. package/src/components/MyProfile/ResearchProjects/ResearchProjectForm.tsx +475 -0
  166. package/src/components/MyProfile/ResearchProjects/ResearchProjects.tsx +55 -0
  167. package/src/components/MyProfile/ResearchProjects/Styles.tsx +26 -0
  168. package/src/components/MyProfile/ResearchProjects/services.tsx +42 -0
  169. package/src/components/MyProfile/StyledTabsContainer.tsx +53 -53
  170. package/src/components/MyProfile/Styles.tsx +128 -128
  171. package/src/components/MyProfile/Workshop/Styles.tsx +38 -38
  172. package/src/components/MyProfile/Workshop/Workshop.tsx +49 -49
  173. package/src/components/MyProfile/Workshop/WorkshopCard.tsx +64 -64
  174. package/src/components/MyProfile/Workshop/WorkshopData.tsx +36 -36
  175. package/src/components/MyProfile/Workshop/WorkshopForm.tsx +215 -215
  176. package/src/components/MyProfile/index.ts +1 -1
  177. package/src/components/MyProfile/service.ts +58 -58
  178. package/src/components/NoDataIllustration.tsx +35 -35
  179. package/src/components/PageContent.tsx +12 -12
  180. package/src/components/PageHeader.tsx +55 -55
  181. package/src/components/PageNotFound.tsx +26 -26
  182. package/src/components/PopupConfirm/ConfirmContextProvider.tsx +40 -40
  183. package/src/components/PopupConfirm/PopupConfirm.tsx +71 -71
  184. package/src/components/PopupConfirm/index.tsx +1 -1
  185. package/src/components/PopupConfirm/useConfirm.ts +47 -47
  186. package/src/components/ResetPassword.tsx +107 -107
  187. package/src/components/Row.tsx +24 -24
  188. package/src/components/Spinner.tsx +18 -18
  189. package/src/components/StepsHeader/StepsHeader.tsx +115 -115
  190. package/src/components/StepsHeader/index.tsx +1 -1
  191. package/src/components/StyledTableContainer.tsx +33 -33
  192. package/src/components/SwitchButton.tsx +41 -41
  193. package/src/components/Table.tsx +42 -42
  194. package/src/components/Tables/BasicTable/Table.tsx +198 -198
  195. package/src/components/Tables/BasicTable/TableFooter.tsx +86 -86
  196. package/src/components/Tables/BasicTable/index.tsx +1 -1
  197. package/src/components/Tables/ReactTable/BatchActionsHeader.tsx +58 -58
  198. package/src/components/Tables/ReactTable/ReactTable.tsx +295 -295
  199. package/src/components/Tables/ReactTable/RenderTableBody.tsx +49 -49
  200. package/src/components/Tables/ReactTable/index.tsx +1 -1
  201. package/src/components/Tables/ReactTable/react-table-config.d.ts +128 -128
  202. package/src/components/Tables/common/NoRecordsFound.tsx +31 -31
  203. package/src/components/Tables/common/TableStats.tsx +22 -22
  204. package/src/components/Tables/common/icons.tsx +50 -50
  205. package/src/components/Tables/common/no-data-illu.svg +23 -23
  206. package/src/components/Tables/common/styles.tsx +170 -170
  207. package/src/components/Tables/common/types.ts +57 -57
  208. package/src/components/Tabs/NavigationTabs.tsx +80 -80
  209. package/src/components/Tabs/Tabs.tsx +53 -53
  210. package/src/components/Tabs/TabsContainer.tsx +56 -56
  211. package/src/components/Tabs/index.tsx +1 -1
  212. package/src/components/Tabs/styles.tsx +55 -55
  213. package/src/components/ToastContainer/ToastContainer.tsx +57 -57
  214. package/src/components/ToastContainer/index.tsx +1 -1
  215. package/src/components/UploadButton/UploadButton.tsx +127 -127
  216. package/src/components/UploadButton/index.tsx +1 -1
  217. package/src/components/UploadButton/types.ts +20 -20
  218. package/src/components/UploadDocument.tsx +108 -108
  219. package/src/components/UploadFileDialog/UploadFileDialog.tsx +256 -256
  220. package/src/components/UploadFileDialog/index.tsx +1 -1
  221. package/src/components/index.ts +110 -110
  222. package/src/config/axios.ts +80 -80
  223. package/src/config/axiosEvaluator.ts +53 -53
  224. package/src/config/axiosXTenant.ts +57 -57
  225. package/src/constants/UIConstants.ts +128 -124
  226. package/src/constants/formValidations.ts +6 -6
  227. package/src/constants/index.ts +5 -5
  228. package/src/constants/isDevelopment.ts +4 -4
  229. package/src/constants/permissions.ts +67 -67
  230. package/src/constants/validateMessages.ts +12 -12
  231. package/src/contexts/LoginFormProvider.tsx +37 -37
  232. package/src/contexts/Providers.tsx +73 -73
  233. package/src/contexts/PublicProviders.tsx +30 -30
  234. package/src/contexts/QueryClientProvider.tsx +22 -22
  235. package/src/contexts/RootModal.tsx +76 -76
  236. package/src/hooks/index.ts +5 -5
  237. package/src/hooks/useAuth.ts +259 -259
  238. package/src/hooks/useExternalScript.ts +38 -38
  239. package/src/hooks/useFetch.ts +53 -53
  240. package/src/hooks/useFilters.ts +83 -83
  241. package/src/hooks/useRouter.ts +31 -31
  242. package/src/layouts/Components/DashBoardMenu.tsx +232 -232
  243. package/src/layouts/Components/icons/index.tsx +403 -403
  244. package/src/layouts/Components/styles.tsx +74 -74
  245. package/src/layouts/ComponentsLayout.tsx +3 -3
  246. package/src/permissions/PageWithPermission.tsx +18 -18
  247. package/src/permissions/PermissionDeniedPage.tsx +16 -16
  248. package/src/permissions/ValidateAccess.tsx +18 -18
  249. package/src/permissions/index.ts +2 -2
  250. package/src/react-app-env.d.ts +1 -1
  251. package/src/shared-state/AssetsStore.ts +15 -15
  252. package/src/shared-state/InstitutionsStore.ts +8 -8
  253. package/src/shared-state/PermissionsStore.ts +1299 -1276
  254. package/src/shared-state/UserStore.ts +15 -15
  255. package/src/shared-state/index.ts +4 -4
  256. package/src/sitemap/enrollx.ts +52 -52
  257. package/src/sitemap/exams_sitemap.ts +172 -172
  258. package/src/sitemap/payments.ts +128 -128
  259. package/src/sitemap/sitemap.ts +26 -26
  260. package/src/sitemap/square.ts +222 -222
  261. package/src/theme/App.less +3 -3
  262. package/src/theme/MuiThemeProvider.tsx +18 -18
  263. package/src/theme/customCssBaseline.ts +135 -135
  264. package/src/theme/index.css +28 -28
  265. package/src/theme/muiTheme.ts +597 -597
  266. package/src/theme/theme.d.ts +77 -77
  267. package/src/utils/adminAxios.ts +15 -15
  268. package/src/utils/alphabet.ts +23 -23
  269. package/src/utils/arrayPadEnd.ts +3 -3
  270. package/src/utils/buffertoCSV.ts +11 -11
  271. package/src/utils/formatCurrency.ts +9 -9
  272. package/src/utils/getUrlParams.ts +5 -5
  273. package/src/utils/index.ts +8 -8
  274. package/src/utils/logout.ts +25 -25
  275. package/src/utils/ordinalSuffixOf.ts +14 -14
  276. package/src/utils/romanize.ts +40 -40
  277. package/src/utils/withRouteWrapper.tsx +25 -25
  278. package/src/utils/withSuspense.tsx +6 -6
  279. package/styled-components.tsx +60 -60
  280. package/tsconfig.json +21 -21
@@ -0,0 +1,53 @@
1
+ import { Box, Typography } from '@mui/material'
2
+ import { DeleteButton } from '../../IconButtons'
3
+ import { StyledUploadedFileContainer } from '../Styles'
4
+
5
+ export const FileRender = ({ state, setState, setValue }) => {
6
+ const onDelete = (fileKey) => {
7
+ setValue(
8
+ 'attachment',
9
+ state.filter((item) => item.key !== fileKey),
10
+ )
11
+ setState((prev) => prev?.filter((item) => item.key !== fileKey))
12
+ }
13
+
14
+ return (
15
+ <>
16
+ {state?.map((file, index) => {
17
+ let extension = file?.fileName?.split('.')[1]
18
+ return (
19
+ <StyledUploadedFileContainer key={index}>
20
+ <Box sx={{ display: 'flex', alignItems: 'center' }}>
21
+ {extension === 'pdf' ? (
22
+ <span>
23
+ <img src={`/images/pdf.png`} />
24
+ </span>
25
+ ) : extension === 'pptx' ? (
26
+ <span>
27
+ <img src={'/images/ppt.png'} />
28
+ </span>
29
+ ) : extension === 'txt' ? (
30
+ <span>
31
+ <img src={'/images/doc.png'} />
32
+ </span>
33
+ ) : (
34
+ <span>
35
+ <img src={'/images/jpg.png'} />
36
+ </span>
37
+ )}
38
+
39
+ <Typography sx={{ margin: '0px 10px' }}>
40
+ {file.fileName}
41
+ </Typography>
42
+ </Box>
43
+ <DeleteButton
44
+ onClick={() => {
45
+ onDelete(file.key)
46
+ }}
47
+ />
48
+ </StyledUploadedFileContainer>
49
+ )
50
+ })}
51
+ </>
52
+ )
53
+ }
@@ -0,0 +1,69 @@
1
+ import { Box, Card, Typography } from '@mui/material'
2
+ import moment from 'moment'
3
+ import { EditButton } from '../../IconButtons'
4
+ import Image from '../../Image/Image'
5
+ import { DialogButton } from '../../ModalButtons'
6
+
7
+ import {
8
+ StyledAvatar,
9
+ StyledBox,
10
+ StyledTextContainer,
11
+ } from '../Workshop/Styles'
12
+ import ResearchProjectForm from './ResearchProjectForm'
13
+
14
+ const ResearchProjectCard = ({ data }) => {
15
+ return (
16
+ <div>
17
+ <Card
18
+ sx={{
19
+ padding: '15px',
20
+ }}
21
+ >
22
+ <StyledBox>
23
+ <Box
24
+ sx={{
25
+ display: 'flex',
26
+ }}
27
+ >
28
+ {data?.coverImage?.url ? (
29
+ <Image
30
+ alt=""
31
+ radius={'10px'}
32
+ src={data?.coverImage?.url}
33
+ width={'100px'}
34
+ height={'100px'}
35
+ fit={'cover'}
36
+ />
37
+ ) : (
38
+ <StyledAvatar>
39
+ <Typography sx={{ color: 'blue', fontSize: '30px' }}>
40
+ {data?.programName.toUpperCase()}
41
+ </Typography>
42
+ </StyledAvatar>
43
+ )}
44
+ <StyledTextContainer>
45
+ <Typography variant="h5">{data?.programName}</Typography>
46
+ <Typography variant="subtitle2">{data?.description}</Typography>
47
+ <Typography variant="subtitle2">
48
+ {moment(data?.startDate).format('DD MMM YYYY')} -{' '}
49
+ {moment(data?.endDate).format('DD MMM YYYY')}
50
+ </Typography>
51
+ </StyledTextContainer>
52
+ </Box>
53
+ <Box>
54
+ <DialogButton
55
+ key={data?.id}
56
+ title={'Edit ResearchProject'}
57
+ anchor={({ open }) => <EditButton onClick={open} />}
58
+ content={({ close }) => (
59
+ <ResearchProjectForm data={data} close={close} />
60
+ )}
61
+ />
62
+ </Box>
63
+ </StyledBox>
64
+ </Card>
65
+ </div>
66
+ )
67
+ }
68
+
69
+ export default ResearchProjectCard
@@ -0,0 +1,36 @@
1
+ /* eslint-disable react/jsx-key */
2
+
3
+ import { Typography } from '@mui/material'
4
+ import ActionButton from '../../ActionButton'
5
+ import { DialogButton } from '../../ModalButtons'
6
+ import ResearchProjectCard from './ResearchProjectCard'
7
+ import ResearchProjectForm from './ResearchProjectForm'
8
+ import { StyledBoxCard, StyledBoxContainer } from './Styles'
9
+
10
+ const ResearchProjectData = ({ title, ResearchProject }) => {
11
+ return (
12
+ <>
13
+ <StyledBoxContainer>
14
+ <Typography variant="h3">ResearchProject - {title}</Typography>
15
+ <DialogButton
16
+ anchor={({ open }) => (
17
+ <ActionButton onClick={open} variant="text">
18
+ +Add Research Project
19
+ </ActionButton>
20
+ )}
21
+ content={({ close }) => (
22
+ <ResearchProjectForm data={null} close={close} />
23
+ )}
24
+ title="Add ResearchProject"
25
+ />
26
+ </StyledBoxContainer>
27
+ <StyledBoxCard>
28
+ {ResearchProject.map((item) => (
29
+ <ResearchProjectCard data={item} />
30
+ ))}
31
+ </StyledBoxCard>
32
+ </>
33
+ )
34
+ }
35
+
36
+ export default ResearchProjectData
@@ -0,0 +1,475 @@
1
+ import { yupResolver } from '@hookform/resolvers/yup'
2
+ import { Add } from '@mui/icons-material'
3
+ import UploadIcon from '@mui/icons-material/Upload'
4
+ import {
5
+ Box,
6
+ Button,
7
+ CircularProgress,
8
+ Stack,
9
+ Typography,
10
+ alpha,
11
+ } from '@mui/material'
12
+ import { useEffect, useState } from 'react'
13
+ import { Controller, useFieldArray, useForm } from 'react-hook-form'
14
+ import { useMutation, useQuery, useQueryClient } from 'react-query'
15
+ import { toast } from 'react-toastify'
16
+ import * as yup from 'yup'
17
+ import { axiosErrorToast } from '../../../config/axios'
18
+ import ActionButton from '../../ActionButton'
19
+ import { FormDatePicker, FormSingleSelect, FormTextField } from '../../HookForm'
20
+ import FormLabel from '../../HookForm/FormLabel'
21
+ import ImageUpload from '../../ImageUpload'
22
+ import AsyncSearchSelect from '../../Input/AsyncSearchSelect/AsyncSearchSelect'
23
+ import MediaRow from '../../MediaRow/MediaRow'
24
+ import Spinner from '../../Spinner'
25
+ import { Media } from '../../UploadButton/types'
26
+ import { StyledDeleteButton } from '../PaperPublication/Styles'
27
+ import { StyledUploadContainer } from '../Styles'
28
+ import { FileRender } from './FileRender'
29
+ import { StyledStack, StyledTypography } from './Styles'
30
+ import {
31
+ FundingSources,
32
+ PatentStatus,
33
+ createProject,
34
+ fetchFacultyUsers,
35
+ fetchPrograms,
36
+ uploadFiles,
37
+ } from './services'
38
+
39
+ export const schema = yup.object().shape({
40
+ title: yup.string().required('Project title is required'),
41
+ programName: yup.string().required('Research Area is required'),
42
+ description: yup.string().required('Description is required'),
43
+ projectLeadIds: yup
44
+ .array()
45
+ .min(1, 'Need at least 1 project lead')
46
+ .required('Lead Researcher is required'),
47
+ projectMemberIds: yup
48
+ .array()
49
+ .min(1, 'Need at least 1 project member')
50
+ .required('Project Member is required'),
51
+ fundingSource: yup.string().required('Funding source is required'),
52
+ patentStatus: yup.string().required('Patent Status should not be empty'),
53
+ startDate: yup.string().required('Start date is required').nullable(),
54
+ fundingAmount: yup.string().required('Funding Amount is required'),
55
+ endDate: yup.string().required('End date is required').nullable(),
56
+ coverImage: yup.array().min(1).required('Cover Image is required').nullable(),
57
+ keywords: yup
58
+ .array()
59
+ .of(
60
+ yup.object().shape({
61
+ keyword: yup.string().required('Keyword is required'),
62
+ }),
63
+ )
64
+ .min(1, 'Need at least 1 keyword')
65
+ .required('Keyword minimum of 1 is required'),
66
+ })
67
+
68
+ function ResearchProjectForm({
69
+ data,
70
+ close,
71
+ }: {
72
+ data?: any
73
+ close: () => void
74
+ }) {
75
+ const [coverMedia, setCoverMedia] = useState<Media[]>([])
76
+ const [attachmentMedia, setAttachmentMedia] = useState<Media[]>([])
77
+ const queryClient = useQueryClient()
78
+
79
+ const { control, handleSubmit, watch, setValue } = useForm({
80
+ resolver: yupResolver(schema),
81
+ defaultValues: {
82
+ ...data,
83
+ keywords:
84
+ data?.keywords?.map((item) => {
85
+ return { keyword: item }
86
+ }) || [],
87
+ projectMemberIds:
88
+ data?.projectMembers?.map((item) => {
89
+ return {
90
+ value: item?.userDetails?._id,
91
+ label: item?.userDetails?.fullName,
92
+ }
93
+ }) || [],
94
+
95
+ projectLeadIds:
96
+ data?.projectMembers
97
+ ?.filter((item) => item?.isLead == true)
98
+ .map((item) => {
99
+ return {
100
+ value: item?.userDetails?._id,
101
+ label: item?.userDetails?.fullName,
102
+ }
103
+ }) || [],
104
+ attachment:
105
+ data?.attachments?.map((item) => {
106
+ return {
107
+ key: item?.key,
108
+ url: item?.url,
109
+ type: item?.mediaType,
110
+ }
111
+ }) || [],
112
+ coverImage: data
113
+ ? [
114
+ {
115
+ key: data?.coverImage?.key,
116
+ url: data?.coverImage?.url,
117
+ type: data?.coverImage?.mediaType,
118
+ },
119
+ ]
120
+ : [],
121
+ },
122
+ })
123
+
124
+ const { isLoading: loadingUsers, data: options } = useQuery('programs', () =>
125
+ fetchPrograms(),
126
+ )
127
+ const { fields, append, remove } = useFieldArray({
128
+ control,
129
+ name: 'keywords',
130
+ })
131
+
132
+ const handleDeleteImage = (key) => {
133
+ setCoverMedia((prev) => prev.filter((m) => m.key !== key))
134
+ }
135
+ const { mutate, isLoading: creatingProject } = useMutation(createProject, {
136
+ onSuccess: (res) => {
137
+ close()
138
+ toast.success(
139
+ data ? 'Project Updated successfully' : `Project created successfully`,
140
+ )
141
+ queryClient.invalidateQueries('research-projects')
142
+ },
143
+ onError: (err) => {
144
+ axiosErrorToast(err)
145
+ },
146
+ })
147
+
148
+ const onSubmit = async (formData) => {
149
+ const postBody = {
150
+ ...formData,
151
+ imageKey: coverMedia[0]?.key,
152
+ attachmentKeys: attachmentMedia?.map((item) => item?.key) ?? [],
153
+ projectLeadIds:
154
+ formData?.projectLeadIds?.map((item) => item?.value.toString()) ?? [],
155
+ projectMemberIds:
156
+ formData?.projectMemberIds?.map((item) => item?.value.toString()) ?? [],
157
+ keywords: formData?.keywords?.map((item) => item?.keyword),
158
+ }
159
+ mutate(postBody)
160
+ }
161
+ const { mutate: uploadFile, isLoading: uploadingFile } = useMutation(
162
+ uploadFiles,
163
+ {
164
+ onSuccess: (res) => {
165
+ setValue('attachment', [
166
+ ...watch('attachment'),
167
+ { fileName: res?.originalFileName, key: res?.key, url: res?.url },
168
+ ])
169
+ setAttachmentMedia((prev) => [
170
+ ...prev,
171
+ {
172
+ key: res?.key,
173
+ type: 'file',
174
+ url: res.url,
175
+ fileName: res.originalFileName,
176
+ },
177
+ ])
178
+ },
179
+ onError: (err) => {
180
+ // eslint-disable-next-line no-console
181
+ console.log(err)
182
+ axiosErrorToast(err)
183
+ },
184
+ },
185
+ )
186
+
187
+ const handleFileInput = (e) => {
188
+ let filesData = e.target.files
189
+ let fileArray = Object.keys(filesData)
190
+ fileArray.forEach(async (file) => {
191
+ const fileData = new FormData()
192
+ fileData.append('file', filesData[file])
193
+ fileData.append('subType', 'attachment')
194
+ uploadFile(fileData)
195
+ })
196
+ }
197
+
198
+ const onFileUploaded = (res: any) => {
199
+ setValue('coverImage', [{ key: res.key, type: 'image', url: res.url }])
200
+ setCoverMedia([{ type: 'image', url: res.url, key: res.key }])
201
+ }
202
+ const onError = (err) => {
203
+ // eslint-disable-next-line no-console
204
+ console.log(err)
205
+ }
206
+
207
+ useEffect(() => {
208
+ if (watch('keywords').length == 0) {
209
+ append({ keyword: '' })
210
+ }
211
+
212
+ data && data?.coverImage?.url
213
+ ? setCoverMedia([
214
+ {
215
+ key: data?.coverImage?.key,
216
+ url: data?.coverImage?.url,
217
+ type: data?.coverImage?.mediaType,
218
+ },
219
+ ])
220
+ : setCoverMedia([])
221
+
222
+ data && data?.attachments?.length
223
+ ? setAttachmentMedia(
224
+ data?.attachments?.map((item) => {
225
+ return {
226
+ key: item?.key,
227
+ url: item?.url,
228
+ type: item?.mediaType,
229
+ fileName: item?.originalFileName,
230
+ }
231
+ }),
232
+ )
233
+ : setAttachmentMedia([])
234
+ }, [data])
235
+
236
+ if (loadingUsers) {
237
+ return <Spinner />
238
+ }
239
+
240
+ return (
241
+ <>
242
+ <form onSubmit={handleSubmit(onSubmit, onError)}>
243
+ <FormLabel label={'Cover Image'} required={true} />
244
+ <Stack gap={3.5}>
245
+ <>
246
+ {!coverMedia.length ? (
247
+ <Controller
248
+ name={'coverImage'}
249
+ control={control}
250
+ render={({ field, fieldState: { error } }) => (
251
+ <>
252
+ <ImageUpload
253
+ onFileUploaded={(res) => {
254
+ onFileUploaded(res)
255
+ }}
256
+ postUrl="/square/research-projects/upload"
257
+ postBody={{ subType: 'image' }}
258
+ />
259
+
260
+ {error && (
261
+ <StyledTypography>{error?.message}</StyledTypography>
262
+ )}
263
+ </>
264
+ )}
265
+ />
266
+ ) : (
267
+ <MediaRow list={coverMedia} onDelete={handleDeleteImage} />
268
+ )}
269
+ </>
270
+ <FormTextField
271
+ name="title"
272
+ label={'Research Project Title'}
273
+ control={control}
274
+ required
275
+ />
276
+ <FormSingleSelect
277
+ label="Research Areas/Field"
278
+ control={control}
279
+ name="programName"
280
+ options={options?.map((item) => ({
281
+ value: item.branchName,
282
+ label: item.branchName,
283
+ }))}
284
+ required
285
+ />
286
+
287
+ <FormTextField
288
+ label="Description/Abstract"
289
+ name="description"
290
+ control={control}
291
+ multiline
292
+ minRows={4}
293
+ required
294
+ />
295
+ <Box
296
+ sx={{
297
+ display: 'flex',
298
+ gap: '20px',
299
+ alignItems: 'center',
300
+ justifyContent: 'center',
301
+ }}
302
+ >
303
+ <FormDatePicker
304
+ maxDate={watch('endDate')}
305
+ name="startDate"
306
+ label="Start date "
307
+ control={control}
308
+ required
309
+ />
310
+
311
+ <FormDatePicker
312
+ name="endDate"
313
+ label="End date "
314
+ control={control}
315
+ required
316
+ minDate={watch('startDate')}
317
+ />
318
+ </Box>
319
+ <StyledStack direction={'row'}>
320
+ <Typography variant="h3">Keywords</Typography>
321
+ <Button
322
+ variant="text"
323
+ startIcon={<Add />}
324
+ size="small"
325
+ onClick={() => append({ keyword: '' })}
326
+ >
327
+ Add
328
+ </Button>
329
+ </StyledStack>
330
+ {fields?.map((field, index) => (
331
+ <Box key={field?.id}>
332
+ <StyledStack
333
+ direction={'row'}
334
+ gap={2}
335
+ sx={{ alignItems: 'flex-end' }}
336
+ >
337
+ <FormTextField
338
+ name={`keywords.${index}.keyword`}
339
+ label={`Keyword ${index + 1}`}
340
+ control={control}
341
+ required
342
+ />
343
+
344
+ <StyledDeleteButton onClick={() => remove(index)} />
345
+ </StyledStack>
346
+ </Box>
347
+ ))}
348
+ <Controller
349
+ name={'projectLeadIds'}
350
+ control={control}
351
+ render={({ field, fieldState: { error } }) => (
352
+ <>
353
+ <AsyncSearchSelect
354
+ label="Lead Researcher"
355
+ fetchFn={fetchFacultyUsers}
356
+ onChange={(value) => {
357
+ setValue('projectLeadIds', value)
358
+ }}
359
+ initialOptions={watch('projectLeadIds')}
360
+ required
361
+ />
362
+ {error && <StyledTypography>{error?.message}</StyledTypography>}
363
+ </>
364
+ )}
365
+ />
366
+
367
+ <Controller
368
+ name={'projectMemberIds'}
369
+ control={control}
370
+ render={({ field, fieldState: { error } }) => (
371
+ <>
372
+ <AsyncSearchSelect
373
+ label="Project Members"
374
+ fetchFn={fetchFacultyUsers}
375
+ onChange={(value) => {
376
+ setValue('projectMemberIds', value)
377
+ }}
378
+ initialOptions={watch('projectMemberIds')}
379
+ required
380
+ />
381
+ {error && <StyledTypography>{error?.message}</StyledTypography>}
382
+ </>
383
+ )}
384
+ />
385
+ <FormSingleSelect
386
+ label={'Funding Source'}
387
+ name="fundingSource"
388
+ control={control}
389
+ options={
390
+ Object.keys(FundingSources)?.map((key) => ({
391
+ label: FundingSources[key],
392
+ value: key,
393
+ })) ?? []
394
+ }
395
+ required
396
+ />
397
+
398
+ <FormTextField
399
+ label={'Funding Amount'}
400
+ name="fundingAmount"
401
+ control={control}
402
+ type="number"
403
+ required
404
+ />
405
+
406
+ <FormSingleSelect
407
+ label={'Patent Status'}
408
+ name="patentStatus"
409
+ control={control}
410
+ options={
411
+ Object.keys(PatentStatus)?.map((key) => ({
412
+ label: PatentStatus[key],
413
+ value: key,
414
+ })) ?? []
415
+ }
416
+ required
417
+ />
418
+ <Box>
419
+ <Typography
420
+ sx={{
421
+ color: alpha('#121212', 0.5),
422
+ lineHeight: 2,
423
+ }}
424
+ >
425
+ Add Files
426
+ </Typography>
427
+ {attachmentMedia.length !== 0 && (
428
+ <FileRender
429
+ state={attachmentMedia}
430
+ setState={setAttachmentMedia}
431
+ setValue={setValue}
432
+ />
433
+ )}
434
+ <Controller
435
+ name={'attachment'}
436
+ control={control}
437
+ render={({ field, fieldState: { error } }) => (
438
+ <>
439
+ <StyledUploadContainer htmlFor="file">
440
+ <UploadIcon />
441
+ <Typography variant="subtitle2" sx={{ margin: '0px 10px' }}>
442
+ Upload Files
443
+ </Typography>
444
+ {uploadingFile && <CircularProgress size={20} />}
445
+ </StyledUploadContainer>
446
+
447
+ {error && (
448
+ <StyledTypography>{error?.message}</StyledTypography>
449
+ )}
450
+ </>
451
+ )}
452
+ />
453
+ <input
454
+ id="file"
455
+ type="file"
456
+ hidden
457
+ multiple
458
+ onChange={handleFileInput}
459
+ />
460
+ </Box>
461
+ </Stack>
462
+ <Stack direction="row" gap={2} mt={3}>
463
+ <ActionButton variant="outlined" fullWidth onClick={close}>
464
+ Cancel
465
+ </ActionButton>
466
+ <ActionButton type="submit" fullWidth loading={creatingProject}>
467
+ {data ? 'Update Project' : 'Add Project'}
468
+ </ActionButton>
469
+ </Stack>
470
+ </form>
471
+ </>
472
+ )
473
+ }
474
+
475
+ export default ResearchProjectForm
@@ -0,0 +1,55 @@
1
+ import NoDataSection from '../NoDataSection'
2
+ import StyledTabsContainer from '../StyledTabsContainer'
3
+ import ResearchProjectData from './ResearchProjectData'
4
+ import ResearchProjectForm from './ResearchProjectForm'
5
+
6
+ function ResearchProjects({ ResearchProject }) {
7
+ const test = []
8
+ const Research = true
9
+ const Ongoing = ResearchProject?.filter(
10
+ (project) => project?.projectStatus == 'ongoing',
11
+ )
12
+ const Completed = test?.filter(
13
+ (project) => project?.projectStatus == 'completed',
14
+ )
15
+
16
+ const tabs = [
17
+ {
18
+ key: 'Ongoing',
19
+ label: 'Ongoing',
20
+ component: (
21
+ <ResearchProjectData title={'Ongoing'} ResearchProject={Ongoing} />
22
+ ),
23
+ },
24
+ {
25
+ key: 'Completed',
26
+ label: 'Completed',
27
+ component: (
28
+ <ResearchProjectData title={'Completed'} ResearchProject={Completed} />
29
+ ),
30
+ },
31
+ ]
32
+ return (
33
+ <>
34
+ {Research ? (
35
+ <StyledTabsContainer
36
+ tabs={tabs}
37
+ centered
38
+ textColor="primary"
39
+ indicatorBackgroundColor="primary"
40
+ />
41
+ ) : (
42
+ <NoDataSection
43
+ title="ResearchProjects"
44
+ subtitle="Add ResearchProjects"
45
+ addButtonTitle="Add Your ResearchProjects"
46
+ addButtonContent={({ close }) => (
47
+ <ResearchProjectForm close={close} data={[]} />
48
+ )}
49
+ />
50
+ )}
51
+ </>
52
+ )
53
+ }
54
+
55
+ export default ResearchProjects