Regroup the management event list to match the member app's agenda look

The desktop "List" view was a flat, paginated <table>. It's now grouped the
same way mobile.views.CalendarView already groups the member app's own
calendar: "This week" / "Next week", then everything further out under its
own month divider -- same algorithm (itertools.groupby over an already-
sorted, already-paginated page of events), applied after pagination so the
two don't fight each other. "Show past events" mode skips the this/next-week
labels (they only make sense for what's ahead) and just groups straight into
months, most recent first.

Each row keeps the same information and admin actions the table had (kind
badge, series icon, teams, location, Edit/Delete) -- just laid out as a list
row instead of table cells, in its own reusable partial.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-23 15:30:59 +02:00
parent 1375083739
commit a13ab20a0f
6 changed files with 139 additions and 50 deletions

View File

@@ -0,0 +1,25 @@
{% load i18n lucide ui %}
<div class="flex items-center gap-3 px-4 py-3 {% if not forloop.last %}border-b border-line{% endif %}">
<span class="badge badge-sm shrink-0 {% if event.kind == "game" %}badge-error{% elif event.kind == "training" %}badge-info{% elif event.kind == "tournament" %}badge-warning{% elif event.kind == "meeting" %}badge-neutral{% elif event.kind == "social" %}border-violet/30 bg-violet/10 text-violet{% else %}badge-outline{% endif %}">
{{ event.get_kind_display }}
</span>
<div class="min-w-0 flex-1">
<div class="flex items-center gap-1.5">
<a class="link link-hover truncate font-semibold text-ink" href="{% url 'management:event_detail' event.pk %}">{{ event.title }}</a>
{% if event.series_id %}
<span class="shrink-0 text-dim" title="{% trans 'Part of a series' %}" aria-label="{% trans 'Part of a series' %}">{% lucide "repeat" size=12 %}</span>
{% endif %}
</div>
<div class="mt-0.5 flex flex-wrap items-center gap-x-3 gap-y-0.5 font-mono text-xs text-muted">
<span>{{ event.start|date:"D j M, H:i" }}</span>
{% if event.teams.all %}<span>{% for team in event.teams.all %}{{ team.short_name }}{% if not forloop.last %}, {% endif %}{% endfor %}</span>{% endif %}
{% if event.location %}<span>{{ event.location.name }}</span>{% endif %}
</div>
</div>
{% if event.can_manage %}
<div class="flex shrink-0 gap-1">
<a class="btn btn-square btn-outline btn-sm" href="{% url 'management:event_detail' event.pk %}" aria-label="{% trans 'Edit' %}">{% lucide "pencil" size=14 %}</a>
<button class="btn btn-square btn-sm btn-outline btn-error" type="button" onclick="document.getElementById('{{ event.pk|dom_id:"event_delete_modal" }}').showModal()" aria-label="{% trans 'Delete' %}">{% lucide "trash-2" size=14 %}</button>
</div>
{% endif %}
</div>

View File

@@ -67,54 +67,30 @@
{% block panel %}
{% if view_mode == "list" %}
<div class="card overflow-hidden">
<div class="overflow-x-auto overflow-y-visible">
<table class="table">
<thead>
<tr>
<th>{% trans "Title" %}</th>
<th>{% trans "Kind" %}</th>
<th>{% trans "When" %}</th>
<th>{% trans "Teams" %}</th>
<th>{% trans "Location" %}</th>
<th></th>
</tr>
</thead>
<tbody>
{% for event in events %}
<tr>
<td>
<a class="link link-hover font-semibold text-ink" href="{% url 'management:event_detail' event.pk %}">{{ event.title }}</a>
{% if event.series_id %}
<span class="ml-1 inline-flex align-middle text-dim" title="{% trans 'Part of a series' %}" aria-label="{% trans 'Part of a series' %}">{% lucide "repeat" size=12 %}</span>
{% endif %}
</td>
<td>
<span class="badge badge-sm {% if event.kind == "game" %}badge-error{% elif event.kind == "training" %}badge-info{% elif event.kind == "tournament" %}badge-warning{% elif event.kind == "meeting" %}badge-neutral{% elif event.kind == "social" %}border-violet/30 bg-violet/10 text-violet{% else %}badge-outline{% endif %}">
{{ event.get_kind_display }}
</span>
</td>
<td class="font-mono text-xs text-ink">{{ event.start|date:"D j M Y H:i" }}</td>
<td>{% for team in event.teams.all %}{{ team.short_name }}{% if not forloop.last %}, {% endif %}{% empty %}<span class="text-dim"></span>{% endfor %}</td>
<td>{{ event.location.name|default:"—" }}</td>
<td class="text-right">
{% if event.can_manage %}
<div class="flex justify-end gap-1">
<a class="btn btn-outline btn-sm" href="{% url 'management:event_detail' event.pk %}" aria-label="{% trans 'Edit' %}">{% lucide "pencil" size=14 %} {% trans "Edit" %}</a>
<button class="btn btn-sm btn-outline btn-error" type="button" onclick="document.getElementById('{{ event.pk|dom_id:"event_delete_modal" }}').showModal()" aria-label="{% trans 'Delete' %}">{% lucide "trash-2" size=14 %} {% trans "Delete" %}</button>
</div>
{% endif %}
</td>
</tr>
{% empty %}
<tr>
<td colspan="6" class="py-8 text-center text-muted">{% trans "No events." %}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% if not events %}
<div class="card p-8 text-center text-muted">{% trans "No events." %}</div>
{% else %}
<div class="flex flex-col gap-4">
{% if list_this_week %}
<div class="card overflow-hidden">
<div class="border-b border-line bg-subhead px-4 py-2 font-display text-xs font-extrabold tracking-[.08em] text-ink uppercase">{% trans "This week" %}</div>
{% for event in list_this_week %}{% include "management/_event_list_row.html" %}{% endfor %}
</div>
{% endif %}
{% if list_next_week %}
<div class="card overflow-hidden">
<div class="border-b border-line bg-subhead px-4 py-2 font-display text-xs font-extrabold tracking-[.08em] text-ink uppercase">{% trans "Next week" %}</div>
{% for event in list_next_week %}{% include "management/_event_list_row.html" %}{% endfor %}
</div>
{% endif %}
{% for month in list_months %}
<div class="card overflow-hidden">
<div class="border-b border-line bg-subhead px-4 py-2 font-display text-xs font-extrabold tracking-[.08em] text-ink uppercase">{{ month.month_start|date:"F Y" }}</div>
{% for event in month.events %}{% include "management/_event_list_row.html" %}{% endfor %}
</div>
{% endfor %}
</div>
</div>
{% endif %}
{% include "management/_pagination.html" %}