Fix scrambled mobile layout on member detail and sweep the rest of the app
The mobile responsive pass still had real gaps: on member_detail.html, dt/dd label-value rows (phone numbers, dates) squeezed onto one line below `sm` instead of stacking, and guardian call/emergency-call buttons -- whose labels embed the guardian's name -- used a bare `grow` inside a non-wrapping flex row, pushing the whole row off screen once a name was long enough. Both patterns are fixed here and propagated to every other page with the same shape of bug: event_detail.html and event_series_detail.html still had the unmigrated dt/dd rows from before the first pass; sponsor_list.html's URLs and parent_claim_list.html's emails could force a table-card wider than the viewport (unbreakable strings, fixed with break-all); parent_claim_list.html's Approve/Reject buttons could both land on the left edge once the row wrapped (fixed with ms-auto); news_list.html's team-badge list and news_detail.html's per-photo action buttons were missing flex-wrap; team_detail.html had a stray table never converted to table-cards and two unstacked stat lists; referee_management.html's per-game referee badges were missing flex-wrap. Also hide the three dashboard charts (signups, fee status, renewal rate) below `lg` -- three squeezed canvases stacked on a phone added scroll without adding readability the stat cards above don't already give, and match family_list.html's search box to member_list.html's icon-only-below-`sm` pattern. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -19,7 +19,7 @@
|
||||
</div>
|
||||
<ul class="divide-y divide-base-200">
|
||||
{% for referee in referees %}
|
||||
<li class="flex items-center justify-between py-2 gap-2">
|
||||
<li class="flex flex-col gap-1 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<span>
|
||||
{{ referee.display_name }}
|
||||
{% if referee.is_external %}<span class="badge badge-neutral badge-xs">{% trans "External" %}</span>{% endif %}
|
||||
|
||||
@@ -37,42 +37,42 @@
|
||||
<div class="card-body">
|
||||
<h2 class="card-title text-base">{% lucide "info" size=18 %} {% trans "Details" %}</h2>
|
||||
<dl class="divide-y divide-base-200">
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "Start" %}</dt>
|
||||
<dd>{{ event.start|date:"j M Y H:i" }}</dd>
|
||||
<dd class="sm:text-right">{{ event.start|date:"j M Y H:i" }}</dd>
|
||||
</div>
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "End" %}</dt>
|
||||
<dd>{{ event.end|date:"j M Y H:i"|default:"—" }}</dd>
|
||||
<dd class="sm:text-right">{{ event.end|date:"j M Y H:i"|default:"—" }}</dd>
|
||||
</div>
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "Gathering" %}</dt>
|
||||
<dd>{{ event.gathering|date:"j M Y H:i"|default:"—" }}</dd>
|
||||
<dd class="sm:text-right">{{ event.gathering|date:"j M Y H:i"|default:"—" }}</dd>
|
||||
</div>
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "Registration deadline" %}</dt>
|
||||
<dd>{{ event.deadline|date:"j M Y H:i"|default:"—" }}</dd>
|
||||
<dd class="sm:text-right">{{ event.deadline|date:"j M Y H:i"|default:"—" }}</dd>
|
||||
</div>
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "Location" %}</dt>
|
||||
<dd>{{ event.location|default:"—" }}</dd>
|
||||
<dd class="sm:text-right">{{ event.location|default:"—" }}</dd>
|
||||
</div>
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "Opponent" %}</dt>
|
||||
<dd>{{ event.opponent|default:"—" }}</dd>
|
||||
<dd class="sm:text-right">{{ event.opponent|default:"—" }}</dd>
|
||||
</div>
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "Teams" %}</dt>
|
||||
<dd>{% for team in event.teams.all %}{{ team.name }}{% if not forloop.last %}, {% endif %}{% empty %}—{% endfor %}</dd>
|
||||
<dd class="sm:text-right">{% for team in event.teams.all %}{{ team.name }}{% if not forloop.last %}, {% endif %}{% empty %}—{% endfor %}</dd>
|
||||
</div>
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "Groups" %}</dt>
|
||||
<dd>{% for group in event.groups.all %}{{ group.name }}{% if not forloop.last %}, {% endif %}{% empty %}—{% endfor %}</dd>
|
||||
<dd class="sm:text-right">{% for group in event.groups.all %}{{ group.name }}{% if not forloop.last %}, {% endif %}{% empty %}—{% endfor %}</dd>
|
||||
</div>
|
||||
{% if event.club_wide %}
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "Audience" %}</dt>
|
||||
<dd><span class="badge badge-primary">{% trans "Whole club" %}</span></dd>
|
||||
<dd class="sm:text-right"><span class="badge badge-primary">{% trans "Whole club" %}</span></dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
</dl>
|
||||
@@ -91,9 +91,9 @@
|
||||
</div>
|
||||
<dl class="divide-y divide-base-200">
|
||||
{% for group in attendance_groups %}
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{{ group.label }}</dt>
|
||||
<dd class="font-semibold tabular-nums font-mono">{{ group.rows|length }}</dd>
|
||||
<dd class="font-semibold tabular-nums font-mono sm:text-right">{{ group.rows|length }}</dd>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</dl>
|
||||
|
||||
@@ -22,21 +22,21 @@
|
||||
<div class="card-body">
|
||||
<h2 class="card-title text-base">{% lucide "repeat" size=18 %} {% trans "Recurrence" %}</h2>
|
||||
<dl class="divide-y divide-base-200">
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "Pattern" %}</dt>
|
||||
<dd>{{ recurrence_summary }}</dd>
|
||||
<dd class="sm:text-right">{{ recurrence_summary }}</dd>
|
||||
</div>
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "First occurrence" %}</dt>
|
||||
<dd>{{ series.dtstart|date:"j M Y H:i" }}</dd>
|
||||
<dd class="sm:text-right">{{ series.dtstart|date:"j M Y H:i" }}</dd>
|
||||
</div>
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "Repeats until" %}</dt>
|
||||
<dd>{{ series.until|date:"j M Y H:i"|default:"—" }}</dd>
|
||||
<dd class="sm:text-right">{{ series.until|date:"j M Y H:i"|default:"—" }}</dd>
|
||||
</div>
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "Generated up to" %}</dt>
|
||||
<dd>{{ series.generated_until|date:"j M Y"|default:"—" }}</dd>
|
||||
<dd class="sm:text-right">{{ series.generated_until|date:"j M Y"|default:"—" }}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
@@ -46,17 +46,17 @@
|
||||
<div class="card-body">
|
||||
<h2 class="card-title text-base">{% lucide "info" size=18 %} {% trans "Template" %}</h2>
|
||||
<dl class="divide-y divide-base-200">
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "Location" %}</dt>
|
||||
<dd>{{ series.location|default:"—" }}</dd>
|
||||
<dd class="sm:text-right">{{ series.location|default:"—" }}</dd>
|
||||
</div>
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "Opponent" %}</dt>
|
||||
<dd>{{ series.opponent|default:"—" }}</dd>
|
||||
<dd class="sm:text-right">{{ series.opponent|default:"—" }}</dd>
|
||||
</div>
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "Teams" %}</dt>
|
||||
<dd>{% for team in series.teams.all %}{{ team.name }}{% if not forloop.last %}, {% endif %}{% empty %}—{% endfor %}</dd>
|
||||
<dd class="sm:text-right">{% for team in series.teams.all %}{{ team.name }}{% if not forloop.last %}, {% endif %}{% empty %}—{% endfor %}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
|
||||
@@ -11,14 +11,15 @@
|
||||
{% endblock actions %}
|
||||
|
||||
{% block panel %}
|
||||
<form method="get" class="mb-2 flex flex-wrap items-center gap-2">
|
||||
<label class="input">
|
||||
<form method="get" class="mb-2 flex items-center gap-2">
|
||||
<label class="input grow sm:grow-0">
|
||||
<span class="opacity-50">{% lucide "search" size=16 %}</span>
|
||||
<input type="search" name="q" value="{{ search }}" placeholder="{% trans 'Search by parent or child name ...' %}" class="input input-bordered w-full max-w-xs">
|
||||
<input type="search" name="q" value="{{ search }}" placeholder="{% trans 'Search by parent or child name ...' %}" class="input input-bordered w-full sm:max-w-xs">
|
||||
</label>
|
||||
<button class="btn btn-outline gap-2" type="submit">{% lucide "search" size=16 %} {% trans "Search" %}</button>
|
||||
{# Icon-only below `sm`: label text next to a growing input is what forced this row to wrap on a phone. #}
|
||||
<button class="btn btn-outline gap-2" type="submit" aria-label="{% trans 'Search' %}">{% lucide "search" size=16 %}<span class="hidden sm:inline">{% trans "Search" %}</span></button>
|
||||
{% if search %}
|
||||
<a class="btn gap-2" href="{% url "management:family_list" %}">{% lucide "x" size=16 %} {% trans "Clear filter" %}</a>
|
||||
<a class="btn gap-2" href="{% url "management:family_list" %}" aria-label="{% trans 'Clear filter' %}">{% lucide "x" size=16 %}<span class="hidden sm:inline">{% trans "Clear filter" %}</span></a>
|
||||
{% endif %}
|
||||
</form>
|
||||
|
||||
|
||||
@@ -140,7 +140,8 @@
|
||||
</div>
|
||||
|
||||
{% if is_club_admin %}
|
||||
<div class="mb-6 grid gap-4 lg:grid-cols-3">
|
||||
{# Charts are desktop-only: three squeezed canvases stacked on a phone add scroll without adding much readability -- the same numbers already sit in the stat cards above. #}
|
||||
<div class="mb-6 hidden gap-4 lg:grid lg:grid-cols-3">
|
||||
<div class="card bg-base-100 shadow">
|
||||
<div class="card-body">
|
||||
<h2 class="card-title text-base">{% lucide "user-plus" size=18 %} {% trans "Signups per month" %}</h2>
|
||||
|
||||
@@ -16,36 +16,37 @@
|
||||
<div class="card-body">
|
||||
<h2 class="card-title text-base">{% lucide "user" size=18 %} {% trans "Personal information" %}</h2>
|
||||
<dl class="divide-y divide-base-200">
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "Date of birth" %}</dt>
|
||||
<dd class="font-semibold">{{ member.date_of_birth|default:"-" }}</dd>
|
||||
<dd class="font-semibold sm:text-right">{{ member.date_of_birth|default:"-" }}</dd>
|
||||
</div>
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "Phone" %}</dt>
|
||||
<dd class="font-semibold">{{ member.phone.as_international|default:"-" }}</dd>
|
||||
<dd class="font-semibold sm:text-right">{{ member.phone.as_international|default:"-" }}</dd>
|
||||
</div>
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "Emergency phone" %}</dt>
|
||||
<dd class="font-semibold">{{ member.emergency_phone.as_international|default:"-" }}</dd>
|
||||
<dd class="font-semibold sm:text-right">{{ member.emergency_phone.as_international|default:"-" }}</dd>
|
||||
</div>
|
||||
{% for guardian in guardians %}
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "Parent phone" %} — {{ guardian.get_full_name }}</dt>
|
||||
<dd class="font-semibold">{{ guardian.phone.as_international|default:"-" }}</dd>
|
||||
<dd class="font-semibold sm:text-right">{{ guardian.phone.as_international|default:"-" }}</dd>
|
||||
</div>
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "Parent emergency phone" %} — {{ guardian.get_full_name }}</dt>
|
||||
<dd class="font-semibold">{{ guardian.emergency_phone.as_international|default:"-" }}</dd>
|
||||
<dd class="font-semibold sm:text-right">{{ guardian.emergency_phone.as_international|default:"-" }}</dd>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</dl>
|
||||
|
||||
<div class="flex flex-row gap-2 items-center mt-2">
|
||||
{# flex-col below `sm`: a button's own label never wraps, so two grow buttons side by side in a fixed row push wider than the screen once either label is long -- stacking avoids that regardless of label length. #}
|
||||
<div class="flex flex-col gap-2 sm:flex-row sm:items-center mt-2">
|
||||
{% if member.phone %}
|
||||
<a class="btn btn-sm btn-outline btn-primary grow" href="tel:{{ member.phone.as_international }}">{% lucide "phone" size=14 %} {% trans "Call" %}</a>
|
||||
<a class="btn btn-sm btn-outline btn-primary sm:grow" href="tel:{{ member.phone.as_international }}">{% lucide "phone" size=14 %} {% trans "Call" %}</a>
|
||||
{% endif %}
|
||||
{% if member.emergency_phone %}
|
||||
<a class="btn btn-sm btn-outline btn-error grow" href="tel:{{ member.emergency_phone.as_international }}">{% lucide "shield-alert" size=14 %} {% trans "Emergency call" %}</a>
|
||||
<a class="btn btn-sm btn-outline btn-error sm:grow" href="tel:{{ member.emergency_phone.as_international }}">{% lucide "shield-alert" size=14 %} {% trans "Emergency call" %}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
@@ -56,12 +57,12 @@
|
||||
</div>
|
||||
{% for guardian in guardians %}
|
||||
{% if guardian.phone or guardian.emergency_phone %}
|
||||
<div class="flex flex-row gap-2 items-center mt-2">
|
||||
<div class="flex flex-col gap-2 sm:flex-row sm:items-center mt-2">
|
||||
{% if guardian.phone %}
|
||||
<a class="btn btn-sm btn-outline btn-primary grow" href="tel:{{ guardian.phone.as_international }}">{% lucide "phone" size=14 %} {% blocktrans with name=guardian.get_full_name %}Call {{ name }}{% endblocktrans %}</a>
|
||||
<a class="btn btn-sm btn-outline btn-primary sm:grow" href="tel:{{ guardian.phone.as_international }}">{% lucide "phone" size=14 %} {% blocktrans with name=guardian.get_full_name %}Call {{ name }}{% endblocktrans %}</a>
|
||||
{% endif %}
|
||||
{% if guardian.emergency_phone %}
|
||||
<a class="btn btn-sm btn-outline btn-error grow" href="tel:{{ guardian.emergency_phone.as_international }}">{% lucide "shield-alert" size=14 %} {% blocktrans with name=guardian.get_full_name %}Emergency: {{ name }}{% endblocktrans %}</a>
|
||||
<a class="btn btn-sm btn-outline btn-error sm:grow" href="tel:{{ guardian.emergency_phone.as_international }}">{% lucide "shield-alert" size=14 %} {% blocktrans with name=guardian.get_full_name %}Emergency: {{ name }}{% endblocktrans %}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
@@ -92,22 +93,22 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
<dl class="divide-y divide-base-200">
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "Joined as" %}</dt>
|
||||
<dd class="font-semibold">{{ current_membership.get_kind_display|capfirst }}</dd>
|
||||
<dd class="font-semibold sm:text-right">{{ current_membership.get_kind_display|capfirst }}</dd>
|
||||
</div>
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "License" %}</dt>
|
||||
<dd class="font-semibold">{{ current_membership.license|default:"-" }}</dd>
|
||||
<dd class="font-semibold sm:text-right">{{ current_membership.license|default:"-" }}</dd>
|
||||
</div>
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "Status" %}</dt>
|
||||
<dd class="font-semibold">{{ current_membership.get_status_display }}</dd>
|
||||
<dd class="font-semibold sm:text-right">{{ current_membership.get_status_display }}</dd>
|
||||
</div>
|
||||
{% if not current_membership.is_guardian %}
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "Fee status" %}</dt>
|
||||
<dd class="font-semibold">{{ current_membership.get_fee_status_display }}</dd>
|
||||
<dd class="font-semibold sm:text-right">{{ current_membership.get_fee_status_display }}</dd>
|
||||
</div>
|
||||
{% endif %}
|
||||
</dl>
|
||||
@@ -157,11 +158,11 @@
|
||||
|
||||
{% if referee_profile and referee_profile.level %}
|
||||
<dl class="divide-y divide-base-200">
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "Level" %}</dt>
|
||||
<dd class="font-semibold">{{ referee_profile.level }}</dd>
|
||||
<dd class="font-semibold sm:text-right">{{ referee_profile.level }}</dd>
|
||||
</div>
|
||||
<div class="flex items-center justify-between py-2">
|
||||
<div class="flex flex-col gap-0.5 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<dt class="text-sm opacity-70">{% trans "Valid until" %}</dt>
|
||||
<dd class="font-semibold flex items-center gap-2">
|
||||
{{ referee_profile.valid_until|default:"—" }}
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
<span class="badge badge-success badge-sm absolute top-1 left-1">{% trans "Main" %}</span>
|
||||
{% endif %}
|
||||
{% if can_edit %}
|
||||
<div class="flex gap-1 mt-1">
|
||||
<div class="flex flex-wrap gap-1 mt-1">
|
||||
{% if not photo.is_main %}
|
||||
<form method="post" action="{% url 'management:news_photo_set_main' news_item.pk photo.pk %}">
|
||||
{% csrf_token %}
|
||||
|
||||
@@ -28,11 +28,13 @@
|
||||
<tr>
|
||||
<td><a class="link link-hover font-semibold" href="{% url 'management:news_detail' news_item.pk %}">{{ news_item.title }}</a></td>
|
||||
<td data-label="{% trans 'Teams' %}">
|
||||
{% for team in news_item.teams.all %}
|
||||
<span class="badge badge-neutral badge-sm">{{ team.short_name }}</span>
|
||||
{% empty %}
|
||||
<span class="opacity-60">{% trans "Club-wide" %}</span>
|
||||
{% endfor %}
|
||||
<div class="flex flex-wrap gap-2">
|
||||
{% for team in news_item.teams.all %}
|
||||
<span class="badge badge-neutral badge-sm">{{ team.short_name }}</span>
|
||||
{% empty %}
|
||||
<span class="opacity-60">{% trans "Club-wide" %}</span>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</td>
|
||||
<td data-label="{% trans 'Visibility' %}">{{ news_item.get_visibility_display }}</td>
|
||||
<td data-label="{% trans 'Status' %}">
|
||||
@@ -46,7 +48,7 @@
|
||||
</td>
|
||||
<td class="text-right">
|
||||
{% if news_item.can_edit %}
|
||||
<div class="flex justify-end gap-1">
|
||||
<div class="flex flex-wrap justify-end gap-1">
|
||||
<a class="btn btn-outline btn-sm" href="{% url 'management:news_detail' news_item.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('{{ news_item.pk|dom_id:"news_delete_modal" }}').showModal()" aria-label="{% trans 'Delete' %}">{% lucide "trash-2" size=14 %} {% trans "Delete" %}</button>
|
||||
</div>
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
<div>
|
||||
<div class="text-xs opacity-70">{% trans "Parent says they are" %}</div>
|
||||
<div class="font-semibold">{{ claim.parent_name }}</div>
|
||||
<div class="text-sm opacity-70">{{ claim.parent_email }}</div>
|
||||
<div class="text-sm opacity-70 break-all">{{ claim.parent_email }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-xs opacity-70">{% trans "Parent of" %}</div>
|
||||
@@ -36,7 +36,12 @@
|
||||
justify-between (rather than everything in one flex-wrap run) keeps
|
||||
Approve and Reject apart even as the row wraps on a narrow card --
|
||||
Approve stays pinned left, Reject right, so the two are never one
|
||||
stray click apart the way adjacent buttons would be.
|
||||
stray click apart the way adjacent buttons would be. ms-auto on Reject
|
||||
is the part that actually guarantees "right": once the row is narrow
|
||||
enough that Approve and Reject fall onto separate flex-wrap lines,
|
||||
justify-between has only one item per line and pins it to the *start*
|
||||
-- margin-inline-start:auto keeps Reject flush right regardless of
|
||||
which line it ends up sharing (or not sharing) with Approve.
|
||||
{% endcomment %}
|
||||
<div class="flex flex-wrap items-center justify-between gap-x-4 gap-y-2">
|
||||
{% if claim.has_candidates %}
|
||||
@@ -49,7 +54,7 @@
|
||||
<p class="text-sm opacity-70">{% trans "No child without a parent matches this. Check the spelling and the date of birth with them before rejecting." %}</p>
|
||||
{% endif %}
|
||||
|
||||
<button class="btn btn-outline btn-error btn-sm gap-2" type="button" onclick="document.getElementById('{{ claim.pk|dom_id:"claim_reject_modal" }}').showModal()">
|
||||
<button class="btn btn-outline btn-error btn-sm gap-2 ms-auto" type="button" onclick="document.getElementById('{{ claim.pk|dom_id:"claim_reject_modal" }}').showModal()">
|
||||
{% lucide "x" size=14 %} {% trans "Reject" %}
|
||||
</button>
|
||||
</div>
|
||||
@@ -76,9 +81,9 @@
|
||||
<p class="text-sm opacity-70">{% trans "Imported without a parent. They stay here until someone claims them." %}</p>
|
||||
<ul class="divide-y divide-base-200">
|
||||
{% for child in awaiting_a_parent %}
|
||||
<li class="py-2 flex items-center justify-between">
|
||||
<li class="py-2 flex flex-col gap-0.5 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<a class="link link-hover" href="{% url 'management:member_detail' child.pk %}">{{ child }}</a>
|
||||
<span class="text-sm opacity-70">{{ child.date_of_birth|date:"j F Y"|default:"—" }}</span>
|
||||
<span class="text-sm opacity-70 sm:text-right">{{ child.date_of_birth|date:"j F Y"|default:"—" }}</span>
|
||||
</li>
|
||||
{% empty %}
|
||||
<li class="py-2 text-sm opacity-60">{% trans "Every child has a parent linked." %}</li>
|
||||
@@ -104,7 +109,7 @@
|
||||
<tbody>
|
||||
{% for claim in reviewed %}
|
||||
<tr>
|
||||
<td class="font-semibold">{{ claim.parent_name }}<div class="text-xs font-normal opacity-60">{{ claim.parent_email }}</div></td>
|
||||
<td class="font-semibold">{{ claim.parent_name }}<div class="text-xs font-normal opacity-60 break-all">{{ claim.parent_email }}</div></td>
|
||||
<td data-label="{% trans 'Claimed' %}">{{ claim.claimed_child_name }}</td>
|
||||
<td data-label="{% trans 'Outcome' %}">
|
||||
{% if claim.status == "approved" %}
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
{% if game.opponent %}{% trans "vs" %} {{ game.opponent }}{% endif %}
|
||||
</a>
|
||||
<div class="text-xs opacity-70">{{ game.start|date:"H:i" }}{% if game.location %} — {{ game.location }}{% endif %}</div>
|
||||
<div class="text-xs">
|
||||
<div class="flex flex-wrap gap-1 text-xs">
|
||||
{% for referee in game.referee_rows %}
|
||||
<span class="badge badge-primary badge-sm">{{ referee.display_name }}{% if referee.is_external %} ({% trans "ext." %}){% endif %}</span>
|
||||
{% empty %}
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
<td class="font-semibold">{{ sponsor.name }}</td>
|
||||
<td data-label="{% trans 'URL' %}">
|
||||
{% if sponsor.url %}
|
||||
<a class="link link-hover" href="{{ sponsor.url }}" target="_blank" rel="noopener noreferrer">{{ sponsor.url }}</a>
|
||||
<a class="link link-hover break-all" href="{{ sponsor.url }}" target="_blank" rel="noopener noreferrer">{{ sponsor.url }}</a>
|
||||
{% else %}
|
||||
<span class="opacity-50">—</span>
|
||||
{% endif %}
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
<h2 class="card-title text-base">{% lucide "trending-up" size=18 %} {% trans "Top attenders" %}</h2>
|
||||
<ul class="divide-y divide-base-200">
|
||||
{% for entry in top_attenders %}
|
||||
<li class="flex items-center justify-between py-2">
|
||||
<li class="flex flex-col gap-1 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<span class="text-sm">{{ entry.member }}</span>
|
||||
<span class="font-semibold tabular-nums font-mono">{{ entry.rate }}%</span>
|
||||
</li>
|
||||
@@ -94,7 +94,7 @@
|
||||
<h2 class="card-title text-base">{% lucide "trending-down" size=18 %} {% trans "Needs attention" %}</h2>
|
||||
<ul class="divide-y divide-base-200">
|
||||
{% for entry in bottom_attenders %}
|
||||
<li class="flex items-center justify-between py-2">
|
||||
<li class="flex flex-col gap-1 py-2 sm:flex-row sm:items-center sm:justify-between sm:gap-4">
|
||||
<span class="text-sm">{{ entry.member }}</span>
|
||||
<span class="font-semibold tabular-nums font-mono">{{ entry.rate }}%</span>
|
||||
</li>
|
||||
@@ -205,7 +205,7 @@
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="overflow-x-auto">
|
||||
<table class="table">
|
||||
<table class="table table-cards">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% trans "Member" %}</th>
|
||||
@@ -216,11 +216,11 @@
|
||||
<tbody>
|
||||
{% for assignment in staff %}
|
||||
<tr>
|
||||
<td>{{ assignment.member }}</td>
|
||||
<td>{{ assignment.position }}</td>
|
||||
<td class="font-semibold">{{ assignment.member }}</td>
|
||||
<td data-label="{% trans 'Position' %}">{{ assignment.position }}</td>
|
||||
<td class="text-right">
|
||||
{% if can_manage %}
|
||||
<div class="flex justify-end gap-1">
|
||||
<div class="flex flex-wrap justify-end gap-1">
|
||||
<button class="btn btn-outline btn-sm" type="button" onclick="document.getElementById('{{ assignment.pk|dom_id:"edit_staff_modal" }}').showModal()" aria-label="{% trans 'Edit' %}">{% lucide "pencil" size=14 %} {% trans "Edit" %}</button>
|
||||
<button class="btn btn-sm btn-outline btn-error" type="button" onclick="document.getElementById('{{ assignment.pk|dom_id:"remove_staff_modal" }}').showModal()" aria-label="{% trans 'Remove' %}">{% lucide "user-minus" size=14 %} {% trans "Remove" %}</button>
|
||||
</div>
|
||||
|
||||
@@ -3107,6 +3107,9 @@
|
||||
border-block-end-width: calc(var(--border, 1px) * var(--join-h));
|
||||
}
|
||||
}
|
||||
.ms-auto {
|
||||
margin-inline-start: auto;
|
||||
}
|
||||
.modal-action {
|
||||
@layer daisyui.l1.l2.l3 {
|
||||
margin-top: calc(0.25rem * 6);
|
||||
@@ -3624,6 +3627,9 @@
|
||||
.justify-start {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.gap-0\.5 {
|
||||
gap: calc(var(--spacing) * 0.5);
|
||||
}
|
||||
.gap-1 {
|
||||
gap: var(--spacing);
|
||||
}
|
||||
@@ -4035,6 +4041,9 @@
|
||||
--tw-tracking: var(--tracking-wider);
|
||||
letter-spacing: var(--tracking-wider);
|
||||
}
|
||||
.break-all {
|
||||
word-break: break-all;
|
||||
}
|
||||
.whitespace-nowrap {
|
||||
white-space: nowrap;
|
||||
}
|
||||
@@ -4426,6 +4435,11 @@
|
||||
max-width: var(--container-xs);
|
||||
}
|
||||
}
|
||||
.sm\:grow {
|
||||
@media (width >= 40rem) {
|
||||
flex-grow: 1;
|
||||
}
|
||||
}
|
||||
.sm\:grow-0 {
|
||||
@media (width >= 40rem) {
|
||||
flex-grow: 0;
|
||||
@@ -4476,6 +4490,11 @@
|
||||
padding-inline: calc(var(--spacing) * 6);
|
||||
}
|
||||
}
|
||||
.sm\:text-right {
|
||||
@media (width >= 40rem) {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
.sm\:text-2xl {
|
||||
@media (width >= 40rem) {
|
||||
font-size: var(--text-2xl);
|
||||
@@ -4528,6 +4547,11 @@
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
.lg\:grid {
|
||||
@media (width >= 64rem) {
|
||||
display: grid;
|
||||
}
|
||||
}
|
||||
.lg\:hidden {
|
||||
@media (width >= 64rem) {
|
||||
display: none;
|
||||
|
||||
Reference in New Issue
Block a user