Unzip files in React App
Code Snippet, using zip.js library:
import React, { useState, ChangeEvent } from "react";
import * as zip from "@zip.js/zip.js";
interface ZipEntry {
name: string;
size: number;
entry: zip.Entry;
}
function PackagePage(): JSX.Element {
const [files, setFiles] = useState<ZipEntry[]>([]);
const [indexFile, setIndexFile] = useState<ZipEntry | null>(null);
const handleFileChange = async (event: ChangeEvent<HTMLInputElement>) => {
const file = event.target.files?.[0];
if (file) {
try {
const zipReader = new zip.ZipReader(new zip.BlobReader(file));
const entries = await zipReader.getEntries();
const fileList: ZipEntry[] = entries.map((entry) => ({
name: entry.filename,
size: entry.uncompressedSize,
entry: entry,
}));
setFiles(fileList);
await zipReader.close();
} catch (error) {
console.error("Error reading zip file:", error);
alert("Error reading zip file. Please try again.");
}
}
};
const handleIndexFileSelect = (event: ChangeEvent<HTMLSelectElement>) => {
const selectedFile = files.find((file) => file.name === event.target.value);
setIndexFile(selectedFile || null);
};
//TODO: Upload All the Files and Save the Index html File
return (
<div className="flex flex-col gap-4 max-w-full w-full bg-white h-fit min-h-screen text-black">
<h2>Read a zip file (demo)</h2>
<div>
<label className="text-black flex flex-row gap-2 w-full">
<span className="form-label">Choose a zip file</span>
<input
type="file"
id="file-input"
accept="application/zip"
onChange={handleFileChange}
/>
</label>
</div>
{files.length > 0 && (
<div>
<h3>Files in the ZIP archive:</h3>
<ul>
{files.map((file, index) => (
<li key={index}>
{file.name} - {file.size} bytes
</li>
))}
</ul>
<div>
<label className="text-black flex flex-row gap-2 w-full">
<span className="form-label">Select index.html file:</span>
<select onChange={handleIndexFileSelect}>
<option value="">Select a file</option>
{files
.filter((file) => file.name.endsWith(".html"))
.map((file, index) => (
<option key={index} value={file.name}>
{file.name}
</option>
))}
</select>
</label>
</div>
{indexFile && (
<div>
<h4>Selected index file:</h4>
<p>{indexFile.name}</p>
</div>
)}
</div>
)}
</div>
);
}
export default PackagePage;