import React, { useState, useRef } from 'react';
const UploadFolderModal = ({ disableBackgroundClose = true }) => {
const [active, setActive] = useState(false);
const [folderName, setFolderName] = useState('');
const [fileList, setFileList] = useState([]);
const [uploadProgress, setUploadProgress] = useState({});
const dropArea = useRef(null);
const fileInput = useRef(null);
const handleDrop = (e) => {
e.preventDefault();
e.stopPropagation();
dropArea.current.classList.remove('dragging');
const items = e.dataTransfer.items;
if (items.length > 0) {
const folder = items[0].webkitGetAsEntry();
if (folder?.isDirectory) {
handleFolder(folder);
} else {
alert('Please drop a folder!');
}
}
};
const handleFolder = async (folder, parentPath = '') => {
setFolderName(folder.name || 'Root');
const reader = folder.createReader();
const entries = await readEntries(reader);
for (const entry of entries) {
if (entry.isFile) {
const file = await new Promise((resolve) => entry.file(resolve));
setFileList((prevFileList) => [
...prevFileList,
{ name: file.name, size: file.size, type: file.type, folderPath: parentPath },
]);
} else if (entry.isDirectory) {
await handleFolder(entry, `${parentPath}/${entry.name}`);
}
}
if (fileList.length > 0) startUpload();
};
const readEntries = (reader) => new Promise((resolve, reject) => {
reader.readEntries(resolve, reject);
});
const uploadFileToS3 = (file, index) => {
const formData = new FormData();
formData.append('file', file);
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('POST', '/api/v1/upload', true);
xhr.upload.onprogress = (e) => {
if (e.lengthComputable) {
const percent = (e.loaded / e.total) * 100;
setUploadProgress((prevProgress) => ({
...prevProgress,
[index]: Math.round(percent),
}));
}
};
xhr.onload = () => xhr.status === 200 ? resolve(JSON.parse(xhr.responseText).fileUrl) : reject('Error uploading file');
xhr.onerror = () => reject('Error uploading file');
xhr.send(formData);
});
};
const handleFileSelect = (e) => {
const files = Array.from(e.target.files).map((file) => ({
name: file.name,
size: file.size,
type: file.type,
folderPath: 'Root',
}));
setFileList(files);
};
const startUpload = async () => {
for (let i = 0; i < fileList.length; i++) {
await uploadFileToS3(fileList[i], i);
}
};
const closeModal = () => {
setActive(false);
setTimeout(() => {}, 200);
};
const handleDragOver = (e) => {
e.preventDefault();
e.stopPropagation();
dropArea.current.classList.add('dragging');
};
const handleDragLeave = (e) => {
e.preventDefault();
e.stopPropagation();
dropArea.current.classList.remove('dragging');
};
return (
<div className={`wrap-upload-modal${active ? ' active' : ''}`}>
<div className="wrap-modal d-flex align-items-center justify-content-center">
<div className="wrap-content">
<div className="body-modal">
<div
ref={dropArea}
className="wrap-area-drop"
onDrop={handleDrop}
onDragOver={handleDragOver}
onDragLeave={handleDragLeave}
>
<p className="text-center main">Kéo và thả thư mục vào đây để lấy thông tin và các tệp bên trong</p>
<p className="text-center sub">Chỉ thả thư mục vào đây</p>
</div>
<div className="text-center">
<button onClick={() => fileInput.current.click()} className="btn btn-primary">Tải tệp lên</button>
<input ref={fileInput} type="file" multiple onChange={handleFileSelect} style={{ display: 'none' }} />
</div>
<div className="text-center">
<button onClick={startUpload} className="btn btn-success mt-3">Bắt đầu tải lên</button>
</div>
</div>
<div className="footer-modal">
<div><strong>Folder Name:</strong> {folderName}</div>
<div><strong>List of Files:</strong>
{fileList.length > 0 ? (
fileList.map((file, index) => (
<div key={index}>
{file.name} - {file.size} bytes - {file.type} - <strong> Folder: {file.folderPath}</strong>
<div>
<progress value={uploadProgress[index] || 0} max={100}></progress>
<span>{uploadProgress[index] ? `${uploadProgress[index]}%` : 'Đang chờ'}</span>
</div>
</div>
))
) : (
<p>No files to display</p>
)}
</div>
</div>
</div>
</div>
</div>
);
};
export default UploadFolderModal;