diff --git a/templates/collections.templ b/templates/collections.templ index 3cb50f7..40c75bd 100644 --- a/templates/collections.templ +++ b/templates/collections.templ @@ -150,7 +150,7 @@ templ CollectionDetail(user User, collection CollectionData, books []handlers.Bo /> + + + +

Books in this Collection

0\" x-text=\"selectedBooks.length + ' selected'\" class=\"badge\" style=\"display: none; background-color: var(--accent); color: var(--bg-primary);\">

Books in this Collection

0\" x-text=\"selectedBooks.length + ' selected'\" class=\"badge\" style=\"display: none; background-color: var(--accent); color: var(--bg-primary);\">

Add Books to Collection

Add Books to Collection

books selected
Clear
books selected

Remove from Collection

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, "\" style=\"display: none;\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } @@ -552,113 +560,113 @@ func BookPickerGrid(books []handlers.BookInfo) templ.Component { } ctx = templ.ClearChildren(ctx) for _, book := range books { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 51, "
") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "\">
") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } if book.CoverImagePath != "" { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 53, "\"")") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "\" class=\"w-full aspect-[2/3] object-cover\" loading=\"lazy\" onerror=\"this.src='/static/placeholder-book.svg'\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } else { - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 56, "\"")") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "\" class=\"w-full aspect-[2/3] object-cover\" loading=\"lazy\">") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 58, "

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 61, "\" class=\"absolute top-1 right-1 w-6 h-6 rounded-full flex items-center justify-center text-sm font-bold pointer-events-none\" style=\"background-color: var(--accent); color: var(--bg-primary);\">✓

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } var templ_7745c5c3_Var31 string templ_7745c5c3_Var31, templ_7745c5c3_Err = templ.JoinStringErrs(book.Title) if templ_7745c5c3_Err != nil { - return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/collections.templ`, Line: 383, Col: 87} + return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/collections.templ`, Line: 407, Col: 87} } _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var31)) if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } - templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 61, "

") + templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 62, "

") if templ_7745c5c3_Err != nil { return templ_7745c5c3_Err } diff --git a/web/src/collections.ts b/web/src/collections.ts index 3e0275f..3163ecc 100644 --- a/web/src/collections.ts +++ b/web/src/collections.ts @@ -159,7 +159,7 @@ function renderCollectionBooks(books: BookInfo[]): void {
- @@ -577,8 +577,7 @@ function toggleSelection(this: any, id: string): void { } } -async function removeBook(id: string): Promise { - if (!confirm("Remove this book from the collection?")) return; +async function doRemoveBook(id: string): Promise { const token = localStorage.getItem("token"); if (!token) return; try { @@ -600,14 +599,7 @@ async function removeBook(id: string): Promise { } } -async function bulkRemove(this: any): Promise { - if (this.selectedBooks.length === 0) return; - if ( - !confirm( - `Remove ${this.selectedBooks.length} book(s) from this collection?`, - ) - ) - return; +async function doBulkRemove(ids: string[]): Promise { const token = localStorage.getItem("token"); if (!token) return; try { @@ -619,15 +611,11 @@ async function bulkRemove(this: any): Promise { "Content-Type": "application/json", Authorization: `Bearer ${token}`, }, - body: JSON.stringify({ book_ids: this.selectedBooks }), + body: JSON.stringify({ book_ids: ids }), }, ); if (response.ok) { - showToast( - `Removed ${this.selectedBooks.length} book(s)`, - "success", - ); - this.selectedBooks = []; + showToast(`Removed ${ids.length} book(s)`, "success"); setTimeout(() => location.reload(), 500); } else { showToast("Failed to remove books", "error"); @@ -655,7 +643,6 @@ function filterCollectionBooks(): void { } export { - bulkRemove, closeCollectionModal, createRule, deleteRule, @@ -668,7 +655,6 @@ export { loadCollections, navigateToCollection, populateIconGrid, - removeBook, selectColor, selectIcon, setupHTMXAuth, @@ -691,7 +677,6 @@ Alpine.data("collections", () => ({ loadCollections, navigateToCollection, populateIconGrid, - removeBook, selectColor, selectIcon, selectedBooks: [] as string[], @@ -699,5 +684,35 @@ Alpine.data("collections", () => ({ showAllIcons, testRule, toggleSelection, - bulkRemove, + + showConfirm: false, + confirmMessage: "", + confirmLabel: "Remove", + pendingAction: null as null | (() => void), + + requestRemoveBook(this: any, id: string) { + this.confirmMessage = "Remove this book from the collection?"; + this.pendingAction = () => doRemoveBook(id); + this.showConfirm = true; + }, + + requestBulkRemove(this: any) { + if (this.selectedBooks.length === 0) return; + this.confirmMessage = `Remove ${this.selectedBooks.length} book(s) from this collection?`; + const ids = [...this.selectedBooks]; + this.pendingAction = () => doBulkRemove(ids); + this.showConfirm = true; + }, + + executeConfirmed(this: any) { + this.showConfirm = false; + const action = this.pendingAction; + this.pendingAction = null; + if (action) action(); + }, + + closeConfirm(this: any) { + this.showConfirm = false; + this.pendingAction = null; + }, }));