11import * as yup from 'yup' ;
22import { SponsorPayload , useGetAllSponsorTiers } from '../../../hooks/finance.hooks' ;
3+ import { useGetImageUrl } from '../../../hooks/onboarding.hook' ;
34import ErrorPage from '../../ErrorPage' ;
45import LoadingIndicator from '../../../components/LoadingIndicator' ;
56import { Control , Controller , FieldErrors , FieldValues , UseFormSetValue , useFieldArray , useWatch } from 'react-hook-form' ;
@@ -14,13 +15,18 @@ import {
1415 Checkbox ,
1516 Autocomplete ,
1617 TextField ,
17- Chip
18+ Chip ,
19+ Stack
1820} from '@mui/material' ;
21+ import FileUploadIcon from '@mui/icons-material/FileUpload' ;
22+ import ImageIcon from '@mui/icons-material/Image' ;
1923import ReactHookTextField from '../../../components/ReactHookTextField' ;
2024import { DatePicker } from '@mui/x-date-pickers' ;
2125import { useAllMembers } from '../../../hooks/users.hooks' ;
2226import React , { useEffect , useRef , useState } from 'react' ;
2327import { Box } from '@mui/system' ;
28+ import { useToast } from '../../../hooks/toasts.hooks' ;
29+ import { MAX_FILE_SIZE } from 'shared' ;
2430import { AddCircle } from '@mui/icons-material' ;
2531import AttachMoneyIcon from '@mui/icons-material/AttachMoney' ;
2632import SponsorTaskCard from './SponsorTaskCard' ;
@@ -31,6 +37,7 @@ interface SponsorFormProps {
3137 errors : FieldErrors < SponsorPayload > ;
3238 setValue : UseFormSetValue < SponsorPayload > ;
3339 defaultValues ?: Sponsor ;
40+ onLogoImageChange ?: ( file : File | null ) => void ;
3441}
3542
3643const getYears = ( startYear = 1950 ) => {
@@ -103,15 +110,25 @@ const sponsorSchema = yup.object().shape(
103110 done : yup . boolean ( ) . optional ( )
104111 } )
105112 )
106- . required ( 'Sponsor Tasks are Required' )
113+ . required ( 'Sponsor Tasks are Required' ) ,
114+ logoImageId : yup . string ( ) . trim ( ) . optional ( )
107115 } ,
108116 [ [ 'contactEmail' , 'contactPhone' ] ]
109117) ;
110118
111- export const SponsorForm : React . FC < SponsorFormProps > = ( { control, errors, setValue, defaultValues } : SponsorFormProps ) => {
119+ export const SponsorForm : React . FC < SponsorFormProps > = ( {
120+ control,
121+ errors,
122+ setValue,
123+ defaultValues,
124+ onLogoImageChange
125+ } : SponsorFormProps ) => {
112126 const yearsOptions = getYears ( ) ;
127+ const toast = useToast ( ) ;
113128
129+ const [ logoImage , setLogoImage ] = useState < File | null > ( null ) ;
114130 const [ datePickerOpenJoin , setDatePickerOpenJoin ] = useState ( false ) ;
131+ const { data : currentLogoUrl } = useGetImageUrl ( defaultValues ?. logoImageId ?? null ) ;
115132
116133 const { isLoading : membersLoading , isError : membersIsError , error : membersError , data : members } = useAllMembers ( ) ;
117134
@@ -444,6 +461,49 @@ export const SponsorForm: React.FC<SponsorFormProps> = ({ control, errors, setVa
444461 < FormHelperText error > { errors . discountCode ?. message } </ FormHelperText >
445462 </ FormControl >
446463 </ Grid >
464+ < Grid item xs = { 12 } sm = { 6 } >
465+ < FormControl fullWidth >
466+ < Typography variant = "h5" color = "#EF4345" >
467+ Sponsor Logo:
468+ </ Typography >
469+ < Box sx = { { display : 'flex' , flexDirection : 'row' , gap : 1 , alignItems : 'center' , mt : 1 } } >
470+ < Button
471+ variant = "contained"
472+ color = "error"
473+ component = "label"
474+ startIcon = { < FileUploadIcon /> }
475+ sx = { { width : 'fit-content' , textTransform : 'none' , color : 'black' } }
476+ >
477+ Upload Logo
478+ < input
479+ onChange = { ( e ) => {
480+ if ( e . target . files && e . target . files [ 0 ] ) {
481+ const [ file ] = e . target . files ;
482+ if ( file . size > MAX_FILE_SIZE ) {
483+ toast . error ( `File "${ file . name } " exceeds the maximum size limit of ${ MAX_FILE_SIZE / 1024 / 1024 } MB` ) ;
484+ return ;
485+ }
486+ setLogoImage ( file ) ;
487+ onLogoImageChange ?.( file ) ;
488+ }
489+ } }
490+ type = "file"
491+ accept = "image/png, image/jpeg"
492+ hidden
493+ />
494+ </ Button >
495+ { logoImage && (
496+ < Stack direction = "row" spacing = { 1 } alignItems = "center" >
497+ < ImageIcon />
498+ < Typography > { logoImage . name } </ Typography >
499+ </ Stack >
500+ ) }
501+ </ Box >
502+ { ! logoImage && currentLogoUrl && (
503+ < Box component = "img" src = { currentLogoUrl } alt = "Sponsor Logo" sx = { { maxWidth : '200px' , mt : 1 } } />
504+ ) }
505+ </ FormControl >
506+ </ Grid >
447507 < Grid item xs = { 12 } >
448508 < FormControl fullWidth >
449509 < Typography variant = "h5" color = "#EF4345" >
0 commit comments