@campxdev/shared 0.1.0

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 (253) hide show
  1. package/.eslintrc.js +34 -0
  2. package/.prettierrc +10 -0
  3. package/.storybook/main.js +16 -0
  4. package/.storybook/preview.js +9 -0
  5. package/antd.customize.less +73 -0
  6. package/exports.ts +20 -0
  7. package/package.json +78 -0
  8. package/public/dean.JPG +0 -0
  9. package/public/download.png +0 -0
  10. package/public/illustrations/bookmark.svg +19 -0
  11. package/public/illustrations/girl-writing.png +0 -0
  12. package/public/illustrations/whiteboard.svg +24 -0
  13. package/public/images/AnimatedUploadFile.gif +0 -0
  14. package/public/images/doc@2x.png +0 -0
  15. package/public/images/greenTick.png +0 -0
  16. package/public/images/jpg.png +0 -0
  17. package/public/images/paperclip@2x.png +0 -0
  18. package/public/images/pdf.png +0 -0
  19. package/public/images/ppt.png +0 -0
  20. package/public/images/profileImage.jpg +0 -0
  21. package/public/images/profileImage.png +0 -0
  22. package/public/index.html +50 -0
  23. package/public/logo.png +0 -0
  24. package/public/logo_campx_full.png +0 -0
  25. package/public/logo_square.svg +21 -0
  26. package/public/omr_sign.jpg +0 -0
  27. package/src/App.tsx +35 -0
  28. package/src/assets/fonts/avenir/Avenir.ttc +0 -0
  29. package/src/assets/fonts/avenir/index.ts +2 -0
  30. package/src/assets/fonts/poppins/Poppins-Bold.ttf +0 -0
  31. package/src/assets/fonts/poppins/Poppins-Italic.ttf +0 -0
  32. package/src/assets/fonts/poppins/Poppins-Light.ttf +0 -0
  33. package/src/assets/fonts/poppins/Poppins-LightItalic.ttf +0 -0
  34. package/src/assets/fonts/poppins/Poppins-Medium.ttf +0 -0
  35. package/src/assets/fonts/poppins/Poppins-MediumItalic.ttf +0 -0
  36. package/src/assets/fonts/poppins/Poppins-Regular.ttf +0 -0
  37. package/src/assets/fonts/poppins/Poppins-SemiBold.ttf +0 -0
  38. package/src/assets/fonts/poppins/Poppins-SemiBoldItalic.ttf +0 -0
  39. package/src/assets/fonts/poppins/index.ts +7 -0
  40. package/src/assets/images/File bundle-bro.svg +122 -0
  41. package/src/assets/images/Filebundle.png +0 -0
  42. package/src/assets/images/NoPart.png +0 -0
  43. package/src/assets/images/ResultProcess.png +0 -0
  44. package/src/assets/images/ResultProcess.svg +99 -0
  45. package/src/assets/images/attachment.svg +1 -0
  46. package/src/assets/images/avatar.png +0 -0
  47. package/src/assets/images/index.ts +19 -0
  48. package/src/assets/images/pdf.png +0 -0
  49. package/src/assets/images/taskAttachment.png +0 -0
  50. package/src/assets/images/welcomeimage.jpg +0 -0
  51. package/src/assets/static_files/External_Marks_Import .xlsx +0 -0
  52. package/src/assets/static_files/Leads_Sample.xlsx +0 -0
  53. package/src/assets/static_files/Subject_Topic_Import_Sheet.xlsx +0 -0
  54. package/src/assets/static_files/admissions_Sample.xlsx +0 -0
  55. package/src/assets/static_files/barcodes_template.xlsx +0 -0
  56. package/src/assets/static_files/hostel_rooms_import.xlsx +0 -0
  57. package/src/assets/static_files/index.ts +24 -0
  58. package/src/assets/static_files/sample_admissions.xlsx +0 -0
  59. package/src/assets/static_files/sample_admissions_report.xlsx +0 -0
  60. package/src/assets/static_files/sample_curriculum_subjects_template.xlsx +0 -0
  61. package/src/assets/static_files/sample_import_students_new.xlsx +0 -0
  62. package/src/assets/static_files/sample_internal_marks.xlsx +0 -0
  63. package/src/assets/static_files/sample_student_subjects_template.xlsx +0 -0
  64. package/src/components/ActionButton.tsx +28 -0
  65. package/src/components/Attachment.tsx +26 -0
  66. package/src/components/AutocompleteSearch/AutocompleteSearch.tsx +57 -0
  67. package/src/components/AutocompleteSearch/index.tsx +1 -0
  68. package/src/components/Breadcrumbs.tsx +73 -0
  69. package/src/components/Card.tsx +97 -0
  70. package/src/components/CardsGrid.tsx +28 -0
  71. package/src/components/Chips.tsx +77 -0
  72. package/src/components/Detail.tsx +15 -0
  73. package/src/components/DetailsGrid.tsx +52 -0
  74. package/src/components/DividerHeading.tsx +40 -0
  75. package/src/components/DrawerWrapper/DialogWrapper.tsx +63 -0
  76. package/src/components/DrawerWrapper/DrawerTemplate.tsx +53 -0
  77. package/src/components/DrawerWrapper/DrawerWrapper.tsx +53 -0
  78. package/src/components/DropDownButton.tsx +184 -0
  79. package/src/components/ErrorBoundary.js +45 -0
  80. package/src/components/ErrorBox.tsx +42 -0
  81. package/src/components/FloatingContainer.tsx +26 -0
  82. package/src/components/FullCalendar/Actions.tsx +162 -0
  83. package/src/components/FullCalendar/FullCalendarWrapper.tsx +54 -0
  84. package/src/components/HookForm/AutoCompleteSearch.tsx +143 -0
  85. package/src/components/HookForm/DatePicker.tsx +65 -0
  86. package/src/components/HookForm/DateTimePicker.tsx +70 -0
  87. package/src/components/HookForm/FormLabel.tsx +14 -0
  88. package/src/components/HookForm/MultiCheckbox.tsx +82 -0
  89. package/src/components/HookForm/MultiSelect.tsx +100 -0
  90. package/src/components/HookForm/RadioGroup.tsx +113 -0
  91. package/src/components/HookForm/SingleCheckbox.tsx +46 -0
  92. package/src/components/HookForm/SingleSelect.tsx +93 -0
  93. package/src/components/HookForm/TextField.tsx +74 -0
  94. package/src/components/HookForm/TimePicker.tsx +82 -0
  95. package/src/components/HookForm/index.ts +23 -0
  96. package/src/components/IconButtons/IconButtons.tsx +137 -0
  97. package/src/components/IconButtons/Icons.tsx +269 -0
  98. package/src/components/IconButtons/assets/edit.svg +4 -0
  99. package/src/components/IconButtons/assets/eye.svg +6 -0
  100. package/src/components/IconButtons/assets/trash.svg +7 -0
  101. package/src/components/IconButtons/index.tsx +8 -0
  102. package/src/components/IconLabel.tsx +37 -0
  103. package/src/components/Image/Image.tsx +43 -0
  104. package/src/components/Image/broken-image.png +0 -0
  105. package/src/components/Image/index.tsx +1 -0
  106. package/src/components/ImageUpload.tsx +98 -0
  107. package/src/components/Input/AutoCompleteSearch.tsx +143 -0
  108. package/src/components/Input/DatePicker.tsx +60 -0
  109. package/src/components/Input/DateRangePicker.tsx +131 -0
  110. package/src/components/Input/DateTimePicker.tsx +70 -0
  111. package/src/components/Input/FormLabel.tsx +14 -0
  112. package/src/components/Input/MultiCheckbox.tsx +79 -0
  113. package/src/components/Input/MultiSelect.tsx +52 -0
  114. package/src/components/Input/RadioGroup.tsx +55 -0
  115. package/src/components/Input/SingleCheckbox.tsx +23 -0
  116. package/src/components/Input/SingleSelect.tsx +139 -0
  117. package/src/components/Input/TextField.tsx +50 -0
  118. package/src/components/Input/TimePicker.tsx +82 -0
  119. package/src/components/Input/index.ts +26 -0
  120. package/src/components/JsonPreview/JsonPreview.tsx +7 -0
  121. package/src/components/JsonPreview/index.tsx +1 -0
  122. package/src/components/LabelValue/LabelValue.tsx +21 -0
  123. package/src/components/LabelValue/index.tsx +1 -0
  124. package/src/components/Layout/ChangePassword.tsx +49 -0
  125. package/src/components/Layout/Header/AppHeader.tsx +150 -0
  126. package/src/components/Layout/Header/CogWheelMenu.tsx +35 -0
  127. package/src/components/Layout/Header/FreshDeskHelpButton.tsx +19 -0
  128. package/src/components/Layout/Header/MainAppHeader.tsx +6 -0
  129. package/src/components/Layout/Header/Notification.tsx +13 -0
  130. package/src/components/Layout/Header/UserBox.tsx +51 -0
  131. package/src/components/Layout/Header/applications.tsx +39 -0
  132. package/src/components/Layout/Header/icons.tsx +57 -0
  133. package/src/components/Layout/Header/index.tsx +1 -0
  134. package/src/components/Layout/Header/styles.tsx +48 -0
  135. package/src/components/LinearProgress/LinearProgress.tsx +27 -0
  136. package/src/components/LinearProgress/index.tsx +1 -0
  137. package/src/components/MediaRow/MediaRow.tsx +69 -0
  138. package/src/components/MediaRow/index.tsx +1 -0
  139. package/src/components/MenuButton.tsx +105 -0
  140. package/src/components/ModalButtons/DialogButton.tsx +84 -0
  141. package/src/components/ModalButtons/DrawerButton.tsx +89 -0
  142. package/src/components/ModalButtons/index.tsx +4 -0
  143. package/src/components/NoDataIllustration/NoDataIllustration.tsx +32 -0
  144. package/src/components/NoDataIllustration/index.tsx +1 -0
  145. package/src/components/PageContent.tsx +14 -0
  146. package/src/components/PageHeader.tsx +52 -0
  147. package/src/components/PopupConfirm/ConfirmContextProvider.tsx +22 -0
  148. package/src/components/PopupConfirm/PopupConfirm.tsx +33 -0
  149. package/src/components/PopupConfirm/index.tsx +1 -0
  150. package/src/components/PopupConfirm/useConfirm.ts +47 -0
  151. package/src/components/Row/Row.tsx +24 -0
  152. package/src/components/Row/index.tsx +1 -0
  153. package/src/components/SearchBar/SearchBar.tsx +53 -0
  154. package/src/components/SearchBar/index.tsx +1 -0
  155. package/src/components/Spinner.tsx +18 -0
  156. package/src/components/StepsHeader/StepsHeader.tsx +115 -0
  157. package/src/components/StepsHeader/index.tsx +1 -0
  158. package/src/components/Styled/OutlinedIconButton.tsx +7 -0
  159. package/src/components/Styled/index.tsx +1 -0
  160. package/src/components/StyledTableContainer.tsx +33 -0
  161. package/src/components/Swiper/Swiper.tsx +39 -0
  162. package/src/components/Swiper/index.tsx +1 -0
  163. package/src/components/SwitchButton/SwitchButton.tsx +41 -0
  164. package/src/components/SwitchButton/index.tsx +1 -0
  165. package/src/components/TableComponent/BatchActionsHeader.tsx +58 -0
  166. package/src/components/TableComponent/Icons/index.tsx +50 -0
  167. package/src/components/TableComponent/ReactTable.tsx +293 -0
  168. package/src/components/TableComponent/RenderTableBody.tsx +65 -0
  169. package/src/components/TableComponent/TableFooter/TableFooter.tsx +102 -0
  170. package/src/components/TableComponent/TableFooter/index.tsx +1 -0
  171. package/src/components/TableComponent/TableFooter/styles.tsx +28 -0
  172. package/src/components/TableComponent/index.tsx +219 -0
  173. package/src/components/TableComponent/no-data-illu.svg +1 -0
  174. package/src/components/TableComponent/react-table-config.d.ts +129 -0
  175. package/src/components/TableComponent/styles.tsx +173 -0
  176. package/src/components/TableComponent/types.ts +57 -0
  177. package/src/components/Tabs/Tabs.tsx +52 -0
  178. package/src/components/Tabs/TabsContainer.tsx +50 -0
  179. package/src/components/Tabs/index.tsx +1 -0
  180. package/src/components/Tabs/styles.tsx +55 -0
  181. package/src/components/ToastContainer/ToastContainer.tsx +42 -0
  182. package/src/components/ToastContainer/index.tsx +1 -0
  183. package/src/components/UploadButton/UploadButton.tsx +98 -0
  184. package/src/components/UploadButton/index.tsx +1 -0
  185. package/src/components/UploadButton/types.ts +14 -0
  186. package/src/components/UploadDocument/UploadDocument.tsx +108 -0
  187. package/src/components/UploadDocument/index.tsx +1 -0
  188. package/src/components/UploadFileDialog/UploadFileDialog.tsx +240 -0
  189. package/src/components/UploadFileDialog/index.tsx +1 -0
  190. package/src/components/index.ts +59 -0
  191. package/src/config/axios.ts +138 -0
  192. package/src/constants/UIConstants.ts +97 -0
  193. package/src/constants/formValidations.ts +6 -0
  194. package/src/constants/index.ts +4 -0
  195. package/src/constants/permissions.ts +67 -0
  196. package/src/constants/validateMessages.ts +12 -0
  197. package/src/contexts/Providers.tsx +24 -0
  198. package/src/contexts/QueryClientProvider.tsx +22 -0
  199. package/src/hooks/index.ts +2 -0
  200. package/src/hooks/useFetch.ts +53 -0
  201. package/src/hooks/useRouter.ts +31 -0
  202. package/src/index.tsx +9 -0
  203. package/src/layouts/ComponentsLayout.tsx +3 -0
  204. package/src/pages/LoginPage/LoginPage.tsx +166 -0
  205. package/src/pages/LoginPage/index.ts +1 -0
  206. package/src/pages/LoginPage/styles.tsx +121 -0
  207. package/src/pages/index.ts +4 -0
  208. package/src/permissions/PageWithPermission.tsx +58 -0
  209. package/src/permissions/PermissionDeniedPage.tsx +23 -0
  210. package/src/permissions/PermissionsStore.ts +289 -0
  211. package/src/permissions/ValidateAccess.tsx +18 -0
  212. package/src/permissions/index.ts +3 -0
  213. package/src/react-app-env.d.ts +1 -0
  214. package/src/shared-state/AssetsStore.ts +15 -0
  215. package/src/shared-state/UserStore.ts +13 -0
  216. package/src/shared-state/index.ts +3 -0
  217. package/src/stories/Button.stories.tsx +41 -0
  218. package/src/stories/Button.tsx +48 -0
  219. package/src/stories/Header.stories.tsx +25 -0
  220. package/src/stories/Header.tsx +56 -0
  221. package/src/stories/Introduction.stories.mdx +211 -0
  222. package/src/stories/Page.stories.tsx +26 -0
  223. package/src/stories/Page.tsx +73 -0
  224. package/src/stories/TextField.stories.tsx +18 -0
  225. package/src/stories/TextField.tsx +49 -0
  226. package/src/stories/assets/code-brackets.svg +1 -0
  227. package/src/stories/assets/colors.svg +1 -0
  228. package/src/stories/assets/comments.svg +1 -0
  229. package/src/stories/assets/direction.svg +1 -0
  230. package/src/stories/assets/flow.svg +1 -0
  231. package/src/stories/assets/plugin.svg +1 -0
  232. package/src/stories/assets/repo.svg +1 -0
  233. package/src/stories/assets/stackalt.svg +1 -0
  234. package/src/stories/button.css +30 -0
  235. package/src/stories/header.css +32 -0
  236. package/src/stories/page.css +69 -0
  237. package/src/theme/App.less +3 -0
  238. package/src/theme/MuiThemeProvider.tsx +11 -0
  239. package/src/theme/customCssBaseline.ts +78 -0
  240. package/src/theme/index.css +75 -0
  241. package/src/theme/muiTheme.ts +516 -0
  242. package/src/theme/theme.d.ts +75 -0
  243. package/src/utils/alphabet.ts +23 -0
  244. package/src/utils/arrayPadEnd.ts +3 -0
  245. package/src/utils/formatCurrency.ts +9 -0
  246. package/src/utils/getUrlParams.ts +5 -0
  247. package/src/utils/index.ts +6 -0
  248. package/src/utils/ordinalSuffixOf.ts +14 -0
  249. package/src/utils/romanize.ts +40 -0
  250. package/src/utils/withRouteWrapper.tsx +25 -0
  251. package/src/utils/withSuspense.tsx +6 -0
  252. package/styled-components.tsx +60 -0
  253. package/tsconfig.json +21 -0
