Series
+No Series Found
+Books with series metadata will appear here
+diff --git a/web/src/main.ts b/web/src/main.ts
index 4a170c9..404f197 100644
--- a/web/src/main.ts
+++ b/web/src/main.ts
@@ -29,6 +29,7 @@ import "./profile-modal";
import "./queue";
import "./register";
import "./search";
+import "./series";
import "./storage";
import "./theme";
import "./toast";
diff --git a/web/src/series.ts b/web/src/series.ts
new file mode 100644
index 0000000..aa1785f
--- /dev/null
+++ b/web/src/series.ts
@@ -0,0 +1,154 @@
+import { Alpine } from "./alpine";
+import { showToast } from "./toast";
+import { setSelectedLibrary } from "./storage";
+
+interface SeriesItem {
+ name: string;
+ book_count: number;
+ total_in_series: number;
+ cover_paths: string[];
+ last_entry_at: string;
+}
+
+function renderSeriesCard(series: SeriesItem, libraryId: string): string {
+ const href = `/bookshelf?series_filter=${encodeURIComponent(series.name)}&sort=series&library_id=${libraryId}`;
+ const coverCount = series.cover_paths.length;
+ const coverClass = `cover-count-${coverCount}`;
+
+ let coversHtml = "";
+ for (let i = 0; i < coverCount; i++) {
+ coversHtml += ``;
+ }
+
+ if (coverCount === 0) {
+ coversHtml = `
+ ${series.book_count} of ${series.total_in_series} books +
+Books with series metadata will appear here
+