Skip to content

Instantly share code, notes, and snippets.

@nitish1402
Created April 24, 2024 11:47
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nitish1402/553e8cffce47204257f9d7bdccb5a933 to your computer and use it in GitHub Desktop.
Save nitish1402/553e8cffce47204257f9d7bdccb5a933 to your computer and use it in GitHub Desktop.
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