przebudowa systemu
This commit is contained in:
@@ -1,168 +1,295 @@
|
||||
/* Import czcionki Roboto */
|
||||
@import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap');
|
||||
|
||||
/* Globalne */
|
||||
/* ========= TOKENS ========= */
|
||||
:root {
|
||||
color-scheme: dark;
|
||||
|
||||
--bg: #121212;
|
||||
/* główne tło */
|
||||
--surface-0: #1a1a1a;
|
||||
/* navbar, header */
|
||||
--surface-1: #202020;
|
||||
/* karty */
|
||||
--surface-2: #2a2a2a;
|
||||
/* nagłówki kart, ciemniejsze sekcje */
|
||||
--border: #3a3a3a;
|
||||
|
||||
--text: #e4e4e4;
|
||||
--text-muted: #a8a8a8;
|
||||
|
||||
--accent: #f5c84c;
|
||||
/* żółty/amber akcent */
|
||||
--accent-600: #e3b23f;
|
||||
--accent-700: #cfa033;
|
||||
--accent-300: #ffe083;
|
||||
|
||||
--radius: 10px;
|
||||
--shadow-sm: 0 1px 2px rgba(0, 0, 0, .5);
|
||||
--shadow-md: 0 4px 12px rgba(0, 0, 0, .45);
|
||||
--trans: 220ms cubic-bezier(.2, .8, .2, 1);
|
||||
}
|
||||
|
||||
/* ========= BASE ========= */
|
||||
body {
|
||||
font-family: 'Roboto', sans-serif;
|
||||
background-color: #121212;
|
||||
color: #dcdcdc;
|
||||
padding-top: 1vh;
|
||||
font-family: 'Roboto', system-ui, -apple-system, Segoe UI, Arial, sans-serif;
|
||||
background: var(--bg);
|
||||
color: var(--text);
|
||||
margin: 0;
|
||||
padding-top: 1vh;
|
||||
}
|
||||
|
||||
/* Nawigacja */
|
||||
.navbar {
|
||||
background-color: #1c1c1c;
|
||||
border-bottom: 1px solid #444;
|
||||
transition: background-color 0.3s ease;
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
color: #f5f5f5;
|
||||
font-weight: bold;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
color: #cccccc;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.nav-link:hover {
|
||||
color: #ffc107;
|
||||
}
|
||||
|
||||
/* Karty */
|
||||
.card {
|
||||
background-color: #444242;
|
||||
border: none;
|
||||
border-radius: 0.5rem;
|
||||
box-shadow: 0px 0px 8px rgba(0, 0, 0, 0.6);
|
||||
margin-bottom: 20px;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
|
||||
.card:hover {
|
||||
transform: translateY(-5px);
|
||||
box-shadow: 0px 3px 16px rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
.card-header {
|
||||
background-color: #272727;
|
||||
border-bottom: 1px solid #444;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
background-color: #444242;
|
||||
}
|
||||
|
||||
/* Przyciski */
|
||||
.btn {
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
transition: background-color 0.3s ease, transform 0.2s ease;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
background-color: #2d2c2c;
|
||||
border-color: #ffeb3b;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: #1e1e1e;
|
||||
border-color: #ffc107;
|
||||
}
|
||||
|
||||
/* Linki */
|
||||
a {
|
||||
color: #ffc107;
|
||||
transition: color 0.3s ease;
|
||||
color: var(--accent);
|
||||
text-decoration: none;
|
||||
transition: color var(--trans);
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #ffeb3b;
|
||||
color: var(--accent-300);
|
||||
}
|
||||
|
||||
/* Progress Bar */
|
||||
.progress {
|
||||
background-color: #2a2a2a;
|
||||
border-radius: 0.5rem;
|
||||
height: 35px;
|
||||
font-size: 1.2rem;
|
||||
/* ========= NAVBAR ========= */
|
||||
.navbar {
|
||||
background: var(--surface-0);
|
||||
border-bottom: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
background: linear-gradient(90deg, #ffc107, #ffeb3b);
|
||||
font-weight: bold;
|
||||
transition: width 0.3s ease;
|
||||
animation: progressAnimation 1s ease-in-out forwards;
|
||||
.navbar-brand {
|
||||
color: var(--text);
|
||||
font-weight: 700;
|
||||
transition: color var(--trans);
|
||||
}
|
||||
|
||||
@keyframes progressAnimation {
|
||||
from { width: 0%; }
|
||||
to { width: var(--progress-width); }
|
||||
.navbar-brand:hover {
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
/* Alerty (flash messages) */
|
||||
.alert {
|
||||
opacity: 0;
|
||||
animation: fadeIn 0.5s forwards;
|
||||
margin-bottom: 1rem;
|
||||
.nav-link {
|
||||
color: var(--text-muted);
|
||||
transition: color var(--trans);
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
to { opacity: 1; }
|
||||
.nav-link:hover,
|
||||
.nav-link:focus {
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
/* Dodatkowe marginesy */
|
||||
.container {
|
||||
padding: 0 15px;
|
||||
/* ========= CARDS ========= */
|
||||
.card {
|
||||
background: var(--surface-1);
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius);
|
||||
box-shadow: var(--shadow-sm);
|
||||
margin-bottom: 20px;
|
||||
transition: transform 160ms ease, box-shadow 160ms ease, border-color var(--trans);
|
||||
}
|
||||
|
||||
/* Responsywność */
|
||||
@media (max-width: 767px) {
|
||||
.card {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
.card-title {
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
.btn {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.card:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: var(--shadow-md);
|
||||
border-color: color-mix(in srgb, var(--accent) 20%, var(--border));
|
||||
}
|
||||
|
||||
h1 { font-size: 2rem; margin-bottom: 1rem; }
|
||||
h2 { font-size: 1.7rem; margin-bottom: 0.8rem; }
|
||||
h3 { font-size: 0.9rem; margin-bottom: 0.6rem; }
|
||||
.card-header {
|
||||
background: var(--surface-2);
|
||||
border-bottom: 1px solid var(--border);
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/* Wspomóż */
|
||||
.card-body {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
/* Wyróżniona karta */
|
||||
.card.wspomoz-card {
|
||||
border: 1px solid #ffc107 !important;
|
||||
border-radius: 0.2rem !important;
|
||||
border: 1px solid var(--accent) !important;
|
||||
border-radius: var(--radius) !important;
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent);
|
||||
}
|
||||
|
||||
.card.wspomoz-card .card-body,
|
||||
.card.wspomoz-card .card-title,
|
||||
.card.wspomoz-card .card-text {
|
||||
color: #ffffff !important;
|
||||
font-weight: bold;
|
||||
font-size: 1.25rem;
|
||||
color: var(--text) !important;
|
||||
font-weight: 700;
|
||||
font-size: 1.15rem;
|
||||
}
|
||||
|
||||
.btn-primary:focus,
|
||||
.btn-primary:active,
|
||||
.btn-primary.focus,
|
||||
.btn-primary.active {
|
||||
background-color: #2d2c2c !important;
|
||||
border-color: #ffeb3b !important;
|
||||
color: #ffffff !important;
|
||||
box-shadow: none;
|
||||
/* ========= BUTTONS ========= */
|
||||
.btn {
|
||||
font-weight: 700;
|
||||
border-radius: 8px;
|
||||
transition: transform 120ms ease, background-color var(--trans), border-color var(--trans), color var(--trans);
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
transform: translateY(-1px);
|
||||
}
|
||||
|
||||
.btn:focus-visible {
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 40%, transparent);
|
||||
outline: none;
|
||||
}
|
||||
|
||||
/* Primary = żółty */
|
||||
.btn-primary {
|
||||
background-color: var(--accent);
|
||||
border-color: var(--accent-600);
|
||||
color: #111;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
background-color: var(--accent-600);
|
||||
border-color: var(--accent-700);
|
||||
color: #111;
|
||||
}
|
||||
|
||||
.btn-primary:active,
|
||||
.btn-primary:focus {
|
||||
background-color: var(--accent-700) !important;
|
||||
border-color: var(--accent-700) !important;
|
||||
color: #111 !important;
|
||||
}
|
||||
|
||||
/* Secondary = ciemna szarość */
|
||||
.btn-secondary,
|
||||
.btn-outline-primary {
|
||||
background: var(--surface-1);
|
||||
border: 1px solid var(--border);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
.btn-secondary:hover,
|
||||
.btn-outline-primary:hover {
|
||||
border-color: var(--accent-600);
|
||||
color: var(--accent);
|
||||
}
|
||||
|
||||
/* ========= PROGRESS ========= */
|
||||
.progress {
|
||||
background: var(--surface-2);
|
||||
border-radius: 999px;
|
||||
height: 14px;
|
||||
overflow: hidden;
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
|
||||
.progress-bar {
|
||||
--progress-width: 0%;
|
||||
width: var(--progress-width);
|
||||
background: linear-gradient(90deg, var(--accent-600), var(--accent));
|
||||
transition: width var(--trans);
|
||||
}
|
||||
|
||||
/* ========= ALERTS ========= */
|
||||
|
||||
|
||||
/* ALERT VARIANTS */
|
||||
.alert-success {
|
||||
background: rgba(40, 167, 69, 0.15);
|
||||
/* lekka zieleń */
|
||||
border-color: #28a745;
|
||||
color: #28a745;
|
||||
}
|
||||
|
||||
.alert-danger {
|
||||
background: rgba(220, 53, 69, 0.15);
|
||||
/* lekka czerwień */
|
||||
border-color: #dc3545;
|
||||
color: #dc3545;
|
||||
}
|
||||
|
||||
.alert-warning {
|
||||
background: rgba(255, 193, 7, 0.15);
|
||||
/* lekki bursztyn */
|
||||
border-color: #ffc107;
|
||||
color: #ffc107;
|
||||
}
|
||||
|
||||
.alert-info {
|
||||
background: rgba(23, 162, 184, 0.15);
|
||||
/* lekki cyjan */
|
||||
border-color: #17a2b8;
|
||||
color: #17a2b8;
|
||||
}
|
||||
|
||||
|
||||
@keyframes fadeIn {
|
||||
to {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* ========= TYPO ========= */
|
||||
h1 {
|
||||
font-size: 2rem;
|
||||
margin-bottom: .75rem;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 1.6rem;
|
||||
margin-bottom: .6rem;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 1.1rem;
|
||||
margin-bottom: .5rem;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
small,
|
||||
.text-muted {
|
||||
color: var(--text-muted) !important;
|
||||
}
|
||||
|
||||
/* ========= RESPONSIVE ========= */
|
||||
.container {
|
||||
padding: 0 15px;
|
||||
}
|
||||
|
||||
@media (max-width: 767px) {
|
||||
.card {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
font-size: .95rem;
|
||||
}
|
||||
}
|
||||
|
||||
.table-responsive {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
.dropdown-menu {
|
||||
z-index: 1080;
|
||||
}
|
||||
|
||||
/* ponad kartą/tabelą */
|
||||
@media (max-width: 576px) {
|
||||
.table-responsive {
|
||||
overflow-x: auto;
|
||||
}
|
||||
}
|
||||
|
||||
/* ========= FORMS ========= */
|
||||
input.form-control,
|
||||
textarea.form-control,
|
||||
select.form-select {
|
||||
background-color: var(--surface-1);
|
||||
border: 1px solid var(--border);
|
||||
color: var(--text);
|
||||
}
|
||||
|
||||
input.form-control:focus,
|
||||
textarea.form-control:focus,
|
||||
select.form-select:focus {
|
||||
background-color: var(--surface-1);
|
||||
border-color: var(--accent-600);
|
||||
color: var(--text);
|
||||
box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 50%, transparent);
|
||||
}
|
0
static/js/admin_dashboard.js
Normal file
0
static/js/admin_dashboard.js
Normal file
21
static/js/dodaj_wplate.js
Normal file
21
static/js/dodaj_wplate.js
Normal 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();
|
||||
}
|
||||
})();
|
37
static/js/dodaj_zbiorke.js
Normal file
37
static/js/dodaj_zbiorke.js
Normal 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
82
static/js/edytuj_stan.js
Normal 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();
|
||||
})();
|
60
static/js/edytuj_zbiorke.js
Normal file
60
static/js/edytuj_zbiorke.js
Normal 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
4
static/js/mde_custom.js
Normal file
@@ -0,0 +1,4 @@
|
||||
var simplemde = new SimpleMDE({
|
||||
element: document.getElementById("opis"),
|
||||
forceSync: true
|
||||
});
|
13
static/js/progress.js
Normal file
13
static/js/progress.js
Normal 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
92
static/js/ustawienia.js
Normal 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();
|
||||
});
|
||||
}
|
||||
})();
|
27
static/js/walidacja_logowanie.js
Normal file
27
static/js/walidacja_logowanie.js
Normal 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);
|
37
static/js/walidacja_rejestracja.js
Normal file
37
static/js/walidacja_rejestracja.js
Normal 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
38
static/js/zbiorka.js
Normal 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();
|
||||
}
|
||||
});
|
||||
});
|
||||
})();
|
Reference in New Issue
Block a user