import { Alpine } from "./alpine"; import { showToast } from "./toast"; let currentLibraryId = ""; let mediaItems: unknown[] = []; function initBookshelf(): void { const savedLibrary = localStorage.getItem("selectedLibrary"); if (savedLibrary) { const select = document.getElementById("library-select") as HTMLSelectElement; if (select && select.value) { currentLibraryId = savedLibrary; loadBookshelf(savedLibrary); } } } function selectLibrary(): void { const select = document.getElementById("library-select") as HTMLSelectElement; if (!select) return; const libraryId = select.value; if (!libraryId) return; currentLibraryId = libraryId; localStorage.setItem("selectedLibrary", libraryId); loadBookshelf(libraryId); } async function loadBookshelf(libraryId: string): Promise { const token = localStorage.getItem("token"); if (!token || !libraryId) return; const loading = document.getElementById("loading"); const booksGrid = document.getElementById("books-grid"); const emptyState = document.getElementById("empty-state"); if (loading) loading.style.display = "block"; if (booksGrid) booksGrid.classList.add("hidden"); if (emptyState) emptyState.classList.add("hidden"); try { const response = await fetch( `/api/media-items?library_id=${libraryId}&limit=100&offset=0`, { headers: { Authorization: `Bearer ${token}`, "Content-Type": "application/json", }, }, ); if (response.ok) { const data = await response.json(); mediaItems = data; renderBookshelf(); } } catch (error) { console.error("Error loading bookshelf:", error); showToast("Error loading books", "error"); } finally { if (loading) loading.style.display = "none"; } } function showEmptyState(): void { const booksGrid = document.getElementById("books-grid"); const emptyState = document.getElementById("empty-state"); const loading = document.getElementById("loading"); if (loading) loading.style.display = "none"; if (booksGrid) booksGrid.classList.add("hidden"); if (emptyState) emptyState.classList.remove("hidden"); } function renderBookshelf(): void { const booksGrid = document.getElementById("books-grid"); const emptyState = document.getElementById("empty-state"); const loading = document.getElementById("loading"); if (!booksGrid) return; if (loading) loading.style.display = "none"; if (emptyState) emptyState.classList.add("hidden"); if (!mediaItems || mediaItems.length === 0) { showEmptyState(); return; } booksGrid.classList.remove("hidden"); const booksPerShelf = 6; const shelves: unknown[][] = []; for (let i = 0; i < mediaItems.length; i += booksPerShelf) { shelves.push(mediaItems.slice(i, i + booksPerShelf)); } let html = ""; shelves.forEach((shelfBooks) => { html += `
${shelfBooks.map((book: any) => renderBookCard(book)).join("")}
`; }); booksGrid.innerHTML = html; } function renderBookCard(book: any): string { const coverUrl = book.cover_image_path || "/static/placeholder-book.svg"; const authorHtml = book.author ? `

${book.author}

` : ""; return `
${book.title}

${book.title}

${authorHtml}
`; } function viewBook(_bookId: string): void { showToast("Book viewer coming soon!", "info"); } function selectBook(bookId: string): void { localStorage.setItem("selectedBook", bookId); window.location.href = `/books/${bookId}`; } function changePage(page: number): void { if (!currentLibraryId) return; const offset = (page - 1) * 50; loadBookshelfPaginated(currentLibraryId, offset); } async function loadBookshelfPaginated( libraryId: string, offset: number, ): Promise { const token = localStorage.getItem("token"); if (!token) return; try { const response = await fetch( `/api/media-items?library_id=${libraryId}&limit=50&offset=${offset}`, { headers: { Authorization: `Bearer ${token}` } }, ); if (response.ok) { const data = await response.json(); mediaItems = data; renderBookshelf(); } } catch (error) { console.error("Failed to load bookshelf:", error); } } function setupEventDelegation(): void { const container = document.getElementById("books-grid"); if (!container) return; container.addEventListener("click", (e) => { const target = e.target as HTMLElement; const card = target.closest("[data-book-id]") as HTMLElement; if (card) { const bookId = card.dataset.bookId; if (bookId) { selectBook(bookId); } } }); } export { changePage, initBookshelf, loadBookshelf, selectBook, selectLibrary, setupEventDelegation, viewBook, }; Alpine.store("bookshelf", { changePage, initBookshelf, loadBookshelf, selectBook, selectLibrary, setupEventDelegation, viewBook, });