@@ -25,10 +25,13 @@ import {
2525} from '@/components/ui/dialog' ;
2626import { Button } from '@/components/ui/button' ;
2727import { ImageIcon , BadgeAlert , PlusCircleIcon } from 'lucide-react' ;
28+ import { useToast } from '@/hooks/use-toast' ;
2829
2930import { Card } from '@/components/ui/card' ;
3031import { SubmissionForm } from '../hooks/useSubmissionFormSecure' ;
3132
33+ const MAX_FILE_SIZE_FOR_UPLOAD = 1 ; // Vercel's limit is 4.5MB, we use 4MB to be safe
34+
3235type MediaUploaderProps = {
3336 name : keyof SubmissionForm ;
3437 label : string ;
@@ -55,6 +58,7 @@ export default function MediaUploader({
5558 buttonText = 'Upload' ,
5659} : MediaUploaderProps ) {
5760 const form = useFormContext < SubmissionForm > ( ) ;
61+ const { toast } = useToast ( ) ;
5862
5963 const uploadInputRef = useRef < HTMLInputElement | null > ( null ) ;
6064 const replaceInputRef = useRef < HTMLInputElement | null > ( null ) ;
@@ -63,6 +67,22 @@ export default function MediaUploader({
6367 const [ deleteDialogOpen , setDeleteDialogOpen ] = useState ( false ) ;
6468 const [ selectedIndex , setSelectedIndex ] = useState < number | null > ( null ) ;
6569
70+ // Use the smaller of maxSizeMB or the Vercel upload limit
71+ const effectiveMaxSize = Math . min ( maxSizeMB , MAX_FILE_SIZE_FOR_UPLOAD ) ;
72+
73+ const validateFileSize = ( file : File ) : boolean => {
74+ const fileSizeMB = file . size / ( 1024 * 1024 ) ;
75+ if ( fileSizeMB > effectiveMaxSize ) {
76+ toast ( {
77+ title : 'File too large' ,
78+ description : `"${ file . name } " is ${ fileSizeMB . toFixed ( 1 ) } MB. Maximum allowed size is ${ effectiveMaxSize } MB.` ,
79+ variant : 'destructive' ,
80+ } ) ;
81+ return false ;
82+ }
83+ return true ;
84+ } ;
85+
6686 const handleUploadClick = ( ) => uploadInputRef . current ?. click ( ) ;
6787
6888 const handleReplace = ( index : number ) => {
@@ -74,6 +94,13 @@ export default function MediaUploader({
7494 if ( e . target . files && selectedIndex !== null ) {
7595 const newFile = e . target . files [ 0 ] ;
7696 if ( ! newFile ) return ;
97+
98+ // Validate file size before replacing
99+ if ( ! validateFileSize ( newFile ) ) {
100+ e . target . value = '' ; // Reset input
101+ return ;
102+ }
103+
77104 const currentValue = form . getValues ( name ) ;
78105 if ( maxItems === 1 ) {
79106 form . setValue ( name , newFile ) ;
@@ -213,18 +240,26 @@ export default function MediaUploader({
213240
214241 const files = Array . from ( e . target . files ) ;
215242
243+ // Validate file sizes before adding
244+ const validFiles = files . filter ( validateFileSize ) ;
245+ if ( validFiles . length === 0 ) {
246+ e . target . value = '' ; // Reset input
247+ return ;
248+ }
249+
216250 if ( maxItems === 1 ) {
217- field . onChange ( files [ 0 ] ) ;
251+ field . onChange ( validFiles [ 0 ] ) ;
218252 } else {
219253 const existingFiles = Array . isArray ( field . value )
220254 ? field . value
221255 : [ ] ;
222- const totalFiles = [ ...existingFiles , ...files ] . slice (
256+ const totalFiles = [ ...existingFiles , ...validFiles ] . slice (
223257 0 ,
224258 maxItems
225259 ) ;
226260 field . onChange ( totalFiles ) ;
227261 }
262+ e . target . value = '' ; // Reset input for future uploads
228263 } }
229264 />
230265 </ FormControl >
0 commit comments