import { CloseCircle, DocumentUpload, Gallery } from 'iconsax-react' import { type FC, useCallback, useEffect, useState } from 'react' import { useDropzone } from 'react-dropzone'; import { clx } from '../helpers/utils'; type Props = { label: string; onChange: (file: File[]) => void; isMultiple?: boolean; isFile?: boolean, preview?: string[], onChangePreview?: (preview: string[]) => void, getCover?: (url: string) => void, coverUrl?: string, /** نمایش وضعیت بارگذاری داخل باکس آپلود */ isLoading?: boolean, loadingLabel?: string, /** بدون پیش‌نمایش زیر باکس (مثلاً گالری جداگانه دارد) */ hidePreview?: boolean, } const UploadBoxDraggble: FC = (props: Props) => { const [files, setFiles] = useState([]); const [perviews, setPerviews] = useState(props.preview ?? []); const [cover, setCover] = useState(props.coverUrl ?? ""); const onDrop = useCallback((acceptedFiles: File[]) => { if (props.hidePreview) { props.onChange(acceptedFiles); return; } // وقتی parent با preview و onChangePreview مدیریت می‌کند، فقط onChange بزن تا فقط یک ردیف (perviews) نمایش داده شود if (props.preview !== undefined && props.onChangePreview) { props.onChange(acceptedFiles); return; } if (props.isMultiple) { const array = [...files, ...acceptedFiles]; setFiles(array); props.onChange(array); } else { setFiles([acceptedFiles[0]]); props.onChange([acceptedFiles[0]]); } // eslint-disable-next-line react-hooks/exhaustive-deps }, [files]); const { getRootProps, getInputProps } = useDropzone({ onDrop, disabled: props.isLoading, }) const handleDelete = (index: number) => { const array = [...files] array.splice(index, 1) setFiles(array) props.onChange(array) } const handleDeletePreview = (index: number) => { const array = [...perviews]; array.splice(index, 1); setPerviews(array); if (props.onChangePreview) { props.onChangePreview(array); } } useEffect(() => { if (props.preview) { setPerviews(props.preview); } }, [props.preview]); useEffect(() => { setCover(props.coverUrl ? props.coverUrl : '') }, [props.coverUrl]) return (
{props.isLoading ? ( <>
{props.loadingLabel ?? 'در حال آپلود...'}
) : ( <>
{props.label}
آپلود
)}
{ !props.hidePreview && (files.length > 0 || perviews.length > 0) ? (
{ perviews && perviews.map((item, index) => { return (
{ if (props.getCover) { setCover(item) props.getCover(item) } }} src={item} className={clx( 'size-10 rounded-full object-cover', cover === item ? 'border-2 border-red-400' : '' )} />
handleDeletePreview(index)} className='absolute -left-2 -top-2 shadow-md bg-white size-5 rounded-full flex justify-center items-center'>
) }) } { files.map((file, index) => { if (props.isFile) { return (
{file.name}
handleDelete(index)} className='size-4 ' color='red' />
) } else return (
{file.name}
handleDelete(index)} className='size-4 ' color='red' />
) }) }
) : null }
) } export default UploadBoxDraggble