Add the D7 attendance sparkline to member detail; tighten the News list rows
Member detail: a 12-bar season attendance sparkline (present/absent/upcoming) beside Present/Absent/No-reply totals, shown for any rostered non-guardian member with events this season (events.services.attendance.member_attendance_ sparkline/_counts). News list: rows are one dense line (status pill inline with the headline, everything else folded into a single meta line) instead of the previous multi-line stacked layout that read as a small card per item. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ECGMEwrc2k4D8VQuwjstj9
This commit is contained in:
@@ -167,6 +167,38 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if show_attendance %}
|
||||
{# D7's season card: a 12-bar attendance sparkline (present/absent/upcoming, oldest first) beside the season's Present/Absent/No-reply totals. #}
|
||||
<div class="card card-body mt-4">
|
||||
<h2 class="card-title">{% lucide "calendar-check" size=18 %} {% trans "Attendance" %}</h2>
|
||||
{% if not attendance_sparkline %}
|
||||
<p class="text-sm text-muted">{% trans "No events yet this season." %}</p>
|
||||
{% else %}
|
||||
<div class="flex flex-wrap items-center gap-8">
|
||||
<div class="attendance-sparkline">
|
||||
{% for bar in attendance_sparkline %}
|
||||
<span class="attendance-bar attendance-bar-{{ bar.state }}" title="{{ bar.event.title }} — {{ bar.event.start|date:"j M" }}"></span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="flex gap-6">
|
||||
<div>
|
||||
<div class="font-display text-2xl leading-none font-extrabold text-ok tabular-nums">{{ attendance_counts.present }}</div>
|
||||
<div class="mt-1 font-display text-[11px] font-bold tracking-[.1em] text-muted uppercase">{% trans "Present" %}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-display text-2xl leading-none font-extrabold text-club tabular-nums">{{ attendance_counts.absent }}</div>
|
||||
<div class="mt-1 font-display text-[11px] font-bold tracking-[.1em] text-muted uppercase">{% trans "Absent" %}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="font-display text-2xl leading-none font-extrabold text-dim tabular-nums">{{ attendance_counts.no_reply }}</div>
|
||||
<div class="mt-1 font-display text-[11px] font-bold tracking-[.1em] text-muted uppercase">{% trans "No reply" %}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% comment %}
|
||||
Onboarding checklist -- club.services.onboarding.checklist_for, paired with
|
||||
MemberRequirementStatus if one exists. Any staff can mark an item done or
|
||||
|
||||
@@ -22,24 +22,26 @@
|
||||
|
||||
<div class="card overflow-hidden divide-y">
|
||||
{% for item in news_items %}
|
||||
<a href="{% querystring selected=item.pk %}" class="flex flex-col gap-1 border-l-[3px] px-4 py-3 {% if news_item and item.pk == news_item.pk %}border-club bg-row-sel{% else %}border-transparent hover:bg-subhead{% endif %}">
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
{% if item.status == "draft" %}
|
||||
<span class="badge badge-sm">{% trans "Draft" %}</span>
|
||||
{% elif item.is_scheduled %}
|
||||
<span class="badge badge-info badge-sm">{% trans "Scheduled" %}</span>
|
||||
{% else %}
|
||||
<span class="badge badge-success badge-sm">{% trans "Published" %}</span>
|
||||
{% endif %}
|
||||
<span class="font-mono text-xs text-dim">
|
||||
{% if item.status == "draft" %}{% blocktrans with time=item.modified|timesince %}Edited {{ time }} ago{% endblocktrans %}
|
||||
{% else %}{{ item.published_at|date:"j M Y" }}{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
<div class="truncate font-display text-base font-extrabold text-ink uppercase">{{ item.title }}</div>
|
||||
<div class="truncate text-[13px] text-muted">
|
||||
{% if item.created_by %}{{ item.created_by }} · {% endif %}
|
||||
{% for team in item.teams.all %}{{ team.short_name }}{% if not forloop.last %}, {% endif %}{% empty %}{% trans "Club-wide" %}{% endfor %}
|
||||
{# One dense line per row (D8's actual list-pane density), not a stacked mini-card: status pill inline with the headline, everything else folded into one muted meta line below. #}
|
||||
<a href="{% querystring selected=item.pk %}" class="flex items-start gap-2.5 border-l-[3px] px-3.5 py-2.5 {% if news_item and item.pk == news_item.pk %}border-club bg-row-sel{% else %}border-transparent hover:bg-subhead{% endif %}">
|
||||
{% if item.status == "draft" %}
|
||||
<span class="badge badge-sm mt-0.5 shrink-0">{% trans "Draft" %}</span>
|
||||
{% elif item.is_scheduled %}
|
||||
<span class="badge badge-info badge-sm mt-0.5 shrink-0">{% trans "Scheduled" %}</span>
|
||||
{% else %}
|
||||
<span class="badge badge-success badge-sm mt-0.5 shrink-0">{% trans "Published" %}</span>
|
||||
{% endif %}
|
||||
<div class="min-w-0 flex-1">
|
||||
<div class="truncate font-display text-sm font-bold text-ink uppercase">{{ item.title }}</div>
|
||||
<div class="truncate text-xs text-muted">
|
||||
<span class="font-mono text-dim">
|
||||
{% if item.status == "draft" %}{% blocktrans with time=item.modified|timesince %}Edited {{ time }} ago{% endblocktrans %}
|
||||
{% else %}{{ item.published_at|date:"j M Y" }}{% endif %}
|
||||
</span>
|
||||
·
|
||||
{% if item.created_by %}{{ item.created_by }} · {% endif %}
|
||||
{% for team in item.teams.all %}{{ team.short_name }}{% if not forloop.last %}, {% endif %}{% empty %}{% trans "Club-wide" %}{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
{% empty %}
|
||||
|
||||
Reference in New Issue
Block a user