refactor(bookshelf): migrate from DOM manipulation to Alpine.js reactive state
Replace direct DOM manipulation with Alpine.js reactive state variables: - Add isLoading and hasBooks state to bookshelf component - Convert loadBookshelf() to update isLoading state instead of toggling DOM visibility - Convert renderBookshelf() to use reactive state for empty state handling - Remove redundant getElementById() calls for loading/empty-state elements This change improves maintainability by: - Centralizing UI state in the Alpine component - Eliminating direct DOM manipulation scattered across functions - Making the component's state more explicit and trackable - Following Alpine.js reactive programming patterns The UI will now respond to state changes automatically rather than requiring manual DOM updates throughout the lifecycle methods.
This commit is contained in:
+11
-20
@@ -33,13 +33,7 @@ async function loadBookshelf(libraryId: string): Promise<void> {
|
||||
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");
|
||||
this.isLoading = true;
|
||||
|
||||
try {
|
||||
const response = await fetch(
|
||||
@@ -60,8 +54,7 @@ async function loadBookshelf(libraryId: string): Promise<void> {
|
||||
} catch (error) {
|
||||
console.error("Error loading bookshelf:", error);
|
||||
showToast("Error loading books", "error");
|
||||
} finally {
|
||||
if (loading) loading.style.display = "none";
|
||||
this.isLoading = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,21 +69,14 @@ function showEmptyState(): void {
|
||||
}
|
||||
|
||||
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();
|
||||
this.isLoading = false;
|
||||
this.hasBooks = false;
|
||||
return;
|
||||
}
|
||||
|
||||
booksGrid.classList.remove("hidden");
|
||||
const booksGrid = document.getElementById("books-grid");
|
||||
if (!booksGrid) return;
|
||||
|
||||
const booksPerShelf = 6;
|
||||
const shelves: unknown[][] = [];
|
||||
@@ -199,6 +185,11 @@ export {
|
||||
};
|
||||
|
||||
Alpine.data("bookshelf", () => ({
|
||||
// State Variables
|
||||
isLoading: true,
|
||||
hasBooks: false,
|
||||
|
||||
// Methods
|
||||
changePage,
|
||||
initBookshelf,
|
||||
loadBookshelf,
|
||||
|
||||
Reference in New Issue
Block a user