Dateien nach "frontend/src" hochladen
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { useState, useEffect, useRef, useCallback } from 'react';
|
||||
import { api, S } from './lib.js';
|
||||
import { TOOLS, getGroupedTools } from './toolRegistry.js';
|
||||
import { HomeIcon, AppsIcon, AdminIcon, MoreIcon, UserIcon, LogOutIcon, ChevronIcon, UpdateIcon } from './icons.jsx';
|
||||
|
||||
const ICONS = ['🔗','🌐','📊','📁','🛠','📧','🗓','💾','🖥','📡','🔒','📖','🎯','⚡','🏠','🔧','📱','🎮','🚀','💡'];
|
||||
|
||||
@@ -136,22 +137,25 @@ function UpdateModal({ data, onClose }) {
|
||||
function Sidebar({ active, setActive, user, onLogout, updateInfo, onUpdateClick }) {
|
||||
const [appsOpen, setAppsOpen] = useState(true);
|
||||
|
||||
const NavBtn = ({ item, sub=false }) => (
|
||||
<button onClick={()=>setActive(item.id)} style={{
|
||||
width:'100%', display:'flex', alignItems:'center', gap:9,
|
||||
padding: '8px 12px 8px 12px',
|
||||
borderRadius:7, border:'none',
|
||||
background: active===item.id ? 'linear-gradient(90deg,rgba(78,205,196,0.14),rgba(78,205,196,0.02))' : 'transparent',
|
||||
color: active===item.id ? '#4ecdc4' : 'rgba(255,255,255,0.6)',
|
||||
cursor:'pointer', fontSize:12,
|
||||
fontFamily:"'Space Mono',monospace", textAlign:'left', marginBottom:1,
|
||||
borderLeft: active===item.id ? '2px solid #4ecdc4' : '2px solid transparent',
|
||||
}}>
|
||||
{sub && <span style={{ width:1, alignSelf:'stretch', background:'rgba(255,255,255,0.08)', marginRight:4, flexShrink:0 }}/>}
|
||||
<span style={{ fontSize:13 }}>{item.icon}</span>
|
||||
<span style={{ flex:1 }}>{item.label}</span>
|
||||
</button>
|
||||
);
|
||||
const NavBtn = ({ item, sub=false }) => {
|
||||
const ic = active===item.id ? '#4ecdc4' : 'rgba(255,255,255,0.55)';
|
||||
return (
|
||||
<button onClick={()=>setActive(item.id)} style={{
|
||||
width:'100%', display:'flex', alignItems:'center', gap:9,
|
||||
padding:'8px 12px', borderRadius:7, border:'none',
|
||||
background: active===item.id ? 'linear-gradient(90deg,rgba(78,205,196,0.14),rgba(78,205,196,0.02))' : 'transparent',
|
||||
cursor:'pointer', fontSize:12,
|
||||
fontFamily:"'Space Mono',monospace", textAlign:'left', marginBottom:1,
|
||||
borderLeft: active===item.id ? '2px solid #4ecdc4' : '2px solid transparent',
|
||||
}}>
|
||||
{sub && <span style={{ width:1, alignSelf:'stretch', background:'rgba(255,255,255,0.08)', marginRight:3, flexShrink:0 }}/>}
|
||||
<span style={{ display:'flex', alignItems:'center', width:18, justifyContent:'center', flexShrink:0 }}>
|
||||
{item.Icon ? <item.Icon size={15} color={ic}/> : <span style={{color:ic,fontSize:13}}>{item.icon}</span>}
|
||||
</span>
|
||||
<span style={{ flex:1, color:ic }}>{item.label}</span>
|
||||
</button>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<aside style={{ width:210, minHeight:'100vh', background:'#0d0d0f',
|
||||
@@ -169,7 +173,7 @@ function Sidebar({ active, setActive, user, onLogout, updateInfo, onUpdateClick
|
||||
</div>
|
||||
</div>
|
||||
<nav style={{ flex:1, padding:'0 8px' }}>
|
||||
<NavBtn item={{ id:'dashboard', icon:'⬡', label:'Dashboard' }} />
|
||||
<NavBtn item={{ id:'dashboard', Icon:HomeIcon, label:'Dashboard' }} />
|
||||
|
||||
{/* Apps Sektion mit Gruppenüberschriften */}
|
||||
<button onClick={()=>setAppsOpen(v=>!v)} style={{
|
||||
@@ -191,7 +195,7 @@ function Sidebar({ active, setActive, user, onLogout, updateInfo, onUpdateClick
|
||||
</div>
|
||||
))}
|
||||
|
||||
{user?.role==='admin' && <NavBtn item={{ id:'admin', icon:'⚙', label:'Admin' }} />}
|
||||
{user?.role==='admin' && <NavBtn item={{ id:'admin', icon:'⚙️', label:'Admin' }} />}
|
||||
</nav>
|
||||
{updateInfo?.hasUpdate && (
|
||||
<button onClick={onUpdateClick} style={{
|
||||
@@ -207,7 +211,7 @@ function Sidebar({ active, setActive, user, onLogout, updateInfo, onUpdateClick
|
||||
<div style={{ padding:'10px 12px 16px', borderTop:'1px solid rgba(255,255,255,0.06)' }}>
|
||||
<div style={{ display:'flex', alignItems:'center', gap:8, marginBottom:8 }}>
|
||||
<div style={{ width:24, height:24, borderRadius:'50%', background:'linear-gradient(135deg,#ff6b9d,#4ecdc4)',
|
||||
display:'flex', alignItems:'center', justifyContent:'center', fontSize:10 }}>👤</div>
|
||||
display:'flex', alignItems:'center', justifyContent:'center' }}><UserIcon size={14} color="#0d0d0f"/></div>
|
||||
<div style={{ color:'#fff', fontSize:11, fontFamily:'monospace' }}>{user?.username}</div>
|
||||
</div>
|
||||
<button onClick={onLogout} style={{ ...S.btn('#ff6b9d',true), width:'100%', textAlign:'center' }}>Ausloggen</button>
|
||||
@@ -225,7 +229,7 @@ function BottomNav({ active, setActive, user, onLogout, updateInfo, onUpdateClic
|
||||
const MI = ({icon, label, onClick, color='#fff'}) => (
|
||||
<button onClick={onClick} style={{ width:'100%', padding:'11px 20px', background:'transparent',
|
||||
border:'none', display:'flex', alignItems:'center', gap:10, cursor:'pointer' }}>
|
||||
<span style={{fontSize:17, flexShrink:0, width:22, textAlign:'center', display:'inline-block', color:'rgba(255,255,255,0.85)'}}>{icon}</span>
|
||||
<span style={{fontSize:17, flexShrink:0, width:22, textAlign:'center', display:'inline-block', }}>{icon}</span>
|
||||
<span style={{color, fontFamily:'monospace', fontSize:13}}>{label}</span>
|
||||
</button>
|
||||
);
|
||||
@@ -246,10 +250,10 @@ function BottomNav({ active, setActive, user, onLogout, updateInfo, onUpdateClic
|
||||
);
|
||||
|
||||
const mainNav = [
|
||||
{ id:'dashboard', icon:'⬡', label:'Home' },
|
||||
{ id:'_apps', icon:'◫', label:'Apps' },
|
||||
...(user?.role==='admin' ? [{ id:'admin', icon:'⚙', label:'Admin' }] : []),
|
||||
{ id:'_mehr', icon:'⋯', label:'Mehr' },
|
||||
{ id:'dashboard', Icon:HomeIcon, label:'Home' },
|
||||
{ id:'_apps', Icon:AppsIcon, label:'Apps' },
|
||||
...(user?.role==='admin' ? [{ id:'admin', Icon:AdminIcon, label:'Admin' }] : []),
|
||||
{ id:'_mehr', Icon:MoreIcon, label:'Mehr' },
|
||||
];
|
||||
|
||||
return (
|
||||
@@ -262,7 +266,7 @@ function BottomNav({ active, setActive, user, onLogout, updateInfo, onUpdateClic
|
||||
<div style={{ color:'rgba(255,255,255,0.28)', fontSize:9, fontFamily:'monospace',
|
||||
letterSpacing:2, padding:'12px 20px 5px' }}>{group.toUpperCase()}</div>
|
||||
{tools.map(t => (
|
||||
<MI key={t.id} icon={t.icon} label={t.label}
|
||||
<MI key={t.id} Icon={t.Icon} label={t.label}
|
||||
onClick={() => { setActive(t.id); setAppsOpen(false); }} />
|
||||
))}
|
||||
</div>
|
||||
@@ -272,10 +276,10 @@ function BottomNav({ active, setActive, user, onLogout, updateInfo, onUpdateClic
|
||||
|
||||
{/* Mehr Sheet */}
|
||||
<Sheet open={menuOpen} onClose={()=>setMenuOpen(false)}>
|
||||
{updateInfo?.hasUpdate && <MI icon="📦" label={`Update: ${updateInfo.latestVersion}`} onClick={()=>{setMenuOpen(false);onUpdateClick();}} color="#ffe66d"/>}
|
||||
{updateInfo?.hasUpdate && <MI Icon={UpdateIcon} label={`Update: ${updateInfo.latestVersion}`} onClick={()=>{setMenuOpen(false);onUpdateClick();}} color="#ffe66d"/>}
|
||||
<div style={{height:1, background:'rgba(255,255,255,0.08)', margin:'4px 0'}}/>
|
||||
<MI icon="👤" label={user?.username||''} onClick={()=>{}} color="rgba(255,255,255,0.35)"/>
|
||||
<MI icon="🚪" label="Ausloggen" onClick={()=>{onLogout();setMenuOpen(false);}} color="#ff6b9d"/>
|
||||
<MI Icon={UserIcon} label={user?.username||''} onClick={()=>{}} color="rgba(255,255,255,0.35)"/>
|
||||
<MI Icon={LogOutIcon} label="Ausloggen" onClick={()=>{onLogout();setMenuOpen(false);}} color="#ff6b9d"/>
|
||||
</Sheet>
|
||||
|
||||
{/* Bottom Bar */}
|
||||
@@ -301,7 +305,7 @@ function BottomNav({ active, setActive, user, onLogout, updateInfo, onUpdateClic
|
||||
width:8, height:8, borderRadius:'50%', background:'#ffe66d',
|
||||
boxShadow:'0 0 6px #ffe66d', display:'inline-block' }} />
|
||||
)}
|
||||
<span style={{ fontSize:20, lineHeight:1 }}>{item.icon}</span>
|
||||
<item.Icon size={20} color={isActive ? '#4ecdc4' : 'rgba(255,255,255,0.45)'}/>
|
||||
<span style={{ fontSize:9, fontFamily:'monospace', letterSpacing:0.3,
|
||||
color: isActive ? '#4ecdc4' : 'rgba(255,255,255,0.4)' }}>{item.label}</span>
|
||||
{isActive && !isApps && !isMehr && (
|
||||
|
||||
Reference in New Issue
Block a user