diff --git a/static/css/custom.css b/static/css/custom.css index 9d0e379..4fa1465 100644 --- a/static/css/custom.css +++ b/static/css/custom.css @@ -303,4 +303,82 @@ select.form-select:focus { /* kursor */ .CodeMirror-cursor { border-left: 1px solid #e0e0e0 !important; +} + +.nav-pills .nav-link.active { + background: var(--accent); + color: #111; +} + +.nav-pills .nav-link { + color: inherit; +} + +/* sticky tylko od md wzwyż, by na mobile nie przyklejać */ +@media (min-width: 768px) { + .sticky-md { + position: sticky; + } +} + +:root { + --sticky-offset: 1rem; +} + +/* Rząd kopiowania: czytelny, łatwy klik w przycisk */ +.copy-row { + display: grid; + grid-template-columns: 1fr auto; + grid-template-rows: auto auto; + gap: .25rem .5rem; + align-items: center; + padding: .5rem .75rem; + border: 1px solid var(--border, rgba(255, 255, 255, .15)); + border-radius: .75rem; + background: rgba(255, 255, 255, .02); +} + +.copy-row+.copy-row { + margin-top: .5rem; +} + +.copy-row__label { + grid-column: 1 / 2; + grid-row: 1 / 2; + font-weight: 600; + font-size: .9rem; + opacity: .85; +} + +.copy-row__value { + grid-column: 1 / 2; + grid-row: 2 / 3; + font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace; + letter-spacing: .02em; + user-select: text; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.copy-row__btn { + grid-column: 2 / 3; + grid-row: 1 / 3; + height: fit-content; + align-self: center; +} + +@media (max-width: 575.98px) { + + /* na XS przycisk pod spodem – łatwiej trafić kciukiem */ + .copy-row { + grid-template-columns: 1fr; + grid-template-rows: auto auto auto; + } + + .copy-row__btn { + grid-column: 1 / -1; + grid-row: 3 / 4; + width: 100%; + } } \ No newline at end of file diff --git a/static/js/edytuj_stan.js b/static/js/edytuj_stan.js index 8170509..f1e3224 100644 --- a/static/js/edytuj_stan.js +++ b/static/js/edytuj_stan.js @@ -26,15 +26,20 @@ const val = clamp(Number(input.value)); const p = Math.max(0, Math.min(100, pct(val))); - if (previewPct) previewPct.textContent = pct(val).toFixed(1); - if (previewBar) previewBar.style.setProperty('--progress-width', p + '%'); + if (previewPct) previewPct.textContent = p.toFixed(1); + + if (previewBar) { + previewBar.style.width = p + '%'; + previewBar.setAttribute('aria-valuenow', p.toFixed(2)); + } if (previewNote) { if (cel > 0) { const diff = cel - val; - if (diff > 0) { + const isZero = Math.abs(diff) < 0.005; // float-safe + if (diff > 0 && !isZero) { previewNote.textContent = 'Do celu brakuje: ' + diff.toFixed(2) + ' PLN'; - } else if (diff === 0) { + } else if (isZero) { previewNote.textContent = 'Cel osiągnięty.'; } else { previewNote.textContent = 'Przekroczono cel o: ' + Math.abs(diff).toFixed(2) + ' PLN'; @@ -45,6 +50,7 @@ } } + // Zmiana ręczna if (input) { input.addEventListener('input', updatePreview); diff --git a/static/js/zbiorka.js b/static/js/zbiorka.js index f83e927..a5515e1 100644 --- a/static/js/zbiorka.js +++ b/static/js/zbiorka.js @@ -1,38 +1,66 @@ + (function () { - const ibanEl = document.getElementById('ibanDisplay'); + // --- Formatowanie IBAN --- + const ibanEl = document.getElementById('ibanInput') || document.getElementById('ibanDisplay'); if (ibanEl) { - const digits = (ibanEl.textContent || '').replace(/\s+/g, '').replace(/^PL/i, '').replace(/\D/g, '').slice(0, 26); - if (digits) ibanEl.textContent = 'PL ' + digits.replace(/(.{4})/g, '$1 ').trim(); - } - const blikEl = document.getElementById('blikDisplay'); - if (blikEl) { - const d = (blikEl.textContent || '').replace(/\D/g, '').slice(0, 9); - const parts = [d.slice(0, 3), d.slice(3, 6), d.slice(6, 9)].filter(Boolean).join(' '); - if (parts) blikEl.textContent = parts; + const raw = (('value' in ibanEl ? ibanEl.value : ibanEl.textContent) || '') + .toString().replace(/\s+/g, '').toUpperCase(); + const digits = raw.replace(/^PL/, '').replace(/\D/g, '').slice(0, 26); + if (digits) { + const pretty = 'PL ' + digits.replace(/(.{4})/g, '$1 ').trim(); + if ('value' in ibanEl) ibanEl.value = pretty; else ibanEl.textContent = pretty; + } } - document.querySelectorAll('[data-copy-target]').forEach(btn => { + // --- Formatowanie BLIK --- + const blikEl = document.getElementById('blikInput') || document.getElementById('blikDisplay'); + if (blikEl) { + const raw = (('value' in blikEl ? blikEl.value : blikEl.textContent) || '') + .toString().replace(/\D/g, '').slice(0, 9); + if (raw) { + const pretty = [raw.slice(0, 3), raw.slice(3, 6), raw.slice(6, 9)] + .filter(Boolean).join(' '); + if ('value' in blikEl) blikEl.value = pretty; else blikEl.textContent = pretty; + } + } + + // --- Kopiowanie: wspiera data-copy-input i data-copy-target --- + const buttons = document.querySelectorAll('[data-copy-input], [data-copy-target]'); + buttons.forEach(btn => { btn.addEventListener('click', async () => { - const sel = btn.getAttribute('data-copy-target'); + const sel = btn.getAttribute('data-copy-input') || btn.getAttribute('data-copy-target'); const el = sel ? document.querySelector(sel) : null; if (!el) return; - const raw = el.textContent.replace(/\u00A0/g, ' ').trim(); - try { - await navigator.clipboard.writeText(raw); - const original = btn.textContent; + + const textRaw = ('value' in el ? el.value : el.textContent || '') + .toString().replace(/\u00A0/g, ' ').trim(); + + const copyWithFallback = async (text) => { + try { + await navigator.clipboard.writeText(text); + return true; + } catch { + // Fallback: tymczasowy textarea + const ta = document.createElement('textarea'); + ta.value = text; + ta.style.position = 'fixed'; + ta.style.top = '-1000px'; + ta.setAttribute('readonly', ''); + document.body.appendChild(ta); + ta.select(); + try { document.execCommand('copy'); } catch { /* ignore */ } + document.body.removeChild(ta); + return true; + } + }; + + const original = btn.textContent; + const ok = await copyWithFallback(textRaw); + if (ok) { btn.textContent = 'Skopiowano!'; btn.disabled = true; setTimeout(() => { btn.textContent = original; btn.disabled = false; }, 1200); - } catch { - // fallback - const r = document.createRange(); - r.selectNodeContents(el); - const selObj = window.getSelection(); - selObj.removeAllRanges(); - selObj.addRange(r); - try { document.execCommand('copy'); } catch { } - selObj.removeAllRanges(); } }); }); -})(); \ No newline at end of file +})(); diff --git a/templates/admin/edytuj_stan.html b/templates/admin/edytuj_stan.html index 855f77b..f83beea 100644 --- a/templates/admin/edytuj_stan.html +++ b/templates/admin/edytuj_stan.html @@ -81,10 +81,7 @@ {% set brakujace = (zbiorka.cel - zbiorka.stan) if (zbiorka.cel - zbiorka.stan) > 0 else 0 %} - {% if brakujace > 0 %} - Brakuje: {{ brakujace|round(2) }} - PLN - {% endif %} + {% endif %} @@ -105,8 +102,7 @@
{% if has_cel %} diff --git a/templates/index.html b/templates/index.html index 7c48e90..43191b5 100644 --- a/templates/index.html +++ b/templates/index.html @@ -8,18 +8,19 @@ zbiórki{% endif %}{% endblock %}

- {% if is_completed_view %}Zrealizowane zbiórki{% else %}Aktualnie aktywne zbiórki{% endif %} + {% if is_completed_view %}Zrealizowane zbiórki{% else %}Aktywne zbiórki{% endif %}

+
{% if zbiorki and zbiorki|length > 0 %} @@ -46,14 +47,15 @@ zbiórki{% endif %}{% endblock %} Cel: {{ z.cel|round(2) }} PLN {% endif %} - + Stan: {{ z.stan|round(2) }} PLN {% if z.cel > 0 %} {% set delta = z.cel - z.stan %} {% if delta > 0 %} - + {# CHANGE: mocniejszy badge „Brakuje” #} + Brakuje: {{ delta|round(2) }} PLN {% elif delta < 0 %} @@ -66,7 +68,6 @@ zbiórki{% endif %}{% endblock %} {% endif %}
-
diff --git a/templates/zbiorka.html b/templates/zbiorka.html index 34480e2..416f20d 100644 --- a/templates/zbiorka.html +++ b/templates/zbiorka.html @@ -159,111 +159,163 @@
-
-
-
-
- Numer konta - -
-
{{ zbiorka.numer_konta }}
+
+
+ +
+
Jak wspomóc?
+ {% if has_cel and not zbiorka.ukryj_kwote %} + {% set brak = (zbiorka.cel - zbiorka.stan) %} + {% if brak > 0 %} + + Brakuje: {{ brak|round(2) }} PLN + + {% else %} + + Zrealizowana + + {% endif %} + {% endif %}
-
-
- Telefon BLIK - + + +
+ +
+ + +
+
+ + +
+ +
+ +
-
{{ zbiorka.numer_telefonu_blik }}
{% if not zbiorka.ukryj_kwote %} -
-
+
    {% if has_cel %} -
    Cel: {{ zbiorka.cel|round(2) }} PLN
    +
  • + Cel + {{ zbiorka.cel|round(2) }} PLN +
  • {% endif %} -
    Stan: {{ zbiorka.stan|round(2) }} PLN
    +
  • + Stan + {{ zbiorka.stan|round(2) }} PLN +
  • {% if has_cel %} - {% set brak = (zbiorka.cel - zbiorka.stan) %} - - {% if brak > 0 %} - Do celu brakuje: {{ brak|round(2) }} PLN - {% elif brak == 0 %} - Cel osiągnięty. - {% else %} - Przekroczono cel o: {{ (brak * -1)|round(2) }} PLN - {% endif %} - +
  • + + {% if brak > 0 %}Brakuje{% elif brak == 0 %}Cel{% else %}Nadwyżka{% endif %} + + + {% if brak > 0 %} + {{ brak|round(2) }} PLN + {% elif brak == 0 %} + osiągnięty + {% else %} + {{ (-brak)|round(2) }} PLN + {% endif %} + +
  • {% endif %} +
+ {% endif %} + + + {% if current_user.is_authenticated and current_user.is_admin %} +
+ {% endif %} - {% if current_user.is_authenticated and current_user.is_admin %} - - - {% endif %}
-
- -
-
-
Aktywność / Transakcje
- {% if aktywnosci and aktywnosci|length > 0 %} - Łącznie pozycji: {{ aktywnosci|length }} - {% endif %} -
-
- {% if aktywnosci and aktywnosci|length > 0 %} -
    - {% for a in aktywnosci %} -
  • -
    - {{ a.data|dt("%d.%m.%Y %H:%M") }} - - {{ a.typ|capitalize }} - - {% if a.opis %} - — {{ a.opis }} - {% endif %} -
    - {% if not zbiorka.ukryj_kwote %} - - {% if a.typ == 'wpłata' %}+{% else %}-{% endif %} {{ a.kwota|round(2) }} PLN - + + +
    +
    +
    Aktywność / Transakcje
    +
    + {% if aktywnosci and aktywnosci|length > 0 %} + Łącznie pozycji: {{ aktywnosci|length }} {% endif %} -
  • - {% endfor %} -
- {% else %} -
-
Brak aktywności
-

Gdy pojawią się pierwsze wpłaty lub wydatki, zobaczysz je tutaj.

+ {% if current_user.is_authenticated and current_user.is_admin %} + + Zarządzaj + + {% endif %} +
+
+ +
+ {% if aktywnosci and aktywnosci|length > 0 %} +
    + {% for a in aktywnosci %} +
  • +
    + {{ a.data|dt("%d.%m.%Y %H:%M") }} + + {{ a.typ|capitalize }} + + {% if a.opis %} + — {{ a.opis }} + {% endif %} +
    + {% if not zbiorka.ukryj_kwote %} + + {% if a.typ == 'wpłata' %}+{% else %}-{% endif %} {{ a.kwota|round(2) }} PLN + + {% endif %} +
  • + {% endfor %} +
+ {% else %} +
+
Brak aktywności
+

Gdy pojawią się pierwsze wpłaty lub wydatki, zobaczysz je tutaj.

+
+ {% endif %}
- {% endif %}
+ + + + +
+ {% endblock %} - - - -
-{% endblock %} - -{% block extra_scripts %} -{{ super() }} - - -{% endblock %} \ No newline at end of file + {% block extra_scripts %} + {{ super() }} + + + + {% endblock %} \ No newline at end of file