Add Download Report button to proof detail view

Rename Download button to Download Asset and add new Download Report
button that generates a PDF report for the current proof version directly
from the proof review screen.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
michael 2026-01-08 09:15:18 -06:00
parent e59960b23b
commit 5fc36e358f

View file

@ -1055,6 +1055,7 @@ const ProofDetailView: React.FC<{
};
const [selectedVersionIndex, setSelectedVersionIndex] = useState(getInitialVersionIndex);
const [isExporting, setIsExporting] = useState(false);
const fileInputRef = useRef<HTMLInputElement>(null);
const handleUploadClick = () => {
@ -1132,6 +1133,69 @@ const ProofDetailView: React.FC<{
}
};
const handleDownloadReport = async () => {
setIsExporting(true);
const reportRootEl = document.createElement('div');
reportRootEl.style.position = 'absolute';
reportRootEl.style.left = '-9999px';
reportRootEl.style.top = '0px';
reportRootEl.style.zIndex = '-1';
document.body.appendChild(reportRootEl);
const reactRoot = ReactDOM.createRoot(reportRootEl);
try {
const proofForReport = {
...proof,
versions: [selectedVersion],
};
reactRoot.render(<PDFReport campaignName={campaignName} proofs={[proofForReport]} />);
await new Promise(resolve => setTimeout(resolve, 1000));
const { default: jspdf } = await import('jspdf');
const { default: html2canvas } = await import('html2canvas');
const reportContent = reportRootEl.children[0] as HTMLElement;
if (!reportContent) throw new Error("PDF report element not found");
const canvas = await html2canvas(reportContent, { scale: 2, useCORS: true });
const imgData = canvas.toDataURL('image/png');
const pdf = new jspdf('p', 'mm', 'a4', true);
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = pdf.internal.pageSize.getHeight();
const ratio = canvas.width / pdfWidth;
const pagedCanvasHeight = canvas.height / ratio;
let heightLeft = pagedCanvasHeight;
let position = 0;
pdf.addImage(imgData, 'PNG', 0, position, pdfWidth, pagedCanvasHeight, undefined, 'FAST');
heightLeft -= pdfHeight;
while (heightLeft > 0) {
position -= pdfHeight;
pdf.addPage();
pdf.addImage(imgData, 'PNG', 0, position, pdfWidth, pagedCanvasHeight, undefined, 'FAST');
heightLeft -= pdfHeight;
}
const fileName = `${campaignName} - ${proof.proofName} V${selectedVersion.version} Report`;
pdf.save(`${fileName.replace(/[^a-zA-Z0-9]/g, '_')}.pdf`);
} catch (error) {
console.error("Failed to generate PDF:", error);
alert("Sorry, there was an error creating the PDF. Please try again.");
} finally {
reactRoot.unmount();
document.body.removeChild(reportRootEl);
setIsExporting(false);
}
};
if (!selectedVersion) {
return (
<div className="p-8">
@ -1196,7 +1260,25 @@ const ProofDetailView: React.FC<{
title={`Download Version ${selectedVersion.version}`}
>
<DownloadIcon className="h-4 w-4" />
Download
Download Asset
</button>
<button
onClick={handleDownloadReport}
disabled={isExporting}
className="flex items-center gap-2 text-sm bg-white text-brand-accent font-semibold py-1.5 px-3 rounded-lg border border-brand-accent hover:bg-brand-accent/10 transition-colors duration-200 disabled:bg-gray-200 disabled:text-gray-500 disabled:cursor-wait"
title={`Download Report for Version ${selectedVersion.version}`}
>
{isExporting ? (
<>
<SpinnerIcon className="h-4 w-4 custom-spinner" />
Exporting...
</>
) : (
<>
<DocumentIcon className="h-4 w-4" />
Download Report
</>
)}
</button>
<button
onClick={handleUploadClick}