@campxdev/shared 1.11.6 → 1.11.7-0.alpha-22
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/.vscode/settings.json +3 -0
- package/exports.ts +4 -0
- package/package.json +17 -9
- package/src/assets/images/X.png +0 -0
- package/src/assets/images/active_devices.svg +3 -0
- package/src/assets/images/animation.gif +0 -0
- package/src/assets/images/change_password.svg +6 -0
- package/src/assets/images/clog_wheel.svg +6 -0
- package/src/assets/images/index.ts +28 -3
- package/src/assets/images/location.svg +6 -0
- package/src/assets/images/logout_icon.svg +6 -0
- package/src/assets/images/lottery.svg +22 -0
- package/src/assets/images/mobile.svg +7 -0
- package/src/assets/images/no_devices.svg +734 -0
- package/src/assets/images/notifications.svg +3 -0
- package/src/assets/images/profile.svg +6 -0
- package/src/assets/images/web.svg +13 -0
- package/src/components/ActiveDevices/ActiveDevices.tsx +60 -0
- package/src/components/ActiveDevices/DeviceInformationCard.tsx +97 -0
- package/src/components/ActiveDevices/index.ts +1 -0
- package/src/components/ActivityLog/ActivityLog.tsx +268 -0
- package/src/components/ActivityLog/Styles.tsx +35 -0
- package/src/components/ActivityLog/index.ts +1 -0
- package/src/components/ApplicationProfile/ApplicationProfile.tsx +1 -0
- package/src/components/ApplicationProfile/UserProfileRelation.tsx +4 -1
- package/src/components/DatabaseConfiguration/DatabaseConfiguration.tsx +28 -0
- package/src/components/DatabaseConfiguration/DatabaseConfigurationForm.tsx +87 -0
- package/src/components/DatabaseConfiguration/components/AddConnectionDrawerButton.tsx +30 -0
- package/src/components/DatabaseConfiguration/components/ConnectionCard.tsx +79 -0
- package/src/components/DatabaseConfiguration/index.ts +5 -0
- package/src/components/DatabaseConfiguration/service.ts +6 -0
- package/src/components/DatabaseConfiguration/styles.ts +30 -0
- package/src/components/DrawerWrapper/DialogTemplate.tsx +58 -0
- package/src/components/DrawerWrapper/DrawerWrapper.tsx +23 -7
- package/src/components/DrawerWrapper/ErrorTemplate.tsx +77 -0
- package/src/components/ErrorModal.tsx +88 -0
- package/src/components/ErrorModalWrapper/ErrorModalTemplate.tsx +118 -0
- package/src/components/ErrorModalWrapper/ErrorModalWrapper.tsx +76 -0
- package/src/components/FilterComponents/SearchBar.tsx +5 -2
- package/src/components/Form/Form.tsx +4 -1
- package/src/components/HookForm/AutoCompleteSearch.tsx +3 -0
- package/src/components/HookForm/MultiSelect.tsx +1 -0
- package/src/components/HookForm/SingleSelect.tsx +2 -2
- package/src/components/ImageUpload.tsx +4 -1
- package/src/components/Input/MultiSelect.tsx +1 -0
- package/src/components/Input/SearchSingleSelect.tsx +1 -1
- package/src/components/Input/SingleSelect.tsx +7 -7
- package/src/components/Institutions/InsititutionsDialog.tsx +2 -2
- package/src/components/Layout/Header/AppHeader.tsx +23 -6
- package/src/components/Layout/Header/HeaderActions/CogWheelMenu.tsx +2 -2
- package/src/components/Layout/Header/HeaderActions/HeaderActions.tsx +41 -16
- package/src/components/Layout/Header/HeaderActions/UserBox.tsx +48 -6
- package/src/components/Layout/Header/applications.ts +43 -30
- package/src/components/Layout/LayoutWrapper.tsx +82 -4
- package/src/components/Layout/SideNav.tsx +42 -9
- package/src/components/LoginForm.tsx +53 -1
- package/src/components/MongoCharts/MongoDashboard.tsx +146 -0
- package/src/components/MongoCharts/index.tsx +1 -0
- package/src/components/MyProfile/MyProfile.tsx +1 -1
- package/src/components/ReportHeader.tsx +2 -2
- 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 +19 -10
- 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 +3 -3
- 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 +3 -3
- package/src/components/Selectors/SemesterSelector.tsx +2 -2
- package/src/components/SignatureFooter.tsx +35 -0
- package/src/components/SwitchButton.tsx +6 -1
- package/src/components/Tables/2DTable/Table.tsx +20 -23
- package/src/components/Tables/BasicTable/Table.tsx +22 -13
- package/src/components/Tables/BasicTable/TableFooter.tsx +35 -9
- package/src/components/Tables/BasicTable/styles.ts +1 -1
- package/src/components/Tables/ReactTable/ReactTable.tsx +42 -8
- package/src/components/Tables/common/types.ts +1 -0
- package/src/components/Tabs/TabsContainer.tsx +5 -5
- package/src/components/Tabs/styles.tsx +1 -0
- package/src/components/ToastContainer/ToastContainer.tsx +2 -3
- package/src/components/UploadButton/UploadButton.tsx +3 -1
- package/src/components/UploadButton/types.ts +2 -2
- package/src/components/UploadDocument.tsx +3 -0
- package/src/components/UploadFileDialog/UploadFileDialog.tsx +20 -9
- package/src/components/index.ts +5 -0
- package/src/config/axios.ts +5 -19
- package/src/constants/UIConstants.ts +65 -2
- package/src/constants/isDevelopment.ts +0 -1
- package/src/contexts/Providers.tsx +5 -43
- package/src/hooks/useAuth.ts +7 -0
- package/src/layouts/Components/styles.tsx +25 -7
- package/src/permissions/PermissionsStore.ts +658 -55
- package/src/permissions/ValidateAccess.tsx +37 -8
- package/src/shared-state/PermissionsStore.ts +779 -85
- package/src/theme/theme.d.ts +69 -35
- package/src/utils/debounce.ts +11 -0
- package/src/utils/getUrlParams.ts +13 -0
- package/src/utils/index.ts +6 -3
- package/src/utils/logout.ts +4 -8
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { Cached } from '@mui/icons-material'
|
|
2
|
+
import { Box, CardActions, IconButton, Typography } from '@mui/material'
|
|
3
|
+
import { toast } from 'react-toastify'
|
|
4
|
+
import axios from '../../../config/axios'
|
|
5
|
+
import { EditButton } from '../../IconButtons'
|
|
6
|
+
import { DrawerButton } from '../../ModalButtons'
|
|
7
|
+
import { DatabaseConfigurationForm } from '../DatabaseConfigurationForm'
|
|
8
|
+
import { StyledCard, StyledCardContent } from '../styles'
|
|
9
|
+
|
|
10
|
+
export const ConnectionCard = ({ data }) => {
|
|
11
|
+
const handleReconnect = async () => {
|
|
12
|
+
const response: string = await axios.post(
|
|
13
|
+
'hrms/punch-logs-database-config/connect',
|
|
14
|
+
{},
|
|
15
|
+
)
|
|
16
|
+
if (response) {
|
|
17
|
+
window.location.reload()
|
|
18
|
+
}
|
|
19
|
+
toast.success(response)
|
|
20
|
+
}
|
|
21
|
+
return (
|
|
22
|
+
<>
|
|
23
|
+
<StyledCard>
|
|
24
|
+
<StyledCardContent>
|
|
25
|
+
<Column label={'Host'} value={data?.host} />
|
|
26
|
+
<Column label={'Username'} value={data?.username} />
|
|
27
|
+
<Column label={'Password'} value={data?.password} />
|
|
28
|
+
<Column label={'Port'} value={data?.port} />
|
|
29
|
+
<Column label={'Database'} value={data?.database} />
|
|
30
|
+
<Column label={'Timezone'} value={data?.timezone} />
|
|
31
|
+
<Column
|
|
32
|
+
label={'Status'}
|
|
33
|
+
value={data?.connectionStatus}
|
|
34
|
+
color={data?.connectionStatus == 'Connected' ? 'green' : 'red'}
|
|
35
|
+
/>
|
|
36
|
+
</StyledCardContent>
|
|
37
|
+
<CardActions>
|
|
38
|
+
<DrawerButton
|
|
39
|
+
key={'1'}
|
|
40
|
+
anchor={({ open }) => <EditButton onClick={open} />}
|
|
41
|
+
content={({ close }) => (
|
|
42
|
+
<DatabaseConfigurationForm
|
|
43
|
+
data={data}
|
|
44
|
+
close={close}
|
|
45
|
+
successToastMessage="Updated Database Configuration"
|
|
46
|
+
type={data.type}
|
|
47
|
+
/>
|
|
48
|
+
)}
|
|
49
|
+
title="Add Database Configuration"
|
|
50
|
+
/>
|
|
51
|
+
<IconButton onClick={handleReconnect}>
|
|
52
|
+
<Cached sx={{ '&:hover': { color: 'green' } }} />
|
|
53
|
+
</IconButton>
|
|
54
|
+
</CardActions>
|
|
55
|
+
</StyledCard>
|
|
56
|
+
</>
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export const Column = ({
|
|
61
|
+
label,
|
|
62
|
+
value,
|
|
63
|
+
color = '#000000',
|
|
64
|
+
}: {
|
|
65
|
+
label: string
|
|
66
|
+
value: string
|
|
67
|
+
color?: string
|
|
68
|
+
}) => {
|
|
69
|
+
return (
|
|
70
|
+
<Box>
|
|
71
|
+
<Typography sx={{ fontSize: 14 }} color="text.secondary" gutterBottom>
|
|
72
|
+
{label}
|
|
73
|
+
</Typography>
|
|
74
|
+
<Typography variant="h5" component="div" color={color}>
|
|
75
|
+
{value}
|
|
76
|
+
</Typography>
|
|
77
|
+
</Box>
|
|
78
|
+
)
|
|
79
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Card, CardContent, FormLabel, styled } from '@mui/material'
|
|
2
|
+
|
|
3
|
+
export const StyledSelectAttachmentsContainer = styled(FormLabel)({
|
|
4
|
+
border: '1px dashed #0000001A',
|
|
5
|
+
margin: '20px',
|
|
6
|
+
display: 'flex',
|
|
7
|
+
justifyContent: 'center',
|
|
8
|
+
alignItems: 'center',
|
|
9
|
+
borderRadius: '10px',
|
|
10
|
+
cursor: 'pointer',
|
|
11
|
+
height: '148px',
|
|
12
|
+
gap: '10px',
|
|
13
|
+
'&:hover': {
|
|
14
|
+
backgroundColor: '#EFEFEF',
|
|
15
|
+
},
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
export const StyledCard = styled(Card)({
|
|
19
|
+
display: 'flex',
|
|
20
|
+
margin: '20px',
|
|
21
|
+
justifyContent: 'center',
|
|
22
|
+
gap: '60px',
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
export const StyledCardContent = styled(CardContent)({
|
|
26
|
+
display: 'flex',
|
|
27
|
+
margin: '20px',
|
|
28
|
+
alignItems: 'center',
|
|
29
|
+
gap: '30px',
|
|
30
|
+
})
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Close } from '@mui/icons-material'
|
|
2
|
+
import {
|
|
3
|
+
alpha,
|
|
4
|
+
Box,
|
|
5
|
+
Dialog,
|
|
6
|
+
DialogContent,
|
|
7
|
+
IconButton,
|
|
8
|
+
styled,
|
|
9
|
+
Typography,
|
|
10
|
+
} from '@mui/material'
|
|
11
|
+
|
|
12
|
+
const StyledDialogHeader = styled(Box)(({ theme }) => ({
|
|
13
|
+
height: '64px',
|
|
14
|
+
backgroundColor: alpha(theme.palette.text.secondary, 0.1),
|
|
15
|
+
display: 'flex',
|
|
16
|
+
justifyContent: 'space-between',
|
|
17
|
+
alignItems: 'center',
|
|
18
|
+
padding: '0.6rem 1rem',
|
|
19
|
+
}))
|
|
20
|
+
|
|
21
|
+
export default function DialogTemplate({
|
|
22
|
+
handleClose,
|
|
23
|
+
modal,
|
|
24
|
+
setModal,
|
|
25
|
+
...props
|
|
26
|
+
}) {
|
|
27
|
+
return (
|
|
28
|
+
<Dialog
|
|
29
|
+
sx={{
|
|
30
|
+
zIndex: 500,
|
|
31
|
+
minHeight: '70vh',
|
|
32
|
+
'& .MuiDialog-container': {
|
|
33
|
+
'& .MuiPaper-root': {
|
|
34
|
+
maxWidth: '1420px',
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
}}
|
|
38
|
+
onClose={handleClose}
|
|
39
|
+
open={modal.open}
|
|
40
|
+
{...props}
|
|
41
|
+
PaperProps={{
|
|
42
|
+
sx: {
|
|
43
|
+
borderRadius: '10px',
|
|
44
|
+
},
|
|
45
|
+
}}
|
|
46
|
+
>
|
|
47
|
+
<StyledDialogHeader>
|
|
48
|
+
<Typography fontWeight={600}>{modal.title}</Typography>
|
|
49
|
+
<IconButton onClick={() => setModal({ ...modal, open: false })}>
|
|
50
|
+
<Close />
|
|
51
|
+
</IconButton>
|
|
52
|
+
</StyledDialogHeader>
|
|
53
|
+
<DialogContent sx={{ padding: '0' }}>
|
|
54
|
+
<>{modal.content({ close: handleClose })}</>
|
|
55
|
+
</DialogContent>
|
|
56
|
+
</Dialog>
|
|
57
|
+
)
|
|
58
|
+
}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { createContext, useContext, useState } from 'react'
|
|
2
|
+
import DialogTemplate from './DialogTemplate'
|
|
2
3
|
import { DrawerTemplate } from './DrawerTemplate'
|
|
4
|
+
import ErrorTemplate from './ErrorTemplate'
|
|
3
5
|
|
|
4
6
|
interface IProps {
|
|
5
7
|
title: string
|
|
6
|
-
modalType?: 'dialog' | 'drawer'
|
|
8
|
+
modalType?: 'dialog' | 'drawer' | 'error'
|
|
7
9
|
content: ({ close }: { close: () => void }) => any
|
|
8
10
|
}
|
|
9
11
|
|
|
@@ -32,7 +34,7 @@ export default function DialogProvider({ children }) {
|
|
|
32
34
|
open: true,
|
|
33
35
|
title: props.title,
|
|
34
36
|
content: props.content,
|
|
35
|
-
|
|
37
|
+
modalType: props.modalType ?? 'drawer',
|
|
36
38
|
})
|
|
37
39
|
}
|
|
38
40
|
|
|
@@ -40,11 +42,25 @@ export default function DialogProvider({ children }) {
|
|
|
40
42
|
<DialogContext.Provider value={showModal}>
|
|
41
43
|
{children}
|
|
42
44
|
<>
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
{modal.modalType == 'drawer' ? (
|
|
46
|
+
<DrawerTemplate
|
|
47
|
+
handleClose={handleClose}
|
|
48
|
+
modal={modal}
|
|
49
|
+
setModal={setModal}
|
|
50
|
+
/>
|
|
51
|
+
) : modal.modalType == 'dialog' ? (
|
|
52
|
+
<DialogTemplate
|
|
53
|
+
handleClose={handleClose}
|
|
54
|
+
modal={modal}
|
|
55
|
+
setModal={setModal}
|
|
56
|
+
/>
|
|
57
|
+
) : (
|
|
58
|
+
<ErrorTemplate
|
|
59
|
+
handleClose={handleClose}
|
|
60
|
+
modal={modal}
|
|
61
|
+
setModal={setModal}
|
|
62
|
+
/>
|
|
63
|
+
)}
|
|
48
64
|
</>
|
|
49
65
|
</DialogContext.Provider>
|
|
50
66
|
)
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { Box, Button, Modal, Typography, styled } from '@mui/material'
|
|
2
|
+
import { animatedImage } from '../../assets/images'
|
|
3
|
+
|
|
4
|
+
const style = {
|
|
5
|
+
position: 'absolute' as 'absolute',
|
|
6
|
+
top: '50%',
|
|
7
|
+
left: '50%',
|
|
8
|
+
transform: 'translate(-50%, -50%)',
|
|
9
|
+
bgcolor: 'background.paper',
|
|
10
|
+
boxShadow: 24,
|
|
11
|
+
width: '700px',
|
|
12
|
+
borderRadius: '10px',
|
|
13
|
+
display: 'flex',
|
|
14
|
+
gap: '15px',
|
|
15
|
+
flexDirection: 'column',
|
|
16
|
+
padding: '20px',
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const StyledImage = styled(Box)(({ theme }) => ({
|
|
20
|
+
width: '154px',
|
|
21
|
+
margin: 'auto',
|
|
22
|
+
'> img': {
|
|
23
|
+
width: '100%',
|
|
24
|
+
height: '120px',
|
|
25
|
+
objectFit: 'contain',
|
|
26
|
+
},
|
|
27
|
+
}))
|
|
28
|
+
|
|
29
|
+
const MessageContainer = styled(Box)(({ theme }) => ({
|
|
30
|
+
maxHeight: '60vh',
|
|
31
|
+
padding: '15px',
|
|
32
|
+
overflowY: 'auto',
|
|
33
|
+
'&::-webkit-scrollbar': {
|
|
34
|
+
width: '0.5em',
|
|
35
|
+
height: '0.5em',
|
|
36
|
+
},
|
|
37
|
+
'&::-webkit-scrollbar-thumb': {
|
|
38
|
+
backgroundColor: 'rgba(0, 0, 0, 0.15)',
|
|
39
|
+
borderRadius: '3px',
|
|
40
|
+
'&:hover': {
|
|
41
|
+
background: 'rgba(0, 0, 0, 0.2)',
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
}))
|
|
45
|
+
|
|
46
|
+
export default function ErrorTemplate({
|
|
47
|
+
handleClose,
|
|
48
|
+
modal,
|
|
49
|
+
setModal,
|
|
50
|
+
...props
|
|
51
|
+
}) {
|
|
52
|
+
return (
|
|
53
|
+
<Modal open={modal.open} onClose={handleClose}>
|
|
54
|
+
<Box sx={style}>
|
|
55
|
+
<StyledImage>
|
|
56
|
+
<img src={animatedImage} alt="Error Image" />
|
|
57
|
+
</StyledImage>
|
|
58
|
+
|
|
59
|
+
<MessageContainer>
|
|
60
|
+
<Typography
|
|
61
|
+
variant="h6"
|
|
62
|
+
sx={{ textAlign: 'center', lineHeight: 1.7 }}
|
|
63
|
+
>
|
|
64
|
+
{modal.content({ close: handleClose })}
|
|
65
|
+
</Typography>
|
|
66
|
+
</MessageContainer>
|
|
67
|
+
<Button
|
|
68
|
+
variant="outlined"
|
|
69
|
+
onClick={handleClose}
|
|
70
|
+
sx={{ height: '40px', margin: 'auto', width: '200px' }}
|
|
71
|
+
>
|
|
72
|
+
OK
|
|
73
|
+
</Button>
|
|
74
|
+
</Box>
|
|
75
|
+
</Modal>
|
|
76
|
+
)
|
|
77
|
+
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { Box, Button, Modal, Typography, styled } from '@mui/material'
|
|
2
|
+
import { useEffect, useState } from 'react'
|
|
3
|
+
import { animatedImage } from '../assets/images'
|
|
4
|
+
|
|
5
|
+
const style = {
|
|
6
|
+
position: 'absolute' as 'absolute',
|
|
7
|
+
top: '50%',
|
|
8
|
+
left: '50%',
|
|
9
|
+
transform: 'translate(-50%, -50%)',
|
|
10
|
+
bgcolor: 'background.paper',
|
|
11
|
+
boxShadow: 24,
|
|
12
|
+
width: '700px',
|
|
13
|
+
borderRadius: '10px',
|
|
14
|
+
display: 'flex',
|
|
15
|
+
gap: '15px',
|
|
16
|
+
flexDirection: 'column',
|
|
17
|
+
padding: '20px',
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const StyledImage = styled(Box)(({ theme }) => ({
|
|
21
|
+
width: '154px',
|
|
22
|
+
margin: 'auto',
|
|
23
|
+
'> img': {
|
|
24
|
+
width: '100%',
|
|
25
|
+
height: '120px',
|
|
26
|
+
objectFit: 'contain',
|
|
27
|
+
},
|
|
28
|
+
}))
|
|
29
|
+
|
|
30
|
+
const MessageContainer = styled(Box)(({ theme }) => ({
|
|
31
|
+
maxHeight: '60vh',
|
|
32
|
+
padding: '15px',
|
|
33
|
+
overflowY: 'auto',
|
|
34
|
+
'&::-webkit-scrollbar': {
|
|
35
|
+
width: '0.5em',
|
|
36
|
+
height: '0.5em',
|
|
37
|
+
},
|
|
38
|
+
'&::-webkit-scrollbar-thumb': {
|
|
39
|
+
backgroundColor: 'rgba(0, 0, 0, 0.15)',
|
|
40
|
+
borderRadius: '3px',
|
|
41
|
+
'&:hover': {
|
|
42
|
+
background: 'rgba(0, 0, 0, 0.2)',
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
}))
|
|
46
|
+
|
|
47
|
+
export default function ErrorModal({
|
|
48
|
+
errorMessage,
|
|
49
|
+
...props
|
|
50
|
+
}: {
|
|
51
|
+
errorMessage: string
|
|
52
|
+
}) {
|
|
53
|
+
const [open, setOpen] = useState(false)
|
|
54
|
+
|
|
55
|
+
const handleClose = () => {
|
|
56
|
+
setOpen((prev) => !prev)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
useEffect(() => {
|
|
60
|
+
setOpen(true)
|
|
61
|
+
}, [])
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<Modal open={open} onClose={handleClose}>
|
|
65
|
+
<Box sx={style}>
|
|
66
|
+
<StyledImage>
|
|
67
|
+
<img src={animatedImage} alt="Error Image" />
|
|
68
|
+
</StyledImage>
|
|
69
|
+
|
|
70
|
+
<MessageContainer>
|
|
71
|
+
<Typography
|
|
72
|
+
variant="h6"
|
|
73
|
+
sx={{ textAlign: 'center', lineHeight: 1.7 }}
|
|
74
|
+
>
|
|
75
|
+
{errorMessage}
|
|
76
|
+
</Typography>
|
|
77
|
+
</MessageContainer>
|
|
78
|
+
<Button
|
|
79
|
+
variant="outlined"
|
|
80
|
+
onClick={handleClose}
|
|
81
|
+
sx={{ height: '40px', margin: 'auto', width: '200px' }}
|
|
82
|
+
>
|
|
83
|
+
OK
|
|
84
|
+
</Button>
|
|
85
|
+
</Box>
|
|
86
|
+
</Modal>
|
|
87
|
+
)
|
|
88
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Alert,
|
|
3
|
+
Box,
|
|
4
|
+
Button,
|
|
5
|
+
Modal,
|
|
6
|
+
Stack,
|
|
7
|
+
styled,
|
|
8
|
+
Typography,
|
|
9
|
+
} from '@mui/material'
|
|
10
|
+
import { animatedImage } from '../../assets/images'
|
|
11
|
+
|
|
12
|
+
const style = {
|
|
13
|
+
position: 'absolute' as 'absolute',
|
|
14
|
+
top: '50%',
|
|
15
|
+
left: '50%',
|
|
16
|
+
transform: 'translate(-50%, -50%)',
|
|
17
|
+
bgcolor: 'background.paper',
|
|
18
|
+
boxShadow: 24,
|
|
19
|
+
width: '700px',
|
|
20
|
+
borderRadius: '10px',
|
|
21
|
+
display: 'flex',
|
|
22
|
+
gap: '15px',
|
|
23
|
+
flexDirection: 'column',
|
|
24
|
+
padding: '35px',
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const StyledImage = styled(Box)(({ theme }) => ({
|
|
28
|
+
width: '154px',
|
|
29
|
+
margin: 'auto',
|
|
30
|
+
'> img': {
|
|
31
|
+
width: '100%',
|
|
32
|
+
height: '120px',
|
|
33
|
+
objectFit: 'contain',
|
|
34
|
+
},
|
|
35
|
+
}))
|
|
36
|
+
|
|
37
|
+
const MessageContainer = styled(Box)(({ theme }) => ({
|
|
38
|
+
maxHeight: '40vh',
|
|
39
|
+
overflowY: 'auto',
|
|
40
|
+
'&::-webkit-scrollbar': {
|
|
41
|
+
width: '0.5em',
|
|
42
|
+
height: '0.5em',
|
|
43
|
+
},
|
|
44
|
+
'&::-webkit-scrollbar-thumb': {
|
|
45
|
+
backgroundColor: 'rgba(0, 0, 0, 0.15)',
|
|
46
|
+
borderRadius: '3px',
|
|
47
|
+
'&:hover': {
|
|
48
|
+
background: 'rgba(0, 0, 0, 0.2)',
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
}))
|
|
52
|
+
|
|
53
|
+
export const StyledTableContainer = styled(Box)({
|
|
54
|
+
background: 'white',
|
|
55
|
+
borderRadius: '16px',
|
|
56
|
+
marginTop: '10px',
|
|
57
|
+
'& table thead tr': {
|
|
58
|
+
backgroundColor: '#efefef',
|
|
59
|
+
},
|
|
60
|
+
'& table tr th': {
|
|
61
|
+
border: '1px solid #bebebe',
|
|
62
|
+
padding: '2px 8px',
|
|
63
|
+
textAlign: 'center',
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
'& table td': {
|
|
67
|
+
border: '1px solid #bebebe',
|
|
68
|
+
padding: '5px 10px',
|
|
69
|
+
fontWeight: 900,
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
'& table': {
|
|
73
|
+
width: ' 100%',
|
|
74
|
+
borderCollapse: 'collapse',
|
|
75
|
+
},
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
export const ErrorModalTemplate = ({ handleClose, modal, setModal }) => {
|
|
79
|
+
return (
|
|
80
|
+
<Modal open={modal.open} onClose={handleClose}>
|
|
81
|
+
<Box sx={style}>
|
|
82
|
+
<StyledImage>
|
|
83
|
+
<img src={animatedImage} alt="Error Image" />
|
|
84
|
+
</StyledImage>
|
|
85
|
+
|
|
86
|
+
{modal.type == 'String' ? (
|
|
87
|
+
<MessageContainer>
|
|
88
|
+
<Typography
|
|
89
|
+
variant="h6"
|
|
90
|
+
sx={{ textAlign: 'center', lineHeight: 1.7 }}
|
|
91
|
+
dangerouslySetInnerHTML={{ __html: modal?.errorMessage }}
|
|
92
|
+
/>
|
|
93
|
+
</MessageContainer>
|
|
94
|
+
) : (
|
|
95
|
+
<>
|
|
96
|
+
<MessageContainer>
|
|
97
|
+
<Alert severity={'error'} sx={{ padding: '10px' }}>
|
|
98
|
+
Please resolve the below mentioned errors to proceed further
|
|
99
|
+
</Alert>
|
|
100
|
+
<StyledTableContainer
|
|
101
|
+
dangerouslySetInnerHTML={{ __html: modal?.errorMessage }}
|
|
102
|
+
/>
|
|
103
|
+
</MessageContainer>
|
|
104
|
+
</>
|
|
105
|
+
)}
|
|
106
|
+
|
|
107
|
+
{modal.content && modal.content({ close: handleClose })}
|
|
108
|
+
<Button
|
|
109
|
+
variant="outlined"
|
|
110
|
+
onClick={() => setModal({ ...modal, open: false })}
|
|
111
|
+
sx={{ height: '40px', margin: 'auto', width: '200px' }}
|
|
112
|
+
>
|
|
113
|
+
Close
|
|
114
|
+
</Button>
|
|
115
|
+
</Box>
|
|
116
|
+
</Modal>
|
|
117
|
+
)
|
|
118
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { createContext, useContext, useState } from 'react'
|
|
2
|
+
import { ErrorModalTemplate } from './ErrorModalTemplate'
|
|
3
|
+
|
|
4
|
+
interface IProps {
|
|
5
|
+
content?: ({ close }: { close: () => void }) => any
|
|
6
|
+
error?: any
|
|
7
|
+
fallBack?: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
type ContextType = (props: IProps) => void
|
|
11
|
+
|
|
12
|
+
const ErrorModalContext = createContext<ContextType>(null)
|
|
13
|
+
|
|
14
|
+
export default function ErrorModalProvider({ children }) {
|
|
15
|
+
const [modal, setModal] = useState({
|
|
16
|
+
open: false,
|
|
17
|
+
content: ({ close }) => null,
|
|
18
|
+
errorMessage: null,
|
|
19
|
+
type: 'String',
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
const handleClose = () => {
|
|
23
|
+
setModal({
|
|
24
|
+
...modal,
|
|
25
|
+
open: false,
|
|
26
|
+
})
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const convertMessageToTable = (message) => {
|
|
30
|
+
const tableRows = message.map((element, index) => {
|
|
31
|
+
return `<tr><td>${index + 1}</td><td>${element}</td></tr>`
|
|
32
|
+
})
|
|
33
|
+
return `<table>
|
|
34
|
+
<thead>
|
|
35
|
+
<tr><th>S No.</th><th>Message</th></tr>
|
|
36
|
+
</thead>
|
|
37
|
+
<tbody>
|
|
38
|
+
${tableRows.join('')}</tbody></table>`
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const showModal = (props) => {
|
|
42
|
+
const fallbackMessage = props.fallBack ?? 'Something went wrong.'
|
|
43
|
+
const type =
|
|
44
|
+
typeof props.error?.response?.data?.message !== 'string'
|
|
45
|
+
? 'Object'
|
|
46
|
+
: 'String'
|
|
47
|
+
const errorMessage =
|
|
48
|
+
typeof props.error?.response?.data?.message !== 'string'
|
|
49
|
+
? convertMessageToTable(props.error?.response?.data?.message) ??
|
|
50
|
+
fallbackMessage
|
|
51
|
+
: props.error?.response?.data?.message
|
|
52
|
+
|
|
53
|
+
setModal({
|
|
54
|
+
...modal,
|
|
55
|
+
open: true,
|
|
56
|
+
type: type,
|
|
57
|
+
content: props.content,
|
|
58
|
+
errorMessage: errorMessage,
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<ErrorModalContext.Provider value={showModal}>
|
|
64
|
+
{children}
|
|
65
|
+
<>
|
|
66
|
+
<ErrorModalTemplate
|
|
67
|
+
handleClose={handleClose}
|
|
68
|
+
modal={modal}
|
|
69
|
+
setModal={setModal}
|
|
70
|
+
/>
|
|
71
|
+
</>
|
|
72
|
+
</ErrorModalContext.Provider>
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export const useErrorModal = () => useContext(ErrorModalContext)
|
|
@@ -8,17 +8,19 @@ import { ITextFieldProps } from '../Input/TextField'
|
|
|
8
8
|
interface SearchBarProps {
|
|
9
9
|
onSearch: (v: string) => void
|
|
10
10
|
label?: ReactNode
|
|
11
|
-
textFieldProps?: ITextFieldProps
|
|
12
11
|
placeholder?: string
|
|
12
|
+
value?: string
|
|
13
|
+
textFieldProps?: ITextFieldProps
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
export default function SearchBar({
|
|
16
17
|
onSearch,
|
|
17
18
|
label,
|
|
18
19
|
placeholder = 'Search',
|
|
20
|
+
value,
|
|
19
21
|
...restProps
|
|
20
22
|
}: SearchBarProps) {
|
|
21
|
-
const [, setSearch] = useState('')
|
|
23
|
+
const [, setSearch] = useState(value || '')
|
|
22
24
|
|
|
23
25
|
const debouncedChangeHandler = useMemo(
|
|
24
26
|
() =>
|
|
@@ -34,6 +36,7 @@ export default function SearchBar({
|
|
|
34
36
|
label={label}
|
|
35
37
|
placeholder={placeholder}
|
|
36
38
|
onChange={debouncedChangeHandler}
|
|
39
|
+
defaultValue={value || ''}
|
|
37
40
|
InputProps={{
|
|
38
41
|
endAdornment: (
|
|
39
42
|
<InputAdornment position="end">
|
|
@@ -14,6 +14,7 @@ import { useMutation, useQueryClient } from 'react-query'
|
|
|
14
14
|
import { toast } from 'react-toastify'
|
|
15
15
|
import axios, { axiosErrorToast } from '../../config/axios'
|
|
16
16
|
import RenderForm, { RenderFormProps, generateYupSchema } from './RenderForm'
|
|
17
|
+
import { useErrorModal } from '../ErrorModalWrapper/ErrorModalWrapper'
|
|
17
18
|
|
|
18
19
|
const makePostRequest = async ({
|
|
19
20
|
endpoint,
|
|
@@ -59,6 +60,7 @@ export default function Form({
|
|
|
59
60
|
onCancel,
|
|
60
61
|
successToastMessage,
|
|
61
62
|
}: FormProps) {
|
|
63
|
+
const errorModal = useErrorModal()
|
|
62
64
|
const queryClient = useQueryClient()
|
|
63
65
|
const [error, setError] = useState<any>(null)
|
|
64
66
|
const { control, watch, handleSubmit } = useForm({
|
|
@@ -74,7 +76,8 @@ export default function Form({
|
|
|
74
76
|
},
|
|
75
77
|
onError(error: any) {
|
|
76
78
|
setError(error?.response?.data?.message)
|
|
77
|
-
axiosErrorToast(error)
|
|
79
|
+
// axiosErrorToast(error)
|
|
80
|
+
errorModal({ error: error })
|
|
78
81
|
},
|
|
79
82
|
})
|
|
80
83
|
|
|
@@ -30,6 +30,7 @@ export default function FormAutoCompleteSearch({
|
|
|
30
30
|
control,
|
|
31
31
|
name,
|
|
32
32
|
options,
|
|
33
|
+
onOpen,
|
|
33
34
|
label,
|
|
34
35
|
loading, // pass this variable when options are from an async operation
|
|
35
36
|
hookForm = true,
|
|
@@ -40,6 +41,7 @@ export default function FormAutoCompleteSearch({
|
|
|
40
41
|
if (!hookForm) {
|
|
41
42
|
return (
|
|
42
43
|
<Autocomplete
|
|
44
|
+
onOpen={onOpen}
|
|
43
45
|
multiple={multiple}
|
|
44
46
|
value={props.value}
|
|
45
47
|
fullWidth
|
|
@@ -69,6 +71,7 @@ export default function FormAutoCompleteSearch({
|
|
|
69
71
|
render={({ field, fieldState: { error } }) => (
|
|
70
72
|
<Box>
|
|
71
73
|
<Autocomplete
|
|
74
|
+
onOpen={onOpen}
|
|
72
75
|
multiple={multiple}
|
|
73
76
|
loading={loading}
|
|
74
77
|
value={field.value}
|