import React, { useCallback } from 'react' import { Box } from '@mui/material' import { useDropzone, DropzoneRootProps, DropzoneInputProps } from 'react-dropzone' import Compressor from 'compressorjs' const toBase64 = (file: File): Promise => new Promise((resolve, reject) => { const reader = new FileReader() reader.readAsDataURL(file) reader.onload = () => resolve(reader.result) reader.onerror = (error) => { reject(error) } }) interface ImageUploaderProps { children: React.ReactNode onPick: (file: File) => void } const ImageUploader: React.FC = ({ children, onPick }) => { const onDrop = useCallback( async (acceptedFiles: File[]) => { if (acceptedFiles.length > 1) { return } const image = acceptedFiles[0] let compressedFile: File | undefined try { // Check if the file is a GIF if (image.type === 'image/gif') { // Check if the GIF is larger than 500 KB if (image.size > 500 * 1024) { console.error('GIF file size exceeds 500KB limit.') return } // No compression for GIF, pass the original file compressedFile = image } else { // For non-GIF files, compress them await new Promise((resolve) => { new Compressor(image, { quality: 0.6, maxWidth: 1200, mimeType: 'image/webp', success(result) { const file = new File([result], image.name, { type: 'image/webp' }) compressedFile = file resolve() }, error(err) { console.error('Compression error:', err) resolve() // Proceed even if there's an error } }) }) } if (!compressedFile) return onPick(compressedFile) } catch (error) { console.error('File processing error:', error) } }, [onPick] ) const { getRootProps, getInputProps, isDragActive }: { getRootProps: () => DropzoneRootProps getInputProps: () => DropzoneInputProps isDragActive: boolean } = useDropzone({ onDrop, accept: { 'image/*': [] } }) return ( {children} ) } export default ImageUploader