From 1de8586b5eeafd3eb42ad791ad5be50cdc2e0b0e Mon Sep 17 00:00:00 2001 From: SowinskiBraeden Date: Sun, 15 Mar 2026 16:18:29 -0700 Subject: [PATCH] filter leaderboard by session --- app.py | 30 ++++++++++++++++++--- static/css/style.css | 55 ++++++++++++++++++++++++++++++++++++++ templates/leaderboard.html | 23 +++++++++++++--- 3 files changed, 100 insertions(+), 8 deletions(-) diff --git a/app.py b/app.py index e0adcc4..166f7d6 100644 --- a/app.py +++ b/app.py @@ -69,14 +69,36 @@ def home() -> str: @app.get("/leaderboard") def leaderboard() -> str: events = load_events(DATA_PATH) - sessions = build_session_summaries(events) - board = build_leaderboard(sessions) - chart_data = cumulative_profit_series(sessions) + all_sessions = build_session_summaries(events) + selected_session_date = request.args.get("through_session", "").strip() + valid_session_dates = {session.session_date for session in all_sessions} + + if selected_session_date not in valid_session_dates: + selected_session_date = "" + + filtered_sessions = all_sessions + if selected_session_date: + filtered_sessions = [ + session + for session in all_sessions + if session.session_date <= selected_session_date + ] + + board = build_leaderboard(filtered_sessions) + chart_data = cumulative_profit_series(filtered_sessions) return render_template( "leaderboard.html", leaderboard=board, - session_count=len(sessions), + session_count=len(filtered_sessions), + total_session_count=len(all_sessions), chart_data=chart_data, + available_sessions=all_sessions, + selected_session_date=selected_session_date, + selected_session_label=( + safe_date_label(selected_session_date) + if selected_session_date + else "Latest session" + ), ) diff --git a/static/css/style.css b/static/css/style.css index 95d39f4..96ec9c5 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -576,6 +576,45 @@ td a:hover { color: var(--accent-2); } +.leaderboard-controls { + display: grid; + gap: 8px; + justify-items: end; +} + +.session-filter-form { + display: flex; + align-items: center; + gap: 10px; + flex-wrap: wrap; +} + +.session-filter-label { + color: var(--text-muted); + font-size: 0.9rem; + font-weight: 600; +} + +.session-filter-select { + min-width: 220px; + min-height: 42px; + padding: 0 14px; + border: 1px solid var(--line-strong); + border-radius: 12px; + background: rgba(255, 255, 255, 0.035); + color: var(--text); + outline: none; +} + +.session-filter-select:focus { + border-color: rgba(240, 138, 56, 0.42); + box-shadow: 0 0 0 4px rgba(240, 138, 56, 0.12); +} + +.compact-button { + min-height: 42px; +} + .positive, .negative, .neutral { @@ -770,3 +809,19 @@ td a:hover { height: min(66vh, 680px); } } + +@media (max-width: 860px) { + .leaderboard-header, + .leaderboard-controls { + align-items: start; + justify-items: start; + } + + .session-filter-form { + width: 100%; + } + + .session-filter-select { + width: 100%; + } +} diff --git a/templates/leaderboard.html b/templates/leaderboard.html index 85b9980..13a66ec 100644 --- a/templates/leaderboard.html +++ b/templates/leaderboard.html @@ -5,7 +5,7 @@

All-time results

Leaderboard

-

Track who is up, who is chasing, and how everyone has moved across {{ session_count }} recorded sessions.

+

Track who is up, who is chasing, and how everyone has moved across {{ session_count }} recorded sessions{% if selected_session_date %} through {{ selected_session_label }}{% endif %}.

@@ -30,7 +30,8 @@

Table snapshot

Players tracked{{ leaderboard|length }}
-
Sessions tracked{{ session_count }}
+
Sessions tracked{{ session_count }}{% if total_session_count != session_count %} / {{ total_session_count }}{% endif %}
+
Through session{{ selected_session_label }}
Best player{% if leaderboard %}{{ leaderboard[0].player_name }}{% else %}—{% endif %}
Worst player{% if leaderboard %}{{ leaderboard[-1].player_name }}{% else %}—{% endif %}
@@ -38,12 +39,26 @@
-
+

Standings

All-time leaderboard

-

Click any column to sort.

+
+
+ + + {% if selected_session_date %} + Reset + {% endif %} +
+

Click any column to sort.

+