Files
pedwfrontend/components/utils/downloads.js
T
2025-10-01 09:18:31 +01:00

326 lines
11 KiB
JavaScript

// // import { useState } from "react";
// // export default function DocumentLink({ detailsObj, caseReference }) {
// // const [downloadStatus, setDownloadStatus] = useState("");
// // const [progress, setProgress] = useState(null);
// // const handleDownload = async () => {
// // setDownloadStatus("Downloading");
// // setProgress(0);
// // try {
// // const res = await fetch(detailsObj.pinswg_hashlink);
// // if (!res.ok) throw new Error("Download failed");
// // const contentDisposition = res.headers.get("content-disposition");
// // const filename = contentDisposition
// // ? contentDisposition.split("filename=")[1]
// // : detailsObj.pinswg_name || "document";
// // const contentLength = res.headers.get("content-length");
// // const totalBytes = contentLength
// // ? parseInt(contentLength, 10)
// // : null;
// // const reader = res.body.getReader();
// // let receivedBytes = 0;
// // const chunks = [];
// // while (true) {
// // const { done, value } = await reader.read();
// // if (done) break;
// // chunks.push(value);
// // receivedBytes += value.length;
// // if (totalBytes) {
// // const percent = Math.round(
// // (receivedBytes / totalBytes) * 100
// // );
// // setProgress(percent);
// // }
// // }
// // // Combine chunks into one blob
// // const blob = new Blob(chunks);
// // const url = window.URL.createObjectURL(blob);
// // const link = document.createElement("a");
// // link.href = url;
// // link.download = filename;
// // document.body.appendChild(link);
// // link.click();
// // document.body.removeChild(link);
// // setDownloadStatus("Download complete!");
// // setProgress(100);
// // // Fire GA event
// // window.gtag?.("event", "DownloadedFile", {
// // caseReference,
// // filename,
// // });
// // } catch (err) {
// // console.error(err);
// // setDownloadStatus("Download failed");
// // setProgress(null);
// // }
// // };
// // return (
// // <>
// // {detailsObj.pinswg_publishtoweb ? (
// // <button className="documentLink" onClick={handleDownload}>
// // <span className="results-visually-hidden">
// // Document name:
// // </span>
// // {detailsObj.pinswg_name || ""}
// // </button>
// // ) : (
// // <>
// // <span className="results-visually-hidden">
// // Document name:
// // </span>
// // {detailsObj.pinswg_name || ""}
// // </>
// // )}
// // {downloadStatus && (
// // <p
// // className={
// // downloadStatus == "Downloading"
// // ? "govuk-!-font-size-14 govuk-!-margin-left-0 textloading"
// // : "govuk-!-font-size-14 govuk-!-margin-left-0 "
// // }
// // >
// // {downloadStatus}
// // {/* {progress !== null && ` (${progress}%)`} */}
// // </p>
// // )}
// // </>
// // );
// // }
// import { useState } from "react";
// export default function DocumentLink({
// id,
// detailsObj,
// caseReference,
// startDownload,
// getStatus,
// }) {
// const [downloadStatus, setDownloadStatus] = useState("");
// const [progress, setProgress] = useState(null);
// const downloadFile = async () => {
// setDownloadStatus("Downloading");
// setProgress(0);
// try {
// const res = await fetch(detailsObj.pinswg_hashlink);
// if (!res.ok) throw new Error("Download failed");
// const contentDisposition = res.headers.get("content-disposition");
// const filename = contentDisposition
// ? contentDisposition.split("filename=")[1]
// : detailsObj.pinswg_name || "document";
// const contentLength = res.headers.get("content-length");
// const totalBytes = contentLength
// ? parseInt(contentLength, 10)
// : null;
// const reader = res.body.getReader();
// let receivedBytes = 0;
// const chunks = [];
// while (true) {
// const { done, value } = await reader.read();
// if (done) break;
// chunks.push(value);
// receivedBytes += value.length;
// if (totalBytes) {
// const percent = Math.round(
// (receivedBytes / totalBytes) * 100
// );
// setProgress(percent);
// }
// }
// const blob = new Blob(chunks);
// const url = window.URL.createObjectURL(blob);
// const link = document.createElement("a");
// link.href = url;
// link.download = filename;
// document.body.appendChild(link);
// link.click();
// document.body.removeChild(link);
// setDownloadStatus("Download complete!");
// setProgress(100);
// window.gtag?.("event", "DownloadedFile", {
// caseReference,
// filename,
// });
// } catch (err) {
// console.error(err);
// setDownloadStatus("Download failed");
// setProgress(null);
// }
// };
// const handleClick = () => {
// if (getStatus(id) !== "idle") return; // don't double enqueue
// startDownload(id, downloadFile);
// };
// const status = getStatus(id);
// return (
// <>
// {detailsObj.pinswg_publishtoweb ? (
// <button className="documentLink" onClick={handleClick}>
// <span className="results-visually-hidden">
// Document name:
// </span>
// {detailsObj.pinswg_name || ""}
// </button>
// ) : (
// <>
// <span className="results-visually-hidden">
// Document name:
// </span>
// {detailsObj.pinswg_name || ""}
// </>
// )}
// {status !== "idle" && (
// <p
// className={
// status === "downloading"
// ? "govuk-!-font-size-14 govuk-!-margin-left-0 textloading"
// : "govuk-!-font-size-14 govuk-!-margin-left-0"
// }
// >
// {status === "downloading" && progress !== null
// ? `Downloading (${progress}%)`
// : status === "queued"
// ? "Queued"
// : status === "done"
// ? "Download complete!"
// : status === "failed"
// ? "Download failed"
// : ""}
// </p>
// )}
// </>
// );
// }
import { useState } from "react";
import useTranslation from "next-translate/useTranslation";
export default function DocumentLink({
id,
detailsObj,
caseReference,
startDownload,
getStatus,
}) {
const [progress, setProgress] = useState(null);
let { t } = useTranslation();
const downloadFile = async () => {
setProgress(0);
const res = await fetch(detailsObj.pinswg_hashlink);
if (!res.ok) throw new Error("Download failed");
const contentDisposition = res.headers.get("content-disposition");
const filename = contentDisposition
? contentDisposition.split("filename=")[1]
: detailsObj.pinswg_name || "document";
const contentLength = res.headers.get("content-length");
const totalBytes = contentLength ? parseInt(contentLength, 10) : null;
const reader = res.body.getReader();
let receivedBytes = 0;
const chunks = [];
while (true) {
const { done, value } = await reader.read();
if (done) break;
chunks.push(value);
receivedBytes += value.length;
if (totalBytes) {
const percent = Math.round((receivedBytes / totalBytes) * 100);
setProgress(percent);
}
}
const blob = new Blob(chunks);
const url = window.URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.download = filename;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
window.URL.revokeObjectURL(url);
setProgress(100);
window.gtag?.("event", "DownloadedFile", { caseReference, filename });
};
const handleClick = () => {
if (getStatus(id) !== "idle") return; // avoid double enqueue
startDownload(id, downloadFile);
};
const status = getStatus(id);
return (
<div>
{detailsObj.pinswg_publishtoweb ? (
<button className="documentLink" onClick={handleClick}>
<span className="results-visually-hidden">
Document name:
</span>
{detailsObj.pinswg_name || ""}
</button>
) : (
<span className="results-visually-hidden">
{detailsObj.pinswg_name || ""}
</span>
)}
{status !== "idle" && (
<p
className={
status === "downloading"
? "govuk-!-font-size-14 govuk-!-margin-left-0 textloading"
: "govuk-!-font-size-14 govuk-!-margin-left-0"
}
>
{status === "downloading" && progress !== null
? t("case:downloading-label")
: status === "queued"
? t("case:download-queued-label")
: status === "done"
? t("case:download-complete-label")
: status === "failed"
? t("case:download-failed-label")
: ""}
</p>
)}
</div>
);
}