${actionButtons}
`;
workflowStepsEl.appendChild(stepDiv);
// Add to history if action was taken
if (approver.status !== 'pending') {
const historyP = document.createElement('p');
const formattedDate = approver.date.toLocaleString('en-US', { year: 'numeric', month: 'short', day: 'numeric', hour: '2-digit', minute: '2-digit' });
historyP.innerHTML = `${approver.name} ${approver.status} on ${formattedDate}.`;
approvalHistoryEl.appendChild(historyP);
}
});
// Add event listeners to new action buttons
document.querySelectorAll('.approve-btn').forEach(btn => btn.addEventListener('click', handleApproval));
document.querySelectorAll('.reject-btn').forEach(btn => btn.addEventListener('click', handleRejection));
}
// Handle approval action
function handleApproval(e) {
const index = parseInt(e.target.dataset.index);
const approver = workflow.approvers[index];
approver.status = 'approved';
approver.date = new Date();
if (index + 1 < workflow.approvers.length) {
workflow.currentApproverIndex++;
} else {
workflow.isComplete = true;
workflow.finalStatus = 'Fully Approved';
moveToFinalTab();
}
renderDashboard();
}
// Handle rejection action
function handleRejection(e) {
const index = parseInt(e.target.dataset.index);
const approver = workflow.approvers[index];
approver.status = 'rejected';
approver.date = new Date();
workflow.isComplete = true;
workflow.finalStatus = 'Rejected';
moveToFinalTab();
renderDashboard();
}
// Update the overall workflow status display
function updateWorkflowStatus() {
const statusEl = document.getElementById('workflowStatus');
statusEl.textContent = workflow.finalStatus;
if (workflow.finalStatus === 'In Progress') {
statusEl.className = 'font-semibold px-2 py-1 rounded-full text-sm bg-yellow-100 text-yellow-800';
} else if (workflow.finalStatus === 'Fully Approved') {
statusEl.className = 'font-semibold px-2 py-1 rounded-full text-sm bg-green-100 text-green-800';
} else {
statusEl.className = 'font-semibold px-2 py-1 rounded-full text-sm bg-red-100 text-red-800';
}
}
// Move to the final tab and render its content
function moveToFinalTab() {
renderFinalSummary();
switchTab(3);
}
// Render the content of the final summary tab
function renderFinalSummary() {
document.getElementById('finalDocName').textContent = workflow.documentName;
const finalStatusEl = document.getElementById('finalStatus');
finalStatusEl.textContent = workflow.finalStatus;
if (workflow.finalStatus === 'Fully Approved') {
finalStatusEl.className = 'text-3xl font-bold p-4 rounded-lg inline-block bg-green-100 text-green-800';
} else {
finalStatusEl.className = 'text-3xl font-bold p-4 rounded-lg inline-block bg-red-100 text-red-800';
}
// Populate PDF content
document.getElementById('generationDate').textContent = new Date().toLocaleString('en-US');
const pdfTableBody = document.getElementById('pdfTableBody');
pdfTableBody.innerHTML = '';
workflow.approvers.forEach(approver => {
const tr = document.createElement('tr');
tr.className = 'border-b';
const statusText = approver.status.charAt(0).toUpperCase() + approver.status.slice(1);
const dateText = approver.date ? approver.date.toLocaleString('en-US') : 'N/A';
tr.innerHTML = `
${approver.name}
${statusText}
${dateText}
`;
pdfTableBody.appendChild(tr);
});
}
// Generate and download the PDF
async function generatePdf() {
const { jsPDF } = window.jspdf;
const pdfContent = document.getElementById('pdfContent');
// Temporarily make the content visible for capture if it's not
const wasHidden = pdfContent.offsetParent === null;
if(wasHidden) pdfContent.style.display = 'block';
try {
const canvas = await html2canvas(pdfContent, {
scale: 2, // Higher scale for better quality
useCORS: true
});
const imgData = canvas.toDataURL('image/png');
const pdf = new jsPDF({
orientation: 'portrait',
unit: 'pt',
format: 'a4'
});
const pdfWidth = pdf.internal.pageSize.getWidth();
const pdfHeight = pdf.internal.pageSize.getHeight();
const imgWidth = canvas.width;
const imgHeight = canvas.height;
const ratio = imgWidth / imgHeight;
let finalImgWidth = pdfWidth - 40; // with margin
let finalImgHeight = finalImgWidth / ratio;
if (finalImgHeight > pdfHeight - 40) {
finalImgHeight = pdfHeight - 40;
finalImgWidth = finalImgHeight * ratio;
}
const x = (pdfWidth - finalImgWidth) / 2;
const y = 20;
pdf.addImage(imgData, 'PNG', x, y, finalImgWidth, finalImgHeight);
pdf.save(`approval-summary-${workflow.documentName.replace(/\s+/g, '-')}.pdf`);
} catch (error) {
console.error("Error generating PDF:", error);
alert("Could not generate PDF. Please try again.");
} finally {
if(wasHidden) pdfContent.style.display = ''; // Hide it back if it was hidden
}
}
// Initialize the view
updateNavButtons();
});
