CC3 R3: Sectioned sidebar redesign (DABI-style) — PORTAL/OPERATIVA/CRM/ERP/ANALITIKA/ADMIN
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) <noreply@anthropic.com>
This commit is contained in:
+12
-15
@@ -32,7 +32,9 @@ button,input,select{font-family:inherit;font-size:inherit;outline:none}
|
||||
::-webkit-scrollbar-thumb:hover{background:var(--pgz-blue2)}
|
||||
|
||||
.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 sidebar replaced by shared /static/shared/sidebar.* — kept hidden but DOM intact for legacy buildNav() calls */
|
||||
.sb{display:none}
|
||||
.sb-old{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}
|
||||
.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)}
|
||||
@@ -63,8 +65,8 @@ button,input,select{font-family:inherit;font-size:inherit;outline:none}
|
||||
.sb.collapsed .nav-sep{font-size:0;padding:6px 0;text-align:center;border-top:1px dashed var(--rim);margin:6px 8px 4px}
|
||||
.sb.collapsed .nav-ext span:last-child{display:none}
|
||||
|
||||
.main{margin-left:240px;flex:1;min-width:0;transition:margin-left .22s ease}
|
||||
.sb.collapsed ~ .main{margin-left:58px}
|
||||
.main{margin-left:0;flex:1;min-width:0;transition:margin-left .22s ease}
|
||||
/* body.pgz-has-sb (from shared/sidebar.css) provides the left padding */
|
||||
.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}
|
||||
.tb-t{font-size:15px;font-weight:700;color:var(--t0)}
|
||||
.tb-s{font-size:11px;color:var(--t2)}
|
||||
@@ -222,6 +224,8 @@ a.tag:hover,.tag[onclick]:hover{transform:translateY(-1px);filter:brightness(1.1
|
||||
.pp-stats{grid-template-columns:repeat(3,1fr)}
|
||||
}
|
||||
</style>
|
||||
<link rel="stylesheet" href="/sport/static/shared/sidebar.css">
|
||||
<script src="/sport/static/shared/sidebar.js" defer data-active="dashboard"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -572,22 +576,15 @@ function closePanel(){
|
||||
document.addEventListener('keydown', e => { if(e.key==='Escape') closePanel(); });
|
||||
|
||||
//=========== NAVIGATION ===========
|
||||
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'}
|
||||
];
|
||||
function buildNav(){
|
||||
const nav = $('#nav');
|
||||
nav.innerHTML = NAV_ITEMS.map(n => '<div class="nav-i '+(n.id===_state.section?'active':'')+'" data-id="'+n.id+'" data-label="'+n.label+'" onclick="navTo(\''+n.id+'\')"><span class="ic">'+n.ic+'</span><span class="lbl">'+n.label+'</span></div>').join('');
|
||||
// PORTALI section + external links
|
||||
nav.innerHTML += '<div class="nav-sep" style="padding:14px 14px 4px 14px;font-size:9.5px;color:var(--t4);text-transform:uppercase;letter-spacing:1.2px;font-weight:700;white-space:nowrap;overflow:hidden">Portali</div>';
|
||||
nav.innerHTML += NAV_EXTERNAL.map(n => '<a class="nav-i nav-ext" href="'+n.href+'" data-id="'+n.id+'" data-label="'+esc(n.label)+'" style="color:var(--cyan);text-decoration:none"><span class="ic">'+n.ic+'</span><span class="lbl">'+esc(n.label)+'</span><span style="margin-left:auto;font-size:10px;opacity:.5">↗</span></a>').join('');
|
||||
}
|
||||
// Hashchange handler — accept routing from unified shared sidebar
|
||||
window.addEventListener('hashchange', () => {
|
||||
const h = (location.hash||'').replace(/^#/,'');
|
||||
if(h && NAV_ITEMS.some(n => n.id===h)) navTo(h);
|
||||
});
|
||||
function toggleSidebar(){
|
||||
const sb = document.getElementById('sb');
|
||||
const tg = document.getElementById('sb-toggle');
|
||||
|
||||
Reference in New Issue
Block a user