@campxdev/shared 1.10.11 → 1.10.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/package.json +1 -1
  2. package/src/assets/images/BackgroundImage.jpg +0 -0
  3. package/src/assets/images/BackgroundImg.png +0 -0
  4. package/src/assets/images/CoverBg.png +0 -0
  5. package/src/assets/images/PaperPublicationBg.png +0 -0
  6. package/src/components/IconButtons/Icons.tsx +33 -2
  7. package/src/components/Layout/Header/HeaderActions/UserBox.tsx +8 -1
  8. package/src/components/MyProfile/Education/Education.tsx +47 -0
  9. package/src/components/MyProfile/Education/EducationCard.tsx +62 -0
  10. package/src/components/MyProfile/Education/EducationForm.tsx +97 -0
  11. package/src/components/MyProfile/Education/Styles.tsx +27 -0
  12. package/src/components/MyProfile/Experience/Experience.tsx +47 -0
  13. package/src/components/MyProfile/Experience/ExperienceCard.tsx +63 -0
  14. package/src/components/MyProfile/Experience/ExperienceForm.tsx +107 -0
  15. package/src/components/MyProfile/Experience/Styles.tsx +27 -0
  16. package/src/components/MyProfile/FileUpload.tsx +69 -0
  17. package/src/components/MyProfile/MyProfile.tsx +166 -0
  18. package/src/components/MyProfile/NoDataSection.tsx +27 -0
  19. package/src/components/MyProfile/PaperPublication/Authors.tsx +88 -0
  20. package/src/components/MyProfile/PaperPublication/PaperPublications.tsx +52 -0
  21. package/src/components/MyProfile/PaperPublication/PublicationCard.tsx +80 -0
  22. package/src/components/MyProfile/PaperPublication/PublicationsForm.tsx +285 -0
  23. package/src/components/MyProfile/PaperPublication/Styles.tsx +51 -0
  24. package/src/components/MyProfile/StyledTabsContainer.tsx +53 -0
  25. package/src/components/MyProfile/Styles.tsx +115 -0
  26. package/src/components/MyProfile/Workshop/Styles.tsx +38 -0
  27. package/src/components/MyProfile/Workshop/Workshop.tsx +49 -0
  28. package/src/components/MyProfile/Workshop/WorkshopCard.tsx +64 -0
  29. package/src/components/MyProfile/Workshop/WorkshopData.tsx +36 -0
  30. package/src/components/MyProfile/Workshop/WorkshopForm.tsx +202 -0
  31. package/src/components/MyProfile/index.ts +1 -0
  32. package/src/components/MyProfile/service.ts +58 -0
  33. package/src/shared-state/PermissionsStore.ts +6 -6
