Files
RosterChief/controlpanel/templates/controlpanel/_club_health_table.html
Bernard Siebens adf1120358 Checkpoint: management app redesign, onboarding/signup workflow, and events calendar backend
Large uncommitted body of work accumulated across sessions on this branch --
committing as a checkpoint so it's tracked and future worktree-isolated agents
see the real codebase instead of a stale ancestor commit. Covers the
management app's dedicated Tailwind theme and templates, the club onboarding
requirement/signup workflow (club/services/onboarding.py, requirement/status
models, sign-up dashboard), fee/status auto-activation decoupling, referee
management, and the new events calendar grid service layer.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01ECGMEwrc2k4D8VQuwjstj9
2026-08-19 23:34:43 +02:00

124 lines
6.7 KiB
HTML

{% load lucide %}
{% comment %}
The club table, shared by the dashboard and the clubs list so the two cannot drift apart.
Health, not vanity: a member total says nothing you can act on, while "no coach",
"nothing scheduled", "€ owed" and "no admins" each name something somebody has to go and
fix. Every column is annotated by clubs_with_health() in a single query.
Expects: clubs (from clubs_with_health), and optionally empty_message.
{% endcomment %}
<div class="overflow-x-auto">
<table class="table">
<thead>
<tr>
<th>Club</th>
<th></th>
<th class="text-right">Members</th>
<th class="text-right">Admins</th>
<th class="text-right">Teams</th>
<th class="text-right">Events</th>
<th class="text-right">Plan</th>
<th class="text-right">Dues</th>
<th class="text-right">Plan end</th>
<th></th>
</tr>
</thead>
<tbody>
{% for club in clubs %}
<tr>
<td>
<div class="flex flex-row items-center gap-3">
{% if club.logo %}
<img class="h-10 w-10 shrink-0 object-contain" src="{{ club.logo.url }}" alt="{{ club.name }}">
{% else %}
<div class="crest flex h-10 w-10 shrink-0 items-center justify-center bg-ink">
<span class="font-display text-xs font-extrabold text-white">{{ club.initials }}</span>
</div>
{% endif %}
<div class="flex flex-col">
<a class="link link-hover font-semibold text-ink" href="{% url "controlpanel:club_detail" club.pk %}">{{ club.name }}</a>
<div class="font-mono text-[11px] text-muted">{{ club.slug }}.rosterchief.app &middot; {{ club.get_sport_type_display }}</div>
</div>
</div>
</td>
<td>
<div class="flex flex-row gap-1.5">
{% if club.is_archived %}
<span class="badge badge-warning badge-sm">{% lucide "archive" size=12 %} Archived</span>
{% else %}
{% if not club.has_season %}
<span class="badge badge-warning badge-sm">{% lucide "calendar-x" size=12 %} No seasons</span>
{% endif %}
{% if not club.upcoming_events %}
<span class="badge badge-ghost badge-sm">{% lucide "moon-star" size=12 %} Dormant</span>
{% endif %}
{% endif %}
</div>
</td>
<td class="text-right font-mono tabular-nums">{{ club.active_members }}</td>
<td class="text-right">
<div class="flex flex-row items-center justify-end gap-1.5">
{% if not club.admin_count %}
<span class="text-club-dark">{% lucide "triangle-alert" size=14 %}</span>
{% endif %}
<span class="font-mono tabular-nums {% if not club.admin_count %}font-bold text-club-dark{% endif %}">{{ club.admin_count }}</span>
</div>
</td>
<td class="text-right font-mono tabular-nums">{{ club.team_count }}</td>
<td class="text-right font-mono tabular-nums">{{ club.upcoming_events }}</td>
<td class="text-right font-mono text-xs text-muted">
{{ club.plan_name|lower|default:"—" }}
</td>
<td class="text-right">
<div class="flex flex-row items-center justify-end gap-1.5">
{% if not club.dues_owed %}
{% if club.plan_name %}
{% comment %}
Not owing and on a plan. covered_until is the settled period's end — the day
grace would start if nothing renews — shown on its own row under the badge,
for a paid period AND a waived one (both cover the club, they just differ in
how). No covered period at all (only cancelled dues, say) shows a dash.
{% endcomment %}
{% if club.covered_status == "waived" %}
<span class="badge badge-ghost badge-sm">Waived</span>
{% elif club.covered_until %}
<span class="badge badge-success badge-sm">Paid</span>
{% else %}
<span class="text-muted"></span>
{% endif %}
{% else %}
<span class="text-muted"></span>
{% endif %}
{% else %}
<span class="font-mono font-semibold text-ink tabular-nums">€{{ club.dues_owed|floatformat:2 }}</span>
{% if club.dues_grace_until < today %}
<span class="badge badge-error badge-sm">Overdue</span>
{% elif club.dues_period_end < today %}
<span class="badge badge-warning badge-sm">Grace</span>
{% endif %}
{% endif %}
</div>
</td>
<td class="text-right font-mono text-xs whitespace-nowrap text-muted">{{ club.covered_until|date:"j M Y"|default:"—" }}</td>
<td>
<a class="btn btn-outline btn-xs gap-1" href="{% url "controlpanel:club_detail" club.pk %}">{% lucide "pencil" size=12 %} Edit</a>
</td>
</tr>
{% empty %}
<tr>
<td colspan="10" class="text-center text-muted">{{ empty_message|default:"No clubs yet." }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>