Add a Payments & dues section to the Me page, matching the design's M5 row
Home already had the M1 dues card; Me's own "Payments & dues" row was explicitly stubbed out with nowhere to lead. Give it a real destination: a Payments screen (open balances for everyone managed, reusing Home's dues-card layout via a shared _dues_row.html partial) and a "N OPEN" pill on the Me row itself, only shown once something is actually owed. club.services.fees.open_dues_rows is factored out so Home and Payments can never drift apart on what counts as "still open". Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01ECGMEwrc2k4D8VQuwjstj9
This commit is contained in:
23
mobile/templates/mobile/_dues_row.html
Normal file
23
mobile/templates/mobile/_dues_row.html
Normal file
@@ -0,0 +1,23 @@
|
||||
{% load i18n %}
|
||||
{% comment %}
|
||||
One open season-dues card. Expects ``row`` ({membership, balance, invoice})
|
||||
in scope -- included from both home.html's dues card and payments.html so
|
||||
the two surfaces render identically (see club.services.fees.open_dues_rows,
|
||||
their shared data source).
|
||||
{% endcomment %}
|
||||
<div class="m-card flex items-center gap-3 p-4">
|
||||
<div class="flex h-11 w-11 shrink-0 items-center justify-center rounded-lg bg-danger-bg">
|
||||
<span class="font-display text-lg font-extrabold text-club">€</span>
|
||||
</div>
|
||||
<div class="min-w-0 flex-1">
|
||||
<div class="text-sm font-semibold text-ink">{% blocktrans with name=row.membership.member.first_name %}Season dues — {{ name }}{% endblocktrans %}</div>
|
||||
<div class="text-xs text-muted">
|
||||
{% if row.invoice %}
|
||||
{% blocktrans with amount=row.balance|floatformat:2 due=row.invoice.due_date|date:"d M" %}€ {{ amount }} · due {{ due }}{% endblocktrans %}
|
||||
{% else %}
|
||||
{% blocktrans with amount=row.balance|floatformat:2 %}€ {{ amount }}{% endblocktrans %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<span class="btn btn-dark shrink-0">{% trans "Pay" %}</span>
|
||||
</div>
|
||||
@@ -112,22 +112,7 @@
|
||||
{% if dues_rows %}
|
||||
<div class="flex flex-col gap-2.5">
|
||||
{% for row in dues_rows %}
|
||||
<div class="m-card flex items-center gap-3 p-4">
|
||||
<div class="flex h-11 w-11 shrink-0 items-center justify-center rounded-lg bg-danger-bg">
|
||||
<span class="font-display text-lg font-extrabold text-club">€</span>
|
||||
</div>
|
||||
<div class="min-w-0 flex-1">
|
||||
<div class="text-sm font-semibold text-ink">{% blocktrans with name=row.membership.member.first_name %}Season dues — {{ name }}{% endblocktrans %}</div>
|
||||
<div class="text-xs text-muted">
|
||||
{% if row.invoice %}
|
||||
{% blocktrans with amount=row.balance|floatformat:2 due=row.invoice.due_date|date:"d M" %}€ {{ amount }} · due {{ due }}{% endblocktrans %}
|
||||
{% else %}
|
||||
{% blocktrans with amount=row.balance|floatformat:2 %}€ {{ amount }}{% endblocktrans %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<span class="btn btn-dark shrink-0">{% trans "Pay" %}</span>
|
||||
</div>
|
||||
{% include "mobile/_dues_row.html" %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
@@ -5,10 +5,12 @@
|
||||
M5 -- design_handoff_rosterchief_platform/README.md's M5 section, "Me &
|
||||
my people". See MeView's own docstring (mobile/views.py) for the judgment
|
||||
calls: no license/eligibility field backing "licence OK", so each row's
|
||||
meta line is real roster data instead; "Household & contacts" and
|
||||
"Payments & dues" have no screen to lead to and are omitted, same for the
|
||||
mockup's "Coach mode" promo (base.html's own precedent -- no Coach mode
|
||||
screens exist yet, so it's never rendered, not even as a dead/inert link).
|
||||
meta line is real roster data instead; "Household & contacts" has no
|
||||
screen to lead to and is omitted, same for the mockup's "Coach mode"
|
||||
promo (base.html's own precedent -- no Coach mode screens exist yet, so
|
||||
it's never rendered, not even as a dead/inert link). "Payments & dues"
|
||||
does lead somewhere (mobile:payments) and carries its "N OPEN" pill only
|
||||
once open_dues_count is actually > 0.
|
||||
The avatar/name/subtitle row lives in header_extra -- merged into the
|
||||
shared navy app-header (base.html) rather than a separately-coloured
|
||||
block of its own, matching the design canvas's own M5 markup.
|
||||
@@ -70,6 +72,16 @@
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" class="shrink-0 text-dim" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 5l7 7-7 7"/></svg>
|
||||
</a>
|
||||
<div class="h-px bg-rule"></div>
|
||||
<a class="flex items-center gap-3 p-3.5" href="{% url "mobile:payments" %}">
|
||||
<span class="flex-1 text-[15px] font-semibold text-ink">{% trans "Payments & dues" %}</span>
|
||||
{% if open_dues_count %}
|
||||
<span class="pill pill-danger shrink-0">
|
||||
{% blocktrans count counter=open_dues_count %}{{ counter }} OPEN{% plural %}{{ counter }} OPEN{% endblocktrans %}
|
||||
</span>
|
||||
{% endif %}
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" class="shrink-0 text-dim" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 5l7 7-7 7"/></svg>
|
||||
</a>
|
||||
<div class="h-px bg-rule"></div>
|
||||
<a class="flex items-center gap-3 p-3.5" href="{% url "mobile:notifications" %}">
|
||||
<span class="flex-1 text-[15px] font-semibold text-ink">{% trans "Notifications" %}</span>
|
||||
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" class="shrink-0 text-dim" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 5l7 7-7 7"/></svg>
|
||||
|
||||
32
mobile/templates/mobile/payments.html
Normal file
32
mobile/templates/mobile/payments.html
Normal file
@@ -0,0 +1,32 @@
|
||||
{% extends "mobile/base.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% comment %}
|
||||
M5's "Payments & dues" row -- every open season-dues balance across every
|
||||
managed person, one card per open row via mobile/_dues_row.html (the same
|
||||
partial Home's dues card uses, so the two never drift apart visually).
|
||||
White sticky back-header, same pattern as calendar_feed_settings.html --
|
||||
not a tab of its own, active_tab stays "me" (PaymentsView's own docstring).
|
||||
{% endcomment %}
|
||||
|
||||
{% block content %}
|
||||
<div class="-mx-4 -mt-4 flex items-center gap-1 border-b border-line bg-white px-4 py-3">
|
||||
<a class="-ml-2.5 flex h-11 w-11 shrink-0 items-center justify-center" href="{% url "mobile:me" %}" aria-label="{% trans "Back" %}">
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#0b1220" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round"><path d="M15 5l-7 7 7 7"/></svg>
|
||||
</a>
|
||||
<span class="min-w-0 flex-1 truncate font-display text-xl leading-none font-extrabold text-ink uppercase">{% trans "Payments & dues" %}</span>
|
||||
</div>
|
||||
|
||||
{% if dues_rows %}
|
||||
<div class="flex flex-col gap-2.5">
|
||||
{% for row in dues_rows %}
|
||||
{% include "mobile/_dues_row.html" %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="m-card p-6 text-center">
|
||||
<p class="font-display text-lg font-extrabold text-ink uppercase">{% trans "All settled up" %}</p>
|
||||
<p class="mt-1 text-sm text-muted">{% trans "There's nothing open right now." %}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock content %}
|
||||
Reference in New Issue
Block a user