przebudowa systemu

This commit is contained in:
Mateusz Gruszczyński
2025-08-28 10:27:06 +02:00
parent d71d33cfe0
commit e9db945bb4
36 changed files with 2307 additions and 809 deletions

View File

21
static/js/dodaj_wplate.js Normal file
View File

@@ -0,0 +1,21 @@
(function () {
const kwota = document.getElementById('kwota');
const opis = document.getElementById('opis');
const opisCount = document.getElementById('opisCount');
document.querySelectorAll('.btn-kwota').forEach(btn => {
btn.addEventListener('click', () => {
const val = btn.getAttribute('data-amount');
if (val && kwota) {
kwota.value = Number(val).toFixed(2);
kwota.focus();
}
});
});
if (opis && opisCount) {
const updateCount = () => opisCount.textContent = opis.value.length.toString();
opis.addEventListener('input', updateCount);
updateCount();
}
})();

View File

@@ -0,0 +1,37 @@
(function () {
const opis = document.getElementById('opis');
const opisCount = document.getElementById('opisCount');
if (opis && opisCount) {
const updateCount = () => opisCount.textContent = opis.value.length.toString();
opis.addEventListener('input', updateCount);
updateCount();
}
const iban = document.getElementById('numer_konta');
if (iban) {
iban.addEventListener('input', () => {
const digits = iban.value.replace(/\D/g, '').slice(0, 26);
const chunked = digits.replace(/(.{4})/g, '$1 ').trim();
iban.value = chunked;
});
}
const tel = document.getElementById('numer_telefonu_blik');
if (tel) {
tel.addEventListener('input', () => {
const digits = tel.value.replace(/\D/g, '').slice(0, 9);
const parts = [];
if (digits.length > 0) parts.push(digits.substring(0, 3));
if (digits.length > 3) parts.push(digits.substring(3, 6));
if (digits.length > 6) parts.push(digits.substring(6, 9));
tel.value = parts.join(' ');
});
}
const cel = document.getElementById('cel');
if (cel) {
cel.addEventListener('change', () => {
if (cel.value && Number(cel.value) < 0.01) cel.value = '0.01';
});
}
})();

82
static/js/edytuj_stan.js Normal file
View File

@@ -0,0 +1,82 @@
(() => {
// Root kontenera z danymi (dataset.cel)
const root = document.querySelector('[data-module="edit-stan"]');
if (!root) return;
const input = root.querySelector('#stan');
const previewPct = root.querySelector('#previewPct');
const previewBar = root.querySelector('#previewBar');
const previewNote = root.querySelector('#previewNote');
// Cel przekazany jako data atrybut
const cel = Number(root.dataset.cel || 0);
function clamp(n) {
if (Number.isNaN(n)) return 0;
return n < 0 ? 0 : n;
}
function pct(val) {
if (!cel || cel <= 0) return 0;
return (val / cel) * 100;
}
function updatePreview() {
if (!input) return;
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 (previewNote) {
if (cel > 0) {
const diff = cel - val;
if (diff > 0) {
previewNote.textContent = 'Do celu brakuje: ' + diff.toFixed(2) + ' PLN';
} else if (diff === 0) {
previewNote.textContent = 'Cel osiągnięty.';
} else {
previewNote.textContent = 'Przekroczono cel o: ' + Math.abs(diff).toFixed(2) + ' PLN';
}
} else {
previewNote.textContent = 'Brak zdefiniowanego celu — procent nie jest wyliczany.';
}
}
}
// Zmiana ręczna
if (input) {
input.addEventListener('input', updatePreview);
input.addEventListener('change', () => {
if (Number(input.value) < 0) input.value = '0.00';
updatePreview();
});
}
// Przyciski +/- delta
root.querySelectorAll('.btn-delta').forEach(btn => {
btn.addEventListener('click', () => {
const d = Number(btn.getAttribute('data-delta') || 0);
const cur = Number(input?.value || 0);
if (!input) return;
input.value = clamp(cur + d).toFixed(2);
updatePreview();
input.focus();
});
});
// Ustaw na konkretną wartość
root.querySelectorAll('.btn-set').forEach(btn => {
btn.addEventListener('click', () => {
const v = Number(btn.getAttribute('data-value') || 0);
if (!input) return;
input.value = clamp(v).toFixed(2);
updatePreview();
input.focus();
});
});
// Inicjalny podgląd
updatePreview();
})();

