No use cases added yet.
";
return;
}
useCases.forEach(uc => {
const itemEl = document.createElement("div");
itemEl.className = "stcs-config-list-item";
itemEl.dataset.id = uc.id;
itemEl.innerHTML = `
${escapeHTML(uc.text.substring(0, 50))}...
`;
configUsecaseList.appendChild(itemEl);
});
}
// --- Dashboard Management ---
function renderDashboard(isInitial = true) {
// Get config values
const name = configName.value;
const func = configFunction.value;
const inventor = configInventor.value;
const principle = configPrinciple.value;
// --- Build Dashboard HTML ---
dashboardOutput.innerHTML = `
`;
// Populate Use Case List
const ucListEl = dashboardOutput.querySelector('#stcs-dash-usecase-list');
useCases.forEach(uc => {
const li = document.createElement('li');
li.dataset.id = uc.id;
li.innerHTML = `
`;
ucListEl.appendChild(li);
});
setupDashboardListeners();
if (!isInitial) showTab('stcs-tab-dashboard');
}
/**
* Attaches listeners to the dashboard elements
*/
function setupDashboardListeners() {
const output = dashboardOutput;
if (!output) return;
// Event delegation for removal
output.addEventListener('click', handleRemoveUsecase);
// Event delegation for input/change updates
output.addEventListener('input', handleDashboardUpdate);
output.addEventListener('change', handleDashboardUpdate);
}
/**
* Handles updates made directly to the dashboard inputs/textareas
*/
function handleDashboardUpdate(e) {
const target = e.target;
const value = target.value;
// Update Config Inputs based on Dashboard edits
if (target.id === 'stcs-dash-name') configName.value = value;
else if (target.id === 'stcs-dash-function') configFunction.value = value;
else if (target.id === 'stcs-dash-inventor') configInventor.value = value;
else if (target.id === 'stcs-dash-principle') configPrinciple.value = value;
// Update Use Case State
const li = target.closest('li');
if (li && target.dataset.field === 'text') {
const ucId = li.dataset.id;
const uc = useCases.find(u => u.id === ucId);
if (uc) {
uc.text = value;
// Rerender config list immediately
updateConfigUsecaseDisplay();
}
}
}
/**
* Generates a PDF report from the dashboard data
*/
function downloadPDF() {
if (typeof window.jspdf === 'undefined') {
alert("Error: PDF library could not be loaded. Please try again.");
return;
}
const name = configName.value || "Sci-Fi Tech Concept";
const func = configFunction.value;
const inventor = configInventor.value;
const principle = configPrinciple.value;
if (!name.trim()) {
alert("Please generate the concept sheet first.");
return;
}
const { jsPDF } = window.jspdf;
const doc = new jsPDF("p", "pt", "a4");
const margin = 40;
let yPos = margin;
const lineHeight = 16;
const usableWidth = doc.internal.pageSize.getWidth() - margin * 2;
// Function to add a section
function addSection(title, text) {
const titleHeight = 20;
const textLines = doc.splitTextToSize(text, usableWidth);
const textHeight = textLines.length * lineHeight;
if (yPos + titleHeight + textHeight > doc.internal.pageSize.getHeight() - margin) {
doc.addPage();
yPos = margin;
}
doc.setFontSize(14);
doc.setFont(undefined, 'bold');
doc.text(title, margin, yPos);
yPos += lineHeight * 1.5;
doc.setFontSize(11);
doc.setFont(undefined, 'normal');
doc.text(textLines, margin, yPos);
yPos += textHeight + lineHeight * 1.5;
}
// Function to add a list
function addList(title, items) {
addSection(title, '', false); // Add title header
doc.setFontSize(11);
doc.setFont(undefined, 'normal');
items.forEach((item, index) => {
const itemLines = doc.splitTextToSize(`- ${item.text}`, usableWidth - 20);
if (yPos + itemLines.length * lineHeight > doc.internal.pageSize.getHeight() - margin) {
doc.addPage();
yPos = margin;
}
doc.text(itemLines, margin + 10, yPos);
yPos += itemLines.length * lineHeight;
});
yPos += lineHeight;
}
// --- Document Title ---
doc.setFontSize(20);
doc.setFont(undefined, 'bold');
doc.text(`Concept Sheet: ${name}`, doc.internal.pageSize.getWidth() / 2, yPos, { align: 'center' });
yPos += lineHeight * 2.5;
// --- Core Details ---
addSection("1. Core Technical Data",
`Inventor/Origin: ${inventor}\nScientific Principle: ${principle}`
);
// --- Primary Function ---
addSection("2. Primary Function / Summary", func);
// --- Use Cases ---
addList("3. Use Cases & Applications", useCases);
doc.save(`${name.replace(/ /g,"_")}_Concept_Sheet.pdf`);
}
/**
* Helper to escape HTML
*/
function escapeHTML(str) {
if (!str) return "";
return str
.replace(/&/g, "&")
.replace(//g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
// --- 4. INITIALIZATION & EVENT LISTENERS ---
// Tab Listeners
tabButtons.forEach((btn) => {
btn.addEventListener("click", () => showTab(btn.dataset.target));
});
navButtons.forEach((btn) => {
btn.addEventListener("click", () => showTab(btn.dataset.target));
});
// Config Tab Listeners
if (addUsecaseForm) {
addUsecaseForm.addEventListener("submit", handleAddUsecase);
}
if (configUsecaseList) {
configUsecaseList.addEventListener("click", handleRemoveUsecase);
}
if (generateBtn) {
generateBtn.addEventListener("click", () => renderDashboard(false));
}
// PDF Button
if (pdfBtn) {
pdfBtn.addEventListener("click", downloadPDF);
}
// Initial config list display
updateConfigUsecaseDisplay();
// Initial State: Generate dashboard with samples
renderDashboard();
showTab("stcs-tab-dashboard");
});