No stages defined yet.
";
}
appState.stages.forEach(function(stage) {
var item = document.createElement("div");
item.className = "sfd-stage-item";
item.innerHTML = `
${stage.name}: ${stage.objective.substring(0, 50)}...
`;
stageList.appendChild(item);
});
};
var renderDashboardTab = function() {
projectTitleDisplay.textContent = appState.projectName;
// 1. Render Visual Funnel
funnelVisualContainer.innerHTML = "";
tableBody.innerHTML = "";
var totalStages = appState.stages.length;
if (totalStages === 0) {
funnelVisualContainer.innerHTML = "
No stages defined. Go to Configuration tab.
";
tableBody.innerHTML = "
| No stages defined. |
";
return;
}
var baseWidth = 100;
var widthDecrement = baseWidth / totalStages;
// Render nodes from top (widest) to bottom (narrowest)
appState.stages.forEach(function(stage, index) {
// Width decreases by a set amount for each stage
var widthPercent = baseWidth - (widthDecrement * index);
var node = document.createElement("div");
node.className = "sfd-stage-node";
node.style.width = widthPercent + "%";
node.style.backgroundColor = stage.content.includes('Trial') || stage.content.includes('Demo') ? '#ffedd5' : '#ffffff';
node.innerHTML = `
${index + 1}. ${stage.name.toUpperCase()}
${stage.objective}
`;
funnelVisualContainer.appendChild(node);
// 2. Render Report Table Row
var tr = document.createElement("tr");
tr.innerHTML = `
${stage.name} |
${stage.objective} |
${stage.content.replace(/\n/g, ' ')} |
${stage.metrics.replace(/\n/g, ' ')} |
`;
tableBody.appendChild(tr);
});
};
// --- Event Handlers ---
// Update Dashboard Button
updateBtn.addEventListener("click", function() {
appState.projectName = projectNameInput.value || "Untitled Funnel";
saveState();
renderDashboardTab();
showTab('sfd-tab-dashboard');
});
// Add Stage
addStageBtn.addEventListener("click", function() {
var name = stageNameInput.value.trim();
var objective = stageObjectiveInput.value.trim();
var content = stageContentInput.value.trim();
var metrics = stageMetricsInput.value.trim();
if (!name || !objective) {
alert("Please enter a Stage Name and Objective.");
return;
}
var newStage = {
id: Date.now(),
name: name,
objective: objective,
content: content,
metrics: metrics
};
appState.stages.push(newStage);
saveState();
renderConfigTab();
// Clear form
stageNameInput.value = "";
stageObjectiveInput.value = "";
stageContentInput.value = "";
stageMetricsInput.value = "";
});
// Remove Stage (Event Delegation)
stageList.addEventListener("click", function(e) {
if (e.target.classList.contains("sfd-remove-btn")) {
var id = parseInt(e.target.dataset.id);
appState.stages = appState.stages.filter(function(stage) { return stage.id !== id; });
saveState();
renderConfigTab();
}
});
// PDF Download
pdfBtn.addEventListener("click", function() {
var jsPDF = window.jspdf.jsPDF;
var fileName = `${appState.projectName.replace(/ /g, '_')}_Funnel_Document.pdf`;
// Temporarily adjust minimum table width for PDF quality
var table = document.getElementById('sfd-report-table');
var originalMinWidth = table.style.minWidth;
table.style.minWidth = '1100px';
html2canvas(exportArea, {
scale: 2,
useCORS: true,
backgroundColor: '#ffffff'
}).then(function(canvas) {
// Restore styles
table.style.minWidth = originalMinWidth;
var imgData = canvas.toDataURL('image/png');
var doc = new jsPDF({
orientation: 'l', // Landscape is better for wide tables
unit: 'pt',
format: 'a4'
});
var pdfWidth = doc.internal.pageSize.getWidth();
var pdfHeight = doc.internal.pageSize.getHeight();
var imgProps = doc.getImageProperties(imgData);
var imgWidth = imgProps.width;
var imgHeight = imgProps.height;
var margin = 30;
var usableWidth = pdfWidth - (2 * margin);
var ratio = usableWidth / imgWidth;
var scaledHeight = imgHeight * ratio;
// Handle multi-page if content exceeds page height
if (scaledHeight > pdfHeight - (2 * margin)) {
var pageHeight = pdfHeight - (2 * margin);
var heightLeft = scaledHeight;
var position = 0;
while (heightLeft > 0) {
doc.addImage(imgData, 'PNG', margin, position + margin, usableWidth, scaledHeight);
heightLeft -= pageHeight;
position -= pageHeight;
if (heightLeft > 0) {
doc.addPage();
}
}
} else {
// Single page
doc.addImage(imgData, 'PNG', margin, margin, usableWidth, scaledHeight);
}
doc.save(fileName);
}).catch(function(err) {
// Restore styles even if PDF fails
table.style.minWidth = originalMinWidth;
console.error("SFD PDF Error:", err);
// alert("An error occurred while generating the PDF."); // Per spec
});
});
// --- Initial Load ---
loadState();
renderConfigTab();
renderDashboardTab();
showTab('sfd-tab-dashboard');
});