06/04 Optimize app

This commit is contained in:
2026-06-04 15:00:09 -04:00
parent 3f2e83ce2d
commit e03eb26417
8 changed files with 125 additions and 23 deletions
+5 -2
View File
@@ -184,11 +184,11 @@ function addCredRow(btn) {
btn.closest('.modal-body').querySelector('.cred-rows').insertAdjacentHTML('beforeend', emptyCredRow());
}
function removeRow(btn) { btn.closest('.cred-row').remove(); }
function esc(s) { return (s||'').replace(/&/g,'&amp;').replace(/"/g,'&quot;').replace(/</g,'&lt;'); }
(function() {
var searchEl = document.getElementById('site-search');
var typeEl = document.getElementById('site-type-filter');
var _timer = null;
function filterSites() {
var q = searchEl.value.trim().toLowerCase();
var type = typeEl.value;
@@ -198,7 +198,10 @@ function esc(s) { return (s||'').replace(/&/g,'&amp;').replace(/"/g,'&quot;').re
row.style.display = (nameMatch && typeMatch) ? '' : 'none';
});
}
searchEl.addEventListener('input', filterSites);
searchEl.addEventListener('input', function() {
clearTimeout(_timer);
_timer = setTimeout(filterSites, 250);
});
typeEl.addEventListener('change', filterSites);
})();
</script>
+3 -2
View File
@@ -10,11 +10,12 @@
<body class="layout">
<!-- Mobile sidebar toggle (hidden on desktop via CSS) -->
<button class="sidebar-toggle" id="sidebar-toggle" aria-label="Open navigation"></button>
<button class="sidebar-toggle" id="sidebar-toggle"
aria-label="Open navigation" aria-expanded="false" aria-controls="sidebar"></button>
<div class="sidebar-backdrop" id="sidebar-backdrop"></div>
<!-- Sidebar -->
<aside class="sidebar" id="sidebar">
<aside class="sidebar" id="sidebar" aria-label="Main navigation">
<div class="sidebar-brand">
<span class="brand-icon">🌐</span>
<span class="brand-name">Website<br>Checker</span>
-7
View File
@@ -472,13 +472,6 @@ document.getElementById('bid-search').addEventListener('input', function() {
}
});
/* ── Escape ─────────────────────────────────────────────── */
function esc(str) {
return String(str || '').replace(/[&<>"']/g, function(c) {
return {'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c];
});
}
/* ── Init ───────────────────────────────────────────────── */
loadBids();
+6 -1
View File
@@ -13,7 +13,11 @@
</div>
<div class="form-group">
<label class="form-label">New Password</label>
<input class="form-control" type="password" name="new_password" required>
<input class="form-control" type="password" name="new_password" id="new-password" required>
<div class="pw-strength-wrap">
<div class="pw-strength-bar"><div class="pw-strength-fill" id="pw-fill"></div></div>
<small class="pw-strength-label" id="pw-label"></small>
</div>
<small class="text-muted">Min 8 chars, uppercase, number, special character.</small>
</div>
<div class="form-group">
@@ -24,4 +28,5 @@
</form>
</div>
</div>
<script>attachPasswordStrength('new-password', 'pw-fill', 'pw-label');</script>
{% endblock %}
+22
View File
@@ -28,6 +28,10 @@
<input type="password" id="password" name="password"
autofocus required minlength="8"
placeholder="Minimum 8 characters">
<div class="pw-strength-wrap">
<div class="pw-strength-bar"><div class="pw-strength-fill" id="pw-fill"></div></div>
<small class="pw-strength-label" id="pw-label"></small>
</div>
</div>
<div class="form-group">
<label for="confirm_password">Confirm Password</label>
@@ -42,5 +46,23 @@
</p>
</div>
<script>
(function() {
var input = document.getElementById('password');
var fill = document.getElementById('pw-fill');
var lbl = document.getElementById('pw-label');
var map = ['pw-weak','pw-weak','pw-fair','pw-strong','pw-great','pw-great'];
var lbls = ['Weak','Weak','Fair','Strong','Very strong','Very strong'];
input.addEventListener('input', function() {
if (!this.value) { fill.className='pw-strength-fill'; lbl.className='pw-strength-label'; lbl.textContent=''; return; }
var pw=this.value, s=0;
if (pw.length>=8) s++; if (pw.length>=12) s++;
if (/[A-Z]/.test(pw)) s++; if (/[0-9]/.test(pw)) s++; if (/[^A-Za-z0-9]/.test(pw)) s++;
fill.className='pw-strength-fill '+map[s];
lbl.className='pw-strength-label '+map[s];
lbl.textContent=lbls[s];
});
}());
</script>
</body>
</html>
+16 -10
View File
@@ -345,9 +345,22 @@ document.getElementById('site-list').addEventListener('click', function(e) {
/* Undo */
if (btn.classList.contains('js-undo')) {
if (confirm('Remove check for ' + btn.dataset.name + '?')) {
btn.closest('form').submit();
}
if (!confirm('Remove check for ' + btn.dataset.name + '?')) return;
var siteName = btn.dataset.name;
var formAction = btn.closest('form').action;
btn.disabled = true;
fetch(formAction, {
method: 'POST', credentials: 'same-origin',
headers: {'Content-Type': 'application/x-www-form-urlencoded', 'X-CSRFToken': getCsrfToken()},
body: ''
}).then(function() {
var toast = document.createElement('div');
toast.className = 'alert alert-info';
toast.style.cssText = 'position:fixed;top:1rem;right:1rem;z-index:9999;min-width:220px;box-shadow:var(--shadow)';
toast.textContent = '↩ Check removed for ' + siteName;
document.body.appendChild(toast);
setTimeout(function() { location.reload(); }, 700);
});
return;
}
});
@@ -371,13 +384,6 @@ document.getElementById('modal-creds').addEventListener('click', function(e) {
}
});
/* ── HTML escape ───────────────────────────────────────────── */
function esc(str) {
return String(str || '').replace(/[&<>"']/g, function(c) {
return {'&':'&amp;','<':'&lt;','>':'&gt;','"':'&quot;',"'":'&#39;'}[c];
});
}
/* ── Health dots — batched with max 4 concurrent requests ─── */
(function() {
var cards = Array.from(document.querySelectorAll('.site-card'));