05/24 Fix UI/UX

This commit is contained in:
2026-05-24 17:59:24 -04:00
parent 07e0ae02c2
commit 6605484927
8 changed files with 154 additions and 24 deletions
+35
View File
@@ -694,6 +694,14 @@ textarea{resize:vertical;min-height:88px}
.sidebar-footer{align-items:center}
.main-content{padding:1.1rem .9rem 2rem}
}
/* Hamburger button — hidden on desktop */
.sidebar-toggle{display:none}
/* Backdrop — always hidden until .open is added */
.sidebar-backdrop{
display:none;position:fixed;inset:0;
background:rgba(0,0,0,.45);z-index:199;
}
@media(max-width:700px){
.sc-actions{flex-direction:column;align-items:flex-start}
.sc-url{display:none}
@@ -702,6 +710,33 @@ textarea{resize:vertical;min-height:88px}
.filter-bar{flex-direction:column}
.credential-entry{grid-template-columns:1fr 1fr}
.page-header{flex-direction:column;align-items:flex-start}
/* ── Mobile sidebar ──────────────────────────────────── */
.sidebar{
width:240px;
transform:translateX(-240px);
transition:transform .25s ease;
}
.sidebar.open{transform:translateX(0)}
/* Restore full labels when sidebar slides in */
.sidebar.open .brand-name,
.sidebar.open .nav-group-label,
.sidebar.open .user-info,
.sidebar.open .sidebar-btn{display:block}
.sidebar.open .sidebar-brand{justify-content:flex-start;padding:1.1rem 1rem .9rem}
.sidebar.open .brand-icon{margin:0}
.sidebar.open .nav-item{justify-content:flex-start;padding:.65rem 1rem;gap:.6rem}
.sidebar.open .sidebar-footer{align-items:stretch}
.sidebar-backdrop.open{display:block}
.sidebar-toggle{
display:flex;align-items:center;justify-content:center;
position:fixed;top:.75rem;left:.75rem;z-index:201;
background:var(--bg-white);border:1px solid var(--border-strong);
border-radius:var(--r-sm);width:2.25rem;height:2.25rem;
font-size:1.1rem;cursor:pointer;box-shadow:var(--shadow-sm);
}
.main-content{margin-left:0;padding-top:3.5rem}
}
/* ══════════════════════════════════════════════════════════
+46
View File
@@ -214,6 +214,52 @@ function getCsrfToken() {
});
}());
/* ── Mobile sidebar toggle ─────────────────────────────────── */
(function() {
var toggle = document.getElementById('sidebar-toggle');
var backdrop = document.getElementById('sidebar-backdrop');
var sidebar = document.getElementById('sidebar');
if (!toggle || !sidebar) return;
function openSidebar() {
sidebar.classList.add('open');
backdrop.classList.add('open');
document.body.style.overflow = 'hidden';
}
function closeSidebar() {
sidebar.classList.remove('open');
backdrop.classList.remove('open');
document.body.style.overflow = '';
}
toggle.addEventListener('click', openSidebar);
backdrop.addEventListener('click', closeSidebar);
sidebar.querySelectorAll('.nav-item').forEach(function(link) {
link.addEventListener('click', closeSidebar);
});
}());
/* ── Relative timestamps ───────────────────────────────────── */
function timeAgo(dateStr) {
if (!dateStr) return '—';
var d = new Date(dateStr.replace(' ', 'T'));
var diff = Math.round((Date.now() - d.getTime()) / 1000);
if (diff < 60) return 'just now';
if (diff < 3600) return Math.floor(diff / 60) + ' min ago';
if (diff < 86400) return Math.floor(diff / 3600) + ' hr ago';
if (diff < 604800) return Math.floor(diff / 86400) + ' days ago';
return d.toLocaleDateString();
}
document.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('[data-ts]').forEach(function(el) {
var iso = el.dataset.ts;
if (!iso) return;
el.title = el.textContent.trim();
el.textContent = timeAgo(iso);
});
});
/* ── Generic fetch-based form submit (JSON response) ───────── */
async function submitJson(url, data, method = 'POST') {
const res = await fetch(url, {