Make the referee dashboard's season stats one compact row, not two
KPIs and the chart now share a single flex row (chart card wider, flex-[3]) instead of a full KPI row followed by a tall standalone chart card -- the per-referee fee breakdown moves into the chart's own tooltip instead of a separate list underneath, so this stays compact and the actual games-needing-a-referee list isn't pushed below the fold. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ECGMEwrc2k4D8VQuwjstj9
This commit is contained in:
@@ -50,43 +50,36 @@
|
||||
Season workload -- separate from the "games in view" KPIs above
|
||||
(which track the upcoming range picked by the filter strip), this is
|
||||
about who's actually done the refereeing this season, all-time
|
||||
within it, not just what's still upcoming.
|
||||
within it, not just what's still upcoming. Deliberately one compact
|
||||
row, not a tall section of its own -- the games-needing-a-referee
|
||||
list below is the actual point of this page, so this shouldn't push
|
||||
it below the fold. Fees ride along as a chart tooltip (see
|
||||
extra_body) rather than a separate list, for the same reason.
|
||||
{% endcomment %}
|
||||
<div class="flex flex-col gap-3.5">
|
||||
<div class="flex flex-wrap gap-3.5">
|
||||
<div class="card min-w-0 flex-1 p-4">
|
||||
<div class="font-display text-xs font-bold tracking-[.12em] text-muted uppercase">{% trans "Active referees" %}</div>
|
||||
<div class="mt-1 font-display text-[34px] leading-none font-extrabold text-ink tabular-nums">{{ kpi_active_referees }}</div>
|
||||
<div class="mt-1 text-[13px] text-muted">{% trans "This season" %}</div>
|
||||
</div>
|
||||
<div class="card min-w-0 flex-1 p-4">
|
||||
<div class="font-display text-xs font-bold tracking-[.12em] text-muted uppercase">{% trans "Games refereed" %}</div>
|
||||
<div class="mt-1 font-display text-[34px] leading-none font-extrabold text-ink tabular-nums">{{ kpi_total_assignments }}</div>
|
||||
<div class="mt-1 text-[13px] text-muted">{% trans "This season" %}</div>
|
||||
</div>
|
||||
<div class="card min-w-0 flex-1 p-4">
|
||||
<div class="font-display text-xs font-bold tracking-[.12em] text-muted uppercase">{% trans "Average per referee" %}</div>
|
||||
<div class="mt-1 font-display text-[34px] leading-none font-extrabold text-ink tabular-nums">{{ kpi_avg_games_per_referee }}</div>
|
||||
<div class="mt-1 text-[13px] text-muted">{% trans "This season" %}</div>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-3.5">
|
||||
<div class="card min-w-0 flex-1 p-4">
|
||||
<div class="font-display text-xs font-bold tracking-[.12em] text-muted uppercase">{% trans "Active referees" %}</div>
|
||||
<div class="mt-1 font-display text-[34px] leading-none font-extrabold text-ink tabular-nums">{{ kpi_active_referees }}</div>
|
||||
<div class="mt-1 text-[13px] text-muted">{% trans "This season" %}</div>
|
||||
</div>
|
||||
<div class="card p-4.5">
|
||||
<div class="mb-1 font-display text-base font-extrabold tracking-[.08em] text-ink uppercase">{% trans "Games refereed per referee" %}</div>
|
||||
<p class="mb-3 text-sm text-muted">{% trans "This season." %}</p>
|
||||
<div class="card min-w-0 flex-1 p-4">
|
||||
<div class="font-display text-xs font-bold tracking-[.12em] text-muted uppercase">{% trans "Games refereed" %}</div>
|
||||
<div class="mt-1 font-display text-[34px] leading-none font-extrabold text-ink tabular-nums">{{ kpi_total_assignments }}</div>
|
||||
<div class="mt-1 text-[13px] text-muted">{% trans "This season" %}</div>
|
||||
</div>
|
||||
<div class="card min-w-0 flex-1 p-4">
|
||||
<div class="font-display text-xs font-bold tracking-[.12em] text-muted uppercase">{% trans "Average per referee" %}</div>
|
||||
<div class="mt-1 font-display text-[34px] leading-none font-extrabold text-ink tabular-nums">{{ kpi_avg_games_per_referee }}</div>
|
||||
<div class="mt-1 text-[13px] text-muted">{% trans "This season" %}</div>
|
||||
</div>
|
||||
<div class="card min-w-0 flex-[3] p-4">
|
||||
<div class="font-display text-xs font-bold tracking-[.12em] text-muted uppercase">{% trans "Games refereed per referee" %}</div>
|
||||
{% if referee_stats %}
|
||||
<div class="h-56">
|
||||
<div class="mt-1 h-20">
|
||||
<canvas id="referee-games-chart"></canvas>
|
||||
</div>
|
||||
<div class="mt-3 max-h-40 overflow-y-auto border-t border-rule">
|
||||
{% for row in referee_stats %}
|
||||
<div class="flex items-center justify-between gap-3 py-1.5 {% if not forloop.last %}border-b border-rule{% endif %}">
|
||||
<span class="truncate text-[13px] text-ink">{{ row.member__first_name }} {{ row.member__last_name }}</span>
|
||||
<span class="shrink-0 font-mono text-xs text-muted">{% blocktrans count counter=row.games %}{{ counter }} game{% plural %}{{ counter }} games{% endblocktrans %}{% if row.total_fees %} · €{{ row.total_fees|floatformat:2 }}{% endif %}</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="py-6 text-center text-sm text-muted">{% trans "No referee assignments recorded yet this season." %}</p>
|
||||
<p class="mt-1 text-[13px] text-muted">{% trans "No referee assignments recorded yet this season." %}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
@@ -175,10 +168,21 @@
|
||||
responsive: true,
|
||||
maintainAspectRatio: false,
|
||||
indexAxis: "y",
|
||||
plugins: {legend: {display: false}},
|
||||
plugins: {
|
||||
legend: {display: false},
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: (context) => {
|
||||
const fee = data.referee_games.fees[context.dataIndex];
|
||||
const label = `{{ games_label|escapejs }}: ${context.parsed.x}`;
|
||||
return fee ? `${label} — €${fee.toFixed(2)}` : label;
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
scales: {
|
||||
x: {beginAtZero: true, ticks: {color: ink, precision: 0}, grid: {color: grid}},
|
||||
y: {ticks: {color: ink}, grid: {display: false}},
|
||||
y: {ticks: {color: ink, font: {size: 11}}, grid: {display: false}},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -2791,12 +2791,16 @@ class RefereeManagementDashboardView(MemberAdminRequiredMixin, TemplateView):
|
||||
kpi_active_referees = len(stats)
|
||||
kpi_total_assignments = sum(row["games"] for row in stats)
|
||||
kpi_avg_games_per_referee = round(kpi_total_assignments / kpi_active_referees, 1) if kpi_active_referees else 0
|
||||
# Top 15 for the chart's own readability -- the table below it lists
|
||||
# every referee, so nothing is actually hidden, just not plotted.
|
||||
# Top 15 for the chart's own readability -- fees ride along per bar
|
||||
# for the tooltip (see referee_management.html's extra_body) rather
|
||||
# than a separate list underneath, to keep this a compact single row
|
||||
# next to the KPIs, not a second tall section pushing the actual
|
||||
# games-needing-a-referee list off screen.
|
||||
charts = {
|
||||
"referee_games": {
|
||||
"labels": [f"{row['member__first_name']} {row['member__last_name']}" for row in stats[:15]],
|
||||
"games": [row["games"] for row in stats[:15]],
|
||||
"fees": [float(row["total_fees"] or 0) for row in stats[:15]],
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user