Created
April 24, 2024 11:47
-
-
Save nitish1402/553e8cffce47204257f9d7bdccb5a933 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useState } from 'react'; | |
import Dropzone from 'react-dropzone'; | |
import axios from 'axios'; | |
const UploadComponent = () => { | |
const [files, setFiles] = useState([]); | |
const [progress, setProgress] = useState(0); | |
const handleDrop = acceptedFiles => { | |
setFiles(acceptedFiles); | |
}; | |
const uploadFiles = async () => { | |
const chunkSize = 1024 * 1024; // 1MB chunk size | |
const totalChunks = Math.ceil(files[0].size / chunkSize); | |
let currentChunk = 0; | |
const uploadChunk = async (start, end) => { | |
const formData = new FormData(); | |
formData.append('file', files[0].slice(start, end)); | |
try { | |
const response = await axios.post('/upload', formData, { | |
headers: { | |
'Content-Type': 'multipart/form-data' | |
}, | |
onUploadProgress: progressEvent => { | |
const percentage = Math.round((progressEvent.loaded / progressEvent.total) * 100); | |
setProgress(percentage); | |
} | |
}); | |
currentChunk++; | |
if (currentChunk < totalChunks) { | |
const start = currentChunk * chunkSize; | |
const end = Math.min((currentChunk + 1) * chunkSize, files[0].size); | |
await uploadChunk(start, end); | |
} | |
} catch (error) { | |
console.error('Error uploading chunk:', error); | |
} | |
}; | |
const start = 0; | |
const end = Math.min(chunkSize, files[0].size); | |
await uploadChunk(start, end); | |
}; | |
return ( | |
<div> | |
<Dropzone onDrop={handleDrop}> | |
{({ getRootProps, getInputProps }) => ( | |
<div {...getRootProps()} style={{ border: '1px solid black', padding: '20px' }}> | |
<input {...getInputProps()} /> | |
<p>Drag and drop some files here, or click to select files</p> | |
</div> | |
)} | |
</Dropzone> | |
<button onClick={uploadFiles}>Upload</button> | |
{progress > 0 && <p>Progress: {progress}%</p>} | |
</div> | |
); | |
}; | |
export default UploadComponent; | |
// 2nd approach | |
import React, { useState, useRef } from 'react'; | |
const ChunkUploader = () => { | |
const [selectedFile, setSelectedFile] = useState(null); | |
const [uploadProgress, setUploadProgress] = useState(0); | |
const fileInputRef = useRef(null); | |
const handleFileChange = (event) => { | |
const file = event.target.files[0]; | |
if (!file) return; | |
const allowedExtensions = ['.csv', '.json', '.xls', '.xlsx']; | |
const extension = file.name.split('.').pop().toLowerCase(); | |
if (!allowedExtensions.includes(extension)) { | |
alert('Invalid file type. Please select a CSV, JSON, or Excel file.'); | |
return; | |
} | |
setSelectedFile(file); | |
}; | |
const handleUpload = async () => { | |
if (!selectedFile) return; | |
const reader = new FileReader(); | |
const chunkSize = 1024 * 1024; // 1 MB chunks | |
let uploadedBytes = 0; | |
let totalBytes = selectedFile.size; | |
reader.onload = (event) => { | |
const chunk = event.target.result; | |
// Simulate network delay for demonstration (remove or adjust for real uploads) | |
setTimeout(async () => { | |
const response = await uploadChunk(chunk); // Replace with your actual upload logic | |
uploadedBytes += chunk.length; | |
const progress = Math.floor((uploadedBytes / totalBytes) * 100); | |
setUploadProgress(progress); | |
}, 1000); // 1 second delay | |
}; | |
reader.onerror = (error) => { | |
console.error('Error uploading file:', error); | |
alert('An error occurred during upload. Please try again.'); | |
}; | |
for (let start = 0; start < totalBytes; start += chunkSize) { | |
const end = Math.min(start + chunkSize, totalBytes); | |
const slice = selectedFile.slice(start, end); | |
reader.readAsArrayBuffer(slice); | |
} | |
}; | |
const uploadChunk = async (chunk) => { | |
// Replace with your actual backend API call to upload the chunk | |
// This is a placeholder for demonstration purposes | |
const response = await fetch('/api/upload-chunk', { | |
method: 'POST', | |
body: chunk, | |
}); | |
return response.json(); // Assuming the response contains success/failure information | |
}; | |
return ( | |
<div> | |
<input type="file" ref={fileInputRef} onChange={handleFileChange} /> | |
<button onClick={() => fileInputRef.current.click()}>Select File</button> | |
<br /> | |
{selectedFile && ( | |
<div> | |
<p>Uploading: {selectedFile.name}</p> | |
<progress value={uploadProgress} max={100} /> | |
<span>{uploadProgress}%</span> | |
</div> | |
)} | |
</div> | |
); | |
}; | |
export default ChunkUploader; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment