Round out referee amounts/colors, and add bilingual (nl/en) news content

Referee display: drop the redundant "External" pill from the PDF form, round
the event/dashboard "due" summary to 2 decimals (a fine-grained km rate like
0.083 was pushing the raw total to 3+ decimals), and theme the PDF's accent
colors off the club's own primary/secondary colors instead of a hardcoded
default.

News: title/body stay the club's own-language (Dutch) text; new optional
title_en/body_en carry a translation, with News.effective_title_en/
effective_body_en resolving the fallback to the original on read rather than
copying it in at save time -- so editing the Dutch text later never leaves a
stale English copy behind, and existing rows get correct fallback behaviour
with no backfill. The news form lays both languages out side by side; the
detail page only shows an English section when one was actually added. The
public API returns both languages in one call (title_nl/body_nl/excerpt_nl
alongside title_en/body_en/excerpt_en, the latter never blank) -- a breaking
rename of the previously-unprefixed title/body/excerpt fields.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-10 20:47:58 +02:00
parent 0a9ac67b21
commit 5dcffefb28
13 changed files with 265 additions and 31 deletions

View File

@@ -24,7 +24,7 @@
{{ referee.display_name }}
{% if referee.is_external %}<span class="badge badge-neutral badge-xs">{% trans "External" %}</span>{% endif %}
{% if referee.assigned_by %}<span class="text-xs opacity-60">— {% blocktrans with name=referee.assigned_by %}assigned by {{ name }}{% endblocktrans %}</span>{% endif %}
{% if referee.total_payable %}<span class="text-xs opacity-60">— {% blocktrans with total=referee.total_payable %}€{{ total }} due{% endblocktrans %}</span>{% endif %}
{% if referee.total_payable %}<span class="text-xs opacity-60">— {% blocktrans with total=referee.total_payable|floatformat:2 %}€{{ total }} due{% endblocktrans %}</span>{% endif %}
</span>
{% if can_manage_referees %}
<div class="flex gap-1 shrink-0">

View File

@@ -24,7 +24,12 @@
color: #8a8a8a;
}
}
:root { --accent: #3730a3; --accent-soft: #eef0fc; --ink: #16181d; --muted: #6b7280; --line: #d8dae0; }
:root {
--accent: {{ club.primary_color|default:"#3730a3" }};
--accent-secondary: {{ club.secondary_color|default:"#be185d" }};
--accent-soft: color-mix(in srgb, var(--accent-secondary) 14%, white);
--ink: #16181d; --muted: #6b7280; --line: #d8dae0;
}
* { box-sizing: border-box; }
body { font-family: sans-serif; font-size: 10pt; color: var(--ink); line-height: 1.45; }
@@ -51,8 +56,7 @@
table.fees td { padding: 2.5mm 2mm 2.5mm 0; border-bottom: 0.75pt solid var(--line); vertical-align: top; }
table.fees td.amount, table.fees th.amount { text-align: right; }
table.fees tr.empty td { color: var(--muted); font-style: italic; }
.badge-external { display: inline-block; font-size: 7pt; color: var(--accent); background: var(--accent-soft); border-radius: 2mm; padding: 0.3mm 1.5mm; margin-left: 1.5mm; }
table.fees tr.total td { border-bottom: none; border-top: 1.5pt solid var(--ink); font-weight: 700; padding-top: 3mm; }
table.fees tr.total td { border-bottom: none; border-top: 1.5pt solid var(--accent); font-weight: 700; padding-top: 3mm; }
.signatures { display: flex; gap: 8mm; margin-top: 4mm; }
.sign-box { flex: 1; }
@@ -120,10 +124,7 @@
<tbody>
{% for referee in referees %}
<tr>
<td>
{{ referee.display_name }}
{% if referee.is_external %}<span class="badge-external">{% trans "External" %}</span>{% endif %}
</td>
<td>{{ referee.display_name }}</td>
<td class="amount">€{{ referee.fee|floatformat:2 }}</td>
<td class="amount">{% if referee.km %}{{ referee.km }} km{% else %}—{% endif %}</td>
<td class="amount">{% if referee.km %}€{{ referee.km_rate }}{% else %}—{% endif %}</td>

View File

@@ -41,6 +41,16 @@
</div>
</div>
{% if news_item.title_en or news_item.body_en %}
<div class="card bg-base-100 shadow mt-4">
<div class="card-body">
<h2 class="card-title text-base">{% trans "English" %}</h2>
{% if news_item.title_en %}<p class="font-semibold">{{ news_item.title_en }}</p>{% endif %}
{% if news_item.body_en %}<p class="whitespace-pre-line">{{ news_item.body_en }}</p>{% endif %}
</div>
</div>
{% endif %}
<div class="card bg-base-100 shadow mt-4">
<div class="card-body">
<div class="flex items-center justify-between">

View File

@@ -19,10 +19,19 @@
<p class="opacity-70 text-sm mb-2">{% trans "Photos can be added once the news item is created." %}</p>
{% endif %}
<div class="grid grid-cols-1 gap-4">
{% for field in form %}
{% form_field field %}
{% endfor %}
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
{% form_field form.title %}
{% form_field form.title_en %}
</div>
<div class="grid grid-cols-1 gap-4 mt-4">
{% form_field form.teams %}
{% form_field form.visibility %}
</div>
<div class="grid grid-cols-1 md:grid-cols-2 gap-4 mt-4">
{% form_field form.body %}
{% form_field form.body_en %}
</div>
<div class="card-actions justify-start pt-2 mt-2">