diff --git a/dashboard/app.py b/dashboard/app.py index de7a4b0..968ff46 100644 --- a/dashboard/app.py +++ b/dashboard/app.py @@ -76,6 +76,8 @@ def index(request: Request): GROUP BY source, status ORDER BY source, status""" ).fetchall() total = conn.execute("SELECT COUNT(*) FROM image_hashes").fetchone()[0] + status_counts = dict(conn.execute( + "SELECT status, COUNT(*) FROM image_hashes GROUP BY status").fetchall()) conn.close() folders = {} for name in ("01_keep", "02_review", "03_delete"): @@ -83,7 +85,7 @@ def index(request: Request): folders[name] = sum(1 for _ in d.rglob("*") if _.is_file()) if d.exists() else 0 return templates.TemplateResponse( request, "index.html", - {"rows": rows, "total": total, "folders": folders}, + {"rows": rows, "total": total, "folders": folders, "status_counts": status_counts}, ) diff --git a/dashboard/templates/index.html b/dashboard/templates/index.html index e63c315..5e4f8e1 100644 --- a/dashboard/templates/index.html +++ b/dashboard/templates/index.html @@ -38,11 +38,24 @@
-
{{ total }}
images fingerprinted
-
{{ folders["01_keep"] }}
in 01_keep
-
{{ folders["02_review"] }}
in 02_review
-
{{ folders["03_delete"] }}
in 03_delete
+ +
{{ status_counts["delete_candidate"] }}
+
⚠ flagged (dark/blurry) — review these →
+
+ +
{{ status_counts["keep"] }}
+
keep (clean) — bulk-approve →
+
+ +
{{ status_counts["approved"] }}
+
approved (your Keep) →
+
+ +
{{ status_counts["rejected"] }}
+
rejected (your Reject) →
+
+

Total fingerprinted: {{ total }}

By source & status

diff --git a/dashboard/templates/review.html b/dashboard/templates/review.html index eeae7c8..218efbd 100644 --- a/dashboard/templates/review.html +++ b/dashboard/templates/review.html @@ -56,12 +56,16 @@ Approved
-
+ + @@ -190,6 +194,13 @@ setTimeout(() => { t.style.display = 'none'; }, 3000); } + // auto-submit filter when dropdown/input changes (no need to press Filter) + document.getElementById('filter-form').addEventListener('change', e => { + if (e.target.name === 'status' || e.target.name === 'source') { + document.getElementById('filter-form').submit(); + } + }); + // stash original labels for busy-state restore document.querySelectorAll('.bulk-bar button').forEach(b => { b.dataset.orig = b.textContent; });