Files
zbiorki_app/templates/zbiorka.html
2025-10-10 13:30:13 +02:00

334 lines
14 KiB
HTML

{% extends 'base.html' %}
{% block title %}{{ zbiorka.nazwa }}{% endblock %}
{% block content %}
<div class="container my-4">
{# Wyliczenia postępu finansowego #}
{% set has_cel = (zbiorka.cel is defined and zbiorka.cel and zbiorka.cel > 0) %}
{% set progress = (zbiorka.stan / zbiorka.cel * 100) if has_cel else 0 %}
{% set progress_clamped = 100 if progress > 100 else (0 if progress < 0 else progress) %} {% set
is_done=(progress_clamped>= 100) %}
<!-- Nagłówek -->
<div class="d-flex flex-wrap align-items-center justify-content-between gap-2 mb-3">
<h2 class="mb-0">{{ zbiorka.nazwa }}</h2>
<div class="d-flex flex-wrap align-items-center gap-2">
{% if is_done %}
<span class="badge rounded-pill" style="background: var(--accent); color:#111;">Zrealizowana</span>
{% endif %}
{% if zbiorka.ukryj_kwote %}
<span class="badge bg-secondary">Kwoty niepubliczne</span>
{% else %}
<span class="badge bg-success">Kwoty widoczne</span>
{% endif %}
</div>
</div>
<div class="row g-4">
<!-- Kolumna lewa: Opis + (opcjonalnie) Lista zakupów + Postęp -->
<div class="col-md-8">
<!-- Card: Opis -->
<div class="card shadow-sm mb-4">
<div class="card-body">
<h5 class="mb-2">Opis</h5>
<hr class="hr-bw">
<div class="mb-0">
{{ zbiorka.opis | markdown }}
</div>
</div>
</div>
{# Czy są produkty? #}
{% set items = zbiorka.przedmioty or [] %}
{% set has_items = (items|length > 0) %}
<!-- Card: Lista zakupów (tylko gdy są produkty) -->
{% if has_items %}
<div class="card shadow-sm mb-4">
<div class="card-body">
<h5 class="mb-2">Lista zakupów</h5>
<hr class="hr-bw">
{% set posortowane = items|sort(attribute='kupione') %}
<ul class="list-group list-group-flush">
{% for it in posortowane %}
<li class="list-group-item bg-transparent d-flex flex-wrap justify-content-between align-items-center">
<div class="d-flex align-items-center gap-2">
{% if it.kupione %}
<span class="badge bg-success">Kupione</span>
{% else %}
<span class="badge bg-warning text-dark">Do kupienia</span>
{% endif %}
<span class="fw-semibold">{{ it.nazwa }}</span>
{% if it.link %}
<a href="{{ it.link }}" target="_blank" rel="noopener" class="btn btn-sm btn-outline-light ms-2">Sklep
</a>
{% endif %}
</div>
<div>
{% if not zbiorka.ukryj_kwote %}
{% if it.cena is not none %}
<span class="badge bg-dark border" style="border-color: var(--border);">
{{ it.cena|round(2) }} PLN
</span>
{% else %}
<span class="text-muted"></span>
{% endif %}
{% else %}
<span class="text-muted"></span>
{% endif %}
</div>
</li>
{% endfor %}
</ul>
</div>
</div>
{% endif %}
<!-- Card: Postęp (POD listą zakupów) -->
{# Dodatkowe wyliczenia do postępu zakupów #}
{% set total_cnt = items|length %}
{% set kupione_cnt = (items|selectattr('kupione')|list|length) %}
{% set items_pct = (kupione_cnt / total_cnt * 100) if total_cnt > 0 else 0 %}
{% if not zbiorka.ukryj_kwote %}
{% set suma_all = (items|selectattr('cena')|map(attribute='cena')|sum) or 0 %}
{% set suma_kupione = (items|selectattr('kupione')|selectattr('cena')|map(attribute='cena')|sum) or 0 %}
{% set suma_pct = (suma_kupione / suma_all * 100) if suma_all > 0 else 0 %}
{% endif %}
<div class="card shadow-sm">
<div class="card-body">
<div class="d-flex flex-wrap align-items-center justify-content-between gap-2 mb-2">
<h5 class="mb-0">Postęp</h5>
<div class="d-flex flex-wrap align-items-center gap-2">
{% if has_cel and not zbiorka.ukryj_kwote and zbiorka.pokaz_postep_finanse %}
<span class="badge bg-dark border" style="border-color: var(--border);">
Finanse: {{ zbiorka.stan|round(2) }} / {{ zbiorka.cel|round(2) }} PLN
</span>
{% endif %}
{% if has_items and zbiorka.pokaz_postep_pozycje %}
<span class="badge bg-secondary">Pozycje: {{ kupione_cnt }}/{{ total_cnt }}</span>
{% endif %}
{% if has_items and not zbiorka.ukryj_kwote and (suma_all or 0) > 0 and zbiorka.pokaz_postep_kwotowo %}
<span class="badge bg-secondary">
Zakupy (kwotowo): {{ (suma_kupione or 0)|round(2) }} / {{ (suma_all or 0)|round(2) }} PLN
</span>
{% endif %}
</div>
</div>
<hr class="hr-bw">
{# Pasek: Finanse #}
{% if zbiorka.pokaz_postep_finanse %}
<div class="mb-3">
<small class="text-muted">Finanse</small>
<div class="progress" role="progressbar" aria-valuenow="{{ progress_clamped|round(2) }}" aria-valuemin="0"
aria-valuemax="100">
<div class="progress-bar" style="width: {{ progress_clamped }}%;"></div>
</div>
<small class="text-muted">
{% if zbiorka.ukryj_kwote %}—{% else %}{{ progress|round(1) }}%{% endif %}
</small>
</div>
{% endif %}
{# Pasek: Zakupy sztukami #}
{% if has_items and zbiorka.pokaz_postep_pozycje %}
<div class="mb-3">
<small class="text-muted">Zakupy (liczba pozycji)</small>
<div class="progress" role="progressbar" aria-valuenow="{{ items_pct|round(2) }}" aria-valuemin="0"
aria-valuemax="100">
<div class="progress-bar" style="width: {{ items_pct }}%;"></div>
</div>
<small class="text-muted">{{ items_pct|round(1) }}%</small>
</div>
{% endif %}
{# Pasek: Zakupy kwotowo #}
{% if has_items and not zbiorka.ukryj_kwote and (suma_all or 0) > 0 and zbiorka.pokaz_postep_kwotowo %}
<div>
<small class="text-muted">Zakupy (kwotowo)</small>
<div class="progress" role="progressbar" aria-valuenow="{{ suma_pct|round(2) }}" aria-valuemin="0"
aria-valuemax="100">
<div class="progress-bar" style="width: {{ suma_pct }}%;"></div>
</div>
<small class="text-muted">{{ suma_pct|round(1) }}%</small>
</div>
{% endif %}
</div>
</div>
</div>
{% set show_iban = zbiorka.uzyj_konta and zbiorka.numer_konta %}
{% set show_blik = zbiorka.uzyj_blik and zbiorka.numer_telefonu_blik %}
<!-- Kolumna prawa: płatności (sticky) -->
<div class="col-md-4">
<div class="card shadow-sm wspomoz-card sticky-md" style="top: var(--sticky-offset, 1rem);">
<div class="card-body d-flex flex-column gap-3">
<div class="d-flex align-items-center justify-content-between">
<h5 class="mb-0">Jak wspomóc?</h5>
{% if has_cel and not zbiorka.ukryj_kwote %}
{% set brak = (zbiorka.cel - zbiorka.stan) %}
{% if brak > 0 %}
<span class="badge bg-warning text-dark border border-warning">Brakuje: {{ brak|round(2) }} PLN</span>
{% else %}
<span class="badge rounded-pill" style="background: var(--accent); color:#111;">Zrealizowana</span>
{% endif %}
{% endif %}
</div>
{% if show_iban or show_blik %}
{% if show_iban %}
<!-- Numer konta -->
<div>
<label for="ibanInput" class="form-label fw-semibold mb-1">Numer konta</label>
<div class="input-group">
<input id="ibanInput" type="text"
class="form-control form-control-sm bg-transparent text-light border monospace-input text-truncate"
value="{{ zbiorka.numer_konta }}" readonly autocomplete="off" autocorrect="off" autocapitalize="off"
spellcheck="false" inputmode="text" aria-label="Numer konta do wpłaty">
<button class="btn btn-sm btn-outline-light copy-btn" type="button" data-copy-input="#ibanInput"
aria-label="Kopiuj numer konta">Kopiuj</button>
</div>
</div>
{% endif %}
{% if show_blik %}
<!-- Telefon BLIK -->
<div>
<label for="blikInput" class="form-label fw-semibold mb-1">Telefon BLIK</label>
<div class="input-group">
<input id="blikInput" type="text"
class="form-control form-control-sm bg-transparent text-light border monospace-input text-truncate"
value="{{ zbiorka.numer_telefonu_blik }}" readonly autocomplete="off" autocorrect="off"
autocapitalize="off" spellcheck="false" inputmode="numeric" aria-label="Telefon BLIK">
<button class="btn btn-sm btn-outline-light copy-btn" type="button" data-copy-input="#blikInput"
aria-label="Kopiuj numer BLIK">Kopiuj</button>
</div>
</div>
{% endif %}
{% else %}
<div class="alert alert-secondary mb-0">
Kanały płatności są wyłączone dla tej zbiórki.
</div>
{% endif %}
{% if not zbiorka.ukryj_kwote %}
<ul class="list-group list-group-flush small">
{% if has_cel %}
<li class="list-group-item bg-transparent d-flex justify-content-between">
<span>Cel</span>
<span class="fw-semibold">{{ zbiorka.cel|round(2) }} PLN</span>
</li>
{% endif %}
<li class="list-group-item bg-transparent d-flex justify-content-between">
<span>Stan</span>
<span class="fw-semibold text-success">{{ zbiorka.stan|round(2) }} PLN</span>
</li>
{% if has_cel %}
<li class="list-group-item bg-transparent d-flex justify-content-between">
<span>
{% if brak > 0 %}Brakuje{% elif brak == 0 %}Cel{% else %}Nadwyżka{% endif %}
</span>
<span class="fw-semibold {% if brak > 0 %}text-warning{% elif brak < 0 %}text-success{% endif %}">
{% if brak > 0 %}
{{ brak|round(2) }} PLN
{% elif brak == 0 %}
osiągnięty
{% else %}
{{ (-brak)|round(2) }} PLN
{% endif %}
</span>
</li>
{% endif %}
</ul>
{% endif %}
{% if current_user.is_authenticated and current_user.czy_admin %}
<hr>
<div class="d-grid gap-2 mt-2">
<a href="{{ url_for('dodaj_wplate', zbiorka_id=zbiorka.id) }}" class="btn btn-outline-light btn-sm">Dodaj
wpłatę</a>
<a href="{{ url_for('dodaj_wydatek', zbiorka_id=zbiorka.id) }}" class="btn btn-outline-light btn-sm">Dodaj
wydatek</a>
<a href="{{ url_for('edytuj_stan', zbiorka_id=zbiorka.id) }}" class="btn btn-outline-light btn-sm">Edytuj
stan</a>
<a href="{{ url_for('formularz_zbiorek', zbiorka_id=zbiorka.id) }}"
class="btn btn-outline-light btn-sm">Edytuj opis</a>
</div>
{% endif %}
</div>
</div>
</div>
<!-- Aktywność -->
<div class="card shadow-sm mt-4">
<div class="card-header bg-transparent d-flex align-items-center justify-content-between">
<h5 class="card-title mb-0">Aktywność / Transakcje</h5>
<div class="d-flex align-items-center gap-2">
{% if aktywnosci and aktywnosci|length > 0 %}
<small class="text-muted">Łącznie pozycji: {{ aktywnosci|length }}</small>
{% endif %}
{% if current_user.is_authenticated and current_user.czy_admin %}
<a href="{{ url_for('transakcje_zbiorki', zbiorka_id=zbiorka.id) }}" class="btn btn-sm btn-outline-light">
Zarządzaj
</a>
{% endif %}
</div>
</div>
<div class="card-body">
{% if aktywnosci and aktywnosci|length > 0 %}
<ul class="list-group list-group-flush">
{% for a in aktywnosci %}
<li class="list-group-item bg-transparent d-flex flex-wrap justify-content-between align-items-center">
<div class="me-3">
<strong>{{ a.data|dt("%d.%m.%Y %H:%M") }}</strong>
<span class="badge {% if a.typ == 'wpłata' %}bg-success{% else %}bg-danger{% endif %} ms-2">
{{ a.typ|capitalize }}
</span>
{% if a.opis %}
<span class="text-muted">— {{ a.opis }}</span>
{% endif %}
</div>
{% if not zbiorka.ukryj_kwote %}
<span class="badge bg-dark border ms-auto" style="border-color: var(--border);">
{% if a.typ == 'wpłata' %}+{% else %}-{% endif %} {{ a.kwota|round(2) }} PLN
</span>
{% endif %}
</li>
{% endfor %}
</ul>
{% else %}
<div class="text-center py-4">
<h6 class="mb-1">Brak aktywności</h6>
<p class="text-muted mb-0">Gdy pojawią się pierwsze wpłaty lub wydatki, zobaczysz je tutaj.</p>
</div>
{% endif %}
</div>
</div>
<!-- Akcje dolne -->
<div class="d-flex gap-2 justify-content-between mt-3">
<div></div>
<a href="{{ url_for('index') }}" class="btn btn-outline-light">Powrót do listy</a>
</div>
</div>
{% endblock %}
{% block extra_scripts %}
{{ super() }}
<script src="{{ url_for('static', filename='js/zbiorka.js') }}?v={{ APP_VERSION }}"></script>
<script src="{{ url_for('static', filename='js/progress.js') }}?v={{ APP_VERSION }}"></script>
{% endblock %}