feat: fee underpayment indicator + premium color on month tiles
Some checks are pending
NordaBiz Tests / Unit & Integration Tests (push) Waiting to run
NordaBiz Tests / E2E Tests (Playwright) (push) Blocked by required conditions
NordaBiz Tests / Smoke Tests (Production) (push) Blocked by required conditions
NordaBiz Tests / Send Failure Notification (push) Blocked by required conditions

- paid 200 zł (stawka 200): green (standard)
- paid 300 zł (stawka 300): teal (paid-premium)
- paid 200 zł (stawka 300): red outline + ! badge (underpaid)
Applied to both board/skladki and admin/fees views.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Maciej Pienczyn 2026-04-10 16:46:37 +02:00
parent 6a94386ee7
commit ea8b622903
2 changed files with 16 additions and 6 deletions

View File

@ -245,6 +245,7 @@
}
.month-cell.paid { background: var(--success); color: white; }
.month-cell.paid-premium { background: #0d9488; color: white; }
.month-cell.partial { background: #60a5fa; color: white; }
.month-cell.pending { background: var(--warning); color: white; }
.month-cell.overdue { background: var(--error); color: white; }
@ -481,12 +482,15 @@
{% for m in range(1, 13) %}
<td class="col-month">
{% set fee = cf.months.get(m) %}
{% set expected = cf.expected_fees.get(m, 200) %}
{% set underpaid = fee and fee.amount and fee.amount|int < expected %}
{% set is_premium = fee and fee.status == 'paid' and expected >= 300 and fee.amount|int >= 300 %}
{% if fee %}
<span class="month-cell {{ fee.status }}" title="{{ fee.status }}: wpłacono {{ fee.amount_paid|int }} z {{ fee.amount|int }} zł (stawka: {{ cf.expected_fees.get(m, 200) }} zł)" style="position:relative;">
{{ m }}{% if fee.status == 'partial' %}<span class="partial-badge">{{ fee.amount_paid|int }}</span>{% endif %}
<span class="month-cell {% if is_premium %}paid-premium{% else %}{{ fee.status }}{% endif %}" title="{{ fee.status }}: wpłacono {{ fee.amount_paid|int }} z {{ fee.amount|int }} zł{% if underpaid %} ⚠ stawka powinna wynosić {{ expected }} zł{% endif %}{% if is_premium %} (stawka pełna 300 zł){% endif %}" style="position:relative;{% if underpaid %}outline:2px solid var(--error);outline-offset:-2px;{% endif %}">
{{ m }}{% if fee.status == 'partial' %}<span class="partial-badge">{{ fee.amount_paid|int }}</span>{% endif %}{% if underpaid %}<span style="position:absolute;top:-6px;right:-6px;background:var(--error);color:white;font-size:8px;font-weight:700;width:14px;height:14px;border-radius:50%;display:flex;align-items:center;justify-content:center;line-height:1;">!</span>{% endif %}
</span>
{% else %}
<span class="month-cell empty" title="Brak rekordu (stawka: {{ cf.expected_fees.get(m, 200) }} zł)">-</span>
<span class="month-cell empty" title="Brak rekordu (stawka: {{ expected }} zł)">-</span>
{% endif %}
</td>
{% endfor %}

View File

@ -125,6 +125,7 @@
}
.month-cell.paid { background: var(--success); color: white; }
.month-cell.paid-premium { background: #0d9488; color: white; }
.month-cell.partial { background: #60a5fa; color: white; }
.month-cell.pending { background: var(--warning); color: white; }
.month-cell.overdue { background: var(--error); color: white; }
@ -241,6 +242,8 @@
<th class="col-month">I</th><th class="col-month">II</th><th class="col-month">III</th><th class="col-month">IV</th><th class="col-month">V</th><th class="col-month">VI</th>
<th class="col-month">VII</th><th class="col-month">VIII</th><th class="col-month">IX</th><th class="col-month">X</th><th class="col-month">XI</th><th class="col-month">XII</th>
<th style="width:70px;font-size:9px;line-height:1.2;">Zaległ.<br><span style="font-weight:400;text-transform:none;">z lat poprz.</span></th>
<th style="width:50px;font-size:9px;">Przyp.</th>
<th style="width:60px;font-size:9px;">Wezwanie</th>
</tr>
</thead>
<tbody>
@ -308,12 +311,15 @@
{% for m in range(1, 13) %}
<td class="col-month">
{% set fee = cf.months.get(m) %}
{% set expected = cf.expected_fees.get(m, 200) %}
{% set underpaid = fee and fee.amount and fee.amount|int < expected %}
{% set is_premium = fee and fee.status == 'paid' and expected >= 300 and fee.amount|int >= 300 %}
{% if fee %}
<span class="month-cell {{ fee.status }}" title="{{ fee.status }}: wpłacono {{ fee.amount_paid|int }} z {{ fee.amount|int }} zł (stawka: {{ cf.expected_fees.get(m, 200) }} zł)" style="position:relative;">
{{ m }}{% if fee.status == 'partial' %}<span class="partial-badge">{{ fee.amount_paid|int }}</span>{% endif %}
<span class="month-cell {% if is_premium %}paid-premium{% else %}{{ fee.status }}{% endif %}" title="{{ fee.status }}: wpłacono {{ fee.amount_paid|int }} z {{ fee.amount|int }} zł{% if underpaid %} ⚠ stawka powinna wynosić {{ expected }} zł{% endif %}{% if is_premium %} (stawka pełna 300 zł){% endif %}" style="position:relative;{% if underpaid %}outline:2px solid var(--error);outline-offset:-2px;{% endif %}">
{{ m }}{% if fee.status == 'partial' %}<span class="partial-badge">{{ fee.amount_paid|int }}</span>{% endif %}{% if underpaid %}<span style="position:absolute;top:-6px;right:-6px;background:var(--error);color:white;font-size:8px;font-weight:700;width:14px;height:14px;border-radius:50%;display:flex;align-items:center;justify-content:center;line-height:1;">!</span>{% endif %}
</span>
{% else %}
<span class="month-cell empty" title="Brak rekordu (stawka: {{ cf.expected_fees.get(m, 200) }} zł)">-</span>
<span class="month-cell empty" title="Brak rekordu (stawka: {{ expected }} zł)">-</span>
{% endif %}
</td>
{% endfor %}