@campxdev/shared 1.10.72 → 1.10.74

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@campxdev/shared",
3
- "version": "1.10.72",
3
+ "version": "1.10.74",
4
4
  "main": "./exports.ts",
5
5
  "scripts": {
6
6
  "start": "react-scripts start",
@@ -41,6 +41,7 @@
41
41
  "moment": "^2.29.4",
42
42
  "pullstate": "^1.24.0",
43
43
  "react": "^18.2.0",
44
+ "react-arrows": "^1.2.0",
44
45
  "react-dom": "^18.2.0",
45
46
  "react-error-boundary": "^3.1.4",
46
47
  "react-flatpickr": "^3.10.13",
@@ -22,6 +22,9 @@ import SearchBar from '../FilterComponents/SearchBar'
22
22
  import { DialogButton, DrawerButton } from '../ModalButtons'
23
23
  import Table from '../Tables/BasicTable/Table'
24
24
  import DepartmentFilter from './DepartmentFilter'
25
+ import ReactJoyRide from '../ReactJoyRide'
26
+ // import Arrow, { DIRECTION } from 'react-arrows'
27
+ import '../CustomJoyRideStyles.css'
25
28
 
26
29
  interface ApplicationProfileProps {
27
30
  application:
@@ -40,6 +43,7 @@ interface ApplicationProfileProps {
40
43
  delete: string
41
44
  }
42
45
  }
46
+
43
47
  function ApplicationProfile({
44
48
  application,
45
49
  title,
@@ -160,9 +164,33 @@ function ApplicationProfile({
160
164
  })
161
165
  }
162
166
 
167
+ const tourSteps = [
168
+ {
169
+ target: '.test',
170
+ title: 'Adding User Profile Relation',
171
+ content: (
172
+ <Typography variant="subtitle1">
173
+ Choose your Profile Relation from the pre-given dropdowns
174
+ </Typography>
175
+ ),
176
+ disableBeacon: true,
177
+ },
178
+ {
179
+ target: '.test2',
180
+ title: 'Search By Name',
181
+ content: (
182
+ <Typography variant="subtitle1">
183
+ You can also find the person by just typing his name away!
184
+ </Typography>
185
+ ),
186
+ },
187
+ ]
188
+
163
189
  if (profilesLoading) return <Spinner />
164
190
  return (
165
191
  <>
192
+ <ReactJoyRide steps={tourSteps} tourName="Application-Profile-Tour" />
193
+
166
194
  <PageHeader
167
195
  title={title}
168
196
  actions={[
@@ -177,7 +205,11 @@ function ApplicationProfile({
177
205
  <DialogButton
178
206
  title={'Add User Profile Relation'}
179
207
  anchor={({ open }) => (
180
- <ActionButton onClick={open}>
208
+ <ActionButton
209
+ onClick={open}
210
+ className="test"
211
+ sx={{ inset: 'auto' }}
212
+ >
181
213
  Add User Profile Relation
182
214
  </ActionButton>
183
215
  )}
@@ -193,6 +225,7 @@ function ApplicationProfile({
193
225
  </ValidateAccess>,
194
226
  ]}
195
227
  />
228
+
196
229
  <PageContent sx={{ marginTop: '25px' }}>
197
230
  <StyledTableContainer>
198
231
  <Box
@@ -211,6 +244,7 @@ function ApplicationProfile({
211
244
  })
212
245
  }
213
246
  textFieldProps={{
247
+ className: 'test2',
214
248
  placeholder: 'Search by Name',
215
249
  title: 'Search by Name',
216
250
  sx: { width: '300px' },
@@ -0,0 +1,48 @@
1
+ import React, { useEffect, useRef } from 'react'
2
+ import './CustomJoyRideStyles.css'
3
+
4
+ class Arrow {
5
+ constructor(w, h) {
6
+ if (!w) w = 300
7
+ if (!h) h = 150
8
+
9
+ const pad = Math.round(w / 6)
10
+
11
+ // container
12
+ const svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
13
+ svg.style.width = `${w}px`
14
+ svg.style.height = `${h}px`
15
+ svg.classList.add('arrow')
16
+
17
+ // line
18
+ const path = document.createElementNS('http://www.w3.org/2000/svg', 'path')
19
+ path.setAttribute(
20
+ 'd',
21
+ `M 0 0 C ${pad} ${h}, ${w - pad - 10} ${h - 10}, ${w - 8} 5`,
22
+ )
23
+ svg.appendChild(path)
24
+
25
+ // arrowhead
26
+ const polygon = document.createElementNS(
27
+ 'http://www.w3.org/2000/svg',
28
+ 'polygon',
29
+ )
30
+ polygon.setAttribute('points', `${w - 3} 0, ${w - 13} 3, ${w - 3} 9`)
31
+ svg.appendChild(polygon)
32
+
33
+ return svg
34
+ }
35
+ }
36
+
37
+ const CurvedArrow = () => {
38
+ const arrowRef = useRef(null)
39
+
40
+ useEffect(() => {
41
+ const arrow = new Arrow(100, 100)
42
+ arrowRef.current.appendChild(arrow)
43
+ }, [])
44
+
45
+ return <div ref={arrowRef}></div>
46
+ }
47
+
48
+ export default CurvedArrow
@@ -0,0 +1,18 @@
1
+ .react-joyride__tooltip {
2
+ background-color: 'rgb(255, 255, 255)';
3
+
4
+ }
5
+
6
+ div.react-joyride__tooltip > div:nth-child(1) {
7
+ text-align: left !important;
8
+ }
9
+
10
+ div.react-joyride__tooltip > div:nth-child(1) div:nth-child(2) {
11
+ padding: 20px 0px !important;
12
+ }
13
+
14
+ div.react-joyride__tooltip > div:nth-child(2) {
15
+ flex-direction: row-reverse !important;
16
+ }
17
+
18
+
@@ -1,24 +1,55 @@
1
1
  import TourIcon from '@mui/icons-material/Tour'
2
2
  import { Box, IconButton } from '@mui/material'
3
- import { ReactNode, useState } from 'react'
3
+ import { ReactNode, useEffect, useState } from 'react'
4
4
  import ReactJoyride, { Step } from 'react-joyride'
5
+ import { useQuery } from 'react-query'
6
+ import axios from '../config/axios'
7
+ import './CustomJoyRideStyles.css'
5
8
 
6
9
  function ReactJoyRide({
7
10
  steps,
8
11
  children,
12
+ tourName,
9
13
  }: {
10
14
  steps: Step[]
11
- children: ReactNode
15
+ children?: ReactNode
16
+ tourName: string
12
17
  }) {
13
18
  const [run, setRun] = useState(false)
14
19
 
15
- const handleTourEnd = (data) => {
16
- if (
17
- data.status === 'finished' ||
18
- data.status === 'skip' ||
19
- data.status === 'closed'
20
- )
20
+ const fetchTours = (params) => {
21
+ return axios.get(`/square/tours`).then((res) => res.data)
22
+ }
23
+
24
+ const { data: toursData, isLoading: toursLoading } = useQuery(
25
+ 'tours',
26
+ fetchTours,
27
+ )
28
+
29
+ useEffect(() => {
30
+ if (toursData && !toursData.includes(tourName)) {
31
+ setRun(true)
32
+ }
33
+ }, [toursLoading])
34
+
35
+ const completeTour = async () => {
36
+ try {
37
+ await axios.post(`/square/tours/complete`, { tourName })
38
+ } catch (error) {
39
+ // console.error('Error in Completing Tour:', error)
40
+ }
41
+ }
42
+
43
+ const handleJoyRideCallback = (data) => {
44
+ const { action, status } = data
45
+
46
+ if (action === 'skip') {
47
+ completeTour()
48
+ }
49
+ if (status === 'finished' || status === 'skip' || status === 'closed') {
21
50
  setRun(false)
51
+ completeTour()
52
+ }
22
53
 
23
54
  if (data.action == 'close' || data.action == 'skip') setRun(false)
24
55
  }
@@ -27,17 +58,53 @@ function ReactJoyRide({
27
58
  <>
28
59
  <Box>
29
60
  <ReactJoyride
30
- callback={handleTourEnd}
61
+ callback={handleJoyRideCallback}
31
62
  run={run}
32
63
  steps={steps}
64
+ styles={{
65
+ buttonNext: {
66
+ backgroundColor: 'black',
67
+ color: 'yellow',
68
+ height: '28px',
69
+ width: '100px',
70
+ padding: '0px',
71
+ },
72
+
73
+ buttonBack: {
74
+ backgroundColor: 'cement',
75
+ color: 'black',
76
+ borderRadius: '4px',
77
+ height: '30px',
78
+ width: '100px',
79
+ gap: '10px',
80
+ marginLeft: '5px',
81
+ padding: '0px',
82
+ },
83
+
84
+ buttonSkip: {
85
+ backgroundColor: 'transparent',
86
+ color: 'cement',
87
+ borderRadius: '0px',
88
+ border: '0px',
89
+ fontSize: '13px',
90
+ padding: '21px 15px',
91
+ right: '0px',
92
+ top: '0px',
93
+ position: 'absolute',
94
+ lineHeight: 1,
95
+ },
96
+ }}
33
97
  continuous
34
98
  showSkipButton
35
- showProgress
36
99
  scrollToFirstStep
100
+ disableOverlay
37
101
  disableOverlayClose
38
102
  disableScrolling
103
+ hideCloseButton
39
104
  />
105
+
40
106
  {children}
107
+
41
108
  <IconButton
42
109
  onClick={() => setRun(true)}
43
110
  sx={{
@@ -0,0 +1,81 @@
1
+ import { SelectProps } from '@mui/material'
2
+ import { useEffect, useState } from 'react'
3
+ import { Controller } from 'react-hook-form'
4
+ import axios from '../../../../config/axios'
5
+ import { MultiSelect } from '../../../Input'
6
+
7
+ type MultiProgramSelectorProps = {
8
+ control: any
9
+ name?: string
10
+ label: string
11
+ required?: boolean
12
+ onChange?: (value: any) => void
13
+ allowAll?: boolean
14
+ error?: boolean
15
+ helperText?: string
16
+ } & SelectProps
17
+ const MultiFeeTypeSelector = (props: MultiProgramSelectorProps) => {
18
+ const {
19
+ control,
20
+ onChange,
21
+ name,
22
+ required = false,
23
+ label,
24
+ multiple = false,
25
+ value,
26
+ allowAll = true,
27
+ } = props
28
+ const [options, setOptions] = useState([])
29
+ const [prevCourseId, setPrevCourseId] = useState(null)
30
+ const handleOpen = () => {
31
+ if (options.length === 0) {
32
+ axios
33
+ .get('/paymentx/fee-types')
34
+ .then((response) => {
35
+ setOptions(response.data)
36
+ })
37
+ .catch((error) => {
38
+ console.error('Error fetching data from the API:', error)
39
+ })
40
+ }
41
+ }
42
+ useEffect(() => {
43
+ if (props?.value && props.value != 'all') {
44
+ handleOpen()
45
+ }
46
+ }, [props.value])
47
+
48
+ const handleOptions =
49
+ options.length > 0
50
+ ? [
51
+ ...(allowAll ? [{ value: 'all', label: 'All' }] : []),
52
+ ...options.map((item) => ({
53
+ label: `${item.name}`,
54
+ value: `${item.id}`,
55
+ })),
56
+ ]
57
+ : allowAll
58
+ ? [{ value: 'all', label: 'All' }]
59
+ : []
60
+
61
+ return (
62
+ <Controller
63
+ name={name}
64
+ control={control}
65
+ render={({ field, fieldState: { error } }) => (
66
+ <MultiSelect
67
+ name={name}
68
+ label={label}
69
+ required={required}
70
+ options={handleOptions}
71
+ onOpen={handleOpen}
72
+ onChange={onChange ?? field.onChange}
73
+ value={value ?? field?.value}
74
+ error={!!error}
75
+ helperText={error?.message}
76
+ />
77
+ )}
78
+ />
79
+ )
80
+ }
81
+ export default MultiFeeTypeSelector
@@ -5,6 +5,7 @@ import FormFeeTypeSelector from './FormSelectors/FormFeeTypeSelector'
5
5
  import FormProgramSelector from './FormSelectors/FormProgramSelector'
6
6
  import FormQuotaSelector from './FormSelectors/FormQuotaSelector'
7
7
  import FormSemseterSelector from './FormSelectors/FormSemesterSelector'
8
+ import MultiFeeTypeSelector from './FormSelectors/MultiSelect/MultiFeeTypeSelector'
8
9
  import MultiProgramSelector from './FormSelectors/MultiSelect/MultiProgramSelector'
9
10
  import MultiQuotaSelector from './FormSelectors/MultiSelect/MultiQuotaSelector'
10
11
  import ProgramSelector from './ProgramSelector'
@@ -19,6 +20,7 @@ export {
19
20
  FormProgramSelector,
20
21
  FormQuotaSelector,
21
22
  FormSemseterSelector,
23
+ MultiFeeTypeSelector,
22
24
  MultiProgramSelector,
23
25
  MultiQuotaSelector,
24
26
  ProgramSelector,
@@ -0,0 +1,285 @@
1
+ import {
2
+ IconButton,
3
+ ListItemIcon,
4
+ TableBody,
5
+ TableHead,
6
+ TableRow,
7
+ Theme,
8
+ } from '@mui/material'
9
+ import { SxProps } from '@mui/system'
10
+ import _ from 'lodash'
11
+ import { useEffect, useState } from 'react'
12
+ import Spinner from '../../Spinner'
13
+ import NoRecordsFound from '../common/NoRecordsFound'
14
+ import { SortAscIcon, SortDescIcon, SortIcon } from '../common/icons'
15
+ import TableFooter from './TableFooter'
16
+ import {
17
+ StyledMuiTable,
18
+ StyledTableCell,
19
+ StyledTableContainer,
20
+ StyledTableRow,
21
+ } from './styles'
22
+
23
+ type Order = 'asc' | 'desc' | ''
24
+ type Sort = {}
25
+ type DataType = 'currency' | 'string' | 'number'
26
+ export interface TableColumn {
27
+ dataIndex: string
28
+ key: string
29
+ title?: any
30
+ render?: (cellData: any, row: any, index: number) => any
31
+ textColor?: string
32
+ sort?: boolean
33
+ width?: string //pixels
34
+ dataType?: DataType
35
+ }
36
+
37
+ export interface ColumnHeader {
38
+ title: any
39
+ colSpan: number
40
+ }
41
+
42
+ interface TableProps {
43
+ columns: Array<TableColumn>
44
+ rowKey?: string
45
+ dataSource?: any[]
46
+ loading?: boolean
47
+ onRowClick?: (row: any) => void
48
+ pagination?: {
49
+ page: number
50
+ limit: number
51
+ totalCount: number
52
+ onChange: (v: number) => void
53
+ onChangeLimit?: (v: number) => void
54
+ }
55
+ onSort?: (sort: any) => void
56
+ dense?: boolean
57
+ showTotal?: boolean
58
+ sx?: Record<string, SxProps<Theme>>
59
+ totalColumns?: number[]
60
+ showTotalInFirstCellOfTotalRow?: boolean
61
+ columnsHeader?: Array<ColumnHeader>
62
+ }
63
+ export default function Table({
64
+ columns,
65
+ dataSource,
66
+ onRowClick,
67
+ pagination,
68
+ loading,
69
+ columnsHeader,
70
+ onSort,
71
+ dense = false,
72
+ showTotal = false,
73
+ sx,
74
+ totalColumns,
75
+ showTotalInFirstCellOfTotalRow,
76
+ }: TableProps) {
77
+ const [sort, setSort] = useState<Sort>({})
78
+ let totalCount = []
79
+ let totalCols = []
80
+ if (showTotalInFirstCellOfTotalRow) {
81
+ totalCols = totalColumns ? [...totalColumns, 1] : [1]
82
+ } else {
83
+ totalCols = totalColumns ? [...totalColumns] : []
84
+ }
85
+
86
+ const handleSortClick = (sortBykey) => {
87
+ setSort((prev) => {
88
+ if (prev[sortBykey]) {
89
+ if (prev[sortBykey] === 'desc') return { ...prev, [sortBykey]: 'asc' }
90
+ if (prev[sortBykey] === 'asc') {
91
+ delete prev[sortBykey]
92
+ return { ...prev }
93
+ }
94
+ } else {
95
+ return {
96
+ ...prev,
97
+ [sortBykey]: 'desc',
98
+ }
99
+ }
100
+ })
101
+ }
102
+
103
+ useEffect(() => {
104
+ if (!onSort) return
105
+
106
+ onSort({
107
+ sortBy: Object.keys(sort).join(','),
108
+ sortOrder: Object.keys(sort)
109
+ .map((item) => sort[item])
110
+ .join(','),
111
+ })
112
+ }, [sort])
113
+
114
+ const calculateTotal = (row) => {
115
+ columns.forEach((col, colIndex) => {
116
+ const colValue = col?.render
117
+ ? col.render(row[col.dataIndex], row, colIndex)
118
+ : _.get(row, col.dataIndex)
119
+
120
+ if (!totalCount[colIndex]) {
121
+ totalCount[colIndex] = 0
122
+ }
123
+
124
+ if (showTotalInFirstCellOfTotalRow && colIndex === 0) {
125
+ totalCount[colIndex] = 'Total'
126
+ return
127
+ }
128
+
129
+ totalCount[colIndex] += colValue
130
+ })
131
+ }
132
+
133
+ const convertToAmount = (data) => {
134
+ return data.toLocaleString('en-IN', {
135
+ style: 'currency',
136
+ currency: 'INR',
137
+ })
138
+ }
139
+
140
+ return (
141
+ <StyledTableContainer sx={sx}>
142
+ <>
143
+ <StyledMuiTable sx={sx}>
144
+ <TableHead>
145
+ {columnsHeader && (
146
+ <TableRow>
147
+ {columnsHeader.map((col, columnIndex) => (
148
+ <StyledTableCell
149
+ key={columnIndex}
150
+ columnsLength={columns.length}
151
+ columnIndex={columnIndex + 1}
152
+ rowIndex={0}
153
+ col={col}
154
+ sx={sx}
155
+ isHeaderCell
156
+ align="center"
157
+ colSpan={col.colSpan}
158
+ >
159
+ {col.title}
160
+ </StyledTableCell>
161
+ ))}
162
+ </TableRow>
163
+ )}
164
+ <TableRow>
165
+ {columns.map((col, columnIndex) => (
166
+ <StyledTableCell
167
+ key={columnIndex}
168
+ columnsLength={columns.length}
169
+ columnIndex={columnIndex + 1}
170
+ rowIndex={0}
171
+ col={col}
172
+ sx={sx}
173
+ align="center"
174
+ isHeaderCell
175
+ >
176
+ {col.title}
177
+
178
+ {col.sort && (
179
+ <IconButton onClick={() => handleSortClick(col.dataIndex)}>
180
+ <ListItemIcon>
181
+ {sort[col.dataIndex] === 'asc' ? (
182
+ <SortAscIcon />
183
+ ) : sort[col.dataIndex] === 'desc' ? (
184
+ <SortDescIcon />
185
+ ) : (
186
+ <SortIcon />
187
+ )}
188
+ </ListItemIcon>
189
+ </IconButton>
190
+ )}
191
+ </StyledTableCell>
192
+ ))}
193
+ </TableRow>
194
+ </TableHead>
195
+ {!loading ? (
196
+ <>
197
+ {dataSource?.length ? (
198
+ <TableBody>
199
+ {dataSource?.map((row, rowIndex) => (
200
+ <StyledTableRow
201
+ canRowClick={!!onRowClick}
202
+ hover={!!onRowClick}
203
+ key={rowIndex}
204
+ onClick={() => {
205
+ return onRowClick && onRowClick(row)
206
+ }}
207
+ >
208
+ <> {showTotal && calculateTotal(row)}</>
209
+ {columns.map((col, colIndex) => (
210
+ <StyledTableCell
211
+ key={colIndex}
212
+ columnsLength={columns.length}
213
+ columnIndex={colIndex + 1}
214
+ rowIndex={rowIndex + 1}
215
+ col={col}
216
+ isBodyCell
217
+ sx={sx}
218
+ >
219
+ {col?.dataType && col?.dataType == 'currency' ? (
220
+ <>{convertToAmount(row[col.dataIndex])}</>
221
+ ) : (
222
+ <>
223
+ {col?.render
224
+ ? col.render(row[col.dataIndex], row, rowIndex)
225
+ : _.get(row, col.dataIndex)}
226
+ </>
227
+ )}
228
+ </StyledTableCell>
229
+ ))}
230
+ </StyledTableRow>
231
+ ))}
232
+
233
+ {showTotal && (
234
+ <StyledTableRow canRowClick={false}>
235
+ {columns.map((col, colIndex) => (
236
+ <>
237
+ <StyledTableCell
238
+ key={colIndex}
239
+ columnsLength={columns.length}
240
+ columnIndex={colIndex + 1}
241
+ rowIndex={dataSource.length + 1}
242
+ col={col}
243
+ isBodyCell
244
+ sx={sx}
245
+ >
246
+ {totalCols.includes(colIndex + 1) ? (
247
+ col?.dataType && col?.dataType == 'currency' ? (
248
+ <>{convertToAmount(totalCount[colIndex])}</>
249
+ ) : (
250
+ <>{totalCount[colIndex]}</>
251
+ )
252
+ ) : (
253
+ '---'
254
+ )}
255
+ </StyledTableCell>
256
+ </>
257
+ ))}
258
+ </StyledTableRow>
259
+ )}
260
+ </TableBody>
261
+ ) : (
262
+ <>
263
+ <NoRecordsFound colLength={columns?.length} />
264
+ </>
265
+ )}
266
+ </>
267
+ ) : (
268
+ <Spinner />
269
+ )}
270
+ </StyledMuiTable>
271
+ </>
272
+ <>
273
+ {pagination && (
274
+ <TableFooter
275
+ page={pagination.page + 1}
276
+ limit={pagination.limit}
277
+ totalCount={pagination.totalCount ?? 0}
278
+ handlePagination={pagination.onChange}
279
+ handlePageLimit={pagination.onChangeLimit}
280
+ />
281
+ )}
282
+ </>
283
+ </StyledTableContainer>
284
+ )
285
+ }
@@ -0,0 +1,86 @@
1
+ import { Box, Typography } from '@mui/material'
2
+ import DropDownButton from '../../DropDownButton/DropDownButton'
3
+ import { StyledPagination, StyledTableFooter } from '../common/styles'
4
+ import TableStats from '../common/TableStats'
5
+
6
+ interface TableFooterProps {
7
+ totalCount: number
8
+ limit: number
9
+ handlePagination: (v: number) => void
10
+ page: number
11
+ handlePageLimit?: (v: number) => void
12
+ }
13
+
14
+ export default function TableFooter({
15
+ totalCount,
16
+ limit,
17
+ handlePagination,
18
+ page,
19
+ handlePageLimit,
20
+ }: TableFooterProps) {
21
+ const onChange = (v: number) => {
22
+ handlePagination(v)
23
+ }
24
+ return (
25
+ <StyledTableFooter>
26
+ <TableStats limit={limit} totalCount={totalCount} page={page} />
27
+ <StyledPagination
28
+ page={page}
29
+ count={Math.ceil(totalCount / limit)}
30
+ onChange={(e, v) => onChange(v)}
31
+ variant="outlined"
32
+ shape="rounded"
33
+ />
34
+ {handlePageLimit ? (
35
+ <LimitField handlePageLimit={handlePageLimit} limit={limit} />
36
+ ) : (
37
+ <Box></Box>
38
+ )}
39
+ </StyledTableFooter>
40
+ )
41
+ }
42
+
43
+ const LimitField = ({ handlePageLimit, limit }) => {
44
+ return (
45
+ <Box>
46
+ <DropDownButton
47
+ button={{
48
+ buttonProps: {
49
+ variant: 'outlined',
50
+ color: 'secondary',
51
+ sx: {
52
+ padding: '0px 10px',
53
+ color: '#121212',
54
+ fontSize: '13px',
55
+ border: '1px solid #1212121A',
56
+ },
57
+ },
58
+ label: `${limit} / page`,
59
+ }}
60
+ menu={[
61
+ {
62
+ label: 10,
63
+ onClick: () => handlePageLimit(10),
64
+ },
65
+
66
+ {
67
+ label: 20,
68
+ onClick: () => handlePageLimit(20),
69
+ },
70
+ {
71
+ label: 30,
72
+ onClick: () => handlePageLimit(30),
73
+ },
74
+ {
75
+ label: 50,
76
+ onClick: () => handlePageLimit(50),
77
+ },
78
+ {
79
+ label: 100,
80
+ onClick: () => handlePageLimit(100),
81
+ },
82
+ ]}
83
+ />
84
+ </Box>
85
+ )
86
+ }
@@ -0,0 +1 @@
1
+ export { default } from './Table'
@@ -0,0 +1,19 @@
1
+ import { Theme } from '@mui/material'
2
+ import { SxProps } from '@mui/system'
3
+
4
+ export interface StyledCellProps {
5
+ columnsLength: number
6
+ columnIndex: number
7
+ rowIndex: number
8
+ col: any
9
+ sx?: Record<string, SxProps<Theme>>
10
+ isBodyCell?: boolean
11
+ isHeaderCell?: boolean
12
+ }
13
+ export interface StyledTableContainerProps {
14
+ sx?: Record<string, SxProps<Theme>>
15
+ }
16
+
17
+ export interface StyledMuiTableProps {
18
+ sx?: Record<string, SxProps<Theme>>
19
+ }
@@ -0,0 +1,105 @@
1
+ import styled, { CSSObject } from '@emotion/styled'
2
+ import {
3
+ Table,
4
+ TableCell,
5
+ TableContainer,
6
+ TableRow,
7
+ Theme,
8
+ alpha,
9
+ } from '@mui/material'
10
+ import { SxProps } from '@mui/system'
11
+ import _ from 'lodash'
12
+ import {
13
+ StyledCellProps,
14
+ StyledMuiTableProps,
15
+ StyledTableContainerProps,
16
+ } from './interface'
17
+
18
+ export const StyledTableCell = styled(TableCell)<StyledCellProps>(
19
+ ({
20
+ theme,
21
+ columnsLength,
22
+ columnIndex,
23
+ rowIndex,
24
+ col,
25
+ sx,
26
+ isBodyCell = false,
27
+ isHeaderCell = false,
28
+ }) => {
29
+ const { rowkey, columnKey, cellKey, allKey } = getSxKeys(
30
+ rowIndex,
31
+ columnIndex,
32
+ )
33
+ const rowSx: SxProps<Theme> = _.get(sx, rowkey)
34
+ const columnSx: SxProps<Theme> = _.get(sx, columnKey)
35
+ const cellSx: SxProps<Theme> = _.get(sx, cellKey)
36
+ const allSx: SxProps<Theme> = _.get(sx, allKey)
37
+ return {
38
+ ...(col?.width && {
39
+ width: col?.width,
40
+ }),
41
+ ['@media(max-width: 680px)']: {
42
+ borderRightColor:
43
+ columnsLength - 1 !== columnIndex ? '#1212121A' : 'none',
44
+ borderRightStyle: columnsLength - 1 !== columnIndex ? 'solid' : 'none',
45
+ },
46
+
47
+ ...(isBodyCell && {
48
+ color: col.textColor,
49
+ padding: '15px',
50
+ font: 'avenir',
51
+ fontSize: '14px',
52
+ }),
53
+ ...(isHeaderCell && {
54
+ fontWeight: 600,
55
+ fontSize: '14px',
56
+ }),
57
+
58
+ ...columnSx,
59
+ ...rowSx,
60
+ ...cellSx,
61
+ ...allSx,
62
+ } as CSSObject
63
+ },
64
+ )
65
+
66
+ export const StyledMuiTable = styled(Table)<StyledMuiTableProps>(
67
+ ({ theme, sx }) => {
68
+ const containerSx: SxProps<Theme> = _.get(sx, 'MuiTable')
69
+ return {
70
+ ...containerSx,
71
+ } as CSSObject
72
+ },
73
+ )
74
+
75
+ export const StyledTableRow = styled(TableRow, {
76
+ shouldForwardProp: (prop) => prop !== 'canRowClick',
77
+ })<{ canRowClick: boolean }>(({ canRowClick }) => ({
78
+ ...(canRowClick && {
79
+ cursor: 'pointer',
80
+ '&.MuiTableRow-hover:hover': {
81
+ backgroundColor: alpha('#f2f2f2', 0.4),
82
+ },
83
+ }),
84
+ }))
85
+
86
+ export const StyledTableContainer = styled(
87
+ TableContainer,
88
+ )<StyledTableContainerProps>(({ theme, sx }) => {
89
+ const containerSx: SxProps<Theme> = _.get(sx, 'TableContainer')
90
+
91
+ return {
92
+ width: '100%',
93
+ overflowX: 'auto',
94
+ ...containerSx,
95
+ } as CSSObject
96
+ })
97
+
98
+ const getSxKeys = (rowIndex, columnIndex) => {
99
+ return {
100
+ rowkey: `row:${rowIndex}`,
101
+ columnKey: `column:${columnIndex}`,
102
+ cellKey: `row:${rowIndex},column:${columnIndex}`,
103
+ allKey: 'Tablecell',
104
+ }
105
+ }
@@ -60,6 +60,7 @@ export { default as ReportPageHeader } from './ReportPageHeader'
60
60
  export { default as Spinner } from './Spinner'
61
61
  export { default as PaymentStepper } from './Stepper'
62
62
  export { default as SwitchButton } from './SwitchButton'
63
+ export { default as Table2D } from './Tables/2DTable'
63
64
  export { default as Table } from './Tables/BasicTable'
64
65
  export { default as TableFooter } from './Tables/BasicTable/TableFooter'
65
66
  export { default as ReactTable } from './Tables/ReactTable'
@@ -313,6 +313,13 @@ export enum SquarePermissions {
313
313
  CAN_SURVEYS_EDIT = 'can_surveys_edit',
314
314
  CAN_SURVEYS_ADD = 'can_surveys_add',
315
315
  CAN_SURVEYS_DELETE = 'can_surveys_delete',
316
+
317
+
318
+
319
+
320
+
321
+
322
+
316
323
  }
317
324
 
318
325
  export enum EnrollPermissions {
@@ -949,6 +956,24 @@ export enum Permission {
949
956
  CAN_SURVEYS_ADD = 'can_surveys_add',
950
957
  CAN_SURVEYS_DELETE = 'can_surveys_delete',
951
958
 
959
+ //Configuration
960
+
961
+ CAN_CONFIGURATION_VIEW = 'can_configuration_view',
962
+
963
+ //Digital Notice Board
964
+ CAN_NOTICE_BOARD_VIEW = 'can_notice_board_view',
965
+ CAN_NOTICE_BOARD_EDIT = 'can_notice_board_edit',
966
+ CAN_NOTICE_BOARD_ADD = 'can_notice_board_add',
967
+ CAN_NOTICE_BOARD_DELETE = 'can_notice_board_delete',
968
+
969
+
970
+ //Research Projects
971
+ CAN_RESEARCH_PROJECT_VIEW = 'can_research_project_view',
972
+ CAN_RESEARCH_PROJECT_EDIT = 'can_research_project_edit',
973
+ CAN_RESEARCH_PROJECT_ADD = 'can_research_project_add',
974
+ CAN_RESEARCH_PROJECT_DELETE = 'can_research_project_delete',
975
+
976
+
952
977
  // Enroll X
953
978
 
954
979
  // manage exams profile_permissions