image-dropzone-single.tsx
unknown
javascript
10 months ago
3.7 kB
2
Indexable
import Image from 'next/image' import { useCallback, useEffect, useState } from 'react' import { useDropzone } from 'react-dropzone' import { FaTrashAlt } from 'react-icons/fa' export default function ImageDropzoneSingle({ className, value, onChange, size, sizeText, }: { className: string value: any onChange: any size: number sizeText: string }) { const [preview, setPreview] = useState(null) const [error, setError] = useState<string>('') const onDrop = useCallback( (acceptedFiles: any) => { const file = acceptedFiles[0] // Check if the file is present and is an image if (file && file.type.startsWith('image/')) { // Check if the file size is within limits (1 MB in this example) if (file.size <= size) { const fileWithPreview = Object.assign(file, { preview: URL.createObjectURL(file), }) setPreview(fileWithPreview.preview) onChange(fileWithPreview) setError('') // Clear any previous errors } else { setError('File size exceeds 1MB. Please choose a smaller file.') } } else { setError('Invalid file type. Please choose a valid image file.') } }, [onChange, size], ) const { getRootProps, getInputProps } = useDropzone({ accept: { 'image/png': ['.png'], 'image/jpeg': ['.jpg', '.jpeg'], }, maxSize: size, // 1 MB onDrop, }) useEffect(() => { // Revoke the data uri to avoid memory leaks return () => { if (preview) { URL.revokeObjectURL(preview) } } }, [preview]) const removeFile = () => { setPreview(null) onChange(null) setError('') // Clear any previous errors } return ( <> <div {...getRootProps({ className: className, })} > {value && preview ? ( <div className="flex items-center gap-3"> <Image src={preview} alt="Uploaded Image" width={0} height={0} sizes="100vw" className="h-24 w-24 rounded-md border border-gray-200 object-contain p-1" /> {value && value.name && <p className="mt-2 text-[14px] font-bold text-gray-800">{value.name}</p>} <button type="button" className="rounded bg-red-500 p-1" onClick={removeFile}> <FaTrashAlt className="hover:fill-secondary-400 h-5 w-5 fill-white transition-colors" /> </button> </div> ) : ( <div className="flex cursor-pointer flex-col items-center justify-center gap-2 rounded-lg border-2 border-dashed p-2"> <input {...getInputProps()} /> <img src="/images/upload.png" height={60} width={60} alt="upload" /> {error ? ( <p className="text-sm text-red-500">{error}</p> ) : ( <> <h3 className="mt-2 text-sm font-medium text-gray-900"> <label htmlFor="file-upload" className="relative cursor-pointer"> <span>Drag and drop</span> <span className="text-primary"> or browse</span> <span> to upload!</span> <input id="file-upload" name="file-upload" type="file" className="sr-only" /> </label> </h3> <p className="mt-1 text-xs text-gray-500">PNG, JPG, GIF up to {sizeText}</p> </> )} </div> )} </div> </> ) }
Editor is loading...
Leave a Comment