@@ -0,0 +1,166 @@
1
+ /* eslint-disable no-console */
2
+ import { Box, Chip, Container, Typography } from '@mui/material'
3
+ import { useQuery } from 'react-query'
4
+ import { useNavigate } from 'react-router-dom'
5
+ import axios from '../../config/axios'
6
+ import PageHeader from '../PageHeader'
7
+ import Spinner from '../Spinner'
8
+ import Education from './Education/Education'
9
+ import Experience from './Experience/Experience'
10
+ import PaperPublications from './PaperPublication/PaperPublications'
11
+ import StyledTabsContainer from './StyledTabsContainer'
12
+ import {
13
+ StyledArrowIcon,
14
+ StyledAvatar,
15
+ StyledBox,
16
+ StyledBoxHeader,
17
+ StyledMainContainer,
18
+ } from './Styles'
19
+ import Workshop from './Workshop/Workshop'
20
+ const classroomSubjects = [
21
+ {
22
+ classroomSubjectId: 1,
23
+ subjectCode: 'M1',
24
+ classroomName: 'ECE A',
25
+ year: 2,
26
+ },
27
+ {
28
+ classroomSubjectId: 2,
29
+ subjectCode: 'AEM',
30
+ classroomName: 'ECE C',
31
+ year: 3,
32
+ },
33
+ ]
34
+ const MyProfile = () => {
35
+ const { data, isLoading } = useQuery('dashboard', () =>
36
+ axios.get('/square/users/dashboard').then((res) => res?.data),
37
+ )
38
+ const { data: userProfile } = useQuery('user-profile', () =>
39
+ axios.get('/square/users/profile').then((res) => res?.data),
40
+ )
41
+ // const { data: classroomSubjects } = useQuery('classroom-subjects', () =>
42
+ // axios.get('/square/subjects/faculty').then((res) => res?.data),
43
+ // )
44
+ const navigate = useNavigate()
45
+
46
+ const handleHomeClick = () => {
47
+ navigate('/')
48
+ }
49
+
50
+ if (isLoading) {
51
+ return <Spinner />
52
+ }
53
+ const tabs = [
54
+ {
55
+ key: 'Experience',
56
+ label: 'Experience',
57
+ component: <Experience experiences={data?.experiences} />,
58
+ },
59
+ {
60
+ key: 'Paper Publications',
61
+ label: 'Paper Publications',
62
+ component: (
63
+ <PaperPublications
64
+ paperPublications={data?.papers}
65
+ userProfile={userProfile}
66
+ />
67
+ ),
68
+ },
69
+ {
70
+ key: 'Workshop',
71
+ label: 'Workshop',
72
+ component: <Workshop workshops={data?.workshops} />,
73
+ },
74
+ {
75
+ key: 'education',
76
+ label: 'Education',
77
+ component: <Education educations={data?.educations} />,
78
+ },
79
+ ]
80
+ function Years(num) {
81
+ switch (num) {
82
+ case 1:
83
+ return '1st'
84
+ case 2:
85
+ return '2nd'
86
+ case 3:
87
+ return '3rd'
88
+ case 4:
89
+ return '4th'
90
+ default:
91
+ ''
92
+ }
93
+ }
94
+
95
+ return (
96
+ <>
97
+ <StyledBox />
98
+ <PageHeader
99
+ title={
100
+ <>
101
+ <StyledArrowIcon onClick={handleHomeClick} />
102
+ <Typography variant="h1" color="white">
103
+ My Profile
104
+ </Typography>
105
+ </>
106
+ }
107
+ />
108
+ <Container maxWidth="lg">
109
+ <Box>
110
+ <StyledBoxHeader>
111
+ <Box sx={{ flex: 1 }}>
112
+ <Box
113
+ sx={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}
114
+ >
115
+ {/* <Image
116
+ alt=""
117
+ radius={'10px'}
118
+ src={BackgroundImg}
119
+ width={'160px'}
120
+ height={'160px'}
121
+ fit={'cover'}
122
+ /> */}
123
+ <StyledAvatar>
124
+ <Typography
125
+ sx={{
126
+ fontSize: '50px',
127
+ color: 'blue',
128
+ }}
129
+ >
130
+ {userProfile?.fullName[0].toUpperCase()}
131
+ </Typography>
132
+ </StyledAvatar>
133
+ <Typography variant="h1">{userProfile?.fullName}</Typography>
134
+ <Typography variant="h4">
135
+ {userProfile?.designation?.name} | Dept. of{' '}
136
+ {userProfile?.department?.name}
137
+ </Typography>
138
+ </Box>
139
+ </Box>
140
+ <Box>
141
+ {classroomSubjects?.map((classroomSubject) => (
142
+ <Chip
143
+ key={classroomSubject.classroomSubjectId}
144
+ label={`${classroomSubject?.subjectCode} - ${
145
+ classroomSubject.classroomName
146
+ }, ${Years(classroomSubject?.year)} year`}
147
+ sx={{
148
+ marginLeft: '1rem',
149
+ backgroundColor: '#149ECD1A',
150
+ fontWeight: 'bold',
151
+ }}
152
+ />
153
+ ))}
154
+ </Box>
155
+ </StyledBoxHeader>
156
+ </Box>
157
+
158
+ <StyledMainContainer>
159
+ <StyledTabsContainer tabs={tabs} centered />
160
+ </StyledMainContainer>
161
+ </Container>
162
+ </>
163
+ )
164
+ }
165
+
166
+ export default MyProfile
@@ -0,0 +1,27 @@
1
+ import { Typography } from '@mui/material'
2
+ import ActionButton from '../ActionButton'
3
+ import { DrawerButton } from '../ModalButtons'
4
+ import { StyledSubContainer } from './Styles'
5
+
6
+ const NoDataSection = ({
7
+ title,
8
+ subtitle,
9
+ addButtonTitle,
10
+ addButtonContent,
11
+ }) => {
12
+ return (
13
+ <StyledSubContainer>
14
+ <Typography variant="h3">{title}</Typography>
15
+ <Typography variant="subtitle1">{subtitle}</Typography>
16
+ <DrawerButton
17
+ anchor={({ open }) => (
18
+ <ActionButton onClick={open}>{addButtonTitle}</ActionButton>
19
+ )}
20
+ content={addButtonContent}
21
+ title={addButtonTitle}
22
+ />
23
+ </StyledSubContainer>
24
+ )
25
+ }
26
+
27
+ export default NoDataSection
@@ -0,0 +1,88 @@
1
+ /* eslint-disable react/jsx-key */
2
+ import { Box, Button } from '@mui/material'
3
+ import { useFieldArray } from 'react-hook-form'
4
+ import { FormTextField } from '../../HookForm'
5
+ import { RadioGroup } from '../../Input'
6
+ import { StyledBox, StyledDeleteButton, StyledStack } from './Styles'
7
+
8
+ const Authors = ({ control, selectedAuthor, setState, authorsSelect }) => {
9
+ const { fields, append, remove } = useFieldArray({
10
+ control,
11
+ name: 'authors',
12
+ })
13
+
14
+ return (
15
+ <Box>
16
+ <RadioGroup
17
+ row
18
+ label="Authors"
19
+ name="authors"
20
+ required
21
+ value={selectedAuthor}
22
+ options={authorsSelect.map((item) => ({
23
+ label: item?.label,
24
+ value: item?.value,
25
+ }))}
26
+ onChange={(e) => {
27
+ setState((s) => {
28
+ s.selectedAuthor = e.target.value
29
+ })
30
+ }}
31
+ />
32
+ {selectedAuthor === 'multipleAuthors' && (
33
+ <Box>
34
+ {!fields.length && (
35
+ <StyledBox>
36
+ <Button
37
+ variant="text"
38
+ color="primary"
39
+ size="small"
40
+ onClick={() => {
41
+ append({ name: '' })
42
+ }}
43
+ >
44
+ Add Author
45
+ </Button>
46
+ </StyledBox>
47
+ )}
48
+
49
+ {fields && (
50
+ <>
51
+ <StyledBox>
52
+ <Button
53
+ variant="text"
54
+ color="primary"
55
+ size="small"
56
+ onClick={() => {
57
+ append({ name: '' })
58
+ }}
59
+ >
60
+ Add Author
61
+ </Button>
62
+ </StyledBox>
63
+ {fields.map((author, index) => (
64
+ <StyledStack
65
+ direction={'row'}
66
+ gap={2}
67
+ sx={{ alignItems: 'flex-end' }}
68
+ >
69
+ <FormTextField
70
+ control={control}
71
+ name={`authors[${index}].name`}
72
+ label="Details about Authors"
73
+ required
74
+ />
75
+ {index > 0 && (
76
+ <StyledDeleteButton onClick={() => remove(index)} />
77
+ )}
78
+ </StyledStack>
79
+ ))}
80
+ </>
81
+ )}
82
+ </Box>
83
+ )}
84
+ </Box>
85
+ )
86
+ }
87
+
88
+ export default Authors
@@ -0,0 +1,52 @@
1
+ /* eslint-disable no-console */
2
+ /* eslint-disable react/jsx-key */
3
+ import { Typography } from '@mui/material'
4
+ import ActionButton from '../../ActionButton'
5
+ import { DrawerButton } from '../../ModalButtons'
6
+ import NoDataSection from '../NoDataSection'
7
+ import PublicationCard from './PublicationCard'
8
+ import { PublicationsForm } from './PublicationsForm'
9
+ import { StyledBoxCard, StyledBoxContainer } from './Styles'
10
+
11
+ const Experience = ({ paperPublications, userProfile }) => {
12
+ const isPaperPublication = paperPublications && paperPublications.length > 0
13
+
14
+ return isPaperPublication ? (
15
+ <>
16
+ <StyledBoxContainer>
17
+ <Typography variant="h3">Paper Publications</Typography>
18
+ <DrawerButton
19
+ anchor={({ open }) => (
20
+ <ActionButton onClick={open} variant="text">
21
+ +Add Paper Publication
22
+ </ActionButton>
23
+ )}
24
+ content={({ close }) => (
25
+ <PublicationsForm
26
+ data={null}
27
+ hideDialog={close}
28
+ userProfile={userProfile}
29
+ />
30
+ )}
31
+ title="Add Paper Publication"
32
+ />
33
+ </StyledBoxContainer>
34
+ <StyledBoxCard>
35
+ {paperPublications.map((data) => (
36
+ <PublicationCard data={data} userProfile={userProfile} />
37
+ ))}
38
+ </StyledBoxCard>
39
+ </>
40
+ ) : (
41
+ <NoDataSection
42
+ title="Paper Publication"
43
+ subtitle="Add Paper Publication"
44
+ addButtonTitle="Add Publication"
45
+ addButtonContent={({ close }) => (
46
+ <PublicationsForm data={null} hideDialog={close} />
47
+ )}
48
+ />
49
+ )
50
+ }
51
+
52
+ export default Experience
@@ -0,0 +1,80 @@
1
+ import { Box, Card, Typography } from '@mui/material'
2
+ import { EditButton } from '../../IconButtons'
3
+ import Image from '../../Image/Image'
4
+ import { DrawerButton } from '../../ModalButtons'
5
+ import PublicationsForm from './PublicationsForm'
6
+ import { StyledAvatar, StyledTextContainer } from './Styles'
7
+
8
+ const PublicationCard = ({ userProfile, data }) => {
9
+ return (
10
+ <div>
11
+ <Card
12
+ sx={{
13
+ padding: '15px',
14
+ }}
15
+ >
16
+ <Box
17
+ sx={{
18
+ display: 'flex',
19
+ justifyContent: 'space-between',
20
+ }}
21
+ >
22
+ <Box
23
+ sx={{
24
+ display: 'flex',
25
+ }}
26
+ >
27
+ {data?.image?.url ? (
28
+ <Image
29
+ alt=""
30
+ radius={'10px'}
31
+ src={data?.image?.url}
32
+ width={'100px'}
33
+ height={'100px'}
34
+ fit={'cover'}
35
+ />
36
+ ) : (
37
+ <StyledAvatar>
38
+ <Typography
39
+ sx={{
40
+ fontSize: '30px',
41
+ color: 'blue',
42
+ }}
43
+ >
44
+ {data?.title[0].toUpperCase()}
45
+ </Typography>
46
+ </StyledAvatar>
47
+ )}
48
+ <StyledTextContainer>
49
+ <Typography variant="h5">{data?.title}</Typography>
50
+ <Typography variant="subtitle2">
51
+ {data?.publicationType}{' '}
52
+ {data?.publicationSubtype !== 'other' &&
53
+ ` - ${data?.publicationSubtype}`}
54
+ </Typography>
55
+ <Typography variant="subtitle1">
56
+ Year of Publication: {data?.publicationYear}
57
+ </Typography>
58
+ </StyledTextContainer>
59
+ </Box>
60
+ <Box>
61
+ <DrawerButton
62
+ key={data?.id}
63
+ title={'Edit Paper Publication'}
64
+ anchor={({ open }) => <EditButton onClick={open} />}
65
+ content={({ close }) => (
66
+ <PublicationsForm
67
+ data={data}
68
+ hideDialog={close}
69
+ userProfile={userProfile}
70
+ />
71
+ )}
72
+ />
73
+ </Box>
74
+ </Box>
75
+ </Card>
76
+ </div>
77
+ )
78
+ }
79
+
80
+ export default PublicationCard
@@ -0,0 +1,285 @@
1
+ /* eslint-disable no-console */
2
+ import { yupResolver } from '@hookform/resolvers/yup'
3
+ import { Stack, Typography } from '@mui/material'
4
+ import { useEffect, useState } from 'react'
5
+ import { useForm } from 'react-hook-form'
6
+ import { useMutation, useQuery } from 'react-query'
7
+ import { toast } from 'react-toastify'
8
+ import { useImmer } from 'use-immer'
9
+ import * as yup from 'yup'
10
+ import axios, { axiosErrorToast } from '../../../config/axios'
11
+ import { queryClient } from '../../../contexts/QueryClientProvider'
12
+ import ActionButton from '../../ActionButton'
13
+ import { FormSingleSelect, FormTextField } from '../../HookForm'
14
+ import ImageUpload from '../../ImageUpload'
15
+ import MediaRow from '../../MediaRow/MediaRow'
16
+ import { Media } from '../../UploadButton/types'
17
+ import FileUpload from '../FileUpload'
18
+ import {
19
+ createUpdatePaperPublicaton,
20
+ getPaperPublicationSubtypes,
21
+ } from '../service'
22
+ import Authors from './Authors'
23
+ const authorsSelect = [
24
+ {
25
+ label: 'Single Author',
26
+ value: 'singleAuthor',
27
+ },
28
+ {
29
+ label: 'Multiple Authors',
30
+ value: 'multipleAuthors',
31
+ },
32
+ ]
33
+
34
+ const schema = yup.object().shape({
35
+ title: yup.string().required('Title is required'),
36
+ publicationType: yup.string().required('Publication Type is required'),
37
+ publicationYear: yup.number().required('Year of Publication is required'),
38
+ stream: yup.string().required('Stream is required'),
39
+ program: yup.string().required('Program is required'),
40
+ })
41
+
42
+ export const PublicationsForm = ({ data, hideDialog, userProfile = null }) => {
43
+ const { control, handleSubmit, watch, setValue } = useForm({
44
+ resolver: yupResolver(schema),
45
+ defaultValues: {
46
+ ...data,
47
+ authors: [{ name: userProfile?.fullName || '' }],
48
+ },
49
+ })
50
+
51
+ const [media, setMedia] = useState<Media[]>([])
52
+ const [state, setState] = useImmer({
53
+ resource: data?.attachments || [],
54
+ selectedAuthor: 'singleAuthor',
55
+ publicationSubtypes: [],
56
+ })
57
+ const { resource, selectedAuthor, publicationSubtypes } = state
58
+
59
+ const { data: paperPublicationTypes } = useQuery(
60
+ 'paper-publication-type',
61
+ () =>
62
+ axios.get('/square/paper-publications/types').then((res) => res?.data),
63
+ {
64
+ onSuccess: (res) => {
65
+ const isOthersCheck = res.includes(data?.publicationType)
66
+ setValue(
67
+ 'publicationType',
68
+ isOthersCheck ? data?.publicationType : 'Other',
69
+ )
70
+
71
+ setValue(
72
+ 'publicationOtherType',
73
+ isOthersCheck ? '' : data?.publicationType,
74
+ )
75
+ },
76
+ },
77
+ )
78
+
79
+ const { mutate: fetchPublicationSubtypes } = useMutation(
80
+ getPaperPublicationSubtypes,
81
+ {
82
+ onSuccess: (data) => {
83
+ setState((s) => {
84
+ s.publicationSubtypes = data
85
+ })
86
+ },
87
+ },
88
+ )
89
+ const { mutate, isLoading } = useMutation(createUpdatePaperPublicaton, {
90
+ onSuccess: () => {
91
+ toast.success(data ? 'Publication Updated' : 'Publication Added')
92
+ queryClient.invalidateQueries('dashboard')
93
+ hideDialog()
94
+ },
95
+ onError: (err) => {
96
+ console.log(err)
97
+ axiosErrorToast(err)
98
+ },
99
+ })
100
+
101
+ useEffect(() => {
102
+ fetchPublicationSubtypes(watch('publicationType'))
103
+ data && data?.image?.key
104
+ ? setMedia([
105
+ {
106
+ key: data?.image?.key,
107
+ url: data?.image?.url,
108
+ type: data?.image?.mediaType,
109
+ },
110
+ ])
111
+ : setMedia([])
112
+
113
+ setState((s) => {
114
+ s.selectedAuthor =
115
+ data?.authors?.length > 1 ? 'multipleAuthors' : 'singleAuthor'
116
+ })
117
+
118
+ setValue(
119
+ 'authors',
120
+ data?.authors?.map((author) => ({ name: author })),
121
+ )
122
+ }, [data, setValue])
123
+
124
+ const onSubmit = (formData) => {
125
+ console.log(formData, 'formDaa')
126
+ const isOthers = formData.publicationType === 'Other'
127
+ const postBody = {
128
+ ...formData,
129
+ authors:
130
+ selectedAuthor === 'singleAuthor'
131
+ ? [userProfile?.fullName]
132
+ : formData?.authors?.map((author) => author?.name),
133
+ publicationType: isOthers
134
+ ? formData.publicationOtherType
135
+ : formData.publicationType,
136
+ publicationSubtype: isOthers ? 'other' : formData.publicationSubtype,
137
+ image: media[0]?.key || null,
138
+ attachments: state.resource.map((file) => file.key),
139
+ }
140
+ console.log(postBody, 'postBody')
141
+ mutate(postBody)
142
+ }
143
+
144
+ const onError = (error) => {
145
+ console.log(error)
146
+ }
147
+
148
+ const handleImageChange = (v) => {
149
+ setMedia([{ type: 'image', url: v.url, key: v.key }])
150
+ }
151
+
152
+ const handleDeleteImage = (key) => {
153
+ setMedia((prev) => prev.filter((m) => m.key !== key))
154
+ }
155
+
156
+ const handleFileInput = (e) => {
157
+ let filesData = e.target.files
158
+ let fileArray = Object.keys(filesData)
159
+ fileArray.forEach(async (file) => {
160
+ const fileData = new FormData()
161
+ fileData.append('file', filesData[file])
162
+ const originalFileName = filesData[file].name
163
+
164
+ try {
165
+ let fileKey = await axios.post(
166
+ `/square/paper-publications/attachment`,
167
+ fileData,
168
+ )
169
+ setState((s) => {
170
+ s.resource.push({
171
+ originalFileName: originalFileName,
172
+ key: fileKey?.data?.key,
173
+ })
174
+ })
175
+ } catch (error) {
176
+ console.log(error)
177
+ }
178
+ })
179
+ }
180
+
181
+ const onDelete = (fileKey) => {
182
+ setState((s) => {
183
+ s.resource = resource.filter((item) => item.key !== fileKey)
184
+ })
185
+ }
186
+
187
+ return (
188
+ <form onSubmit={handleSubmit(onSubmit, onError)}>
189
+ <Stack gap={2.5}>
190
+ <>
191
+ {!media.length ? (
192
+ <ImageUpload
193
+ key={media.length}
194
+ onFileUploaded={handleImageChange}
195
+ postUrl="/square/paper-publications/image"
196
+ />
197
+ ) : (
198
+ <MediaRow list={media} onDelete={handleDeleteImage} />
199
+ )}
200
+ <FormTextField
201
+ control={control}
202
+ name="title"
203
+ label="Title"
204
+ required
205
+ />
206
+
207
+ <Authors
208
+ control={control}
209
+ selectedAuthor={selectedAuthor}
210
+ setState={setState}
211
+ authorsSelect={authorsSelect}
212
+ />
213
+
214
+ <Typography variant="h5">{userProfile?.fullName}</Typography>
215
+ <FormSingleSelect
216
+ name="publicationType"
217
+ label="Publication Type"
218
+ control={control}
219
+ options={paperPublicationTypes?.map((item) => ({
220
+ value: item,
221
+ label: item,
222
+ }))}
223
+ required
224
+ onChange={(e) => {
225
+ setValue('publicationType', e.target.value)
226
+ fetchPublicationSubtypes(e.target.value)
227
+ }}
228
+ />
229
+ {watch('publicationType') === 'Other' ? (
230
+ <FormTextField
231
+ name="publicationOtherType"
232
+ label="Publication Type Name"
233
+ control={control}
234
+ required
235
+ />
236
+ ) : (
237
+ <FormSingleSelect
238
+ name="publicationSubtype"
239
+ label="Sub Type"
240
+ control={control}
241
+ options={publicationSubtypes?.map((item) => ({
242
+ value: item,
243
+ label: item,
244
+ }))}
245
+ required
246
+ />
247
+ )}
248
+ <FormTextField
249
+ name="publicationYear"
250
+ label="Year of Publication"
251
+ control={control}
252
+ required
253
+ />
254
+ <FormTextField
255
+ name="stream"
256
+ label="Stream"
257
+ control={control}
258
+ required
259
+ />
260
+ <FormTextField
261
+ name="program"
262
+ label="Program"
263
+ control={control}
264
+ required
265
+ />
266
+ <FileUpload
267
+ handleFileInput={handleFileInput}
268
+ onDelete={onDelete}
269
+ resource={resource}
270
+ />
271
+ </>
272
+ </Stack>
273
+ <Stack direction="row" gap={2} mt={3}>
274
+ <ActionButton type="submit" fullWidth loading={isLoading}>
275
+ {data ? 'Edit' : 'Submit'}
276
+ </ActionButton>
277
+ <ActionButton variant="outlined" fullWidth onClick={() => hideDialog()}>
278
+ Cancel
279
+ </ActionButton>
280
+ </Stack>
281
+ </form>
282
+ )
283
+ }
284
+
285
+ export default PublicationsForm