View File

@@ -0,0 +1,60 @@
(function () {
// Licznik znaków opisu
const opis = document.getElementById('opis');
const opisCount = document.getElementById('opisCount');
if (opis && opisCount) {
const updateCount = () => opisCount.textContent = opis.value.length.toString();
opis.addEventListener('input', updateCount);
updateCount();
}
// IBAN: tylko cyfry, auto-grupowanie co 4
const iban = document.getElementById('numer_konta');
if (iban) {
iban.addEventListener('input', () => {
const digits = iban.value.replace(/\D/g, '').slice(0, 26); // 26 cyfr po "PL"
const chunked = digits.replace(/(.{4})/g, '$1 ').trim();
iban.value = chunked;
});
}
// BLIK telefon: tylko cyfry, format 3-3-3
const tel = document.getElementById('numer_telefonu_blik');
if (tel) {
tel.addEventListener('input', () => {
const digits = tel.value.replace(/\D/g, '').slice(0, 9);
const parts = [];
if (digits.length > 0) parts.push(digits.substring(0, 3));
if (digits.length > 3) parts.push(digits.substring(3, 6));
if (digits.length > 6) parts.push(digits.substring(6, 9));
tel.value = parts.join(' ');
});
}
// „Ustaw globalne” z data-atrybutów (bez wstrzykiwania wartości w JS)
const setGlobalBtn = document.getElementById('ustaw-globalne');
if (setGlobalBtn && iban && tel) {
setGlobalBtn.addEventListener('click', () => {
const gIban = setGlobalBtn.dataset.iban || '';
const gBlik = setGlobalBtn.dataset.blik || '';
if (gIban) {
iban.value = gIban.replace(/\D/g, '').replace(/(.{4})/g, '$1 ').trim();
}
if (gBlik) {
const d = gBlik.replace(/\D/g, '').slice(0, 9);
const p = [d.slice(0, 3), d.slice(3, 6), d.slice(6, 9)].filter(Boolean).join(' ');
tel.value = p;
}
iban.dispatchEvent(new Event('input'));
tel.dispatchEvent(new Event('input'));
});
}
// Cel: minimalna wartość
const cel = document.getElementById('cel');
if (cel) {
cel.addEventListener('change', () => {
if (cel.value && Number(cel.value) < 0.01) cel.value = '0.01';
});
}
})();

4
static/js/mde_custom.js Normal file
View File

@@ -0,0 +1,4 @@
var simplemde = new SimpleMDE({
element: document.getElementById("opis"),
forceSync: true
});

13
static/js/progress.js Normal file
View File

@@ -0,0 +1,13 @@
function animateProgressBars() {
document.querySelectorAll('.progress-bar').forEach(bar => {
const progressValue = bar.getAttribute('aria-valuenow');
bar.style.setProperty('--progress-width', progressBarWidth(progressBarValue(progressBar)));
});
}
document.addEventListener('DOMContentLoaded', () => {
document.querySelectorAll('.progress-bar').forEach(bar => {
const width = bar.getAttribute('aria-valuenow') + '%';
bar.style.setProperty('--progress-width', width);
});
});

92
static/js/ustawienia.js Normal file
View File

