Reading List Generator
Your Reading List (Editable)
Go to the "Generation Settings" tab to select options and generate your reading list.
Generation Options
Error: No book data found for this genre.
`; showTab("rlg-tab-dashboard"); return; } const selectedBooks = getRandomUnique(source, numToGen); renderDashboard(selectedBooks); showTab("rlg-tab-dashboard"); } /** * Renders the editable checklist to the dashboard */ function renderDashboard(books) { dashboardList.innerHTML = ""; // Clear list if (books.length === 0) { dashboardList.innerHTML = `No books selected. Please configure and generate the plan.
`; return; } // Add header row for desktop view if (window.innerWidth > 768) { const headerRow = document.createElement('div'); headerRow.className = 'rlg-dash-header'; headerRow.innerHTML = `Book Title
Author
Priority
Notes/Why
`;
dashboardList.appendChild(headerRow);
}
books.forEach((book, index) => {
const itemEl = document.createElement("div");
itemEl.className = "rlg-dash-item";
itemEl.dataset.id = `book-${index}`;
itemEl.innerHTML = `
`;
dashboardList.appendChild(itemEl);
});
// Setup listeners for the new elements (remove functionality)
setupDashboardListeners();
}
/**
* Attaches listeners to the dashboard elements
*/
function setupDashboardListeners() {
if (!dashboardList) return;
// Listen for removal clicks (delegation)
dashboardList.querySelectorAll('button[data-action="remove"]').forEach(button => {
button.addEventListener('click', handleDashboardRemove);
});
}
/**
* Handles removing an item directly from the dashboard
*/
function handleDashboardRemove(e) {
const itemEl = e.target.closest(".rlg-dash-item");
if (itemEl) {
itemEl.remove();
}
}
/**
* 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;
}
const genreText = genreSelect.options[genreSelect.selectedIndex].text;
const title = `Reading List: ${genreText}`;
const { jsPDF } = window.jspdf;
const doc = new jsPDF("p", "pt", "a4");
const margin = 40;
let yPos = margin;
const tableHead = [["#", "Title", "Author", "Priority", "Notes"]];
const tableBody = [];
// Get data *from the dashboard's editable fields*
const dashItems = dashboardList.querySelectorAll(".rlg-dash-item");
if (dashItems.length === 0) {
alert("Reading list is empty. Please generate items before downloading.");
return;
}
dashItems.forEach((item, index) => {
const title = item.querySelector(".rlg-dash-title").value;
const author = item.querySelector(".rlg-dash-author").value;
const priority = item.querySelector(".rlg-dash-priority").value;
const notes = item.querySelector(".rlg-dash-notes").value;
tableBody.push([
index + 1,
title,
author,
priority,
notes
]);
});
// Document Title
doc.setFontSize(18);
doc.text(title, margin, yPos);
yPos += 30;
doc.autoTable({
startY: yPos,
head: tableHead,
body: tableBody,
theme: 'striped',
headStyles: {
fillColor: [0, 115, 230], // Blue
textColor: [255, 255, 255],
},
columnStyles: {
0: { cellWidth: 20 },
1: { cellWidth: 150 },
2: { cellWidth: 100 },
3: { cellWidth: 60 },
4: { cellWidth: 'auto' },
},
styles: {
fontSize: 9,
cellPadding: 3,
overflow: 'linebreak'
},
margin: { left: margin, right: margin }
});
doc.save(`${title.replace(/ /g,"_")}_List.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
if (pdfBtn) {
pdfBtn.addEventListener("click", downloadPDF);
}
// Initial State: Generate a default list on load
handleGenerate();
showTab("rlg-tab-dashboard");
});
