pmtool / src /hooks /use-file-upload.ts
devarshia5's picture
Upload 487 files
d97b8f9 verified
Raw
History Blame Contribute Delete
2.75 kB
import { useState, useRef, useCallback } from 'react';
import { toast } from 'sonner';
interface UseFileUploadOptions {
acceptedTypes?: string[];
maxSizeMB?: number;
onFileSelected?: (file: File) => void;
}
interface UseFileUploadResult {
fileInputRef: React.RefObject<HTMLInputElement>;
isSelecting: boolean;
selectedFile: File | null;
triggerFileSelect: () => void;
handleFileChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
clearSelectedFile: () => void;
}
/**
* A custom hook for handling file uploads with validation
*/
export function useFileUpload(options: UseFileUploadOptions = {}): UseFileUploadResult {
const {
acceptedTypes = ['.xlsx', '.xls', '.csv'],
maxSizeMB = 10,
onFileSelected
} = options;
const fileInputRef = useRef<HTMLInputElement>(null);
const [isSelecting, setIsSelecting] = useState(false);
const [selectedFile, setSelectedFile] = useState<File | null>(null);
const triggerFileSelect = useCallback(() => {
if (fileInputRef.current) {
fileInputRef.current.click();
}
}, []);
const clearSelectedFile = useCallback(() => {
setSelectedFile(null);
if (fileInputRef.current) {
fileInputRef.current.value = '';
}
}, []);
const handleFileChange = useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
setIsSelecting(true);
try {
const file = event.target.files?.[0];
if (!file) {
return;
}
// Validate file type
const fileExtension = file.name.substring(file.name.lastIndexOf('.')).toLowerCase();
if (acceptedTypes.length > 0 && !acceptedTypes.includes(fileExtension)) {
toast.error(`Invalid file type. Accepted types: ${acceptedTypes.join(', ')}`);
return;
}
// Validate file size
const maxSizeBytes = maxSizeMB * 1024 * 1024;
if (file.size > maxSizeBytes) {
toast.error(`File size too large. Maximum size is ${maxSizeMB}MB`);
return;
}
// Set the selected file
setSelectedFile(file);
// Call the onFileSelected callback if provided
if (onFileSelected) {
onFileSelected(file);
}
// Reset input value
event.target.value = '';
} catch (error) {
console.error('Error selecting file:', error);
toast.error('Error selecting file. Please try again.');
} finally {
setIsSelecting(false);
}
}, [acceptedTypes, maxSizeMB, onFileSelected]);
return {
fileInputRef,
isSelecting,
selectedFile,
triggerFileSelect,
handleFileChange,
clearSelectedFile,
};
}
export default useFileUpload;