Apply the sidebar shell and bold primitives across the rest of the app so the whole experience shares one visual language: - Browse/organize: series (keeps stacked-covers/series-card CSS), collections (keeps wood-paneling + carousel classes), browse_detail. - Account/stats: profile + form + modal, progress, analytics (stat-card tiles), devices, conflicts (status semantics), queue (status/priority badges). - Admin: admin sidebar restyled with icons, dashboard/users/library/ processing-issues/settings migrated to .card/.btn/.input primitives. - Docs/setup/misc: docs (keeps prose/highlight.js), api_explorer, setup wizard, unlinked_books, custom_section builder. - Modals/fragments: collection_modal, collection_rules, restore_system_collection_modal, filter_item, book_detail_modals — all overlays use --surface-overlay + --shadow-pop. Every Alpine handler, HTMX attribute, id, name, and data-* is preserved; only presentation changes.
53 lines
2.1 KiB
Templ
53 lines
2.1 KiB
Templ
package templates
|
|
|
|
import (
|
|
"bookhoard/internal/handlers"
|
|
"fmt"
|
|
)
|
|
|
|
templ BrowseDetail(user User, badgeIcon string, badgeLabel string, title string, pageTitle string, backUrl string, backLabel string, emptyIcon string, emptyMessage string, books []handlers.BookInfo, errorMessage string) {
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<meta charset="UTF-8"/>
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
|
<title>{ pageTitle } - Bookhoard</title>
|
|
<link href="/static/style.css" rel="stylesheet"/>
|
|
</head>
|
|
<body class="theme-{ user.Theme }">
|
|
@Header(user, backUrl)
|
|
<div class="app-subbar border-b" style="background-color: color-mix(in srgb, var(--bg-secondary) 82%, transparent); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border-color: color-mix(in srgb, var(--text-primary) 6%, transparent);">
|
|
<div class="mx-auto container px-4 sm:px-6 lg:px-8 py-3">
|
|
<a href={ backUrl } class="btn btn-ghost">
|
|
@Icon("arrow-left", "h-4 w-4")
|
|
<span>{ backLabel }</span>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<div class="mx-auto container px-4 sm:px-6 lg:px-8 py-8">
|
|
<div class="flex flex-wrap items-center gap-3 mb-6">
|
|
<span class="chip" style="background-color: var(--accent); color: var(--bg-primary);">
|
|
{ badgeIcon } { badgeLabel }
|
|
</span>
|
|
<h1 class="text-2xl font-bold tracking-tight" style="color: var(--text-primary)">{ title }</h1>
|
|
<span class="badge" style="background-color: var(--accent-muted); color: var(--accent);">{ fmt.Sprintf("%d", len(books)) } books</span>
|
|
</div>
|
|
if len(books) > 0 {
|
|
<div class="grid grid-cols-2 md:grid-cols-4 lg:grid-cols-6 xl:grid-cols-8 gap-4">
|
|
for _, book := range books {
|
|
@BookCard(book)
|
|
}
|
|
</div>
|
|
} else {
|
|
<div class="card text-center py-16 px-6">
|
|
<div class="text-5xl mb-4">{ emptyIcon }</div>
|
|
<h3 class="text-xl font-semibold mb-2" style="color: var(--text-primary)">No Books Found</h3>
|
|
<p style="color: var(--text-secondary)">{ emptyMessage }</p>
|
|
</div>
|
|
}
|
|
</div>
|
|
@ErrorToast(errorMessage)
|
|
</body>
|
|
</html>
|
|
}
|