// Sidebar, Topbar, common chrome (Superadmin flavor) const Icon = ({name, size=18, color='currentColor'}) => { const paths = { dashboard: <>, building: <>, users: <>, credit: <>, headset: <>, activity: <>, shield: <>, settings: <>, bell: <>, search: <>, chevdown: <>, chevright: <>, plus: <>, check: <>, alert: <>, zap: <>, book: <>, logout: <>, sun: <>, moon: <>, ext: <>, download: <>, filter: <>, dot: , spark: <>, arrow_up: <>, arrow_dn: <>, }; return ( {paths[name] || null} ); }; const NAV_ITEMS = [ { k:'dashboard', lbl:'Nadzorna plošča', icon:'dashboard' }, { k:'organizations',lbl:'Organizacije', icon:'building', badge:12 }, { k:'users', lbl:'Uporabniki', icon:'users' }, { k:'billing', lbl:'Naročnine in plačila',icon:'credit' }, { k:'support', lbl:'Podpora', icon:'headset', badge:5 }, { k:'system', lbl:'Sistem in integracije', icon:'activity' }, { k:'audit', lbl:'Dnevnik dogodkov', icon:'shield' }, { k:'settings', lbl:'Platforma', icon:'settings' }, ]; function Sidebar({ active, onNav, collapsed, dark }) { const w = collapsed ? 72 : 252; const bg = dark ? '#1A1A1A' : '#FFFFFF'; const border = dark ? '#2B2B2B' : '#E5E5E5'; const fg = dark ? '#C8C8C8' : '#333'; const fgMuted = dark ? '#707070' : '#9A9A9A'; return ( ); } function Topbar({ onToggleSidebar, onSearch, dark, onToggleDark, role, onRoleChange }) { const [searchOpen, setSearchOpen] = React.useState(false); const [notifOpen, setNotifOpen] = React.useState(false); const [userOpen, setUserOpen] = React.useState(false); const bg = dark ? '#1A1A1A' : '#fff'; const border = dark ? '#2B2B2B' : '#E5E5E5'; const fg = dark ? '#E5E5E5' : '#333'; const fgMuted = dark ? '#9A9A9A' : '#707070'; return (
setSearchOpen(true)} onBlur={()=>setTimeout(()=>setSearchOpen(false),150)} style={{ width:'100%', padding:'9px 12px 9px 36px', background: dark?'#2B2B2B':'#F5F5F5', border:`1px solid ${dark?'#333':'transparent'}`, borderRadius:10, fontSize:13, fontFamily:'inherit', color:fg, outline:'none', }}/> {searchOpen && (
Predlogi
{['Adria Hotels Group','Marko Kranjc','T-2847 — Booking.com sync','INV-4082'].map(s=>(
e.currentTarget.style.background=dark?'#2B2B2B':'#F5F5F5'} onMouseLeave={e=>e.currentTarget.style.background='transparent'}>{s}
))}
)}
{notifOpen && (
Obvestila
Označi vse kot prebrano
{[ ['alert','#FF9800','Piran Seaside Inn · neplačana naročnina (INV-4082)', 'pred 2 ur'], ['zap','#E53935','Google Hotel Ads integracija ni dosegljiva', 'pred 30 min'], ['check','#2DD164','Nova registracija: Kras Boutique (14-dnevni poskus)', 'včeraj'], ['headset','#2196F3','T-2846 eskaliran na urgent — Grand Union', 'pred 1 ur'], ].map(([ic,c,txt,time],i)=>(
e.currentTarget.style.background=dark?'#2B2B2B':'#FAFAFA'} onMouseLeave={e=>e.currentTarget.style.background='transparent'}>
{txt}
{time}
))}
)}
{userOpen && (
Zamenjaj vlogo
{['Superadmin','Hotel Admin','Recepcija','Vzdrževanje','Gost (brez dostopa)'].map(r=>(
{onRoleChange(r); setUserOpen(false);}} style={{ padding:'8px 10px', borderRadius:6, fontSize:13, cursor:'pointer', background: role===r ? (dark?'rgba(33,150,243,.15)':'#E3F2FD') : 'transparent', color: role===r ? '#2196F3' : fg, fontWeight: role===r ? 600 : 400, display:'flex', alignItems:'center', justifyContent:'space-between', }}>{r} {role===r && }
))}
{['Moj račun','Pomoč in dokumentacija','Bližnjice tipkovnice'].map(x=>(
e.currentTarget.style.background=dark?'#2B2B2B':'#F5F5F5'} onMouseLeave={e=>e.currentTarget.style.background='transparent'}>{x}
))}
e.currentTarget.style.background=dark?'#2B2B2B':'#FDECEA'} onMouseLeave={e=>e.currentTarget.style.background='transparent'}> Odjava
)}
); } function PageHeader({ title, subtitle, actions, breadcrumbs, dark }) { const fgMuted = dark ? '#9A9A9A' : '#707070'; return (
{breadcrumbs && (
{breadcrumbs.map((b,i)=>( {b} {i} ))}
)}

{title}

{subtitle &&
{subtitle}
}
{actions &&
{actions}
}
); } function Btn({ children, variant='primary', size='md', onClick, icon, dark, style={} }) { const base = { fontFamily:'inherit', fontWeight:600, border:'none', cursor:'pointer', display:'inline-flex', alignItems:'center', gap:8, transition:'all 120ms', borderRadius:10, whiteSpace:'nowrap', }; const sizes = { sm:{padding:'6px 12px', fontSize:13}, md:{padding:'9px 16px', fontSize:14}, lg:{padding:'12px 22px', fontSize:15}, }; const variants = { primary:{background:'#2196F3', color:'#fff'}, cyan:{background:'#00BCD4', color:'#fff'}, ghost:{background: dark?'#2B2B2B':'#fff', color: dark?'#E5E5E5':'#333', border:`1px solid ${dark?'#333':'#E5E5E5'}`}, danger:{background:'#fff', color:'#E53935', border:'1px solid #E53935'}, subtle:{background: dark?'rgba(33,150,243,.15)':'#E3F2FD', color:'#2196F3'}, }; return ( ); } function Card({ children, dark, padding=20, style={} }) { return (
{children}
); } function Badge({ children, tone='neutral' }) { const tones = { cyan: {bg:'#E0F7FA', fg:'#006064', dot:'#00BCD4'}, blue: {bg:'#E3F2FD', fg:'#0D47A1', dot:'#2196F3'}, orange: {bg:'#FFF3E0', fg:'#E65100', dot:'#FF9800'}, success: {bg:'#E6F9EC', fg:'#117A34', dot:'#2DD164'}, danger: {bg:'#FDECEA', fg:'#B71C1C', dot:'#E53935'}, neutral: {bg:'#F5F5F5', fg:'#4D4D4D', dot:'#9A9A9A'}, purple: {bg:'#F3E5F5', fg:'#4A148C', dot:'#9C27B0'}, }; const t = tones[tone] || tones.neutral; return ( {children} ); } Object.assign(window, { Icon, Sidebar, Topbar, PageHeader, Btn, Card, Badge, NAV_ITEMS });