for i, cover := range series.CoverPaths {
diff --git a/templates/series_detail.templ b/templates/series_detail.templ
new file mode 100644
index 0000000..1e5bbe0
--- /dev/null
+++ b/templates/series_detail.templ
@@ -0,0 +1,72 @@
+package templates
+
+import (
+ "bookhoard/internal/handlers"
+ "fmt"
+)
+
+templ SeriesDetail(user User, seriesName string, books []handlers.BookInfo, libData []LibraryData, currentLibraryID string, errorMessage string) {
+
+
+
+
+
+
{ seriesName } - Bookhoard
+
+
+
+ @Header(user, "/series")
+
+
+
+
+
+ ← All Series
+
+
|
+
+
+
+
+
+
+
+
+
+ 📚 Series
+
+
{ seriesName }
+ { fmt.Sprintf("%d", len(books)) } books
+
+
+ if len(books) > 0 {
+
+ for _, book := range books {
+ @BookCard(book)
+ }
+
+ } else {
+
+
📚
+
No Books Found
+
This series doesn't have any books in this library yet
+
+ }
+
+ @ErrorToast(errorMessage)
+
+
+}
diff --git a/templates/series_detail_templ.go b/templates/series_detail_templ.go
new file mode 100644
index 0000000..a90d265
--- /dev/null
+++ b/templates/series_detail_templ.go
@@ -0,0 +1,194 @@
+// Code generated by templ - DO NOT EDIT.
+
+// templ: version: v0.3.1001
+package templates
+
+//lint:file-ignore SA4006 This context is only used if a nested component is present.
+
+import "github.com/a-h/templ"
+import templruntime "github.com/a-h/templ/runtime"
+
+import (
+ "bookhoard/internal/handlers"
+ "fmt"
+)
+
+func SeriesDetail(user User, seriesName string, books []handlers.BookInfo, libData []LibraryData, currentLibraryID string, errorMessage string) templ.Component {
+ return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) {
+ templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context
+ if templ_7745c5c3_CtxErr := ctx.Err(); templ_7745c5c3_CtxErr != nil {
+ return templ_7745c5c3_CtxErr
+ }
+ templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W)
+ if !templ_7745c5c3_IsBuffer {
+ defer func() {
+ templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err == nil {
+ templ_7745c5c3_Err = templ_7745c5c3_BufErr
+ }
+ }()
+ }
+ ctx = templ.InitializeContext(ctx)
+ templ_7745c5c3_Var1 := templ.GetChildren(ctx)
+ if templ_7745c5c3_Var1 == nil {
+ templ_7745c5c3_Var1 = templ.NopComponent
+ }
+ ctx = templ.ClearChildren(ctx)
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 1, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var2 string
+ templ_7745c5c3_Var2, templ_7745c5c3_Err = templ.JoinStringErrs(seriesName)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `series_detail.templ`, Line: 14, Col: 22}
+ }
+ _, 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, 2, " - Bookhoard")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = Header(user, "/series").Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 3, "
← All Series | 📚 Series
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var7 string
+ templ_7745c5c3_Var7, templ_7745c5c3_Err = templ.JoinStringErrs(seriesName)
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `series_detail.templ`, Line: 51, Col: 83}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var7))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 11, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ var templ_7745c5c3_Var8 string
+ templ_7745c5c3_Var8, templ_7745c5c3_Err = templ.JoinStringErrs(fmt.Sprintf("%d", len(books)))
+ if templ_7745c5c3_Err != nil {
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `series_detail.templ`, Line: 52, Col: 95}
+ }
+ _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var8))
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 12, " books")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ if len(books) > 0 {
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 13, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ for _, book := range books {
+ templ_7745c5c3_Err = BookCard(book).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 14, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ } else {
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 15, "
📚
No Books Found
This series doesn't have any books in this library yet
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 16, "
")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = ErrorToast(errorMessage).Render(ctx, templ_7745c5c3_Buffer)
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ templ_7745c5c3_Err = templruntime.WriteString(templ_7745c5c3_Buffer, 17, "")
+ if templ_7745c5c3_Err != nil {
+ return templ_7745c5c3_Err
+ }
+ return nil
+ })
+}
+
+var _ = templruntime.GeneratedTemplate
diff --git a/templates/series_templ.go b/templates/series_templ.go
index 8d646f1..5007379 100644
--- a/templates/series_templ.go
+++ b/templates/series_templ.go
@@ -255,9 +255,9 @@ func SeriesCard(series SeriesCardData, libraryID string) templ.Component {
return templ_7745c5c3_Err
}
var templ_7745c5c3_Var11 templ.SafeURL
- templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinURLErrs("/bookshelf?series_filter=" + url.QueryEscape(series.Name) + "&sort=series&library_id=" + libraryID)
+ templ_7745c5c3_Var11, templ_7745c5c3_Err = templ.JoinURLErrs("/series/detail?name=" + url.QueryEscape(series.Name) + "&library_id=" + libraryID)
if templ_7745c5c3_Err != nil {
- return templ.Error{Err: templ_7745c5c3_Err, FileName: `series.templ`, Line: 98, Col: 110}
+ return templ.Error{Err: templ_7745c5c3_Err, FileName: `series.templ`, Line: 98, Col: 93}
}
_, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var11))
if templ_7745c5c3_Err != nil {
diff --git a/web/src/series.ts b/web/src/series.ts
index aa1785f..616b466 100644
--- a/web/src/series.ts
+++ b/web/src/series.ts
@@ -11,7 +11,7 @@ interface SeriesItem {
}
function renderSeriesCard(series: SeriesItem, libraryId: string): string {
- const href = `/bookshelf?series_filter=${encodeURIComponent(series.name)}&sort=series&library_id=${libraryId}`;
+ const href = `/series/detail?name=${encodeURIComponent(series.name)}&library_id=${libraryId}`;
const coverCount = series.cover_paths.length;
const coverClass = `cover-count-${coverCount}`;
@@ -152,3 +152,22 @@ Alpine.data("seriesPage", () => ({
}
},
}));
+
+Alpine.data("seriesDetailPage", () => ({
+ initSeriesDetailPage() {
+ const librarySelect = document.getElementById(
+ "library-select",
+ ) as HTMLSelectElement;
+ if (librarySelect) {
+ librarySelect.addEventListener("change", () => {
+ if (librarySelect.value) {
+ const url = new URL(window.location.href);
+ const currentLib = url.searchParams.get("library_id");
+ if (currentLib === librarySelect.value) return;
+ url.searchParams.set("library_id", librarySelect.value);
+ window.location.href = url.toString();
+ }
+ });
+ }
+ },
+}));