From 3a79965899b095a15e400c37dbe2cbd385133aa8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Raduli=C4=87?= Date: Tue, 5 May 2026 01:42:16 +0200 Subject: [PATCH] =?UTF-8?q?CC3=20R3:=20Sectioned=20sidebar=20redesign=20(D?= =?UTF-8?q?ABI-style)=20=E2=80=94=20PORTAL/OPERATIVA/CRM/ERP/ANALITIKA/ADM?= =?UTF-8?q?IN?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reference: app.rinet.one/klasik/dabi — uppercase section headers + grouped items. Shared module rewrite: - /static/shared/sidebar.css v2.0 * 6 named sections, 240px expanded / 58px collapsed * Active item: gold left-border + transparent gradient fill * Hover: blue left-border accent * Section header hidden in collapsed mode (replaced with dashed separator) * Tooltip on hover (data-label) when collapsed * Mobile <768px overlay with backdrop - /static/shared/sidebar.js v2.0 * SIDEBAR_SECTIONS = [PORTAL, OPERATIVA, CRM, ERP, ANALITIKA, ADMIN] * ADMIN section hidden unless user_type ∈ {pgz_admin, super_admin} (gated by /api/auth/me) * Cross-portal links (↗ marker) for items that target a different page * Same-page items trigger hashchange instead of full reload * Footer = avatar + name + role + ▾ user menu (Profil / Postavke / Public portal / Prijava ↔ Odjava) * localStorage 'sidebarCollapsed' persists across all 8 pages Page integration: - sport2.html ← native .sb hidden; data-active=dashboard; hashchange→navTo - app.html ← native .sb hidden; data-active=profil; hashchange→navTo - admin.html ← native .sidebar hidden; data-active=korisnici - erp.html ← native .sidebar hidden; data-active=racuni - crm.html ← data-active=clanarine - audit.html ← data-active=audit (existing) - kpi.html ← data-active=kpi (existing) - login.html ← data-active=login (no item match → no highlight; user menu shows Prijava) Backups: _backups/*.cc3_pre_redesign.{TS} Live verified: all 8 pages HTTP 200; shared sidebar.css 200 (8664 B); sidebar.js 200 (12678 B); 6 sections present. Co-Authored-By: Claude Opus 4.7 (1M context) --- static/admin.html | 26 ++-- static/app.html | 46 +++---- static/crm.html | 36 +++++- static/erp.html | 21 +-- static/shared/sidebar.css | 143 ++++++++++++-------- static/shared/sidebar.js | 266 +++++++++++++++++++++++++------------- static/sport2.html | 27 ++-- 7 files changed, 354 insertions(+), 211 deletions(-) diff --git a/static/admin.html b/static/admin.html index f4523b7..2790c49 100644 --- a/static/admin.html +++ b/static/admin.html @@ -32,13 +32,9 @@ body { font-size: 14px; line-height: 1.5; } -.app { display: grid; grid-template-columns: 240px 1fr; min-height: 100vh; } -.sidebar { - background: var(--bg-2); - border-right: 1px solid var(--border); - padding: 20px 0; - display: flex; flex-direction: column; -} +.app { display: grid; grid-template-columns: 1fr; min-height: 100vh; } +/* Native .sidebar hidden — shared sidebar (/static/shared/sidebar.*) handles sectioned menu */ +.sidebar { display: none; } .brand { padding: 0 20px 20px; border-bottom: 1px solid var(--border); @@ -161,6 +157,8 @@ td.num { font-family: 'JetBrains Mono', monospace; text-align: right; } .sidebar { display: none; } } + +
@@ -206,13 +204,13 @@ td.num { font-family: 'JetBrains Mono', monospace; text-align: right; }
Portali
- 🔑Prijava - 📱Aplikacija - 🛡Administracija - 👥CRM - 💰ERP - 📈KPI - 📋Audit + 🔑Prijava + 📱Aplikacija + 🛡Administracija + 👥CRM + 💰ERP + 📈KPI + 📋Audit 🌐Public portal diff --git a/static/app.html b/static/app.html index fd20395..5e9ad96 100644 --- a/static/app.html +++ b/static/app.html @@ -36,7 +36,8 @@ button,input,select,textarea{font-family:inherit;font-size:inherit;outline:none} /* ============ LAYOUT ============ */ .app{display:flex;min-height:100vh} -.sb{width:240px;background:linear-gradient(180deg,var(--bg1) 0%,var(--bg0) 100%);border-right:1px solid var(--rim);position:fixed;top:0;left:0;bottom:0;display:flex;flex-direction:column;z-index:10;transition:width .22s ease} +/* Native .sb hidden — shared sidebar (/static/shared/sidebar.*) handles sectioned menu */ +.sb{display:none} .sb-h{padding:18px 18px 14px;border-bottom:1px solid var(--rim);position:relative} .sb-h .logo{font-weight:800;font-size:14px;color:var(--t0);letter-spacing:.5px;white-space:nowrap;overflow:hidden} .sb-h .logo .g{color:var(--pgz-gold)} @@ -78,7 +79,7 @@ button,input,select,textarea{font-family:inherit;font-size:inherit;outline:none} .nav-ext:hover{color:var(--pgz-gold);background:var(--bg2)} .nav-ext.active{background:linear-gradient(90deg,var(--pgz-blue) 0%,var(--pgz-blue2) 100%);color:#fff} -.main{margin-left:240px;flex:1;min-width:0;transition:margin-left .22s ease} +.main{margin-left:0;flex:1;min-width:0;transition:margin-left .22s ease} .sb.collapsed ~ .main{margin-left:58px} .tb{background:var(--bg1);border-bottom:1px solid var(--rim);padding:12px 22px;display:flex;align-items:center;justify-content:space-between;position:sticky;top:0;z-index:5;gap:12px} .tb-t{font-size:15px;font-weight:700;color:var(--t0)} @@ -256,6 +257,8 @@ table tbody tr:hover{background:var(--bg3)} .role-switch{display:none} } + + @@ -600,35 +603,22 @@ function setRole(r){ } //=========== NAV =========== -const NAV_EXTERNAL = [ - {id:'login', href:'/sport/login', ic:'\u{1F511}', label:'Prijava'}, - {id:'app', href:'/sport/app', ic:'\u{1F4F1}', label:'Aplikacija'}, - {id:'admin', href:'/sport/admin', ic:'\u{1F6E1}', label:'Administracija'}, - {id:'crm', href:'/sport/crm', ic:'\u{1F465}', label:'CRM'}, - {id:'erp', href:'/sport/erp', ic:'\u{1F4B0}', label:'ERP'}, - {id:'kpi', href:'/sport/kpi', ic:'\u{1F4C8}', label:'KPI'}, - {id:'audit', href:'/sport/audit', ic:'\u{1F4CB}', label:'Audit'}, - {id:'sport2', href:'/sport/static/sport2.html', ic:'\u{1F310}', label:'Public portal'} -]; function buildNav(){ const items = NAV_BY_ROLE[_state.role] || []; - let html = items.map(n => + $('#nav').innerHTML = items.map(n => `` ).join(''); - // PORTALI separator + external links (active = 'app') - html += ''; - html += NAV_EXTERNAL.map(n => - ` - ${n.ic}${esc(n.label)} - - ` - ).join(''); - $('#nav').innerHTML = html; } +window.addEventListener('hashchange', () => { + const h = (location.hash||'').replace(/^#/,''); + if(!h) return; + const items = NAV_BY_ROLE[_state.role] || []; + if(items.some(n => n.id===h)) navTo(h); +}); function navTo(id){ _state.section = id; $$('.nav-i').forEach(el => el.classList.toggle('active', el.dataset.id===id)); @@ -1158,7 +1148,7 @@ SECTIONS['pgz:racuni'] = () => ` SECTIONS['pgz:crm'] = () => `
- 📋 Otvori CRM workspace (Članarine • Liječnički • Obrasci) — live API + 📋 Otvori CRM workspace (Članarine • Liječnički • Obrasci) — live API
@@ -1255,7 +1245,7 @@ async function renderKalendar(opts){ const isToday = (k === today.toISOString().slice(0,10)); const evHtml = ev.slice(0,3).map(e => `
${esc(e.title.substring(0,28))}
`).join(''); const more = ev.length > 3 ? `
+${ev.length-3} više
` : ''; - grid += `
${d}
${evHtml}${more}
`; + grid += `
${d}
${evHtml}${more}
`; } grid += '
'; @@ -1505,7 +1495,7 @@ SECTIONS['klub:clanovi'] = () => `
`; SECTIONS['klub:clanarine'] = () => ` -
📋 Otvori live CRM (HUB-3 PDF + EPC QR generator)
+
📋 Otvori live CRM (HUB-3 PDF + EPC QR generator)
€ Članarine 2026
Plaćeno
80
Dug
7
@@ -1527,7 +1517,7 @@ SECTIONS['klub:clanarine'] = () => `
`; SECTIONS['klub:lijecnicki'] = () => ` -
⚕ Otvori live CRM — pregledi + ZZJZ PGŽ scheduling
+
⚕ Otvori live CRM — pregledi + ZZJZ PGŽ scheduling
⚕ Liječnički pregledi članova
@@ -1626,7 +1616,7 @@ SECTIONS['sportas:clanarina'] = () => ` `; SECTIONS['sportas:lijecnicki'] = () => ` -
⚕ Otvori live CRM — pregledi + ZZJZ PGŽ scheduling
`+` +
⚕ Otvori live CRM — pregledi + ZZJZ PGŽ scheduling
`+`
⚕ Moji liječnički pregledi
⚠ Trenutni: vrijedi do 2026-08-15 (103 dana)
@@ -1658,7 +1648,7 @@ SECTIONS['sportas:dokumenti'] = () => `
`; SECTIONS['sportas:obrasci'] = () => ` - +
📝 Obrasci za potpis
GDPR suglasnost 2026 — obvezno do 2026-06-01
diff --git a/static/crm.html b/static/crm.html index 612574c..7303ce6 100644 --- a/static/crm.html +++ b/static/crm.html @@ -136,7 +136,8 @@ table tr:hover td { background: rgba(26, 115, 232, 0.05); } .toast.err { border-left-color: var(--err); } - + + @@ -158,6 +159,7 @@ table tr:hover td { background: rgba(26, 115, 232, 0.05); }
📝 Obrasci
📊 Statistika
🔔 Notifikacije
+
📨 E-mail templates
ROLA:
ČlanDatum pregledaVrijedi doDoktorStatus