added the ability to download multiple files as a zip
This commit is contained in:
parent
cca038397c
commit
b9be0f9cb8
1 changed files with 63 additions and 1 deletions
|
@ -1,4 +1,5 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
|
import JSZip from 'jszip';
|
||||||
|
|
||||||
interface FileType {
|
interface FileType {
|
||||||
url: string;
|
url: string;
|
||||||
|
@ -82,6 +83,7 @@ const FileViewerModal: React.FC<FileViewerModalProps> = ({ isOpen, onClose, file
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
const [selectedFile, setSelectedFile] = useState<FileType | null>(null);
|
const [selectedFile, setSelectedFile] = useState<FileType | null>(null);
|
||||||
const [showPreview, setShowPreview] = useState(false);
|
const [showPreview, setShowPreview] = useState(false);
|
||||||
|
const [downloadingAll, setDownloadingAll] = useState(false);
|
||||||
|
|
||||||
const fileArray = Array.isArray(files) ? files : [files];
|
const fileArray = Array.isArray(files) ? files : [files];
|
||||||
|
|
||||||
|
@ -146,6 +148,42 @@ const FileViewerModal: React.FC<FileViewerModalProps> = ({ isOpen, onClose, file
|
||||||
setSelectedFile(null);
|
setSelectedFile(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Function to download all files as zip
|
||||||
|
const downloadAllFiles = async () => {
|
||||||
|
if (fileArray.length === 0) return;
|
||||||
|
|
||||||
|
setDownloadingAll(true);
|
||||||
|
const zip = new JSZip();
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Download all files
|
||||||
|
const filePromises = fileArray.map(async (file) => {
|
||||||
|
const response = await fetch(file.url);
|
||||||
|
const blob = await response.blob();
|
||||||
|
zip.file(file.name, blob);
|
||||||
|
});
|
||||||
|
|
||||||
|
await Promise.all(filePromises);
|
||||||
|
|
||||||
|
// Generate and download zip
|
||||||
|
const content = await zip.generateAsync({ type: "blob" });
|
||||||
|
const zipUrl = URL.createObjectURL(content);
|
||||||
|
|
||||||
|
const link = document.createElement('a');
|
||||||
|
link.href = zipUrl;
|
||||||
|
link.download = 'files.zip';
|
||||||
|
document.body.appendChild(link);
|
||||||
|
link.click();
|
||||||
|
document.body.removeChild(link);
|
||||||
|
URL.revokeObjectURL(zipUrl);
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Failed to download files:', err);
|
||||||
|
setError('Failed to download files');
|
||||||
|
} finally {
|
||||||
|
setDownloadingAll(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const renderFileContent = (file: FileType) => {
|
const renderFileContent = (file: FileType) => {
|
||||||
const fileType = file.type.toLowerCase();
|
const fileType = file.type.toLowerCase();
|
||||||
|
|
||||||
|
@ -256,7 +294,31 @@ const FileViewerModal: React.FC<FileViewerModalProps> = ({ isOpen, onClose, file
|
||||||
const renderFileList = () => {
|
const renderFileList = () => {
|
||||||
return (
|
return (
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
<h3 className="font-bold text-lg mb-4">Files ({fileArray.length})</h3>
|
<div className="flex justify-between items-center mb-4">
|
||||||
|
<h3 className="font-bold text-lg">Files ({fileArray.length})</h3>
|
||||||
|
{fileArray.length > 1 && (
|
||||||
|
<button
|
||||||
|
className={`btn btn-primary btn-sm ${downloadingAll ? 'loading' : ''}`}
|
||||||
|
onClick={downloadAllFiles}
|
||||||
|
disabled={downloadingAll}
|
||||||
|
>
|
||||||
|
{!downloadingAll && (
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
className="h-4 w-4 mr-2"
|
||||||
|
viewBox="0 0 20 20"
|
||||||
|
fill="currentColor"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
fillRule="evenodd"
|
||||||
|
d="M3 17a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zm3.293-7.707a1 1 0 011.414 0L9 10.586V3a1 1 0 112 0v7.586l1.293-1.293a1 1 0 111.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
)}
|
||||||
|
{downloadingAll ? 'Preparing Download...' : 'Download All'}
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
<div className="overflow-y-auto max-h-[60vh]">
|
<div className="overflow-y-auto max-h-[60vh]">
|
||||||
{fileArray.map((file, index) => (
|
{fileArray.map((file, index) => (
|
||||||
<div
|
<div
|
||||||
|
|
Loading…
Reference in a new issue