@campxdev/shared 1.11.28 → 1.11.30
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 +4 -3
- package/src/components/ActivityLog/ActivityLog.tsx +209 -0
- package/src/components/ActivityLog/Styles.tsx +37 -0
- package/src/components/HookForm/SingleSelect.tsx +2 -2
- package/src/components/Input/SearchSingleSelect.tsx +1 -1
- package/src/components/Input/SingleSelect.tsx +7 -7
- package/src/components/Institutions/InsititutionsDialog.tsx +1 -1
- package/src/components/Layout/Header/AppHeader.tsx +15 -6
- package/src/components/Layout/Header/HeaderActions/HeaderActions.tsx +3 -0
- package/src/components/Layout/Header/HeaderActions/UserBox.tsx +3 -1
- package/src/components/Selectors/ClassRoomSelector.tsx +2 -2
- package/src/components/Selectors/CourseSelector.tsx +2 -2
- package/src/components/Selectors/DepartmentSelector.tsx +2 -2
- package/src/components/Selectors/ExamGroupSelector.tsx +2 -2
- package/src/components/Selectors/FacultySelector.tsx +2 -2
- package/src/components/Selectors/FeeTypeSelector.tsx +2 -2
- package/src/components/Selectors/FormSelectors/FormClassRoomSelector.tsx +2 -2
- package/src/components/Selectors/FormSelectors/FormCourseSelector.tsx +2 -2
- package/src/components/Selectors/FormSelectors/FormDepartmentSelector.tsx +2 -2
- package/src/components/Selectors/FormSelectors/FormExamGroupSelector.tsx +2 -2
- package/src/components/Selectors/FormSelectors/FormFacultySelector.tsx +2 -2
- package/src/components/Selectors/FormSelectors/FormFeeTypeSelector.tsx +2 -2
- package/src/components/Selectors/FormSelectors/FormProgramSelector.tsx +2 -2
- package/src/components/Selectors/FormSelectors/FormQuotaSelector.tsx +2 -2
- package/src/components/Selectors/FormSelectors/FormSemesterSelector.tsx +2 -2
- package/src/components/Selectors/FormSelectors/MultiSelect/MultiFacultySelector.tsx +2 -2
- package/src/components/Selectors/FormSelectors/MultiSelect/MultiFeeTypeSelector.tsx +2 -2
- package/src/components/Selectors/FormSelectors/MultiSelect/MultiProgramSelector.tsx +2 -2
- package/src/components/Selectors/FormSelectors/MultiSelect/MultiQuotaSelector.tsx +2 -2
- package/src/components/Selectors/ProgramSelector.tsx +3 -3
- package/src/components/Selectors/QuotaSelector.tsx +2 -2
- package/src/components/Selectors/SemesterSelector.tsx +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@campxdev/shared",
|
|
3
|
-
"version": "1.11.
|
|
3
|
+
"version": "1.11.30",
|
|
4
4
|
"main": "./exports.ts",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"start": "react-scripts start",
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"lint:fix": "eslint --fix \"./src/**/*.{js,jsx,ts,tsx,json}\"",
|
|
14
14
|
"format": "prettier --write \"./src/**/*.{js,jsx,ts,tsx,css,md,json}\" --config ./.prettierrc",
|
|
15
15
|
"storybook": "start-storybook -p 6006 -s public",
|
|
16
|
-
"build-storybook": "
|
|
16
|
+
"build-storybook": "cross-env NODE_OPTIONS=--openssl-legacy-provider build-storybook"
|
|
17
17
|
},
|
|
18
18
|
"browserslist": {
|
|
19
19
|
"production": [
|
|
@@ -91,6 +91,7 @@
|
|
|
91
91
|
"storybook-addon-react-router-v6": "^0.2.1"
|
|
92
92
|
},
|
|
93
93
|
"resolutions": {
|
|
94
|
-
"react-dev-utils/fork-ts-checker-webpack-plugin": "^6.5.3"
|
|
94
|
+
"react-dev-utils/fork-ts-checker-webpack-plugin": "^6.5.3",
|
|
95
|
+
"@storybook/react-docgen-typescript-plugin": "1.0.6--canary.9.cd77847.0"
|
|
95
96
|
}
|
|
96
97
|
}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Timeline,
|
|
3
|
+
TimelineContent,
|
|
4
|
+
TimelineItem,
|
|
5
|
+
TimelineSeparator,
|
|
6
|
+
} from '@mui/lab'
|
|
7
|
+
import { Box, SxProps, Typography } from '@mui/material'
|
|
8
|
+
import axios from 'axios'
|
|
9
|
+
import { useCallback, useRef } from 'react'
|
|
10
|
+
import { useInfiniteQuery } from 'react-query'
|
|
11
|
+
import { useErrorModal } from '../ErrorModalWrapper/ErrorModalWrapper'
|
|
12
|
+
import Spinner from '../Spinner'
|
|
13
|
+
import Table from '../Tables/BasicTable/Table'
|
|
14
|
+
import {
|
|
15
|
+
StyledAvatar,
|
|
16
|
+
StyledCircleIcon,
|
|
17
|
+
StyledSpinnerBox,
|
|
18
|
+
StyledTimeLineDot,
|
|
19
|
+
} from './Styles'
|
|
20
|
+
|
|
21
|
+
interface Props {
|
|
22
|
+
endPoint: string
|
|
23
|
+
tableView: boolean
|
|
24
|
+
sx?: SxProps
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default function ActivityLog({ endPoint, tableView, sx }: Props) {
|
|
28
|
+
const errorModal = useErrorModal()
|
|
29
|
+
const fetchActivities = async ({ pageParam = 0 }) => {
|
|
30
|
+
try {
|
|
31
|
+
const response = await axios.get(endPoint, {
|
|
32
|
+
params: {
|
|
33
|
+
limit: 4,
|
|
34
|
+
skip: pageParam,
|
|
35
|
+
},
|
|
36
|
+
})
|
|
37
|
+
return response.data.posts
|
|
38
|
+
} catch (error) {
|
|
39
|
+
// eslint-disable-next-line no-console
|
|
40
|
+
console.log(error)
|
|
41
|
+
errorModal({ error: error })
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading } =
|
|
46
|
+
useInfiniteQuery('activities', fetchActivities, {
|
|
47
|
+
getNextPageParam: (lastPage) => {
|
|
48
|
+
return lastPage.length ? lastPage[lastPage.length - 1].id : null
|
|
49
|
+
},
|
|
50
|
+
})
|
|
51
|
+
|
|
52
|
+
const activitesData = data ? data.pages.flatMap((page) => page) : []
|
|
53
|
+
|
|
54
|
+
if (isLoading) return <Spinner />
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<Box>
|
|
58
|
+
<Typography
|
|
59
|
+
variant="h1"
|
|
60
|
+
sx={{ fontSize: '18px', fontWeight: 700, margin: '20px' }}
|
|
61
|
+
>
|
|
62
|
+
Activity Log
|
|
63
|
+
</Typography>
|
|
64
|
+
|
|
65
|
+
{!tableView ? (
|
|
66
|
+
<Box
|
|
67
|
+
sx={{
|
|
68
|
+
overflowY: 'scroll',
|
|
69
|
+
'&::-webkit-scrollbar': {
|
|
70
|
+
display: 'none',
|
|
71
|
+
},
|
|
72
|
+
height: '380px',
|
|
73
|
+
}}
|
|
74
|
+
>
|
|
75
|
+
<TimeLineComponent
|
|
76
|
+
activitesData={activitesData}
|
|
77
|
+
fetchNextPage={fetchNextPage}
|
|
78
|
+
isFetchingNextPage={isFetchingNextPage}
|
|
79
|
+
hasNextPage={hasNextPage}
|
|
80
|
+
sx={sx}
|
|
81
|
+
/>
|
|
82
|
+
</Box>
|
|
83
|
+
) : (
|
|
84
|
+
<Box sx={{ margin: '0 25px' }}>
|
|
85
|
+
<Table
|
|
86
|
+
columns={columns}
|
|
87
|
+
dataSource={activitesData}
|
|
88
|
+
loading={isLoading}
|
|
89
|
+
/>
|
|
90
|
+
</Box>
|
|
91
|
+
)}
|
|
92
|
+
</Box>
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const columns = [
|
|
97
|
+
{ title: 'Date', dataIndex: 'date', key: 'date' },
|
|
98
|
+
{ title: 'Time', dataIndex: 'time', key: 'time' },
|
|
99
|
+
{ title: 'Message', dataIndex: 'message', key: 'message' },
|
|
100
|
+
{ title: 'User', dataIndex: 'userName', key: 'userName' },
|
|
101
|
+
]
|
|
102
|
+
|
|
103
|
+
export const TimeLineComponent = ({
|
|
104
|
+
activitesData,
|
|
105
|
+
isFetchingNextPage,
|
|
106
|
+
hasNextPage,
|
|
107
|
+
fetchNextPage,
|
|
108
|
+
sx,
|
|
109
|
+
}) => {
|
|
110
|
+
const lastItemRef = useIntersectionObserver<HTMLElement>(() => {
|
|
111
|
+
if (!isFetchingNextPage && hasNextPage) fetchNextPage()
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
return (
|
|
115
|
+
<Timeline sx={{ padding: 0, margin: 0 }}>
|
|
116
|
+
{activitesData.map((item, index, items) => (
|
|
117
|
+
<Box
|
|
118
|
+
key={index}
|
|
119
|
+
ref={items.length - 1 === index ? lastItemRef : null}
|
|
120
|
+
sx={{ maxWidth: '550px', ...sx }}
|
|
121
|
+
>
|
|
122
|
+
<TimelineItem
|
|
123
|
+
sx={{
|
|
124
|
+
margin: 2,
|
|
125
|
+
padding: 0,
|
|
126
|
+
'&:before': { display: 'none' },
|
|
127
|
+
}}
|
|
128
|
+
>
|
|
129
|
+
<TimelineSeparator>
|
|
130
|
+
<StyledTimeLineDot>
|
|
131
|
+
<StyledCircleIcon />
|
|
132
|
+
</StyledTimeLineDot>
|
|
133
|
+
{index < activitesData.length - 1 && (
|
|
134
|
+
<Box
|
|
135
|
+
sx={{
|
|
136
|
+
width: '1px',
|
|
137
|
+
height: '110px',
|
|
138
|
+
bgcolor: '#12121233',
|
|
139
|
+
position: 'absolute',
|
|
140
|
+
top: '25px',
|
|
141
|
+
}}
|
|
142
|
+
/>
|
|
143
|
+
)}
|
|
144
|
+
</TimelineSeparator>
|
|
145
|
+
<TimelineContent sx={{ padding: '6px 10px' }}>
|
|
146
|
+
<Box>
|
|
147
|
+
<Typography variant="subtitle2" sx={{ fontSize: '14px' }}>
|
|
148
|
+
{`${Math.floor(Math.random() * 30) + 1} ${
|
|
149
|
+
Math.random() > 0.5 ? 'June' : 'July'
|
|
150
|
+
}, 2023`}{' '}
|
|
151
|
+
-{' '}
|
|
152
|
+
{`${Math.floor(Math.random() * 12) + 1}:${
|
|
153
|
+
Math.floor(Math.random() * 60) + 1
|
|
154
|
+
} ${Math.random() > 0.5 ? 'AM' : 'PM'}`}
|
|
155
|
+
{/* {item.date} - {item.time} */}
|
|
156
|
+
</Typography>
|
|
157
|
+
<Typography sx={{ fontSize: '16px' }} variant="body1">
|
|
158
|
+
{item.title}
|
|
159
|
+
{/* {item.message} */}
|
|
160
|
+
</Typography>
|
|
161
|
+
<Typography
|
|
162
|
+
style={{
|
|
163
|
+
display: 'flex',
|
|
164
|
+
alignItems: 'center',
|
|
165
|
+
marginTop: '8px',
|
|
166
|
+
}}
|
|
167
|
+
>
|
|
168
|
+
<StyledAvatar>
|
|
169
|
+
{'John Doe'
|
|
170
|
+
.split(' ')
|
|
171
|
+
.map((n) => n[0])
|
|
172
|
+
.join('')
|
|
173
|
+
.toUpperCase()}
|
|
174
|
+
</StyledAvatar>
|
|
175
|
+
<Typography sx={{ fontSize: '13px', fontWeight: 900 }}>
|
|
176
|
+
{`John Doe ${item.id}`}
|
|
177
|
+
{/* {item.userName} */}
|
|
178
|
+
</Typography>
|
|
179
|
+
</Typography>
|
|
180
|
+
</Box>
|
|
181
|
+
</TimelineContent>
|
|
182
|
+
</TimelineItem>
|
|
183
|
+
{isFetchingNextPage && index === items.length - 1 && hasNextPage && (
|
|
184
|
+
<StyledSpinnerBox>
|
|
185
|
+
<Spinner />
|
|
186
|
+
</StyledSpinnerBox>
|
|
187
|
+
)}
|
|
188
|
+
</Box>
|
|
189
|
+
))}
|
|
190
|
+
</Timeline>
|
|
191
|
+
)
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function useIntersectionObserver<T extends HTMLElement>(callback: () => void) {
|
|
195
|
+
const observer = useRef<IntersectionObserver | null>(null)
|
|
196
|
+
|
|
197
|
+
const handleObserver = useCallback(
|
|
198
|
+
(node: T) => {
|
|
199
|
+
if (observer.current) observer.current.disconnect()
|
|
200
|
+
observer.current = new IntersectionObserver((entries) => {
|
|
201
|
+
if (entries[0].isIntersecting) callback()
|
|
202
|
+
})
|
|
203
|
+
if (node) observer.current.observe(node)
|
|
204
|
+
},
|
|
205
|
+
[callback],
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
return handleObserver
|
|
209
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import CircleRoundedIcon from '@mui/icons-material/CircleRounded'
|
|
2
|
+
import { TimelineDot } from '@mui/lab'
|
|
3
|
+
import { Avatar, Box, styled } from '@mui/material'
|
|
4
|
+
|
|
5
|
+
export const StyledTimeLineDot = styled(TimelineDot)({
|
|
6
|
+
width: '20px',
|
|
7
|
+
height: '20px',
|
|
8
|
+
boxShadow: 'none',
|
|
9
|
+
backgroundColor: '#F5F5F5',
|
|
10
|
+
border: '1px solid #12121233',
|
|
11
|
+
borderRadius: '50%',
|
|
12
|
+
margin: '5.5px 0',
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
export const StyledCircleIcon = styled(CircleRoundedIcon)({
|
|
16
|
+
position: 'relative',
|
|
17
|
+
left: '1px',
|
|
18
|
+
top: '1px',
|
|
19
|
+
color: 'black',
|
|
20
|
+
width: '7px',
|
|
21
|
+
height: '7px',
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
export const StyledAvatar = styled(Avatar)(({ theme }) => ({
|
|
25
|
+
width: 30,
|
|
26
|
+
height: 30,
|
|
27
|
+
marginRight: '8px',
|
|
28
|
+
backgroundColor: theme.palette.primary.main,
|
|
29
|
+
fontSize: '14px',
|
|
30
|
+
}))
|
|
31
|
+
|
|
32
|
+
export const StyledSpinnerBox = styled(Box)({
|
|
33
|
+
display: 'flex',
|
|
34
|
+
justifyContent: 'center',
|
|
35
|
+
alignItems: 'center',
|
|
36
|
+
padding: '20px',
|
|
37
|
+
})
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseSelectProps } from '@mui/material'
|
|
2
2
|
import { ReactNode } from 'react'
|
|
3
3
|
import { Controller } from 'react-hook-form'
|
|
4
4
|
import { SingleSelect } from '../Input'
|
|
@@ -9,7 +9,7 @@ type Props = {
|
|
|
9
9
|
options: Array<{ label: ReactNode; value: any }>
|
|
10
10
|
firstItemEmpty?: boolean
|
|
11
11
|
onOpen?: (e: any) => void
|
|
12
|
-
} &
|
|
12
|
+
} & BaseSelectProps
|
|
13
13
|
|
|
14
14
|
export default function FormSingleSelect(props: Props) {
|
|
15
15
|
const {
|
|
@@ -87,7 +87,7 @@ export const SearchSingleSelect = ({ options, value, onChange }: Props) => {
|
|
|
87
87
|
<TextField
|
|
88
88
|
inputRef={(input) => {
|
|
89
89
|
if (input && value) {
|
|
90
|
-
input.style.width = `${value.label
|
|
90
|
+
input.style.width = `${value.label?.length * 9}px`
|
|
91
91
|
}
|
|
92
92
|
}}
|
|
93
93
|
InputProps={{
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { KeyboardArrowDown } from '@mui/icons-material'
|
|
2
2
|
import {
|
|
3
|
+
BaseSelectProps,
|
|
4
|
+
Box,
|
|
5
|
+
BoxProps,
|
|
3
6
|
FormControl,
|
|
7
|
+
FormHelperText,
|
|
4
8
|
MenuItem,
|
|
5
|
-
SelectProps,
|
|
6
|
-
styled,
|
|
7
9
|
Select,
|
|
8
|
-
|
|
9
|
-
Box,
|
|
10
|
-
BoxProps,
|
|
10
|
+
styled,
|
|
11
11
|
} from '@mui/material'
|
|
12
12
|
import { ReactNode } from 'react'
|
|
13
13
|
import FormLabel from './FormLabel'
|
|
@@ -55,7 +55,7 @@ type Props = {
|
|
|
55
55
|
helperText?: string
|
|
56
56
|
containerProps?: BoxProps
|
|
57
57
|
onOpen?: (e: any) => void
|
|
58
|
-
} &
|
|
58
|
+
} & BaseSelectProps
|
|
59
59
|
|
|
60
60
|
export default function SingleSelect({
|
|
61
61
|
name = 'select',
|
|
@@ -46,7 +46,7 @@ const InstitutionCard = ({ institution }) => {
|
|
|
46
46
|
alt="logo"
|
|
47
47
|
height={'100px'}
|
|
48
48
|
width="100%"
|
|
49
|
-
src={institution?.
|
|
49
|
+
src={institution?.imageSquare?.url}
|
|
50
50
|
/>
|
|
51
51
|
<Typography variant="body2">{institution?.name}</Typography>
|
|
52
52
|
</StyledInstitutionCard>
|
|
@@ -38,6 +38,7 @@ interface AppHeaderProps {
|
|
|
38
38
|
clientLogo: string
|
|
39
39
|
fullName: string
|
|
40
40
|
profileUrl?: string
|
|
41
|
+
showMenu?: boolean
|
|
41
42
|
actions?: ReactNode[]
|
|
42
43
|
userBoxActions: {
|
|
43
44
|
label: ReactNode
|
|
@@ -45,23 +46,30 @@ interface AppHeaderProps {
|
|
|
45
46
|
onClick: any
|
|
46
47
|
}[]
|
|
47
48
|
customHeaderActions?: ReactNode
|
|
49
|
+
headerSx?: any
|
|
50
|
+
imageSx?: any
|
|
51
|
+
profileSx?: any
|
|
48
52
|
cogWheelMenu?: { label: string; path: string; openNewTab?: boolean }[]
|
|
49
53
|
}
|
|
50
54
|
|
|
51
55
|
export default function AppHeader({
|
|
52
56
|
clientLogo = imageMap.campx,
|
|
57
|
+
showMenu = true,
|
|
53
58
|
fullName,
|
|
54
59
|
userBoxActions = [],
|
|
55
60
|
cogWheelMenu = [],
|
|
56
61
|
customHeaderActions,
|
|
57
62
|
profileUrl,
|
|
58
63
|
actions = [],
|
|
64
|
+
headerSx = {},
|
|
65
|
+
profileSx = {},
|
|
66
|
+
imageSx = {},
|
|
59
67
|
}: AppHeaderProps) {
|
|
60
68
|
return (
|
|
61
|
-
<StyledHeader>
|
|
69
|
+
<StyledHeader sx={headerSx}>
|
|
62
70
|
<Box sx={{ display: 'flex', alignItems: 'center', gap: '10px' }}>
|
|
63
|
-
<AppsMenu />
|
|
64
|
-
<AppLogo clientLogo={clientLogo} />
|
|
71
|
+
{showMenu && <AppsMenu />}
|
|
72
|
+
<AppLogo clientLogo={clientLogo} imageSx={imageSx} />
|
|
65
73
|
</Box>
|
|
66
74
|
<Box className="actions">
|
|
67
75
|
{customHeaderActions ? (
|
|
@@ -73,6 +81,7 @@ export default function AppHeader({
|
|
|
73
81
|
userBoxActions={userBoxActions}
|
|
74
82
|
profileUrl={profileUrl}
|
|
75
83
|
actions={actions}
|
|
84
|
+
profileSx={profileSx}
|
|
76
85
|
/>
|
|
77
86
|
)}
|
|
78
87
|
</Box>
|
|
@@ -80,16 +89,16 @@ export default function AppHeader({
|
|
|
80
89
|
)
|
|
81
90
|
}
|
|
82
91
|
|
|
83
|
-
const AppLogo = ({ clientLogo }) => {
|
|
92
|
+
const AppLogo = ({ clientLogo, imageSx }) => {
|
|
84
93
|
const originSubdomain = window.location.host.split('.')?.slice(-3)[0] ?? 'ums'
|
|
85
94
|
const currentApp =
|
|
86
95
|
applications.find((item) => item.domainName === originSubdomain)
|
|
87
|
-
?.domainName ?? '
|
|
96
|
+
?.domainName ?? 'admin'
|
|
88
97
|
|
|
89
98
|
return (
|
|
90
99
|
<StyledRouterLink to={'/'}>
|
|
91
100
|
<StyledLogosWrapper>
|
|
92
|
-
<StyledImageWrapper>
|
|
101
|
+
<StyledImageWrapper sx={imageSx}>
|
|
93
102
|
<img src={imageMap[currentApp]} />
|
|
94
103
|
</StyledImageWrapper>
|
|
95
104
|
<Box
|
|
@@ -18,12 +18,14 @@ export default function HeaderActions({
|
|
|
18
18
|
userBoxActions,
|
|
19
19
|
profileUrl = '',
|
|
20
20
|
actions = [],
|
|
21
|
+
profileSx = {},
|
|
21
22
|
}: {
|
|
22
23
|
cogWheelMenu?: any[]
|
|
23
24
|
fullName: string
|
|
24
25
|
userBoxActions: IMenuItemProps[] | []
|
|
25
26
|
profileUrl: string
|
|
26
27
|
actions?: ReactNode[]
|
|
28
|
+
profileSx?: any
|
|
27
29
|
}) {
|
|
28
30
|
const navigate = useNavigate()
|
|
29
31
|
return (
|
|
@@ -46,6 +48,7 @@ export default function HeaderActions({
|
|
|
46
48
|
fullName={fullName}
|
|
47
49
|
actions={userBoxActions}
|
|
48
50
|
profileUrl={profileUrl}
|
|
51
|
+
profileSx={profileSx}
|
|
49
52
|
/>
|
|
50
53
|
</Stack>
|
|
51
54
|
</Stack>
|
|
@@ -27,17 +27,19 @@ export default function UserBox({
|
|
|
27
27
|
actions,
|
|
28
28
|
customActions = [],
|
|
29
29
|
profileUrl,
|
|
30
|
+
profileSx = {},
|
|
30
31
|
}: {
|
|
31
32
|
fullName: string
|
|
32
33
|
actions: IMenuItemProps[] | []
|
|
33
34
|
customActions?: IMenuItemProps[] | []
|
|
34
35
|
profileUrl?: string
|
|
36
|
+
profileSx?: any
|
|
35
37
|
}) {
|
|
36
38
|
const navigate = useNavigate()
|
|
37
39
|
return (
|
|
38
40
|
<DropDownButton
|
|
39
41
|
anchor={({ open }) => (
|
|
40
|
-
<StyledAvatar src={profileUrl ?? ''} onClick={open}>
|
|
42
|
+
<StyledAvatar src={profileUrl ?? ''} onClick={open} sx={profileSx}>
|
|
41
43
|
{getStartingLetters(fullName)}
|
|
42
44
|
</StyledAvatar>
|
|
43
45
|
)}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseSelectProps } from '@mui/material'
|
|
2
2
|
import { useEffect, useState } from 'react'
|
|
3
3
|
import axios from '../../config/axios'
|
|
4
4
|
import { SingleSelect } from '../Input'
|
|
@@ -13,7 +13,7 @@ type ClassRoomSelectorProps = {
|
|
|
13
13
|
error?: boolean
|
|
14
14
|
helperText?: string
|
|
15
15
|
api?: string
|
|
16
|
-
} &
|
|
16
|
+
} & BaseSelectProps
|
|
17
17
|
const ClassRoomSelector = (props: ClassRoomSelectorProps) => {
|
|
18
18
|
const {
|
|
19
19
|
name,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseSelectProps } from '@mui/material'
|
|
2
2
|
import { useEffect, useState } from 'react'
|
|
3
3
|
import axios from '../../config/axios'
|
|
4
4
|
import { SingleSelect } from '../Input'
|
|
@@ -13,7 +13,7 @@ type CourseSelectorProps = {
|
|
|
13
13
|
helperText?: string
|
|
14
14
|
api?: string
|
|
15
15
|
valueByUniqueId?: boolean
|
|
16
|
-
} &
|
|
16
|
+
} & BaseSelectProps
|
|
17
17
|
export default function CourseSelector(props: CourseSelectorProps) {
|
|
18
18
|
const {
|
|
19
19
|
name,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseSelectProps } from '@mui/material'
|
|
2
2
|
import { useEffect, useState } from 'react'
|
|
3
3
|
import axios from '../../config/axios'
|
|
4
4
|
import { SingleSelect } from '../Input'
|
|
@@ -12,7 +12,7 @@ type DepartmentSelectorProps = {
|
|
|
12
12
|
error?: boolean
|
|
13
13
|
helperText?: string
|
|
14
14
|
api?: string
|
|
15
|
-
} &
|
|
15
|
+
} & BaseSelectProps
|
|
16
16
|
export default function DepartmentSelector(props: DepartmentSelectorProps) {
|
|
17
17
|
const {
|
|
18
18
|
name,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseSelectProps } from '@mui/material'
|
|
2
2
|
import { useEffect, useState } from 'react'
|
|
3
3
|
import axios from '../../config/axios'
|
|
4
4
|
import { SingleSelect } from '../Input'
|
|
@@ -12,7 +12,7 @@ type ExamGroupSelectorProps = {
|
|
|
12
12
|
allowAll?: boolean
|
|
13
13
|
error?: boolean
|
|
14
14
|
helperText?: string
|
|
15
|
-
} &
|
|
15
|
+
} & BaseSelectProps
|
|
16
16
|
const ExamGroupSelector = (props: ExamGroupSelectorProps) => {
|
|
17
17
|
const {
|
|
18
18
|
name,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseSelectProps } from '@mui/material'
|
|
2
2
|
import { useEffect, useState } from 'react'
|
|
3
3
|
import axios from '../../config/axios'
|
|
4
4
|
import { SingleSelect } from '../Input'
|
|
@@ -18,7 +18,7 @@ type FacultySelectorProps = {
|
|
|
18
18
|
error?: boolean
|
|
19
19
|
helperText?: string
|
|
20
20
|
api?: string
|
|
21
|
-
} &
|
|
21
|
+
} & BaseSelectProps
|
|
22
22
|
const FacultySelector = (props: FacultySelectorProps) => {
|
|
23
23
|
const {
|
|
24
24
|
name,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseSelectProps } from '@mui/material'
|
|
2
2
|
import { useEffect, useState } from 'react'
|
|
3
3
|
import axios from '../../config/axios'
|
|
4
4
|
import { SingleSelect } from '../Input'
|
|
@@ -11,7 +11,7 @@ type FeeTypeSelectorProps = {
|
|
|
11
11
|
onChange?: (value: any) => void
|
|
12
12
|
error?: boolean
|
|
13
13
|
helperText?: string
|
|
14
|
-
} &
|
|
14
|
+
} & BaseSelectProps
|
|
15
15
|
export default function FeeTypeSelector(props: FeeTypeSelectorProps) {
|
|
16
16
|
const { name, required = false, label, onChange, allowAll = true } = props
|
|
17
17
|
const [options, setOptions] = useState([])
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseSelectProps } from '@mui/material'
|
|
2
2
|
import { Controller } from 'react-hook-form'
|
|
3
3
|
import ClassRoomSelector from '../ClassRoomSelector'
|
|
4
4
|
|
|
@@ -12,7 +12,7 @@ type ClassRoomSelectorProps = {
|
|
|
12
12
|
filters?: { programId: number; courseId: number; batch: string }
|
|
13
13
|
onChange?: (value: any) => void
|
|
14
14
|
api?: string
|
|
15
|
-
} &
|
|
15
|
+
} & BaseSelectProps
|
|
16
16
|
export default function FormClassRoomSelector(props: ClassRoomSelectorProps) {
|
|
17
17
|
const {
|
|
18
18
|
name,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseSelectProps } from '@mui/material'
|
|
2
2
|
import { Controller } from 'react-hook-form'
|
|
3
3
|
import CourseSelector from '../CourseSelector'
|
|
4
4
|
|
|
@@ -12,7 +12,7 @@ type FormCourseSelectorProps = {
|
|
|
12
12
|
onChange?: (value: any) => void
|
|
13
13
|
api?: string
|
|
14
14
|
valueByUniqueId?: boolean
|
|
15
|
-
} &
|
|
15
|
+
} & BaseSelectProps
|
|
16
16
|
export default function FormCourseSelector(props: FormCourseSelectorProps) {
|
|
17
17
|
const {
|
|
18
18
|
name,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseSelectProps } from '@mui/material'
|
|
2
2
|
import { Controller } from 'react-hook-form'
|
|
3
3
|
import DepartmentSelector from '../DepartmentSelector'
|
|
4
4
|
|
|
@@ -11,7 +11,7 @@ type FormDepartmentSelectorProps = {
|
|
|
11
11
|
allowAll?: boolean
|
|
12
12
|
onChange?: (value: any) => void
|
|
13
13
|
api?: string
|
|
14
|
-
} &
|
|
14
|
+
} & BaseSelectProps
|
|
15
15
|
export default function FormDepartmentSelector(
|
|
16
16
|
props: FormDepartmentSelectorProps,
|
|
17
17
|
) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseSelectProps } from '@mui/material'
|
|
2
2
|
import { Controller } from 'react-hook-form'
|
|
3
3
|
import ExamGroupSelector from '../ExamGroupSelector'
|
|
4
4
|
|
|
@@ -11,7 +11,7 @@ type ExamGroupSelectorProps = {
|
|
|
11
11
|
allowAll?: boolean
|
|
12
12
|
filters?: { courseId: number; examType: string }
|
|
13
13
|
onChange?: (value: any) => void
|
|
14
|
-
} &
|
|
14
|
+
} & BaseSelectProps
|
|
15
15
|
export default function FormExamGroupSelector(props: ExamGroupSelectorProps) {
|
|
16
16
|
const {
|
|
17
17
|
name,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseSelectProps } from '@mui/material'
|
|
2
2
|
import { Controller } from 'react-hook-form'
|
|
3
3
|
import FacultySelector from '../FacultySelector'
|
|
4
4
|
|
|
@@ -17,7 +17,7 @@ type FacultySelectorProps = {
|
|
|
17
17
|
}
|
|
18
18
|
onChange?: (value: any) => void
|
|
19
19
|
api?: string
|
|
20
|
-
} &
|
|
20
|
+
} & BaseSelectProps
|
|
21
21
|
export default function FormFacultySelector(props: FacultySelectorProps) {
|
|
22
22
|
const {
|
|
23
23
|
name,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseSelectProps } from '@mui/material'
|
|
2
2
|
import { Controller } from 'react-hook-form'
|
|
3
3
|
import FeeTypeSelector from '../FeeTypeSelector'
|
|
4
4
|
|
|
@@ -11,7 +11,7 @@ type FormFeeTypeSelectorProps = {
|
|
|
11
11
|
allowAll?: boolean
|
|
12
12
|
onChange?: (value: any) => void
|
|
13
13
|
api?: string
|
|
14
|
-
} &
|
|
14
|
+
} & BaseSelectProps
|
|
15
15
|
export default function FormFeeTypeSelector(props: FormFeeTypeSelectorProps) {
|
|
16
16
|
const {
|
|
17
17
|
name,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseSelectProps } from '@mui/material'
|
|
2
2
|
import { Controller } from 'react-hook-form'
|
|
3
3
|
import ProgramSelector from '../ProgramSelector'
|
|
4
4
|
|
|
@@ -13,7 +13,7 @@ type ProgramSelectorProps = {
|
|
|
13
13
|
onChange?: (value: any) => void
|
|
14
14
|
api?: string
|
|
15
15
|
valueByBranchCode?: boolean
|
|
16
|
-
} &
|
|
16
|
+
} & BaseSelectProps
|
|
17
17
|
export default function FormProgramSelector(props: ProgramSelectorProps) {
|
|
18
18
|
const {
|
|
19
19
|
name,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseSelectProps } from '@mui/material'
|
|
2
2
|
import { Controller } from 'react-hook-form'
|
|
3
3
|
import QuotaSelector from '../QuotaSelector'
|
|
4
4
|
|
|
@@ -12,7 +12,7 @@ type FormQuotaSelectorProps = {
|
|
|
12
12
|
onChange?: (value: any) => void
|
|
13
13
|
filters?: { courseId: number }
|
|
14
14
|
api?: string
|
|
15
|
-
} &
|
|
15
|
+
} & BaseSelectProps
|
|
16
16
|
export default function FormQuotaSelector(props: FormQuotaSelectorProps) {
|
|
17
17
|
const {
|
|
18
18
|
name,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseSelectProps } from '@mui/material'
|
|
2
2
|
import { Controller } from 'react-hook-form'
|
|
3
3
|
import SemesterSelector from '../SemesterSelector'
|
|
4
4
|
|
|
@@ -12,7 +12,7 @@ type SemesterSelectorProps = {
|
|
|
12
12
|
filters?: { courseId: number }
|
|
13
13
|
onChange?: (value: any) => void
|
|
14
14
|
api?: string
|
|
15
|
-
} &
|
|
15
|
+
} & BaseSelectProps
|
|
16
16
|
export default function FormSemseterSelector(props: SemesterSelectorProps) {
|
|
17
17
|
const {
|
|
18
18
|
name,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseSelectProps } from '@mui/material'
|
|
2
2
|
import { useEffect, useState } from 'react'
|
|
3
3
|
import { Controller } from 'react-hook-form'
|
|
4
4
|
import axios from '../../../../config/axios'
|
|
@@ -20,7 +20,7 @@ type MultiFacultySelectorProps = {
|
|
|
20
20
|
error?: boolean
|
|
21
21
|
helperText?: string
|
|
22
22
|
api?: string
|
|
23
|
-
} &
|
|
23
|
+
} & BaseSelectProps
|
|
24
24
|
const MultiFacultySelector = (props: MultiFacultySelectorProps) => {
|
|
25
25
|
const {
|
|
26
26
|
control,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseSelectProps } from '@mui/material'
|
|
2
2
|
import { useEffect, useState } from 'react'
|
|
3
3
|
import { Controller } from 'react-hook-form'
|
|
4
4
|
import axios from '../../../../config/axios'
|
|
@@ -13,7 +13,7 @@ type MultiProgramSelectorProps = {
|
|
|
13
13
|
allowAll?: boolean
|
|
14
14
|
error?: boolean
|
|
15
15
|
helperText?: string
|
|
16
|
-
} &
|
|
16
|
+
} & BaseSelectProps
|
|
17
17
|
const MultiFeeTypeSelector = (props: MultiProgramSelectorProps) => {
|
|
18
18
|
const {
|
|
19
19
|
control,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseSelectProps } from '@mui/material'
|
|
2
2
|
import { useEffect, useState } from 'react'
|
|
3
3
|
import { Controller } from 'react-hook-form'
|
|
4
4
|
import axios from '../../../../config/axios'
|
|
@@ -15,7 +15,7 @@ type MultiProgramSelectorProps = {
|
|
|
15
15
|
error?: boolean
|
|
16
16
|
helperText?: string
|
|
17
17
|
api?: string
|
|
18
|
-
} &
|
|
18
|
+
} & BaseSelectProps
|
|
19
19
|
const MultiProgramSelector = (props: MultiProgramSelectorProps) => {
|
|
20
20
|
const {
|
|
21
21
|
control,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseSelectProps } from '@mui/material'
|
|
2
2
|
import { useEffect, useState } from 'react'
|
|
3
3
|
import { Controller } from 'react-hook-form'
|
|
4
4
|
import axios from '../../../../config/axios'
|
|
@@ -15,7 +15,7 @@ type MultiQuotaSelectorProps = {
|
|
|
15
15
|
error?: boolean
|
|
16
16
|
helperText?: string
|
|
17
17
|
api?: string
|
|
18
|
-
} &
|
|
18
|
+
} & BaseSelectProps
|
|
19
19
|
export default function MultiQuotaSelector(props: MultiQuotaSelectorProps) {
|
|
20
20
|
const {
|
|
21
21
|
control,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseSelectProps } from '@mui/material'
|
|
2
2
|
import { useEffect, useState } from 'react'
|
|
3
3
|
import axios from '../../config/axios'
|
|
4
4
|
import { SingleSelect } from '../Input'
|
|
@@ -6,7 +6,7 @@ import { SingleSelect } from '../Input'
|
|
|
6
6
|
type ProgramSelectorProps = {
|
|
7
7
|
name?: string
|
|
8
8
|
label: string
|
|
9
|
-
filters?: { courseId: number| string }
|
|
9
|
+
filters?: { courseId: number | string }
|
|
10
10
|
required?: boolean
|
|
11
11
|
onChange?: (value: any) => void
|
|
12
12
|
allowAll?: boolean
|
|
@@ -14,7 +14,7 @@ type ProgramSelectorProps = {
|
|
|
14
14
|
helperText?: string
|
|
15
15
|
api?: string
|
|
16
16
|
valueByBranchCode?: boolean
|
|
17
|
-
} &
|
|
17
|
+
} & BaseSelectProps
|
|
18
18
|
const ProgramSelector = (props: ProgramSelectorProps) => {
|
|
19
19
|
const {
|
|
20
20
|
name,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseSelectProps } from '@mui/material'
|
|
2
2
|
import { useEffect, useState } from 'react'
|
|
3
3
|
import axios from '../../config/axios'
|
|
4
4
|
import { SingleSelect } from '../Input'
|
|
@@ -13,7 +13,7 @@ type QuotaSelectorProps = {
|
|
|
13
13
|
error?: boolean
|
|
14
14
|
helperText?: string
|
|
15
15
|
api?: string
|
|
16
|
-
} &
|
|
16
|
+
} & BaseSelectProps
|
|
17
17
|
export default function QuotaSelector(props: QuotaSelectorProps) {
|
|
18
18
|
const {
|
|
19
19
|
name,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { BaseSelectProps } from '@mui/material'
|
|
2
2
|
import { useEffect, useState } from 'react'
|
|
3
3
|
import axios from '../../config/axios'
|
|
4
4
|
import { SingleSelect } from '../Input'
|
|
@@ -13,7 +13,7 @@ type SemesterSelectorProps = {
|
|
|
13
13
|
error?: boolean
|
|
14
14
|
helperText?: string
|
|
15
15
|
api?: string
|
|
16
|
-
} &
|
|
16
|
+
} & BaseSelectProps
|
|
17
17
|
const SemesterSelector = (props: SemesterSelectorProps) => {
|
|
18
18
|
const {
|
|
19
19
|
name,
|