From 4279408876268f4960c98492d3814f5475e36e38 Mon Sep 17 00:00:00 2001 From: Tyler Hoang Date: Tue, 12 May 2026 03:15:17 -0700 Subject: Add stats totals, runtime summary, and duplicate detection on add form - Stats page now shows total films watched and total runtime (formatted as Xd Yh) in an overview panel above the world map - /stats/data endpoint includes total_runtime_minutes in payload - New GET /films/find endpoint returns all shelf matches for a tmdb_id - Add film form shows an inline notice when the selected TMDB film is already logged, with shelf name, date, and a link to the entry - Update CLAUDE.md and README to reflect current auth, OMDb, and router/service structure Co-Authored-By: Claude Sonnet 4.6 --- templates/form.html | 1 + templates/stats.html | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) (limited to 'templates') diff --git a/templates/form.html b/templates/form.html index 83e888e..cd29e67 100644 --- a/templates/form.html +++ b/templates/form.html @@ -38,6 +38,7 @@
+
diff --git a/templates/stats.html b/templates/stats.html index 797054a..6e3a987 100644 --- a/templates/stats.html +++ b/templates/stats.html @@ -14,6 +14,19 @@
+
+
+
+ Films watched + +
+
+ Total runtime + +
+
+
+
@@ -124,7 +137,25 @@ return String(value).padStart(3, "0"); } + function formatRuntime(minutes) { + if (!minutes) return "0h"; + const totalHours = Math.floor(minutes / 60); + if (totalHours >= 24) { + const days = Math.floor(totalHours / 24); + const hours = totalHours % 24; + return hours > 0 ? `${days}d ${hours}h` : `${days}d`; + } + const mins = minutes % 60; + return mins > 0 ? `${totalHours}h ${mins}m` : `${totalHours}h`; + } + function renderLists(data) { + const totalFilms = document.getElementById("stats-total-films"); + if (totalFilms) totalFilms.textContent = data.total_watched; + + const totalRuntime = document.getElementById("stats-total-runtime"); + if (totalRuntime) totalRuntime.textContent = formatRuntime(data.total_runtime_minutes); + const topDirectors = document.getElementById("top-directors"); topDirectors.innerHTML = data.most_watched_directors.slice(0, 8).map((item) => `
  • ${item.director}${item.count}
  • -- cgit v1.3-2-g0d8e