@campxdev/shared 1.10.11 → 1.10.12
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 +1 -1
- package/src/assets/images/BackgroundImage.jpg +0 -0
- package/src/assets/images/BackgroundImg.png +0 -0
- package/src/assets/images/CoverBg.png +0 -0
- package/src/assets/images/PaperPublicationBg.png +0 -0
- package/src/components/IconButtons/Icons.tsx +33 -2
- package/src/components/Layout/Header/HeaderActions/UserBox.tsx +8 -1
- package/src/components/MyProfile/Education/Education.tsx +47 -0
- package/src/components/MyProfile/Education/EducationCard.tsx +62 -0
- package/src/components/MyProfile/Education/EducationForm.tsx +97 -0
- package/src/components/MyProfile/Education/Styles.tsx +27 -0
- package/src/components/MyProfile/Experience/Experience.tsx +47 -0
- package/src/components/MyProfile/Experience/ExperienceCard.tsx +63 -0
- package/src/components/MyProfile/Experience/ExperienceForm.tsx +107 -0
- package/src/components/MyProfile/Experience/Styles.tsx +27 -0
- package/src/components/MyProfile/FileUpload.tsx +69 -0
- package/src/components/MyProfile/MyProfile.tsx +166 -0
- package/src/components/MyProfile/NoDataSection.tsx +27 -0
- package/src/components/MyProfile/PaperPublication/Authors.tsx +88 -0
- package/src/components/MyProfile/PaperPublication/PaperPublications.tsx +52 -0
- package/src/components/MyProfile/PaperPublication/PublicationCard.tsx +80 -0
- package/src/components/MyProfile/PaperPublication/PublicationsForm.tsx +285 -0
- package/src/components/MyProfile/PaperPublication/Styles.tsx +51 -0
- package/src/components/MyProfile/StyledTabsContainer.tsx +53 -0
- package/src/components/MyProfile/Styles.tsx +115 -0
- package/src/components/MyProfile/Workshop/Styles.tsx +38 -0
- package/src/components/MyProfile/Workshop/Workshop.tsx +49 -0
- package/src/components/MyProfile/Workshop/WorkshopCard.tsx +64 -0
- package/src/components/MyProfile/Workshop/WorkshopData.tsx +36 -0
- package/src/components/MyProfile/Workshop/WorkshopForm.tsx +202 -0
- package/src/components/MyProfile/index.ts +1 -0
- package/src/components/MyProfile/service.ts +58 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { Box, Stack, styled } from '@mui/material'
|
|
2
|
+
import { DeleteButton } from '../../IconButtons'
|
|
3
|
+
|
|
4
|
+
export const StyledBox = styled(Box)({
|
|
5
|
+
display: 'flex',
|
|
6
|
+
justifyContent: 'flex-end',
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
export const StyledBoxContainer = styled(Box)({
|
|
10
|
+
display: 'flex',
|
|
11
|
+
justifyContent: 'space-between',
|
|
12
|
+
alignItems: 'center',
|
|
13
|
+
margin: '10px 5px',
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
export const StyledBoxCard = styled(Box)({
|
|
17
|
+
display: 'grid',
|
|
18
|
+
gridTemplateColumns: 'repeat(auto-fill, minmax(500px, 1fr))',
|
|
19
|
+
gap: '1rem',
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
export const StyledAvatar = styled(Box)({
|
|
23
|
+
width: '100px',
|
|
24
|
+
height: '100px',
|
|
25
|
+
borderRadius: '10px',
|
|
26
|
+
border: '1px solid #E5E5E5',
|
|
27
|
+
display: 'flex',
|
|
28
|
+
justifyContent: 'center',
|
|
29
|
+
alignItems: 'center',
|
|
30
|
+
backgroundColor: '#E5E5E5',
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
export const StyledTextContainer = styled(Box)({
|
|
34
|
+
marginTop: '8px',
|
|
35
|
+
marginLeft: '20px',
|
|
36
|
+
display: 'flex',
|
|
37
|
+
flexDirection: 'column',
|
|
38
|
+
justifyContent: 'center',
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
export const StyledDeleteButton = styled(DeleteButton)({
|
|
42
|
+
border: '1px solid #0000001A',
|
|
43
|
+
borderRadius: '10px',
|
|
44
|
+
width: '50px',
|
|
45
|
+
height: '50px',
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
export const StyledStack = styled(Stack)({
|
|
49
|
+
alignItems: 'center',
|
|
50
|
+
justifyContent: 'space-between',
|
|
51
|
+
})
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Tab } from '@mui/material'
|
|
2
|
+
import { ChangeEvent, ReactNode, useEffect, useState } from 'react'
|
|
3
|
+
import { StyledComponentWrapper, StyledTabs } from './Styles'
|
|
4
|
+
|
|
5
|
+
export interface TabsContainerProps {
|
|
6
|
+
tabs: {
|
|
7
|
+
key: string
|
|
8
|
+
label: string
|
|
9
|
+
component: ReactNode
|
|
10
|
+
}[]
|
|
11
|
+
size?: 'small' | 'medium'
|
|
12
|
+
onTabChange?: (tabKey: string) => void
|
|
13
|
+
centered: any
|
|
14
|
+
textColor?: any
|
|
15
|
+
indicatorBackgroundColor?: any
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export default function StyledTabsContainer({
|
|
19
|
+
tabs,
|
|
20
|
+
onTabChange,
|
|
21
|
+
textColor,
|
|
22
|
+
indicatorBackgroundColor,
|
|
23
|
+
}: TabsContainerProps) {
|
|
24
|
+
const [currentTab, setCurrentTab] = useState(tabs[0].key)
|
|
25
|
+
|
|
26
|
+
const handleTabsChange = (_event: ChangeEvent<{}>, value: string): void => {
|
|
27
|
+
setCurrentTab(value)
|
|
28
|
+
onTabChange && onTabChange(value)
|
|
29
|
+
}
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
setCurrentTab(tabs[0].key)
|
|
32
|
+
}, [])
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<>
|
|
36
|
+
<StyledTabs
|
|
37
|
+
onChange={handleTabsChange}
|
|
38
|
+
value={currentTab}
|
|
39
|
+
size="small"
|
|
40
|
+
centered
|
|
41
|
+
textColor={textColor}
|
|
42
|
+
indicatorBackgroundColor={indicatorBackgroundColor}
|
|
43
|
+
>
|
|
44
|
+
{tabs.map((tab) => (
|
|
45
|
+
<Tab key={tab.key} label={tab.label} value={tab.key} />
|
|
46
|
+
))}
|
|
47
|
+
</StyledTabs>
|
|
48
|
+
<StyledComponentWrapper>
|
|
49
|
+
{tabs.find((tab) => tab.key === currentTab)?.component}
|
|
50
|
+
</StyledComponentWrapper>
|
|
51
|
+
</>
|
|
52
|
+
)
|
|
53
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { KeyboardArrowLeft } from '@mui/icons-material'
|
|
2
|
+
import { Avatar, Box, FormLabel, Tabs, styled } from '@mui/material'
|
|
3
|
+
import CoverBg from '../../assets/images/CoverBg.png'
|
|
4
|
+
|
|
5
|
+
export const StyledSubContainer = styled(Box)(({ theme }) => ({
|
|
6
|
+
display: 'flex',
|
|
7
|
+
flexDirection: 'column',
|
|
8
|
+
alignItems: 'center',
|
|
9
|
+
justifyContent: 'center',
|
|
10
|
+
gap: '5px',
|
|
11
|
+
height: '50vh',
|
|
12
|
+
}))
|
|
13
|
+
export const StyledArrowIcon = styled(KeyboardArrowLeft)({
|
|
14
|
+
marginRight: '8px',
|
|
15
|
+
width: '2rem',
|
|
16
|
+
height: '25px',
|
|
17
|
+
cursor: 'pointer',
|
|
18
|
+
color: 'white',
|
|
19
|
+
})
|
|
20
|
+
export const StyledMainContainer = styled(Box)(({ theme }) => ({
|
|
21
|
+
minHeight: '70vh',
|
|
22
|
+
height: 'auto',
|
|
23
|
+
marginTop: '25px',
|
|
24
|
+
overflowY: 'hidden',
|
|
25
|
+
border: theme.borders.grayLight,
|
|
26
|
+
borderRadius: '10px',
|
|
27
|
+
'& .MuiTabs-root': {
|
|
28
|
+
backgroundColor: 'white',
|
|
29
|
+
borderBottom: theme.borders.grayLight,
|
|
30
|
+
'& .MuiTab-root': {
|
|
31
|
+
padding: '0 20px',
|
|
32
|
+
paddingBottom: '8px',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
}))
|
|
36
|
+
export const StyledTabs = styled(Tabs)<{
|
|
37
|
+
size: 'small' | 'medium'
|
|
38
|
+
indicatorBackgroundColor?: string
|
|
39
|
+
textColor?: string
|
|
40
|
+
}>(({ theme, size, indicatorBackgroundColor, textColor }) => ({
|
|
41
|
+
borderTopRightRadius: '10px',
|
|
42
|
+
borderTopLeftRadius: '10px',
|
|
43
|
+
background: theme.palette.secondary.light,
|
|
44
|
+
minHeight: '60px',
|
|
45
|
+
paddingLeft: '15px',
|
|
46
|
+
'& .MuiTabs-flexContainer': {
|
|
47
|
+
height: '100%',
|
|
48
|
+
alignItems: 'end',
|
|
49
|
+
},
|
|
50
|
+
'& .MuiTabs-indicator': {
|
|
51
|
+
backgroundColor: indicatorBackgroundColor || theme.palette.common.yellow,
|
|
52
|
+
},
|
|
53
|
+
'& .MuiTab-root.Mui-selected': {
|
|
54
|
+
color: textColor || theme.palette.secondary.main,
|
|
55
|
+
},
|
|
56
|
+
'& .MuiTab-root': {
|
|
57
|
+
textTransform: 'none',
|
|
58
|
+
transition: 'color 0.2s ease-in-out',
|
|
59
|
+
padding: '5px 15px',
|
|
60
|
+
paddingBottom: '8px',
|
|
61
|
+
minHeight: 0,
|
|
62
|
+
fontSize: size === 'medium' ? '16px' : '14px',
|
|
63
|
+
fontWeight: '600',
|
|
64
|
+
},
|
|
65
|
+
}))
|
|
66
|
+
|
|
67
|
+
export const StyledComponentWrapper = styled(Box)<{}>(({ theme }) => ({
|
|
68
|
+
padding: '15px',
|
|
69
|
+
height: '100%',
|
|
70
|
+
}))
|
|
71
|
+
|
|
72
|
+
export const StyledUploadContainer = styled(FormLabel)({
|
|
73
|
+
border: '1px dashed #0000001A',
|
|
74
|
+
padding: '40px',
|
|
75
|
+
display: 'flex',
|
|
76
|
+
justifyContent: 'center',
|
|
77
|
+
alignItems: 'center',
|
|
78
|
+
borderRadius: '10px',
|
|
79
|
+
cursor: 'pointer',
|
|
80
|
+
'&:hover': {
|
|
81
|
+
backgroundColor: '#EFEFEF',
|
|
82
|
+
},
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
export const StyledUploadedFileContainer = styled(Box)({
|
|
86
|
+
border: '1px solid #1212121A',
|
|
87
|
+
borderRadius: '10px',
|
|
88
|
+
padding: '10px',
|
|
89
|
+
display: 'flex',
|
|
90
|
+
justifyContent: 'space-between',
|
|
91
|
+
alignItems: 'center',
|
|
92
|
+
margin: '10px 0px',
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
export const StyledBox = styled(Box)({
|
|
96
|
+
height: '200px',
|
|
97
|
+
width: '100%',
|
|
98
|
+
background: `url(${CoverBg})`,
|
|
99
|
+
position: 'absolute',
|
|
100
|
+
zIndex: -1,
|
|
101
|
+
})
|
|
102
|
+
|
|
103
|
+
export const StyledBoxHeader = styled(Box)({
|
|
104
|
+
display: 'flex',
|
|
105
|
+
justifyContent: 'space-between',
|
|
106
|
+
alignItems: 'flex-end',
|
|
107
|
+
marginTop: '1rem',
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
export const StyledAvatar = styled(Avatar)({
|
|
111
|
+
width: '160px',
|
|
112
|
+
height: '160px',
|
|
113
|
+
borderRadius: '10px',
|
|
114
|
+
backgroundColor: 'lightgrey',
|
|
115
|
+
})
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Box, styled } from '@mui/material'
|
|
2
|
+
|
|
3
|
+
export const StyledBox = styled(Box)({
|
|
4
|
+
display: 'flex',
|
|
5
|
+
justifyContent: 'space-between',
|
|
6
|
+
})
|
|
7
|
+
|
|
8
|
+
export const StyledBoxContainer = styled(Box)({
|
|
9
|
+
display: 'flex',
|
|
10
|
+
justifyContent: 'space-between',
|
|
11
|
+
alignItems: 'center',
|
|
12
|
+
margin: '10px 0',
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
export const StyledAvatar = styled(Box)({
|
|
16
|
+
width: '100px',
|
|
17
|
+
height: '100px',
|
|
18
|
+
borderRadius: '10px',
|
|
19
|
+
border: '1px solid #E5E5E5',
|
|
20
|
+
display: 'flex',
|
|
21
|
+
justifyContent: 'center',
|
|
22
|
+
alignItems: 'center',
|
|
23
|
+
backgroundColor: '#E5E5E5',
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
export const StyledTextContainer = styled(Box)({
|
|
27
|
+
marginTop: '8px',
|
|
28
|
+
marginLeft: '20px',
|
|
29
|
+
display: 'flex',
|
|
30
|
+
flexDirection: 'column',
|
|
31
|
+
justifyContent: 'center',
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
export const StyledBoxCard = styled(Box)({
|
|
35
|
+
display: 'grid',
|
|
36
|
+
gridTemplateColumns: 'repeat(auto-fill, minmax(500px, 1fr))',
|
|
37
|
+
gap: '1rem',
|
|
38
|
+
})
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import NoDataSection from '../NoDataSection'
|
|
2
|
+
import StyledTabsContainer from '../StyledTabsContainer'
|
|
3
|
+
import WorkshopData from './WorkshopData'
|
|
4
|
+
import { WorkshopForm } from './WorkshopForm'
|
|
5
|
+
|
|
6
|
+
const Workshop = ({ workshops }) => {
|
|
7
|
+
const attendedWorkshops = workshops?.filter((w) => !w.organized)
|
|
8
|
+
const organisedWorkshops = workshops?.filter((w) => w.organized)
|
|
9
|
+
|
|
10
|
+
const tabs = [
|
|
11
|
+
{
|
|
12
|
+
key: 'Attended',
|
|
13
|
+
label: 'Attended',
|
|
14
|
+
component: (
|
|
15
|
+
<WorkshopData title={'Attended'} workshop={attendedWorkshops} />
|
|
16
|
+
),
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
key: 'Organised',
|
|
20
|
+
label: 'Organised',
|
|
21
|
+
component: (
|
|
22
|
+
<WorkshopData title={'Organised'} workshop={organisedWorkshops} />
|
|
23
|
+
),
|
|
24
|
+
},
|
|
25
|
+
]
|
|
26
|
+
const isWorkshop = workshops && workshops?.length > 0
|
|
27
|
+
|
|
28
|
+
return isWorkshop ? (
|
|
29
|
+
<>
|
|
30
|
+
<StyledTabsContainer
|
|
31
|
+
tabs={tabs}
|
|
32
|
+
centered
|
|
33
|
+
textColor="primary"
|
|
34
|
+
indicatorBackgroundColor="primary"
|
|
35
|
+
/>
|
|
36
|
+
</>
|
|
37
|
+
) : (
|
|
38
|
+
<NoDataSection
|
|
39
|
+
title="Workshop"
|
|
40
|
+
subtitle="Add Workshop"
|
|
41
|
+
addButtonTitle="Add Your workshop"
|
|
42
|
+
addButtonContent={({ close }) => (
|
|
43
|
+
<WorkshopForm data={null} hideDialog={close} />
|
|
44
|
+
)}
|
|
45
|
+
/>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export default Workshop
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Box, Card, Typography } from '@mui/material'
|
|
2
|
+
import moment from 'moment'
|
|
3
|
+
import { EditButton } from '../../IconButtons'
|
|
4
|
+
import Image from '../../Image/Image'
|
|
5
|
+
import { DrawerButton } from '../../ModalButtons'
|
|
6
|
+
import { StyledAvatar, StyledBox, StyledTextContainer } from './Styles'
|
|
7
|
+
import { WorkshopForm } from './WorkshopForm'
|
|
8
|
+
|
|
9
|
+
const WorkshopCard = ({ data }) => {
|
|
10
|
+
return (
|
|
11
|
+
<div>
|
|
12
|
+
<Card
|
|
13
|
+
sx={{
|
|
14
|
+
padding: '15px',
|
|
15
|
+
}}
|
|
16
|
+
>
|
|
17
|
+
<StyledBox>
|
|
18
|
+
<Box
|
|
19
|
+
sx={{
|
|
20
|
+
display: 'flex',
|
|
21
|
+
}}
|
|
22
|
+
>
|
|
23
|
+
{data?.image?.url ? (
|
|
24
|
+
<Image
|
|
25
|
+
alt=""
|
|
26
|
+
radius={'10px'}
|
|
27
|
+
src={data?.image?.url}
|
|
28
|
+
width={'100px'}
|
|
29
|
+
height={'100px'}
|
|
30
|
+
fit={'cover'}
|
|
31
|
+
/>
|
|
32
|
+
) : (
|
|
33
|
+
<StyledAvatar>
|
|
34
|
+
<Typography sx={{ color: 'blue', fontSize: '30px' }}>
|
|
35
|
+
{data?.title[0].toUpperCase()}
|
|
36
|
+
</Typography>
|
|
37
|
+
</StyledAvatar>
|
|
38
|
+
)}
|
|
39
|
+
<StyledTextContainer>
|
|
40
|
+
<Typography variant="h5">{data?.title}</Typography>
|
|
41
|
+
<Typography variant="subtitle2">{data?.stream}</Typography>
|
|
42
|
+
<Typography variant="subtitle2">
|
|
43
|
+
{moment(data?.fromDate).format('DD MMM YYYY')} -{' '}
|
|
44
|
+
{moment(data?.toDate).format('DD MMM YYYY')}
|
|
45
|
+
</Typography>
|
|
46
|
+
</StyledTextContainer>
|
|
47
|
+
</Box>
|
|
48
|
+
<Box>
|
|
49
|
+
<DrawerButton
|
|
50
|
+
key={data?.id}
|
|
51
|
+
title={'Edit Workshop'}
|
|
52
|
+
anchor={({ open }) => <EditButton onClick={open} />}
|
|
53
|
+
content={({ close }) => (
|
|
54
|
+
<WorkshopForm data={data} hideDialog={close} />
|
|
55
|
+
)}
|
|
56
|
+
/>
|
|
57
|
+
</Box>
|
|
58
|
+
</StyledBox>
|
|
59
|
+
</Card>
|
|
60
|
+
</div>
|
|
61
|
+
)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export default WorkshopCard
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/* eslint-disable react/jsx-key */
|
|
2
|
+
|
|
3
|
+
import { Typography } from '@mui/material'
|
|
4
|
+
import ActionButton from '../../ActionButton'
|
|
5
|
+
import { DrawerButton } from '../../ModalButtons'
|
|
6
|
+
import { StyledBoxCard, StyledBoxContainer } from './Styles'
|
|
7
|
+
import WorkshopCard from './WorkshopCard'
|
|
8
|
+
import { WorkshopForm } from './WorkshopForm'
|
|
9
|
+
|
|
10
|
+
const WorkshopData = ({ title, workshop }) => {
|
|
11
|
+
return (
|
|
12
|
+
<>
|
|
13
|
+
<StyledBoxContainer>
|
|
14
|
+
<Typography variant="h3">Workshops - {title}</Typography>
|
|
15
|
+
<DrawerButton
|
|
16
|
+
anchor={({ open }) => (
|
|
17
|
+
<ActionButton onClick={open} variant="text">
|
|
18
|
+
+Add Workshop
|
|
19
|
+
</ActionButton>
|
|
20
|
+
)}
|
|
21
|
+
content={({ close }) => (
|
|
22
|
+
<WorkshopForm data={null} hideDialog={close} />
|
|
23
|
+
)}
|
|
24
|
+
title="Add Workshops"
|
|
25
|
+
/>
|
|
26
|
+
</StyledBoxContainer>
|
|
27
|
+
<StyledBoxCard>
|
|
28
|
+
{workshop.map((item) => (
|
|
29
|
+
<WorkshopCard data={item} />
|
|
30
|
+
))}
|
|
31
|
+
</StyledBoxCard>
|
|
32
|
+
</>
|
|
33
|
+
)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export default WorkshopData
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/* eslint-disable react/jsx-key */
|
|
2
|
+
/* eslint-disable no-console */
|
|
3
|
+
import { yupResolver } from '@hookform/resolvers/yup'
|
|
4
|
+
import { Stack } from '@mui/material'
|
|
5
|
+
import moment from 'moment'
|
|
6
|
+
import { useEffect, useState } from 'react'
|
|
7
|
+
import { useForm } from 'react-hook-form'
|
|
8
|
+
import { useMutation, useQueryClient } from 'react-query'
|
|
9
|
+
import { toast } from 'react-toastify'
|
|
10
|
+
import * as yup from 'yup'
|
|
11
|
+
import axios, { axiosErrorToast } from '../../../config/axios'
|
|
12
|
+
import ActionButton from '../../ActionButton'
|
|
13
|
+
import { FormDatePicker, FormTextField } from '../../HookForm'
|
|
14
|
+
import ImageUpload from '../../ImageUpload'
|
|
15
|
+
import { RadioGroup } from '../../Input'
|
|
16
|
+
import MediaRow from '../../MediaRow/MediaRow'
|
|
17
|
+
import { Media } from '../../UploadButton/types'
|
|
18
|
+
import FileUpload from '../FileUpload'
|
|
19
|
+
import { createUpdateWorkshop } from '../service'
|
|
20
|
+
const workshopsSelect = [
|
|
21
|
+
{
|
|
22
|
+
label: 'Attended',
|
|
23
|
+
value: 'attended',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
label: 'Organized',
|
|
27
|
+
value: 'organized',
|
|
28
|
+
},
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
const schema = yup.object().shape({
|
|
32
|
+
title: yup.string().required('Title is required'),
|
|
33
|
+
organization: yup.string().required('Organization is required'),
|
|
34
|
+
stream: yup.string().required('Stream is required'),
|
|
35
|
+
program: yup.string().required('Program is required'),
|
|
36
|
+
fromDate: yup.string().required('From Date is required'),
|
|
37
|
+
toDate: yup.string().required('To Date is required'),
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
export const WorkshopForm = ({ data, hideDialog }) => {
|
|
41
|
+
const [media, setMedia] = useState<Media[]>([])
|
|
42
|
+
|
|
43
|
+
const [selectedWorkshop, setSelectedWorkshop] = useState(
|
|
44
|
+
data && data?.organized ? 'organized' : 'attended',
|
|
45
|
+
)
|
|
46
|
+
const [resource, setResource] = useState(data?.attachments || [])
|
|
47
|
+
|
|
48
|
+
const queryClient = useQueryClient()
|
|
49
|
+
const { control, handleSubmit } = useForm({
|
|
50
|
+
resolver: yupResolver(schema),
|
|
51
|
+
defaultValues: {
|
|
52
|
+
...data,
|
|
53
|
+
fromDate: data ? moment(data.fromDate).toISOString() : '',
|
|
54
|
+
toDate: data ? moment(data.toDate).toISOString() : '',
|
|
55
|
+
image: [{ key: data?.image?.key, url: data?.image?.url }] ?? [],
|
|
56
|
+
},
|
|
57
|
+
})
|
|
58
|
+
const { mutate, isLoading } = useMutation(createUpdateWorkshop, {
|
|
59
|
+
onSuccess: () => {
|
|
60
|
+
toast.success(data ? 'Workshop Updated' : 'Workshop Added')
|
|
61
|
+
queryClient.invalidateQueries('dashboard')
|
|
62
|
+
hideDialog()
|
|
63
|
+
},
|
|
64
|
+
onError: (err) => {
|
|
65
|
+
console.log(err)
|
|
66
|
+
axiosErrorToast(err)
|
|
67
|
+
},
|
|
68
|
+
})
|
|
69
|
+
useEffect(() => {
|
|
70
|
+
data && data?.image?.url
|
|
71
|
+
? setMedia([
|
|
72
|
+
{
|
|
73
|
+
key: data?.image?.key,
|
|
74
|
+
url: data?.image?.url,
|
|
75
|
+
type: data?.image?.mediaType,
|
|
76
|
+
},
|
|
77
|
+
])
|
|
78
|
+
: setMedia([])
|
|
79
|
+
}, [data])
|
|
80
|
+
const onSubmit = (formData) => {
|
|
81
|
+
const postBody = {
|
|
82
|
+
...formData,
|
|
83
|
+
organized: selectedWorkshop === 'organized',
|
|
84
|
+
fromDate: moment(formData?.fromDate).format('YYYY-MM-DD'),
|
|
85
|
+
toDate: moment(formData.toDate).format('YYYY-MM-DD'),
|
|
86
|
+
image: media[0]?.key || null,
|
|
87
|
+
attachments: resource.map((file) => file.key),
|
|
88
|
+
}
|
|
89
|
+
mutate(postBody)
|
|
90
|
+
}
|
|
91
|
+
const onError = (error) => {
|
|
92
|
+
console.log(error)
|
|
93
|
+
}
|
|
94
|
+
const handleFileInput = (e) => {
|
|
95
|
+
let filesData = e.target.files
|
|
96
|
+
let fileArray = Object.keys(filesData)
|
|
97
|
+
fileArray.forEach(async (file) => {
|
|
98
|
+
const fileData = new FormData()
|
|
99
|
+
fileData.append('file', filesData[file])
|
|
100
|
+
const originalFileName = filesData[file].name
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
let fileKey = await axios.post(`/square/workshops/attachment`, fileData)
|
|
104
|
+
setResource([
|
|
105
|
+
...resource,
|
|
106
|
+
{
|
|
107
|
+
originalFileName: originalFileName,
|
|
108
|
+
key: fileKey?.data?.key,
|
|
109
|
+
},
|
|
110
|
+
])
|
|
111
|
+
} catch (error) {
|
|
112
|
+
console.log(error)
|
|
113
|
+
}
|
|
114
|
+
})
|
|
115
|
+
}
|
|
116
|
+
const onDelete = (fileKey) => {
|
|
117
|
+
setResource(resource?.filter((item) => item.key !== fileKey))
|
|
118
|
+
}
|
|
119
|
+
const handleImageChange = (v) => {
|
|
120
|
+
setMedia([{ type: 'image', url: v.url, key: v.key }])
|
|
121
|
+
}
|
|
122
|
+
const handleDeleteImage = (key) => {
|
|
123
|
+
setMedia((prev) => prev.filter((m) => m.key !== key))
|
|
124
|
+
}
|
|
125
|
+
return (
|
|
126
|
+
<form onSubmit={handleSubmit(onSubmit, onError)}>
|
|
127
|
+
<Stack gap={2.5}>
|
|
128
|
+
<>
|
|
129
|
+
{!media.length ? (
|
|
130
|
+
<ImageUpload
|
|
131
|
+
onFileUploaded={handleImageChange}
|
|
132
|
+
postUrl="/square/workshops/image"
|
|
133
|
+
/>
|
|
134
|
+
) : (
|
|
135
|
+
<MediaRow list={media} onDelete={handleDeleteImage} />
|
|
136
|
+
)}
|
|
137
|
+
<RadioGroup
|
|
138
|
+
row
|
|
139
|
+
label="Workshop"
|
|
140
|
+
name="organized"
|
|
141
|
+
required
|
|
142
|
+
value={selectedWorkshop}
|
|
143
|
+
options={workshopsSelect.map((item) => ({
|
|
144
|
+
label: item?.label,
|
|
145
|
+
value: item?.value,
|
|
146
|
+
}))}
|
|
147
|
+
onChange={(e) => setSelectedWorkshop(e.target.value)}
|
|
148
|
+
/>
|
|
149
|
+
<FormTextField
|
|
150
|
+
control={control}
|
|
151
|
+
name="title"
|
|
152
|
+
label="Title"
|
|
153
|
+
required
|
|
154
|
+
/>
|
|
155
|
+
<FormTextField
|
|
156
|
+
control={control}
|
|
157
|
+
name="organization"
|
|
158
|
+
label="Organization"
|
|
159
|
+
required
|
|
160
|
+
/>
|
|
161
|
+
<FormDatePicker
|
|
162
|
+
control={control}
|
|
163
|
+
name="fromDate"
|
|
164
|
+
label="From Date"
|
|
165
|
+
required
|
|
166
|
+
/>
|
|
167
|
+
<FormDatePicker
|
|
168
|
+
control={control}
|
|
169
|
+
name="toDate"
|
|
170
|
+
label="To Date"
|
|
171
|
+
required
|
|
172
|
+
/>
|
|
173
|
+
<FormTextField
|
|
174
|
+
control={control}
|
|
175
|
+
name="stream"
|
|
176
|
+
label="Stream"
|
|
177
|
+
required
|
|
178
|
+
/>
|
|
179
|
+
<FormTextField
|
|
180
|
+
control={control}
|
|
181
|
+
name="program"
|
|
182
|
+
label="Program"
|
|
183
|
+
required
|
|
184
|
+
/>
|
|
185
|
+
<FileUpload
|
|
186
|
+
handleFileInput={handleFileInput}
|
|
187
|
+
onDelete={onDelete}
|
|
188
|
+
resource={resource}
|
|
189
|
+
/>
|
|
190
|
+
</>
|
|
191
|
+
</Stack>
|
|
192
|
+
<Stack direction="row" gap={2} mt={2}>
|
|
193
|
+
<ActionButton type="submit" fullWidth loading={isLoading}>
|
|
194
|
+
{data ? 'Update Workshop' : 'Add Workshop'}
|
|
195
|
+
</ActionButton>
|
|
196
|
+
<ActionButton variant="outlined" fullWidth onClick={() => hideDialog()}>
|
|
197
|
+
Cancel
|
|
198
|
+
</ActionButton>
|
|
199
|
+
</Stack>
|
|
200
|
+
</form>
|
|
201
|
+
)
|
|
202
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from './MyProfile'
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { AxiosRequestConfig } from 'axios'
|
|
2
|
+
import axios from '../../config/axios'
|
|
3
|
+
|
|
4
|
+
export const createUpdateExperience = async ({ id, ...postBody }) => {
|
|
5
|
+
const config: AxiosRequestConfig = {
|
|
6
|
+
method: id ? 'PUT' : 'POST',
|
|
7
|
+
url: id ? `/square/experience/${id}` : '/square/experience',
|
|
8
|
+
data: postBody,
|
|
9
|
+
}
|
|
10
|
+
const res = await axios(config)
|
|
11
|
+
return res.data
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const createUpdatePaperPublicaton = async ({ id, ...postBody }) => {
|
|
15
|
+
const config: AxiosRequestConfig = {
|
|
16
|
+
method: id ? 'PUT' : 'POST',
|
|
17
|
+
url: id ? `/square/paper-publications/${id}` : '/square/paper-publications',
|
|
18
|
+
data: postBody,
|
|
19
|
+
}
|
|
20
|
+
const res = await axios(config)
|
|
21
|
+
return res.data
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const createUpdateEducation = async ({ id, ...postBody }) => {
|
|
25
|
+
const config: AxiosRequestConfig = {
|
|
26
|
+
method: id ? 'PUT' : 'POST',
|
|
27
|
+
url: id ? `/square/education/${id}` : '/square/education',
|
|
28
|
+
data: postBody,
|
|
29
|
+
}
|
|
30
|
+
const res = await axios(config)
|
|
31
|
+
return res.data
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export const createUpdateWorkshop = async ({ id, ...postBody }) => {
|
|
35
|
+
const config: AxiosRequestConfig = {
|
|
36
|
+
method: id ? 'PUT' : 'POST',
|
|
37
|
+
url: id ? `/square/workshops/${id}` : '/square/workshops',
|
|
38
|
+
data: postBody,
|
|
39
|
+
}
|
|
40
|
+
const res = await axios(config)
|
|
41
|
+
return res.data
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export const getPaperPublicationSubtypes = async (publicationType) => {
|
|
45
|
+
if (publicationType !== 'Other' && publicationType !== undefined) {
|
|
46
|
+
const config: AxiosRequestConfig = {
|
|
47
|
+
method: 'GET',
|
|
48
|
+
url: '/square/paper-publications/sub-types',
|
|
49
|
+
params: {
|
|
50
|
+
type: publicationType,
|
|
51
|
+
},
|
|
52
|
+
}
|
|
53
|
+
const res = await axios(config)
|
|
54
|
+
return res.data
|
|
55
|
+
} else {
|
|
56
|
+
return []
|
|
57
|
+
}
|
|
58
|
+
}
|