refactor(templates): simplify BooksGrid component

Remove wrapper div and pagination from BooksGrid component.
The component now only renders book cards, making it more reusable.

Changes:
- Remove books-grid wrapper div from BooksGrid
- Remove pagination controls from BooksGrid
- Component now only renders book card grid

This allows the parent template to control the wrapper div
placement and pagination location, which is needed for proper
HTMX targeting on the bookshelf page.

Related: Issue with pagination displaying inside grid instead of below
This commit is contained in:
2026-03-27 15:52:02 -04:00
parent 0c5831f9c0
commit 804d765988
2 changed files with 1 additions and 83 deletions
-31
View File
@@ -3,7 +3,6 @@ package templates
import "bookhoard/internal/handlers"
templ BooksGrid(books []handlers.BookInfo, limit int, offset int, count int, currentLibraryID string) {
<div id="books-grid" class="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 xl:grid-cols-8 gap-4">
if len(books) > 0 {
for _, book := range books {
@BookCard(book)
@@ -15,34 +14,4 @@ templ BooksGrid(books []handlers.BookInfo, limit int, offset int, count int, cur
<p class="text-sm">Try adjusting your filters or add some books to your library.</p>
</div>
}
</div>
<!-- Pagination -->
<div id="pagination" class="mt-6 flex justify-center gap-2">
if count > 0 {
<button
type="button"
class="px-4 py-2 rounded-lg border disabled:opacity-50"
style="border-color: var(--border); color: var(--text-primary);"
hx-get="/api/media-items/search?library_id={ currentLibraryID }&limit={ limit }&offset={ offset - limit }"
hx-target="#books-grid"
hx-include="#filter-form"
disabled?={ offset <= 0 }
>
Previous
</button>
<span class="px-4 py-2" style="color: var(--text-secondary);">
Page { offset / limit + 1 }
</span>
<button
class="px-4 py-2 rounded-lg border disabled:opacity-50"
style="border-color: var(--border); color: var(--text-primary);"
hx-get="/api/media-items/search?library_id={ currentLibraryID }&limit={ limit }&offset={ offset + limit }"
hx-target="#books-grid"
hx-include="#filter-form"
disabled?={ offset+limit >= count }
>
Next
</button>
}
</div>
}
+1 -52
View File
@@ -31,10 +31,6 @@ func BooksGrid(books []handlers.BookInfo, limit int, offset int, count int, curr
templ_7745c5c3_Var1 = templ.NopComponent
}
ctx = templ.ClearChildren(ctx)
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<div id=\"books-grid\" class=\"grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 xl:grid-cols-8 gap-4\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if len(books) > 0 {
for _, book := range books {
templ_7745c5c3_Err = BookCard(book).Render(ctx, templ_7745c5c3_Buffer)
@@ -43,58 +39,11 @@ func BooksGrid(books []handlers.BookInfo, limit int, offset int, count int, curr
}
}
} else {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 2, "<!-- Empty state --> <div class=\"col-span-full text-center py-12\" style=\"color: var(--text-secondary);\"><p class=\"text-lg mb-2\">📚 No books found</p><p class=\"text-sm\">Try adjusting your filters or add some books to your library.</p></div>")
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "<!-- Empty state --> <div class=\"col-span-full text-center py-12\" style=\"color: var(--text-secondary);\"><p class=\"text-lg mb-2\">📚 No books found</p><p class=\"text-sm\">Try adjusting your filters or add some books to your library.</p></div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "</div><!-- Pagination --><div id=\"pagination\" class=\"mt-6 flex justify-center gap-2\">")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if count > 0 {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 4, "<button type=\"button\" class=\"px-4 py-2 rounded-lg border disabled:opacity-50\" style=\"border-color: var(--border); color: var(--text-primary);\" hx-get=\"/api/media-items/search?library_id={ currentLibraryID }&limit={ limit }&offset={ offset - limit }\" hx-target=\"#books-grid\" hx-include=\"#filter-form\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if offset <= 0 {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 5, " disabled")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 6, ">← Previous</button> <span class=\"px-4 py-2\" style=\"color: var(--text-secondary);\">Page ")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var2 string
templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(offset/limit + 1)
if templ_7745c5c3_Err != nil {
return templ.Error{Err: templ_7745c5c3_Err, FileName: `templates/books_grid.templ`, Line: 34, Col: 29}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var2))
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 7, "</span> <button class=\"px-4 py-2 rounded-lg border disabled:opacity-50\" style=\"border-color: var(--border); color: var(--text-primary);\" hx-get=\"/api/media-items/search?library_id={ currentLibraryID }&limit={ limit }&offset={ offset + limit }\" hx-target=\"#books-grid\" hx-include=\"#filter-form\"")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
if offset+limit >= count {
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 8, " disabled")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 9, ">Next →</button>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
}
templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 10, "</div>")
if templ_7745c5c3_Err != nil {
return templ_7745c5c3_Err
}
return nil
})
}