import { Upload, Button, Flex, Typography, Space, Progress, Card } from 'antd' import PropTypes from 'prop-types' import { ApiServerContext } from '../context/ApiServerContext' import UploadIcon from '../../Icons/UploadIcon' import { useCallback, useContext, useEffect, useMemo, useRef, useState } from 'react' import ObjectSelect from './ObjectSelect' import FileList from './FileList' import PlusIcon from '../../Icons/PlusIcon' import { LoadingOutlined } from '@ant-design/icons' import FileIcon from '../../Icons/FileIcon' const { Text } = Typography const getFileIdentity = (value, multiple) => { if (multiple) { return Array.isArray(value) ? value.map((file) => file?._id || file).join(',') : '' } return value?._id || value || '' } const FileUpload = ({ value, onChange, minimal = false, multiple = true, defaultPreviewOpen = false, showPreview = true, showInfo }) => { const { uploadFile } = useContext(ApiServerContext) const [uploading, setUploading] = useState(false) const [uploadProgress, setUploadProgress] = useState(0) const onChangeRef = useRef(onChange) useEffect(() => { onChangeRef.current = onChange }, [onChange]) // Track current files using useState const [currentFiles, setCurrentFiles] = useState(() => { if (multiple) { return Array.isArray(value) ? value : [] } else { return value || null } }) // Update currentFiles when value prop changes useEffect(() => { setCurrentFiles((prev) => { if ( getFileIdentity(prev, multiple) === getFileIdentity(value, multiple) ) { return prev } return multiple ? (Array.isArray(value) ? value : []) : value || null }) }, [value, multiple]) // Track the selected file from ObjectSelect const [selectedFile, setSelectedFile] = useState(null) const hasNoItems = useMemo( () => multiple ? !currentFiles || !Array.isArray(currentFiles) || currentFiles.length === 0 : !currentFiles, [currentFiles, multiple] ) const updateCurrentFiles = useCallback((nextFiles) => { setCurrentFiles(nextFiles) onChangeRef.current?.(nextFiles) }, []) const handleFileUpload = async (file) => { try { setUploading(true) const uploadedFile = await uploadFile(file, {}, (progress) => { setUploadProgress(progress) }) setUploading(false) if (uploadedFile) { if (multiple) { // For multiple files, add to existing array const newFiles = [...currentFiles, uploadedFile] updateCurrentFiles(newFiles) } else { // For single file, replace the value updateCurrentFiles(uploadedFile) } } } catch (error) { console.error('File upload failed:', error) } return false // Prevent default upload behavior } // Handle adding selected file to the list const handleAddSelectedFile = () => { if (selectedFile) { if (multiple) { // For multiple files, add to existing array const newFiles = [...currentFiles, selectedFile] updateCurrentFiles(newFiles) } else { // For single file, replace the value updateCurrentFiles(selectedFile) } // Clear the selection setSelectedFile(null) } } if (minimal == true) { return ( {currentFiles[0]?.name} ) } return ( {hasNoItems && uploading == false ? ( ) : null} {uploading == true ? ( Uploading... {uploadProgress > 0 ? ( <> {uploadProgress >= 0 && uploadProgress < 100 ? ( <> {uploadProgress}% ) : null} {uploadProgress == 100 ? : null} ) : null} ) : null} { updateCurrentFiles(updatedFiles) }} /> ) } FileUpload.propTypes = { value: PropTypes.oneOfType([PropTypes.object, PropTypes.array]), onChange: PropTypes.func, multiple: PropTypes.bool, showPreview: PropTypes.bool, showInfo: PropTypes.bool, defaultPreviewOpen: PropTypes.bool, minimal: PropTypes.bool } export default FileUpload