Reading List Organizer

Reading List Organizer

Curate, track, and manage your personal library.

Add a New Book

My Reading List

No books found. Add one to start your list or adjust your filter.

`; } else { filteredBooks.forEach(book => { const bookCard = document.createElement('div'); bookCard.className = 'book-card-animation p-4 border rounded-lg bg-white flex flex-col justify-between'; bookCard.dataset.id = book.id; const statusColors = { 'To Read': 'bg-blue-100 text-blue-800', 'Reading': 'bg-yellow-100 text-yellow-800', 'Finished': 'bg-green-100 text-green-800' }; bookCard.innerHTML = `

${book.title}

${book.status}

by ${book.author}

${book.genre}

`; bookListGrid.appendChild(bookCard); }); } }; const handleFormSubmit = (e) => { e.preventDefault(); const id = bookIdInput.value; const bookData = { title: bookTitle.value, author: bookAuthor.value, genre: bookGenre.value, status: bookStatus.value, }; if (id) { // Editing existing book const bookIndex = books.findIndex(b => b.id == id); if (bookIndex > -1) { books[bookIndex] = { ...books[bookIndex], ...bookData }; } } else { // Adding new book bookData.id = Date.now(); books.push(bookData); } saveBooks(); renderBooks(); bookForm.reset(); resetFormState(); }; const handleBookListClick = (e) => { const editBtn = e.target.closest('.edit-btn'); const deleteBtn = e.target.closest('.delete-btn'); if (!editBtn && !deleteBtn) return; const bookCard = e.target.closest('[data-id]'); const bookId = parseInt(bookCard.dataset.id); if (editBtn) { const book = books.find(b => b.id === bookId); if (book) { bookTitle.value = book.title; bookAuthor.value = book.author; bookGenre.value = book.genre; bookStatus.value = book.status; bookIdInput.value = book.id; formTitle.textContent = 'Edit Book'; submitBtn.textContent = 'Update Book'; cancelEditBtn.classList.remove('hidden'); bookTitle.focus(); window.scrollTo({ top: 0, behavior: 'smooth' }); } } else if (deleteBtn) { books = books.filter(b => b.id !== bookId); saveBooks(); renderBooks(); } }; const resetFormState = () => { bookIdInput.value = ''; formTitle.textContent = 'Add a New Book'; submitBtn.textContent = 'Add to List'; cancelEditBtn.classList.add('hidden'); bookForm.reset(); }; const generatePDF = () => { const printableContent = document.createElement('div'); printableContent.style.position = 'absolute'; printableContent.style.left = '-9999px'; printableContent.style.width = '210mm'; // A4 width printableContent.innerHTML = `

My Reading List

${books.map(book => ` `).join('')}
TitleAuthorGenreStatus
${book.title} ${book.author} ${book.genre} ${book.status}
`; document.body.appendChild(printableContent); html2canvas(printableContent, { scale: 2 }).then(canvas => { document.body.removeChild(printableContent); const imgData = canvas.toDataURL('image/png'); const { jsPDF } = window.jspdf; const pdf = new jsPDF({ orientation: 'portrait', unit: 'mm', format: 'a4' }); const pdfWidth = pdf.internal.pageSize.getWidth(); const ratio = canvas.width / canvas.height; const pdfImgWidth = pdfWidth - 20; const pdfImgHeight = pdfImgWidth / ratio; pdf.addImage(imgData, 'PNG', 10, 10, pdfImgWidth, pdfImgHeight); pdf.save('My_Reading_List.pdf'); }).catch(err => { if (document.body.contains(printableContent)) { document.body.removeChild(printableContent); } console.error("PDF generation failed:", err); }); }; // --- Event Listeners --- if (bookForm) bookForm.addEventListener('submit', handleFormSubmit); if (bookListGrid) bookListGrid.addEventListener('click', handleBookListClick); if (cancelEditBtn) cancelEditBtn.addEventListener('click', resetFormState); if (filterStatusSelect) filterStatusSelect.addEventListener('change', renderBooks); if (downloadPdfBtn) downloadPdfBtn.addEventListener('click', generatePDF); // --- Initial Load --- loadBooks(); renderBooks(); });
Scroll to Top