diff --git a/src/pages/pdf/PdfSearchPage/PdfTable.js b/src/pages/pdf/PdfSearchPage/PdfTable.js index f8bb41e..dac5792 100644 --- a/src/pages/pdf/PdfSearchPage/PdfTable.js +++ b/src/pages/pdf/PdfSearchPage/PdfTable.js @@ -10,7 +10,11 @@ import { import EditIcon from '@mui/icons-material/Edit'; import UploadFileIcon from '@mui/icons-material/UploadFile'; import CheckCircleIcon from '@mui/icons-material/CheckCircle'; + +// FIX 1: Correctly import both download icons from their respective paths import FileDownloadIcon from '@mui/icons-material/FileDownload'; +import DownloadDoneIcon from '@mui/icons-material/DownloadDone'; + import { Dialog, DialogTitle, @@ -96,9 +100,12 @@ export default function PdfTable({recordList}) { setIsDialogOpen(true); }; + /** + * Handles the standard download (fillable file, endpoint: /download-ff/{id}) + */ const handleDownloadClick = (id) => () => { - // 1. Construct the download URL with the ID query parameter + // 1. Construct the download URL for the FILLABLE file const downloadUrl = `${apiPath}/pdf/download-ff/${id}`; // Use axios to fetch the PDF as a Blob @@ -113,7 +120,6 @@ export default function PdfTable({recordList}) { if (contentDisposition) { // Regex to find filename="name.pdf" or filename*=UTF-8''name.pdf - // The server should be setting the filename header correctly. const filenameMatch = contentDisposition.match(/filename\*?=['"]?([^'"]+)/); if (filenameMatch && filenameMatch[1]) { // Decode URI component and remove extra quotes @@ -142,6 +148,54 @@ export default function PdfTable({recordList}) { }); }; + /** + * Handles the flat download (finalized file, endpoint: /download-flat/{id}) + */ + const handleFlatDownloadClick = (id) => () => { + + // 1. Construct the download URL for the FLATTENED file + const downloadUrl = `${apiPath}/pdf/download-flat/${id}`; + + // Use axios to fetch the PDF as a Blob + axios.get(downloadUrl, { + responseType: 'blob', // IMPORTANT: Tells axios to handle the response as binary data + }) + .then((response) => { + + // 2. Extract Filename from Content-Disposition Header + const contentDisposition = response.headers['content-disposition']; + let filename = `document-flat-${id}.pdf`; // Fallback filename + + if (contentDisposition) { + // Regex to find filename="name.pdf" or filename*=UTF-8''name.pdf + const filenameMatch = contentDisposition.match(/filename\*?=['"]?([^'"]+)/); + if (filenameMatch && filenameMatch[1]) { + // Decode URI component and remove extra quotes + filename = decodeURIComponent(filenameMatch[1].replace(/\\"/g, '')); + } + } + + // 3. Create a temporary anchor tag () to trigger the download + const blob = new Blob([response.data], { type: 'application/pdf' }); + const url = window.URL.createObjectURL(blob); + const link = document.createElement('a'); + + link.href = url; + link.setAttribute('download', filename); + document.body.appendChild(link); + link.click(); + + // 4. Clean up + document.body.removeChild(link); + window.URL.revokeObjectURL(url); + }) + .catch((error) => { + console.error(`Flat download failed for ID ${id}:`, error); + // Handle error response (e.g., if the backend returns a 404 or a JSON error) + alert('Failed to download the flattened PDF file. Check server logs.'); + }); + }; + const handleCloseDialog = () => { setIsDialogOpen(false); setCurrentUploadRow(initialUploadState); // Reset the current row @@ -203,7 +257,7 @@ export default function PdfTable({recordList}) { // Function to handle file selection and API submission const handleFileChange = async (event) => { const file = event.target.files[0]; - const { id, templateName, refType } = currentUploadRow; + const { id, refType } = currentUploadRow; // Removed templateName as it's not needed for FormData if (!file || !id || !refType) return; @@ -327,16 +381,16 @@ export default function PdfTable({recordList}) { cellClassName: 'actions', getActions: ({ id, row }) => { - // Check if a file ID exists to determine if a file is present for Upload 1 + // Check upload status const isUploaded1 = !!row.upload1FileId; - const isUploaded2 = !!row.upload2FileId; // <<< ADD THIS LINE <<< + const isUploaded2 = !!row.upload2FileId; const templateName = row.templateName; const formCode = row.formCode; - // Determine the icon and label based on upload status for Upload 1 + // FIX 5: Use conditional colors for Upload 1 const upload1Icon = isUploaded1 ? // Green tick if uploaded - : ; // Upload icon if not uploaded + : ; // Warning color if not uploaded const upload1Label = isUploaded1 ? "Update Signature" : "Upload Signature"; @@ -347,29 +401,29 @@ export default function PdfTable({recordList}) { icon={upload1Icon} // Use the dynamic icon label={upload1Label} // Use the dynamic label className="textPrimary" - onClick={handleUploadClick(id, templateName, formCode)} // Pass templateName here - color="upload" // Use 'upload' color which will apply to the button + onClick={handleUploadClick(id, templateName, formCode)} + color="upload" /> ]; // Conditional rendering logic for Upload 2 if (row.formCode === "MLB03S" || row.formCode === "SLGII" || row.formCode === "SLAPP") { - // Determine the icon and label based on upload status for Upload 2 <<< START CHANGES HERE <<< + + // FIX 5: Use conditional colors for Upload 2 const upload2Icon = isUploaded2 ? // Green tick if uploaded - : ; // Upload icon if not uploaded + : ; // Warning color if not uploaded const upload2Label = isUploaded2 ? "Update 2" : "Upload 2"; - // >>> END CHANGES HERE <<< - + actions.push( @@ -380,7 +434,7 @@ export default function PdfTable({recordList}) { }, }, { - field: 'actions2', + field: 'download_live', type: 'actions', headerName: 'Download', width: 100, @@ -393,7 +447,34 @@ export default function PdfTable({recordList}) { label="Download" className="textPrimary" onClick={handleDownloadClick(id)} - color="download" + // CHANGED: Use a standard MUI color like "primary" + color="primary" + /> + + ] + }, + }, + { + field: 'download_flat', // Unique field name + type: 'actions', + headerName: ( +
+ Download +
+ without signature +
+ ), + width: 100, + cellClassName: 'actionsFlatDownload', + getActions: ({id}) => { + return [ + + } + label="Download flat" + className="textPrimary" + onClick={handleFlatDownloadClick(id)} + color="default" /> ]