filter leaderboard by session
This commit is contained in:
3 files changed
+100
-8
No files matched your search
@@ -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"
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -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%;
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
<div>
|
||||
<p class="eyebrow">All-time results</p>
|
||||
<h1>Leaderboard</h1>
|
||||
<p class="muted-text">Track who is up, who is chasing, and how everyone has moved across {{ session_count }} recorded sessions.</p>
|
||||
<p class="muted-text">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 %}.</p>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
<h2>Table snapshot</h2>
|
||||
<div class="stat-list">
|
||||
<div class="stat-row"><span>Players tracked</span><strong>{{ leaderboard|length }}</strong></div>
|
||||
<div class="stat-row"><span>Sessions tracked</span><strong>{{ session_count }}</strong></div>
|
||||
<div class="stat-row"><span>Sessions tracked</span><strong>{{ session_count }}{% if total_session_count != session_count %} / {{ total_session_count }}{% endif %}</strong></div>
|
||||
<div class="stat-row"><span>Through session</span><strong>{{ selected_session_label }}</strong></div>
|
||||
<div class="stat-row"><span>Best player</span><strong>{% if leaderboard %}{{ leaderboard[0].player_name }}{% else %}—{% endif %}</strong></div>
|
||||
<div class="stat-row"><span>Worst player</span><strong>{% if leaderboard %}{{ leaderboard[-1].player_name }}{% else %}—{% endif %}</strong></div>
|
||||
</div>
|
||||
@@ -38,12 +39,26 @@
|
||||
</section>
|
||||
|
||||
<section class="panel">
|
||||
<div class="panel-header">
|
||||
<div class="panel-header leaderboard-header">
|
||||
<div>
|
||||
<p class="eyebrow">Standings</p>
|
||||
<h2>All-time leaderboard</h2>
|
||||
</div>
|
||||
<p class="muted-text small">Click any column to sort.</p>
|
||||
<div class="leaderboard-controls">
|
||||
<form method="get" class="session-filter-form">
|
||||
<label for="through_session" class="session-filter-label">Through session</label>
|
||||
<select id="through_session" name="through_session" class="session-filter-select" onchange="this.form.submit()">
|
||||
<option value="" {% if not selected_session_date %}selected{% endif %}>Latest session</option>
|
||||
{% for session in available_sessions %}
|
||||
<option value="{{ session.session_date }}" {% if selected_session_date == session.session_date %}selected{% endif %}>{{ session.session_date | pretty_date }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% if selected_session_date %}
|
||||
<a class="ghost-button compact-button" href="{{ url_for('leaderboard') }}">Reset</a>
|
||||
{% endif %}
|
||||
</form>
|
||||
<p class="muted-text small">Click any column to sort.</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="table-wrap">
|
||||
|
||||
Reference in new issue
Block a user