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");
|
const token = localStorage.getItem("token");
|
||||||
if (!token || !libraryId) return;
|
if (!token || !libraryId) return;
|
||||||
|
|
||||||
const loading = document.getElementById("loading");
|
this.isLoading = true;
|
||||||
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 {
|
try {
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
@@ -60,8 +54,7 @@ async function loadBookshelf(libraryId: string): Promise<void> {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error loading bookshelf:", error);
|
console.error("Error loading bookshelf:", error);
|
||||||
showToast("Error loading books", "error");
|
showToast("Error loading books", "error");
|
||||||
} finally {
|
this.isLoading = false;
|
||||||
if (loading) loading.style.display = "none";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,21 +69,14 @@ function showEmptyState(): void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function renderBookshelf(): 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) {
|
if (!mediaItems || mediaItems.length === 0) {
|
||||||
showEmptyState();
|
this.isLoading = false;
|
||||||
|
this.hasBooks = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
booksGrid.classList.remove("hidden");
|
const booksGrid = document.getElementById("books-grid");
|
||||||
|
if (!booksGrid) return;
|
||||||
|
|
||||||
const booksPerShelf = 6;
|
const booksPerShelf = 6;
|
||||||
const shelves: unknown[][] = [];
|
const shelves: unknown[][] = [];
|
||||||
@@ -199,6 +185,11 @@ export {
|
|||||||
};
|
};
|
||||||
|
|
||||||
Alpine.data("bookshelf", () => ({
|
Alpine.data("bookshelf", () => ({
|
||||||
|
// State Variables
|
||||||
|
isLoading: true,
|
||||||
|
hasBooks: false,
|
||||||
|
|
||||||
|
// Methods
|
||||||
changePage,
|
changePage,
|
||||||
initBookshelf,
|
initBookshelf,
|
||||||
loadBookshelf,
|
loadBookshelf,
|
||||||
|
|||||||
Reference in New Issue
Block a user