@@ -0,0 +1,92 @@
(function () {
// IBAN: tylko cyfry, auto-grupowanie co 4 (po prefiksie PL)
const iban = document.getElementById('numer_konta');
if (iban) {
iban.addEventListener('input', () => {
const digits = iban.value.replace(/\\D/g, '').slice(0, 26); // 26 cyfr po "PL"
const chunked = digits.replace(/(.{4})/g, '$1 ').trim();
iban.value = chunked;
});
}
// Telefon BLIK: tylko cyfry, format 3-3-3
const tel = document.getElementById('numer_telefonu_blik');
if (tel) {
tel.addEventListener('input', () => {
const digits = tel.value.replace(/\\D/g, '').slice(0, 9);
const parts = [];
if (digits.length > 0) parts.push(digits.substring(0, 3));
if (digits.length > 3) parts.push(digits.substring(3, 6));
if (digits.length > 6) parts.push(digits.substring(6, 9));
tel.value = parts.join(' ');
});
}
// Biała lista IP/hostów — helpery
const ta = document.getElementById('allowed_login_hosts');
const count = document.getElementById('hostsCount');
const addBtn = document.getElementById('btn-add-host');
const addMyBtn = document.getElementById('btn-add-my-ip');
const input = document.getElementById('host_input');
function parseList(text) {
// akceptuj przecinki, średniki i nowe linie; trimuj; usuń puste
return text
.split(/[\\n,;]+/)
.map(s => s.trim())
.filter(Boolean);
}
function formatList(arr) {
return arr.join('\\n');
}
function dedupe(arr) {
const seen = new Set();
const out = [];
for (const v of arr) {
const k = v.toLowerCase();
if (!seen.has(k)) { seen.add(k); out.push(v); }
}
return out;
}
function updateCount() {
if (!ta || !count) return;
count.textContent = parseList(ta.value).length.toString();
}
function addEntry(val) {
if (!ta || !val) return;
const list = dedupe([...parseList(ta.value), val]);
ta.value = formatList(list);
updateCount();
}
if (ta) {
ta.addEventListener('input', updateCount);
// inicjalny przelicznik
updateCount();
}
if (addBtn && input) {
addBtn.addEventListener('click', () => {
const val = (input.value || '').trim();
if (!val) return;
addEntry(val);
input.value = '';
input.focus();
});
}
if (addMyBtn) {
addMyBtn.addEventListener('click', () => {
const ip = addMyBtn.dataset.myIp || '';
if (ip) addEntry(ip);
});
}
const dedupeBtn = document.getElementById('btn-dedupe');
if (dedupeBtn && ta) {
dedupeBtn.addEventListener('click', () => {
ta.value = formatList(dedupe(parseList(ta.value)));
updateCount();
});
}
})();

View File

@@ -0,0 +1,27 @@
(function () {
const form = document.querySelector('form.needs-validation');
form.addEventListener('submit', function (e) {
if (!form.checkValidity()) {
e.preventDefault();
e.stopPropagation();
}
form.classList.add('was-validated');
}, false);
})();
const pw = document.getElementById('password');
const toggle = document.getElementById('togglePw');
toggle.addEventListener('click', () => {
const isText = pw.type === 'text';
pw.type = isText ? 'password' : 'text';
toggle.textContent = isText ? 'Pokaż' : 'Ukryj';
toggle.setAttribute('aria-pressed', (!isText).toString());
pw.focus();
});
const caps = document.getElementById('capsWarning');
function handleCaps(e) {
const capsOn = e.getModifierState && e.getModifierState('CapsLock');
caps.style.display = capsOn ? 'inline' : 'none';
}
pw.addEventListener('keyup', handleCaps);
pw.addEventListener('keydown', handleCaps);

View File

@@ -0,0 +1,37 @@
(function () {
const form = document.querySelector('form.needs-validation');
form.addEventListener('submit', function (e) {
if (!form.checkValidity()) {
e.preventDefault();
e.stopPropagation();
}
const pw1 = document.getElementById('password');
const pw2 = document.getElementById('password2');
if (pw1.value !== pw2.value) {
e.preventDefault();
e.stopPropagation();
pw2.setCustomValidity("Hasła muszą być identyczne.");
pw2.reportValidity();
} else {
pw2.setCustomValidity("");
}
form.classList.add('was-validated');
}, false);
})();
const pw = document.getElementById('password');
const toggle = document.getElementById('togglePw');
toggle.addEventListener('click', () => {
const isText = pw.type === 'text';
pw.type = isText ? 'password' : 'text';
toggle.textContent = isText ? 'Pokaż' : 'Ukryj';
pw.focus();
});
const caps = document.getElementById('capsWarning');
function handleCaps(e) {
const capsOn = e.getModifierState && e.getModifierState('CapsLock');
caps.style.display = capsOn ? 'inline' : 'none';
}
pw.addEventListener('keyup', handleCaps);
pw.addEventListener('keydown', handleCaps);

38
static/js/zbiorka.js Normal file
View File

@@ -0,0 +1,38 @@
(function () {
const ibanEl = 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;
}
document.querySelectorAll('[data-copy-target]').forEach(btn => {
btn.addEventListener('click', async () => {
const sel = 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;
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();
}
});
});
})();