65 lines
1.8 KiB
TypeScript
65 lines
1.8 KiB
TypeScript
import React from "react";
|
|
import axios from "axios";
|
|
import { toast } from "react-toastify";
|
|
import { BsFilePdf, BsFileExcel} from "react-icons/bs";
|
|
|
|
type DownloadingPdf = {
|
|
[key: string]: boolean;
|
|
};
|
|
|
|
type PdfEndpoint = "stats" | "assignments";
|
|
type FileType = "pdf" | "excel";
|
|
|
|
export const usePDFDownload = (endpoint: PdfEndpoint, file: FileType = 'pdf') => {
|
|
const [downloadingPdf, setDownloadingPdf] = React.useState<DownloadingPdf>(
|
|
{}
|
|
);
|
|
|
|
const triggerDownload = async (id: string) => {
|
|
try {
|
|
setDownloadingPdf((prev) => ({ ...prev, [id]: true }));
|
|
const res = await axios.post(`/api/${endpoint}/${id}/export/${file}`);
|
|
toast.success("Report ready!");
|
|
const link = document.createElement("a");
|
|
link.href = res.data;
|
|
// download should have worked but there are some CORS issues
|
|
// https://firebase.google.com/docs/storage/web/download-files#cors_configuration
|
|
// link.download="report.pdf";
|
|
link.target = "_blank";
|
|
link.rel = "noreferrer";
|
|
link.click();
|
|
setDownloadingPdf((prev) => ({ ...prev, [id]: false }));
|
|
} catch (err) {
|
|
toast.error("Failed to display the report!");
|
|
console.error(err);
|
|
setDownloadingPdf((prev) => ({ ...prev, [id]: false }));
|
|
}
|
|
};
|
|
|
|
const renderIcon = (
|
|
id: string,
|
|
downloadClasses: string,
|
|
loadingClasses: string
|
|
) => {
|
|
if (downloadingPdf[id]) {
|
|
return (
|
|
<span className={`${loadingClasses} loading loading-infinity w-6`} />
|
|
);
|
|
}
|
|
|
|
const Icon = file === "excel" ? BsFileExcel : BsFilePdf;
|
|
|
|
return (
|
|
<Icon
|
|
className={`${downloadClasses} text-2xl cursor-pointer`}
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
triggerDownload(id);
|
|
}}
|
|
/>
|
|
);
|
|
};
|
|
|
|
return renderIcon;
|
|
};
|