Transaction log will appear here...
`;
return;
}
transactionLog.innerHTML = transactionState.log.map(entry =>
`
${entry.message}
${entry.timestamp}
`
).join('');
};
const renderStepper = () => {
stepperContainer.innerHTML = STEPS.map((step, index) => {
if (index === STEPS.length - 1) return ''; // Don't render "Completed" as a step
let statusClass = 'upcoming';
if (index < transactionState.currentStep) statusClass = 'completed';
if (index === transactionState.currentStep) statusClass = 'active';
return `
${statusClass === 'completed' ? '✓' : index + 1}
${step.text}
${index < STEPS.length - 2 ? '
' : ''}
`;
}).join('');
};
const updateUI = () => {
renderStepper();
const nextStepIndex = transactionState.currentStep + 1;
if (nextStepIndex < STEPS.length) {
const nextStep = STEPS[nextStepIndex];
nextActionText.textContent = nextStep.nextActionDesc;
actionBtn.textContent = nextStep.actionText;
actionBtn.disabled = false;
}
if (transactionState.currentStep === STEPS.length - 2) { // When at "Funds Released"
const finalStep = STEPS[STEPS.length - 1];
nextActionText.textContent = finalStep.nextActionDesc;
actionBtn.textContent = finalStep.actionText;
actionBtn.disabled = true;
actionBtn.classList.add('bg-gray-400', 'cursor-not-allowed');
actionBtn.classList.remove('bg-indigo-600', 'hover:bg-indigo-700');
downloadPdfBtn.disabled = false;
}
if (transactionState.currentStep > -1) {
downloadPdfBtn.disabled = false;
}
};
const advanceStep = () => {
if (transactionState.currentStep === -1) { // Starting
updateDetailsFromInputs();
addToLog(`Transaction initiated for ${transactionState.details.itemDescription}.`);
} else {
const currentStepInfo = STEPS[transactionState.currentStep];
addToLog(`${currentStepInfo.text} confirmed.`);
}
transactionState.currentStep++;
updateUI();
};
const generatePdf = () => {
if (!transactionState.details.referenceNumber) return;
const { jsPDF } = window.jspdf;
const doc = new jsPDF({ orientation: 'p', unit: 'pt', format: 'a4' });
const docWidth = doc.internal.pageSize.getWidth();
// PDF Header
doc.setFillColor(30, 41, 59);
doc.rect(0, 0, docWidth, 75, 'F');
doc.setFontSize(24);
doc.setTextColor(255);
doc.setFont('helvetica', 'bold');
doc.text("Escrow Agreement Summary", 40, 45);
// Reference and Date
let yPos = 110;
doc.setFontSize(11);
doc.setTextColor(100);
doc.text(`Ref #: ${transactionState.details.referenceNumber}`, 40, yPos);
doc.text(`Date: ${new Date().toLocaleDateString('en-US')}`, docWidth - 40, yPos, { align: 'right' });
yPos += 30;
// Parties Involved
doc.setFontSize(16);
doc.setTextColor(30);
doc.text("Parties Involved", 40, yPos);
yPos += 20;
doc.autoTable({
startY: yPos,
theme: 'grid',
head: [['Role', 'Name']],
body: [['Buyer', transactionState.details.buyerName], ['Seller', transactionState.details.sellerName]],
headStyles: { fillColor: [45, 55, 72] }
});
yPos = doc.autoTable.previous.finalY + 30;
// Transaction Details
doc.setFontSize(16);
doc.text("Transaction Details", 40, yPos);
yPos += 20;
doc.autoTable({
startY: yPos,
theme: 'plain',
body: [
['Escrow Amount:', `$${transactionState.details.escrowAmount}`],
['Item Description:', transactionState.details.itemDescription],
['Release Conditions:', transactionState.details.releaseConditions],
['Current Status:', STEPS[transactionState.currentStep].text]
],
styles: { fontSize: 11, cellPadding: 8 },
columnStyles: { 0: { fontStyle: 'bold' } }
});
// Footer & Signatures
const pageHeight = doc.internal.pageSize.getHeight();
const footerY = pageHeight - 120;
doc.setFontSize(10);
doc.setTextColor(150);
doc.text("By proceeding with the transaction, both parties agree to the terms outlined in this summary.", 40, footerY, { maxWidth: docWidth - 80 });
doc.setLineWidth(1);
doc.setDrawColor(150);
doc.line(40, footerY + 50, docWidth / 2 - 20, footerY + 50);
doc.line(docWidth / 2 + 20, footerY + 50, docWidth - 40, footerY + 50);
doc.text("Buyer's Signature", 40, footerY + 65);
doc.text("Seller's Signature", docWidth / 2 + 20, footerY + 65);
doc.save(`Escrow_Agreement_${transactionState.details.referenceNumber}.pdf`);
};
// --- EVENT LISTENERS ---
actionBtn.addEventListener('click', advanceStep);
downloadPdfBtn.addEventListener('click', generatePdf);
// --- INITIALIZATION ---
renderStepper();
});