@@ -0,0 +1,115 @@
1
+ import { Done } from '@mui/icons-material'
2
+ import { alpha, Box, styled, Typography } from '@mui/material'
3
+ import { useEffect, useState } from 'react'
4
+
5
+ export const StyledStepsContainer = styled(Box)(({ theme }) => ({
6
+ padding: '10px 0',
7
+ display: 'flex',
8
+ justifyContent: 'center',
9
+ gap: '10px',
10
+ }))
11
+
12
+ export const StyledStep = styled(Box, {
13
+ shouldForwardProp: (prop) =>
14
+ !['active', 'disableHover'].includes(prop as string),
15
+ })<{ active: boolean; disableHover: boolean }>(
16
+ ({ theme, active, disableHover }) => ({
17
+ maxWidth: '130px',
18
+ position: 'relative',
19
+ display: 'grid',
20
+ gridTemplateRows: '50px 1fr',
21
+ placeItems: 'center',
22
+ gap: '10px',
23
+ cursor: disableHover ? 'default' : 'pointer',
24
+ padding: '6px',
25
+ borderRadius: '10px',
26
+ transition: 'background 0.3s ease',
27
+ '&:hover': {
28
+ background: disableHover ? 'none' : theme.palette.secondary.light,
29
+ },
30
+ '& .MuiTypography-root': {
31
+ color: alpha(theme.palette.secondary.main, active ? 1 : 0.6),
32
+ fontWeight: 'bold',
33
+ textAlign: 'center',
34
+ },
35
+ '& .connector': {
36
+ position: 'absolute',
37
+ top: '30%',
38
+ left: '50%',
39
+ width: '100%',
40
+ borderBottom: `1px dashed #1212128A`,
41
+ },
42
+ '&:last-of-type': {
43
+ '& .connector': {
44
+ display: 'none',
45
+ },
46
+ },
47
+ }),
48
+ )
49
+
50
+ export const StyledCircle = styled(Box, {
51
+ shouldForwardProp: (prop) => prop !== 'active',
52
+ })<{ active: boolean }>(({ theme, active }) => ({
53
+ height: '50px',
54
+ width: '50px',
55
+ borderRadius: '50%',
56
+ background: 'white',
57
+ zIndex: 30,
58
+ backgroundImage: `url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' rx='100' ry='100' stroke='gray' stroke-width='1.2' stroke-dasharray='8' stroke-dashoffset='0' stroke-linecap='square'/%3e%3c/svg%3e")`,
59
+ display: 'flex',
60
+ justifyContent: 'center',
61
+ alignItems: 'center',
62
+ ...(active && {
63
+ border: `1px solid ${theme.palette.primary.main}`,
64
+ backgroundImage: 'none',
65
+ }),
66
+ }))
67
+
68
+ interface StepsHeaderProps {
69
+ steps: { step: number; label: string }[]
70
+ onChange: (step: number) => void
71
+ activeStep?: number
72
+ disableClick?: boolean
73
+ }
74
+
75
+ export default function StepsHeader({
76
+ steps,
77
+ onChange,
78
+ activeStep: _activeStep = 0,
79
+ disableClick = false,
80
+ }: StepsHeaderProps) {
81
+ const [activeStep, setActiveStep] = useState(0)
82
+
83
+ const handleClick = (step) => {
84
+ setActiveStep(step)
85
+ onChange(step)
86
+ }
87
+
88
+ useEffect(() => {
89
+ setActiveStep(_activeStep)
90
+ }, [_activeStep])
91
+
92
+ return (
93
+ <StyledStepsContainer>
94
+ {steps?.map((item) => (
95
+ <StyledStep
96
+ active={activeStep > item?.step - 1}
97
+ disableHover={disableClick}
98
+ onClick={() => {
99
+ if (disableClick) return
100
+ handleClick(item.step)
101
+ }}
102
+ key={item?.step}
103
+ >
104
+ <StyledCircle active={activeStep > item?.step - 1}>
105
+ {activeStep > item?.step - 1 && <Done color="success" />}
106
+ </StyledCircle>
107
+ <Typography variant="body1" sx={{ fontSize: '13px' }}>
108
+ {item?.label}
109
+ </Typography>
110
+ <Box className="connector"></Box>
111
+ </StyledStep>
112
+ ))}
113
+ </StyledStepsContainer>
114
+ )
115
+ }
@@ -0,0 +1 @@
1
+ export { default } from './StepsHeader'
@@ -0,0 +1,7 @@
1
+ import { IconButton, styled } from '@mui/material'
2
+
3
+ const OutlinedIconButton = styled(IconButton)(({ theme }) => ({
4
+ border: theme.borders.grayLight,
5
+ minWidth: '50px',
6
+ }))
7
+ export default OutlinedIconButton
@@ -0,0 +1 @@
1
+ export { default as OutlinedIconButton } from './OutlinedIconButton'
@@ -0,0 +1,33 @@
1
+ import styled from 'styled-components'
2
+
3
+ export const StyledTableContainer = styled.div`
4
+ /* background: white; */
5
+ margin-top: 10px;
6
+ border-radius: 16px;
7
+
8
+ table thead tr {
9
+ background-color: #efefef;
10
+ }
11
+
12
+ table,
13
+ td,
14
+ th {
15
+ border: 1px solid #bebebe;
16
+ padding: 8px;
17
+ }
18
+
19
+ table {
20
+ background: white;
21
+ width: 100%;
22
+ border-collapse: collapse;
23
+ }
24
+
25
+ @media print {
26
+ table,
27
+ td,
28
+ th {
29
+ border: 1px solid black;
30
+ padding: 8px;
31
+ }
32
+ }
33
+ `
@@ -0,0 +1,39 @@
1
+ import { Swiper as Swipe, SwiperSlide } from 'swiper/react'
2
+ import 'swiper/css/pagination'
3
+ import 'swiper/css/navigation'
4
+ import { Pagination, Navigation } from 'swiper'
5
+ import { ReactNode } from 'react'
6
+ import { Box, styled } from '@mui/material'
7
+
8
+ const StyledSwiperContainer = styled(Box)(({ theme }) => ({
9
+ '& .swiper-button-next:after, .swiper-button-prev:after': {
10
+ fontSize: '1.5rem',
11
+ color: theme.palette.common.yellow,
12
+ },
13
+ '& .swiper-pagination-bullet-active': {
14
+ background: theme.palette.common.yellow,
15
+ },
16
+ '& .swiper-pagination': {
17
+ bottom: '-5px',
18
+ },
19
+ }))
20
+
21
+ interface SwipeProps {
22
+ list: ReactNode[]
23
+ }
24
+
25
+ export default function Swiper({ list }: SwipeProps) {
26
+ return (
27
+ <StyledSwiperContainer>
28
+ <Swipe
29
+ pagination={true}
30
+ navigation={true}
31
+ modules={[Pagination, Navigation]}
32
+ >
33
+ {list?.map((item, index) => (
34
+ <SwiperSlide key={index}>{item}</SwiperSlide>
35
+ ))}
36
+ </Swipe>
37
+ </StyledSwiperContainer>
38
+ )
39
+ }
@@ -0,0 +1 @@
1
+ export { default } from './Swiper'
@@ -0,0 +1,41 @@
1
+ import { Box, styled, Switch, Typography } from '@mui/material'
2
+ import { ReactNode } from 'react'
3
+
4
+ interface SwicthButtonProps {
5
+ label: ReactNode
6
+ checked: boolean
7
+ onChange: (v: any) => void
8
+ subtitle?: ReactNode
9
+ }
10
+
11
+ export default function SwitchButton({
12
+ label,
13
+ checked,
14
+ onChange,
15
+ subtitle,
16
+ }: SwicthButtonProps) {
17
+ return (
18
+ <StyledBox>
19
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: '1rem' }}>
20
+ <Typography variant="body1">{label}</Typography>
21
+ <Switch
22
+ checked={checked}
23
+ onChange={(e, checked) => onChange(checked)}
24
+ />
25
+ </Box>
26
+ {subtitle && <Typography variant="subtitle1">{subtitle}</Typography>}
27
+ </StyledBox>
28
+ )
29
+ }
30
+
31
+ const StyledBox = styled(Box)(({ theme }) => ({
32
+ '& > .MuiBox-root': {
33
+ display: 'flex',
34
+ alignItems: 'center',
35
+ justifyContent: 'space-between',
36
+ gap: '1rem',
37
+ },
38
+ '& > .MuiTypography-root': {
39
+ marginTop: '0.5rem',
40
+ },
41
+ }))
@@ -0,0 +1 @@
1
+ export { default } from './SwitchButton'
@@ -0,0 +1,58 @@
1
+ import { Box, Typography } from '@mui/material'
2
+ import DropDownButton from '../DropDownButton'
3
+ import {
4
+ StyledActionIconButton,
5
+ StyledActionsRow,
6
+ StyledTableActionsHeader,
7
+ } from './styles'
8
+
9
+ export default function BatchActionsHeader({
10
+ selectedRowIds,
11
+ actions,
12
+ clearSelection,
13
+ }) {
14
+ const ids = Object?.keys(selectedRowIds)
15
+ const rowActions = actions?.filter((item) => !item?.dropdown)
16
+ const dropDownActions = actions?.filter((item) => item?.dropdown)
17
+
18
+ if (!ids?.length) return null
19
+ return (
20
+ <StyledTableActionsHeader>
21
+ <Typography variant="subtitle1">
22
+ Selected <span>{ids?.length}</span> rows
23
+ </Typography>
24
+ <RowActions actions={rowActions} ids={ids} clear={clearSelection} />
25
+ <DropDownActions
26
+ actions={dropDownActions}
27
+ ids={ids}
28
+ clear={clearSelection}
29
+ />
30
+ </StyledTableActionsHeader>
31
+ )
32
+ }
33
+
34
+ const RowActions = ({ actions, ids, clear }) => {
35
+ if (!actions?.length) return null
36
+
37
+ return (
38
+ <StyledActionsRow>
39
+ {actions?.map(({ component }, index) => (
40
+ <Box key={index}>{component(ids, clear)}</Box>
41
+ ))}
42
+ </StyledActionsRow>
43
+ )
44
+ }
45
+ const DropDownActions = ({ actions, ids, clear }) => {
46
+ if (!actions?.length) return null
47
+ return (
48
+ <DropDownButton
49
+ icon={{
50
+ icon: <StyledActionIconButton />,
51
+ }}
52
+ menu={actions?.map((action) => ({
53
+ ...action,
54
+ // onClick: () => action?.onClick(ids, clear),
55
+ }))}
56
+ />
57
+ )
58
+ }
@@ -0,0 +1,50 @@
1
+ export const SortIcon = () => {
2
+ return (
3
+ <>
4
+ <svg
5
+ xmlns="http://www.w3.org/2000/svg"
6
+ id="Layer_1"
7
+ data-name="Layer 1"
8
+ viewBox="0 0 24 24"
9
+ width="16.416"
10
+ height="16.416"
11
+ >
12
+ <path d="M11.293,17.707l-3.293,3.293V1c0-.553-.447-1-1-1s-1,.447-1,1V21l-3.293-3.293c-.391-.391-1.023-.391-1.414,0s-.391,1.023,0,1.414l4.293,4.293c.39,.39,.902,.585,1.414,.585s1.024-.195,1.414-.585l4.293-4.293c.391-.391,.391-1.023,0-1.414s-1.023-.391-1.414,0ZM22.707,6.293c.391-.391,.391-1.023,0-1.414L18.414,.586C18.024,.196,17.512,0,17,0s-1.024,.195-1.414,.585l-4.293,4.293c-.391,.391-.391,1.023,0,1.414s1.023,.391,1.414,0l3.293-3.293V23c0,.553,.447,1,1,1s1-.447,1-1V3l3.293,3.293c.391,.391,1.023,.391,1.414,0Z" />
13
+ </svg>
14
+ </>
15
+ )
16
+ }
17
+
18
+ export const SortAscIcon = () => {
19
+ return (
20
+ <>
21
+ <svg
22
+ xmlns="http://www.w3.org/2000/svg"
23
+ id="Layer_1"
24
+ data-name="Layer 1"
25
+ viewBox="0 0 24 24"
26
+ width="16.416"
27
+ height="16.416"
28
+ >
29
+ <path d="M24,8c0,.553-.447,1-1,1H10c-.552,0-1-.447-1-1s.448-1,1-1h13c.553,0,1,.447,1,1Zm-4,4H10c-.552,0-1,.447-1,1s.448,1,1,1h10c.553,0,1-.447,1-1s-.447-1-1-1Zm-3,5h-7c-.552,0-1,.447-1,1s.448,1,1,1h7c.553,0,1-.447,1-1s-.447-1-1-1Zm-3,5h-4c-.552,0-1,.447-1,1s.448,1,1,1h4c.552,0,1-.447,1-1s-.448-1-1-1ZM9.121,3.293L6.413,.584c-.779-.777-2.047-.778-2.828,0L.878,3.293c-.391,.391-.391,1.023,0,1.414s1.024,.391,1.414,0l1.708-1.708V23c0,.553,.448,1,1,1s1-.447,1-1V2.999l1.707,1.708c.195,.195,.451,.293,.707,.293s.512-.098,.707-.293c.391-.391,.391-1.023,0-1.414Z" />
30
+ </svg>
31
+ </>
32
+ )
33
+ }
34
+
35
+ export const SortDescIcon = () => {
36
+ return (
37
+ <>
38
+ <svg
39
+ xmlns="http://www.w3.org/2000/svg"
40
+ id="Layer_1"
41
+ data-name="Layer 1"
42
+ viewBox="0 0 24 24"
43
+ width="16.416"
44
+ height="16.416"
45
+ >
46
+ <path d="M24,1c0,.553-.448,1-1,1H10c-.552,0-1-.447-1-1s.448-1,1-1h13c.552,0,1,.447,1,1Zm-4,4H10c-.552,0-1,.447-1,1s.448,1,1,1h10c.552,0,1-.447,1-1s-.448-1-1-1Zm-3,5h-7c-.552,0-1,.447-1,1s.448,1,1,1h7c.552,0,1-.447,1-1s-.448-1-1-1Zm-3,5h-4c-.552,0-1,.447-1,1s.448,1,1,1h4c.552,0,1-.447,1-1s-.448-1-1-1Zm-6.293,4.293l-1.707,1.707V1c0-.553-.448-1-1-1s-1,.447-1,1V21l-1.708-1.708c-.391-.391-1.023-.391-1.414,0s-.391,1.023,0,1.414l2.707,2.707c.39,.39,.902,.585,1.415,.585s1.024-.195,1.414-.585l2.707-2.707c.391-.391,.391-1.023,0-1.414s-1.023-.391-1.414,0Z" />
47
+ </svg>
48
+ </>
49
+ )
50
+ }
@@ -0,0 +1,293 @@
1
+ import { ExpandMore } from '@mui/icons-material'
2
+ import {
3
+ Box,
4
+ Checkbox,
5
+ IconButton,
6
+ ListItemIcon,
7
+ MenuItem,
8
+ Table,
9
+ TableCell,
10
+ TableHead,
11
+ TableRow,
12
+ Typography,
13
+ } from '@mui/material'
14
+ import { useEffect, useMemo, useState } from 'react'
15
+ import { usePagination, useRowSelect, useTable } from 'react-table'
16
+ import BatchActionsHeader from './BatchActionsHeader'
17
+ import { SortAscIcon, SortDescIcon, SortIcon } from './Icons'
18
+ import { RenderTableBody } from './RenderTableBody'
19
+ import {
20
+ StyledLimitBox,
21
+ StyledLimitMenu,
22
+ StyledPagination,
23
+ StyledTableFooter,
24
+ } from './styles'
25
+ import { TableStats } from './TableFooter/TableFooter'
26
+ import { ColumnProps, Sort, TableProps } from './types'
27
+
28
+ type ReactTableCell = {
29
+ Header: any
30
+ accessor: any
31
+ Cell?: any
32
+ sort?: boolean
33
+ } & ColumnProps
34
+
35
+ const selectColumn = {
36
+ id: 'selection',
37
+ Header: ({ getToggleAllPageRowsSelectedProps }) => (
38
+ <Checkbox size="small" {...getToggleAllPageRowsSelectedProps()} />
39
+ ),
40
+ Cell: ({ row }) => (
41
+ <Checkbox size="small" {...row.getToggleRowSelectedProps()} />
42
+ ),
43
+ }
44
+
45
+ const getTableCol = (headerItem: ColumnProps) => {
46
+ let col: ReactTableCell = {
47
+ Header: headerItem?.title,
48
+ accessor: headerItem?.dataIndex,
49
+ ...headerItem,
50
+ }
51
+
52
+ if (headerItem?.render) {
53
+ return {
54
+ ...col,
55
+ Cell: ({ row }) =>
56
+ headerItem?.render(
57
+ row?.original[headerItem?.dataIndex],
58
+ row?.original,
59
+ row?.index,
60
+ ),
61
+ }
62
+ }
63
+ return col
64
+ }
65
+
66
+ export default function TableComponent({
67
+ columns,
68
+ dataSource,
69
+ loading,
70
+ pagination,
71
+ refetching,
72
+ onSort,
73
+ select = {
74
+ enable: false,
75
+ },
76
+ }: TableProps) {
77
+ const [sort, setSort] = useState<Sort>({})
78
+
79
+ const headers = useMemo(() => {
80
+ if (!columns) return []
81
+
82
+ return columns?.map((item) => getTableCol(item))
83
+ }, [columns])
84
+
85
+ const tableData = useMemo(() => {
86
+ if (!dataSource) return []
87
+ return [...dataSource]
88
+ }, [dataSource])
89
+
90
+ const {
91
+ getTableProps,
92
+ getTableBodyProps,
93
+ headerGroups,
94
+ rows,
95
+ prepareRow,
96
+ pageCount,
97
+ gotoPage,
98
+ setPageSize,
99
+ selectedFlatRows,
100
+ toggleAllRowsSelected,
101
+ state: { pageIndex, pageSize, selectedRowIds },
102
+ } = useTable(
103
+ {
104
+ columns: headers || [],
105
+ data: tableData || [],
106
+ stateReducer: (newState, action) => {
107
+ switch (action.type) {
108
+ case 'toggleAllRowsSelected':
109
+ return {
110
+ ...newState,
111
+ selectedRowIds: {},
112
+ }
113
+
114
+ default:
115
+ return newState
116
+ }
117
+ },
118
+ initialState: {
119
+ pageIndex: pagination?.page ?? 0,
120
+ pageSize: pagination?.limit ?? 10,
121
+ },
122
+ manualPagination: true,
123
+ autoResetSelectedRows: false,
124
+ pageCount: pagination?.totalCount ?? dataSource?.length,
125
+ getRowId: select?.enable
126
+ ? (row) => {
127
+ return row?.id
128
+ }
129
+ : undefined,
130
+ },
131
+ // useSortBy,
132
+ usePagination,
133
+ useRowSelect,
134
+ (hooks) => {
135
+ if (!select.enable) return
136
+ hooks.visibleColumns.push((columns) => [selectColumn, ...columns])
137
+ },
138
+ )
139
+
140
+ const handleSortClick = (sortBykey) => {
141
+ setSort((prev) => {
142
+ if (prev[sortBykey]) {
143
+ if (prev[sortBykey] === 'desc') return { ...prev, [sortBykey]: 'asc' }
144
+ if (prev[sortBykey] === 'asc') {
145
+ delete prev[sortBykey]
146
+ return { ...prev }
147
+ }
148
+ } else {
149
+ return {
150
+ ...prev,
151
+ [sortBykey]: 'desc',
152
+ }
153
+ }
154
+ })
155
+ }
156
+ useEffect(() => {
157
+ if (!onSort) return
158
+
159
+ onSort({
160
+ sortBy: Object.keys(sort).join(','),
161
+ sortOrder: Object.keys(sort)
162
+ .map((item) => sort[item])
163
+ .join(','),
164
+ })
165
+ }, [sort])
166
+
167
+ const handlePagination = (e, value) => {
168
+ gotoPage(value - 1)
169
+ }
170
+
171
+ useEffect(() => {
172
+ if (!pagination) return
173
+ pagination.onChange(pageIndex * pageSize)
174
+ }, [pageIndex])
175
+
176
+ useEffect(() => {
177
+ if (!pagination) return
178
+ pagination.onChangeLimit(pageSize)
179
+ pagination.onChange(0)
180
+ }, [pageSize])
181
+
182
+ const clearSelection = () => {
183
+ toggleAllRowsSelected(false)
184
+ }
185
+
186
+ return (
187
+ <>
188
+ <BatchActionsHeader
189
+ actions={select?.actions || []}
190
+ selectedRowIds={selectedRowIds}
191
+ clearSelection={clearSelection}
192
+ />
193
+ <Table sx={{ position: 'relative' }} {...getTableProps()}>
194
+ <TableHead>
195
+ {headerGroups.map((headerGroup, index) => (
196
+ <TableRow key={index} {...headerGroup.getHeaderGroupProps()}>
197
+ {headerGroup.headers.map((column: any, index) => (
198
+ <TableCell key={index} {...column.getHeaderProps()}>
199
+ {column.render('Header')}
200
+ {column.sort && (
201
+ <IconButton onClick={() => handleSortClick(column.id)}>
202
+ <ListItemIcon>
203
+ {sort[column.id] === 'asc' ? (
204
+ <SortAscIcon />
205
+ ) : sort[column.id] === 'desc' ? (
206
+ <SortDescIcon />
207
+ ) : (
208
+ <SortIcon />
209
+ )}
210
+ </ListItemIcon>
211
+ </IconButton>
212
+ )}
213
+ </TableCell>
214
+ ))}
215
+ </TableRow>
216
+ ))}
217
+ </TableHead>
218
+ <RenderTableBody
219
+ colLength={columns?.length}
220
+ loading={loading || refetching}
221
+ currentRows={rows?.length}
222
+ getTableBodyProps={getTableBodyProps}
223
+ rows={rows}
224
+ prepareRow={prepareRow}
225
+ />
226
+ </Table>
227
+ {pagination && dataSource && !loading && (
228
+ <StyledTableFooter>
229
+ <TableStats
230
+ limit={pageSize}
231
+ page={pageIndex + 1}
232
+ totalCount={pageCount}
233
+ />
234
+ <StyledPagination
235
+ variant="outlined"
236
+ shape="rounded"
237
+ onChange={handlePagination}
238
+ count={Math.ceil(pageCount / pageSize)}
239
+ page={pageIndex + 1}
240
+ />
241
+ <Limit pageSize={pageSize} setPageSize={setPageSize} />
242
+ </StyledTableFooter>
243
+ )}
244
+ </>
245
+ )
246
+ }
247
+
248
+ const Limit = ({ pageSize, setPageSize }) => {
249
+ const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null)
250
+ const open = Boolean(anchorEl)
251
+
252
+ const handleClick = (event) => {
253
+ setAnchorEl(event.currentTarget)
254
+ }
255
+
256
+ const handleClose = () => {
257
+ setAnchorEl(null)
258
+ }
259
+ const menuItems = [
260
+ { label: '10', value: 10 },
261
+ { label: '20', value: 20 },
262
+ { label: '50', value: 50 },
263
+ { label: '100', value: 100 },
264
+ ]
265
+
266
+ return (
267
+ <StyledLimitBox open={open}>
268
+ <Box onClick={handleClick}>
269
+ <Typography>{`${pageSize} / Page`}</Typography>
270
+ <ExpandMore />
271
+ </Box>
272
+ <StyledLimitMenu
273
+ id="basic-menu"
274
+ anchorEl={anchorEl}
275
+ open={open}
276
+ onClose={handleClose}
277
+ >
278
+ {menuItems?.map((item, index) => (
279
+ <MenuItem
280
+ onClick={() => {
281
+ setPageSize(item?.value)
282
+ handleClose()
283
+ }}
284
+ value={item?.value}
285
+ key={index}
286
+ >
287
+ {item?.label}
288
+ </MenuItem>
289
+ ))}
290
+ </StyledLimitMenu>
291
+ </StyledLimitBox>
292
+ )
293
+ }