'use client' import { FC, useState } from 'react' import { getImageString, useNotification } from '@baseapp-frontend/utils' import { AddRounded as AddRoundedIcon, InsertPhotoOutlined as InsertPhotoOutlinedIcon, } from '@mui/icons-material' import { Button, Card, Typography } from '@mui/material' import { useDropzone } from 'react-dropzone' import DefaultDropzonePreview from './DropzonePreview' import { AddFileButton, AddFileWrapper, ButtonContainer, CancelIcon, DropzoneContainer, DropzoneText, InputContainer, } from './styled' import { DropzoneProps } from './types' const Dropzone: FC = ({ accept, storedImg, onSelect, onRemove, includeActionButton = false, actionText = 'Upload Image', maxFileSize = 15, title, subTitle = `Max. File Size: ${maxFileSize}MB`, DropzoneOptions, InputProps, InputContainerStyle, multiple = false, asBase64 = true, onFileClick, DropzonePreview = DefaultDropzonePreview, DropzonePreviewProps = {}, DropZoneIcon = InsertPhotoOutlinedIcon, DropZoneIconProps = {}, DropZoneCancelIcon = CancelIcon, DropZoneCancelIconProps = {}, }) => { const [files, setFiles] = useState(storedImg) const { sendToast } = useNotification() const { open, getRootProps, getInputProps, isFocused, isDragAccept, isDragReject } = useDropzone({ accept, onDrop: async (acceptedFiles) => { if (acceptedFiles.length === 0 || !acceptedFiles[0]) return if ((acceptedFiles[0]?.size || 0) > maxFileSize * 1024 * 1024) { sendToast(`This file is too large (max ${maxFileSize} MB).`, { type: 'error' }) return } if (multiple) { const resultingFiles = await Promise.all( acceptedFiles.map(async (f) => (asBase64 ? getImageString(f) : f)), ) const newFiles = [...((files || []) as File[]), ...resultingFiles] setFiles(newFiles as any) onSelect(newFiles as any) } else { const file = asBase64 ? await getImageString(acceptedFiles[0]) : acceptedFiles[0] if (!file) return setFiles(file) onSelect(file as any) } }, ...DropzoneOptions, }) const handleRemove = (index?: number) => { if (multiple) { const updatedFiles = (files as File[])?.filter((file, i) => i !== index) setFiles(updatedFiles) onRemove(index) } else { setFiles(undefined) onRemove() } } const hasFiles = Boolean((!multiple && files) || (multiple && (files as [])?.length)) const renderContent = () => { const ariaLabel = 'Drag and drop files to upload' return (
{!hasFiles && ( {isDragReject ? ( <> File not accepted, please choose the correct type {subTitle} ) : ( <> {title || ( <> Click to browse or drag and drop. )} {subTitle} )} )} {!!(files as [])?.length && multiple && ( {(files as unknown as [])?.map((file, index) => ( onFileClick?.(selectedFile, index)} file={file} key={`${(file as File)?.name}_${index}`} handleRemoveFile={() => handleRemove(index)} {...DropzonePreviewProps} /> ))} )} {files && !multiple && ( handleRemove()} {...DropzonePreviewProps} /> )}
) } return (
{renderContent()} {includeActionButton && ( {files && ( )} )}
) } export default Dropzone