From 6899e203f664a872586db2ff49fe517816c5e887 Mon Sep 17 00:00:00 2001 From: Bernard Siebens Date: Tue, 14 Jul 2026 01:24:31 +0200 Subject: [PATCH] Show club health on the clubs list too The list page carried the same vanity counts the dashboard just lost. It now shows active members, unpaid members, money owed, teams (flagging those nobody can pick a squad for), upcoming events and admins, with the same No season / Dormant badges -- and the annotations survive search and the archived filter. The table lives in one partial, included by both pages, so they cannot drift apart. Archived clubs are badged "Archived" rather than "Dormant": their subdomain does not resolve, so of course nothing is scheduled, and flagging that as a problem would be noise on the one page where every row has it. assertNumQueries(1) covers the list as well now -- health is annotated per club, so the page must not fan out as clubs are added. Co-Authored-By: Claude Opus 4.8 --- .../templates/controlpanel/club_list.html | 38 ++------------ .../templates/controlpanel/dashboard.html | 50 +------------------ controlpanel/views.py | 4 +- 3 files changed, 8 insertions(+), 84 deletions(-) diff --git a/controlpanel/templates/controlpanel/club_list.html b/controlpanel/templates/controlpanel/club_list.html index 5d4f740..6427ce6 100644 --- a/controlpanel/templates/controlpanel/club_list.html +++ b/controlpanel/templates/controlpanel/club_list.html @@ -24,39 +24,11 @@
-
- - - - - - - - - - - - {% for club in clubs %} - - - - - - - - {% empty %} - - - - {% endfor %} - -
ClubMembersTeamsEventsAdmins
- {{ club.name }} -
{{ club.slug }}
-
{{ club.member_count }}{{ club.team_count }}{{ club.event_count }}{{ club.admin_count }}
- {% if show_archived %}No archived clubs.{% else %}No clubs yet.{% endif %} -
-
+ {% if show_archived %} + {% include "controlpanel/_club_health_table.html" with empty_message="No archived clubs." %} + {% else %} + {% include "controlpanel/_club_health_table.html" %} + {% endif %}
{% endblock panel %} diff --git a/controlpanel/templates/controlpanel/dashboard.html b/controlpanel/templates/controlpanel/dashboard.html index ff02672..b553d4f 100644 --- a/controlpanel/templates/controlpanel/dashboard.html +++ b/controlpanel/templates/controlpanel/dashboard.html @@ -143,55 +143,7 @@

Clubs

- {% comment %} - Health, not vanity: a club's member count says nothing you can act on, while - "no coach", "nothing scheduled" and "€ owed" each name a thing somebody has to - go and fix. Every column here is annotated in the same single query. - {% endcomment %} -
- - - - - - - - - - - - - - {% for club in clubs %} - - - - - - - - - - {% empty %} - - - - {% endfor %} - -
ClubMembersUnpaidOwedTeamsUpcomingAdmins
- {{ club.name }} -
- {{ club.slug }} - {% if not club.has_season %}{% lucide "calendar-x" size=10 %} No season{% endif %} - {% if not club.upcoming_events %}{% lucide "moon-star" size=10 %} Dormant{% endif %} -
-
{{ club.active_members }}{{ club.unpaid_members }}€{{ club.outstanding|floatformat:2 }} - {{ club.team_count }} - {% if club.teams_without_coach %} - {{ club.teams_without_coach }} no coach - {% endif %} - {{ club.upcoming_events }}{{ club.admin_count }}
No clubs yet.
-
+ {% include "controlpanel/_club_health_table.html" %}
{% endblock panel %} diff --git a/controlpanel/views.py b/controlpanel/views.py index 4547c3b..eebf84c 100644 --- a/controlpanel/views.py +++ b/controlpanel/views.py @@ -17,7 +17,7 @@ from .services.platform_admins import ( revoke_platform_access, set_platform_access, ) -from .services.statistics import club_attention, club_charts, club_statistics, clubs_with_health, clubs_with_totals, flag_adoption, onboarding_funnel, platform_attention, platform_charts, platform_totals +from .services.statistics import club_attention, club_charts, club_statistics, clubs_with_health, flag_adoption, onboarding_funnel, platform_attention, platform_charts, platform_totals Flag = get_waffle_flag_model() Switch = get_waffle_switch_model() @@ -52,7 +52,7 @@ class ClubListView(PlatformStaffRequiredMixin, ListView): search = self.request.GET.get("q", "").strip() if search: clubs = clubs.filter(name__icontains=search) - return clubs_with_totals(clubs) + return clubs_with_health(clubs) def get_context_data(self, **kwargs): return super().get_context_data(nav="clubs", show_archived=self.show_archived, search=self.request.GET.get("q", ""), **kwargs)