Untitled
user_5257650
plain_text
2 years ago
5.3 kB
13
Indexable
import Image from 'next/image';
import { useCallback, useEffect, useState } from 'react';
import { useDropzone } from 'react-dropzone';
import { FaTrashAlt } from 'react-icons/fa';
const ImageDropSingle = ({ className, value, onChange }) => {
const [preview, setPreview] = useState(null);
const [error, setError] = useState(null);
const onDrop = useCallback(
(acceptedFiles) => {
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 <= 1024 * 1000) {
const fileWithPreview = Object.assign(file, {
preview: URL.createObjectURL(file),
});
setPreview(fileWithPreview.preview);
onChange(fileWithPreview);
setError(null); // 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]
);
const { getRootProps, getInputProps } = useDropzone({
accept: 'image/*',
maxSize: 1024 * 1000, // 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(null); // 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 bg-rose-50 p-2">
<input {...getInputProps()} />
<svg
width="80px"
height="80px"
viewBox="0 0 48 48"
version="1"
xmlns="http://www.w3.org/2000/svg"
enable-background="new 0 0 48 48"
>
<path
fill="#8CBCD6"
d="M31,41H8c-2.2,0-4-1.8-4-4V11c0-2.2,1.8-4,4-4h32c2.2,0,4,1.8,4,4v17C44,35.2,38.2,41,31,41z"
/>
<circle fill="#B3DDF5" cx="35" cy="16" r="3" />
<polygon fill="#9AC9E3" points="20,16 9,32 31,32" />
<polygon fill="#B3DDF5" points="31,22 23,32 39,32" />
<path
fill="#E57373"
d="M47.7,29.1l-2.8-2.8c-0.4-0.4-1.1-0.4-1.6,0L42,27.6l4.4,4.4l1.3-1.3C48.1,30.3,48.1,29.6,47.7,29.1z"
/>
<rect
x="27.1"
y="35.1"
transform="matrix(.707 -.707 .707 .707 -16.508 36.511)"
fill="#FF9800"
width="17.4"
height="6.2"
/>
<rect
x="41.5"
y="27.8"
transform="matrix(-.707 .707 -.707 -.707 95.395 22.352)"
fill="#B0BEC5"
width="3.1"
height="6.2"
/>
<polygon fill="#FFC107" points="27.5,42.2 26,48 31.8,46.5" />
<polygon fill="#37474F" points="26.7,45 26,48 29,47.3" />
</svg>
{error ? (
<p className="text-red-500 text-sm">{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-indigo-600"> 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 1MB
</p>
</>
)}
</div>
)}
</div>
</>
);
};
export default ImageDropSingle;Editor is loading...
Leave a Comment