Skip to content

Commit a197460

Browse files
authored
Merge branch 'master' into fix/mobile-nav-explorer-sync
2 parents 14fa4d0 + 3f3b943 commit a197460

File tree

1 file changed

+37
-2
lines changed

1 file changed

+37
-2
lines changed

components/hackathons/project-submission/components/MediaUploader.tsx

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,13 @@ import {
2525
} from '@/components/ui/dialog';
2626
import { Button } from '@/components/ui/button';
2727
import { ImageIcon, BadgeAlert, PlusCircleIcon } from 'lucide-react';
28+
import { useToast } from '@/hooks/use-toast';
2829

2930
import { Card } from '@/components/ui/card';
3031
import { 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+
3235
type 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

Comments
 (0)