Publishing Checklist Generator

Publishing Checklist Generator

Your Publication Checklist (Editable)

Go to the "Configuration" tab to select your publication type and generate your checklist.

Publication Details

No checklist items. Please configure and generate the plan.

"; return; } let currentPhase = ""; // Add header row for desktop view if (window.innerWidth > 768) { const headerRow = document.createElement('div'); headerRow.className = 'pub-dash-header'; headerRow.innerHTML = `
Checklist Item
Status
Notes
`; dashboardList.appendChild(headerRow); } currentChecklist.forEach(item => { if (item.phase !== currentPhase) { // Add Phase Header const h3 = document.createElement('h3'); h3.textContent = item.phase; dashboardList.appendChild(h3); currentPhase = item.phase; } const itemEl = document.createElement("div"); itemEl.className = "pub-dash-item"; itemEl.dataset.id = item.id; itemEl.innerHTML = ` `; dashboardList.appendChild(itemEl); }); // Setup listeners for the new elements setupDashboardListeners(); } /** * Attaches listeners to the dashboard elements */ function setupDashboardListeners() { if (!dashboardList) return; // Listen for all input/change events to update state dashboardList.querySelectorAll('input, select').forEach(element => { element.addEventListener('change', handleDashboardUpdate); element.addEventListener('input', handleDashboardUpdate); }); // Listen for removal clicks (delegation) dashboardList.querySelectorAll('button[data-action="remove"]').forEach(button => { button.addEventListener('click', handleDashboardRemove); }); } /** * Handles updates made directly to items (inputs, selects) */ function handleDashboardUpdate(e) { const itemEl = e.target.closest(".pub-dash-item"); if (!itemEl) return; const itemId = parseInt(itemEl.dataset.id); const itemIndex = currentChecklist.findIndex(i => i.id === itemId); if (itemIndex === -1) return; const field = e.target.dataset.field; if (!field) return; // Update the master state array currentChecklist[itemIndex][field] = e.target.value; } /** * Handles removing an item directly from the dashboard */ function handleDashboardRemove(e) { const itemEl = e.target.closest(".pub-dash-item"); if (!itemEl) return; const itemId = parseInt(itemEl.dataset.id); // Remove from master array currentChecklist = currentChecklist.filter(item => item.id !== itemId); // Re-render the dashboard to clean up phase headers renderDashboard(); } /** * Generates a PDF report from the dashboard data */ function downloadPDF() { if (typeof window.jspdf === 'undefined' || typeof window.jspdf.jsPDF.autoTable === 'undefined') { alert("Error: PDF libraries could not be loaded. Please try again."); return; } if (currentChecklist.length === 0) { alert("Checklist is empty. Please generate a checklist first."); return; } const { jsPDF } = window.jspdf; const doc = new jsPDF("p", "pt", "a4"); const margin = 40; let yPos = margin; const tableHead = [["Item", "Status", "Notes"]]; let currentPhase = ""; // Document Title doc.setFontSize(18); doc.text(`Publishing Checklist: ${configTitle.value}`, margin, yPos); yPos += 15; doc.setFontSize(10); doc.setTextColor(100); doc.text(`Type: ${configType.options[configType.selectedIndex].text} | Target Audience: ${configAudience.value}`, margin, yPos); yPos += 30; doc.setTextColor(51); // Reset text color // Loop through checklist items to create tables grouped by Phase currentChecklist.forEach(item => { if (item.phase !== currentPhase) { // Add new phase header currentPhase = item.phase; // Add a page break if too close to bottom if (yPos > doc.internal.pageSize.getHeight() - 80) { doc.addPage(); yPos = margin; } doc.setFontSize(14); doc.setFont(undefined, 'bold'); doc.text(currentPhase, margin, yPos); yPos += 20; // Start a new table for the phase doc.autoTable({ startY: yPos, head: tableHead, body: [], // Start with an empty body theme: 'striped', headStyles: { fillColor: [0, 115, 230], // Blue textColor: [255, 255, 255], fontSize: 10 }, columnStyles: { 0: { cellWidth: 250 }, 1: { cellWidth: 60 }, 2: { cellWidth: 'auto' }, }, styles: { fontSize: 9, cellPadding: 3, overflow: 'linebreak' }, margin: { left: margin, right: margin } }); yPos = doc.autoTable.previous.finalY; // Set Y to where the table ended } // Add row to the current table body (hack: access previous table body array) const lastTableBody = doc.autoTable.previous.body; if (lastTableBody) { lastTableBody.push([ item.item, item.status, item.notes ]); } }); // Re-run the last autoTable call to render the final rows of the last group if (doc.autoTable.previous) { doc.autoTable(doc.autoTable.previous.settings); } doc.save(`${configTitle.value.replace(/ /g,"_")}_Checklist.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 (generateBtn) { generateBtn.addEventListener("click", handleGenerate); } // Dashboard Tab Listeners (Delegated) if (dashboardList) { // Event delegation will handle updates and removal logic } // Initial State: Generate a default checklist on load handleGenerate(); showTab("pub-tab-dashboard"); });
Scroll to Top