Schnellzugriff: Pfeile entfernt; Benutzerliste: mobil-optimiertes Layout
This commit is contained in:
@@ -487,28 +487,6 @@ function QuickLinksCarousel({ links }) {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Left arrow */}
|
|
||||||
{canLeft && (
|
|
||||||
<button onClick={() => scrollTo(page-1)} style={{
|
|
||||||
position:'absolute', left:-10, top:'50%', transform:'translateY(-50%)',
|
|
||||||
background:'rgba(0,0,0,0.55)', border:'1px solid rgba(255,255,255,0.12)',
|
|
||||||
borderRadius:'50%', width:24, height:24, cursor:'pointer',
|
|
||||||
color:'rgba(255,255,255,0.6)', fontSize:13, display:'flex',
|
|
||||||
alignItems:'center', justifyContent:'center', zIndex:2,
|
|
||||||
}}>‹</button>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Right arrow */}
|
|
||||||
{canRight && (
|
|
||||||
<button onClick={() => scrollTo(page+1)} style={{
|
|
||||||
position:'absolute', right:-10, top:'50%', transform:'translateY(-50%)',
|
|
||||||
background:'rgba(0,0,0,0.55)', border:'1px solid rgba(255,255,255,0.12)',
|
|
||||||
borderRadius:'50%', width:24, height:24, cursor:'pointer',
|
|
||||||
color:'rgba(255,255,255,0.6)', fontSize:13, display:'flex',
|
|
||||||
alignItems:'center', justifyContent:'center', zIndex:2,
|
|
||||||
}}>›</button>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Page dots */}
|
{/* Page dots */}
|
||||||
{pageCount > 1 && (
|
{pageCount > 1 && (
|
||||||
<div style={{ display:'flex', justifyContent:'center', gap:4, marginTop:6 }}>
|
<div style={{ display:'flex', justifyContent:'center', gap:4, marginTop:6 }}>
|
||||||
@@ -1841,75 +1819,65 @@ function UserManagement({ toast }) {
|
|||||||
<div key={u.id} style={{
|
<div key={u.id} style={{
|
||||||
padding:'12px 0', borderBottom:'1px solid rgba(255,255,255,0.06)',
|
padding:'12px 0', borderBottom:'1px solid rgba(255,255,255,0.06)',
|
||||||
}}>
|
}}>
|
||||||
<div style={{display:'flex',justifyContent:'space-between',alignItems:'center',marginBottom:8}}>
|
{/* Zeile 1: Name + Badges */}
|
||||||
<div>
|
<div style={{display:'flex',alignItems:'flex-start',justifyContent:'space-between',gap:8,marginBottom:6}}>
|
||||||
|
<div style={{minWidth:0,flex:1}}>
|
||||||
|
<div style={{display:'flex',alignItems:'center',flexWrap:'wrap',gap:4,marginBottom:3}}>
|
||||||
<span style={{color:'#fff',fontFamily:'monospace',fontSize:13,fontWeight:700}}>{u.username}</span>
|
<span style={{color:'#fff',fontFamily:'monospace',fontSize:13,fontWeight:700}}>{u.username}</span>
|
||||||
<span style={{
|
<span style={{
|
||||||
marginLeft:8, fontSize:9, fontFamily:'monospace',
|
fontSize:9, fontFamily:'monospace',
|
||||||
color: u.role==='admin'?'#ffe66d':'#4ecdc4',
|
color: u.role==='admin'?'#ffe66d':'#4ecdc4',
|
||||||
background: u.role==='admin'?'rgba(255,230,109,0.1)':'rgba(78,205,196,0.1)',
|
background: u.role==='admin'?'rgba(255,230,109,0.1)':'rgba(78,205,196,0.1)',
|
||||||
border:`1px solid ${u.role==='admin'?'rgba(255,230,109,0.3)':'rgba(78,205,196,0.3)'}`,
|
border:`1px solid ${u.role==='admin'?'rgba(255,230,109,0.3)':'rgba(78,205,196,0.3)'}`,
|
||||||
borderRadius:4, padding:'1px 6px',
|
borderRadius:4, padding:'1px 6px',
|
||||||
}}>{u.role}</span>
|
}}>{u.role}</span>
|
||||||
{!!u.has_pushover && (
|
{!!u.has_pushover && (
|
||||||
<span title="Pushover eingerichtet" style={{
|
<span style={{fontSize:9,fontFamily:'monospace',color:'rgba(255,107,157,0.8)',
|
||||||
marginLeft:4, fontSize:9, fontFamily:'monospace',
|
background:'rgba(255,107,157,0.1)',border:'1px solid rgba(255,107,157,0.25)',
|
||||||
color:'rgba(255,107,157,0.8)',
|
borderRadius:4,padding:'1px 6px'}}>🔔 Push</span>
|
||||||
background:'rgba(255,107,157,0.1)',
|
|
||||||
border:'1px solid rgba(255,107,157,0.25)',
|
|
||||||
borderRadius:4, padding:'1px 6px',
|
|
||||||
}}>🔔 Push</span>
|
|
||||||
)}
|
)}
|
||||||
{!!u.hidden && (
|
{!!u.hidden && (
|
||||||
<span title="Für andere Benutzer unsichtbar" style={{
|
<span style={{fontSize:9,fontFamily:'monospace',color:'rgba(255,230,109,0.7)',
|
||||||
marginLeft:4, fontSize:9, fontFamily:'monospace',
|
background:'rgba(255,230,109,0.08)',border:'1px solid rgba(255,230,109,0.2)',
|
||||||
color:'rgba(255,230,109,0.7)',
|
borderRadius:4,padding:'1px 6px'}}>👁 versteckt</span>
|
||||||
background:'rgba(255,230,109,0.08)',
|
|
||||||
border:'1px solid rgba(255,230,109,0.2)',
|
|
||||||
borderRadius:4, padding:'1px 6px',
|
|
||||||
}}>👁 versteckt</span>
|
|
||||||
)}
|
)}
|
||||||
|
</div>
|
||||||
{u.last_active_at && (
|
{u.last_active_at && (
|
||||||
<span style={{
|
<div style={{color:'rgba(255,255,255,0.3)',fontFamily:'monospace',fontSize:9}}>
|
||||||
marginLeft:6, fontSize:9, fontFamily:'monospace',
|
|
||||||
color:'rgba(255,255,255,0.35)',
|
|
||||||
}}>
|
|
||||||
● {(() => {
|
● {(() => {
|
||||||
const d = new Date(u.last_active_at.replace(' ','T'));
|
const d = new Date(u.last_active_at.replace(' ','T'));
|
||||||
const now = new Date();
|
const diff = Math.floor((new Date() - d) / 60000);
|
||||||
const diff = Math.floor((now - d) / 60000);
|
|
||||||
if (diff < 2) return 'gerade eben';
|
if (diff < 2) return 'gerade eben';
|
||||||
if (diff < 60) return `vor ${diff} min`;
|
if (diff < 60) return `vor ${diff} min`;
|
||||||
if (diff < 1440) return `vor ${Math.floor(diff/60)} h`;
|
if (diff < 1440) return `vor ${Math.floor(diff/60)} h`;
|
||||||
return d.toLocaleDateString('de-DE', {day:'2-digit',month:'2-digit',hour:'2-digit',minute:'2-digit'});
|
return d.toLocaleDateString('de-DE',{day:'2-digit',month:'2-digit',hour:'2-digit',minute:'2-digit'});
|
||||||
})()}
|
})()}
|
||||||
</span>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div style={{display:'flex',gap:5}}>
|
{/* Aktions-Buttons */}
|
||||||
|
<div style={{display:'flex',gap:4,flexShrink:0,flexWrap:'wrap',justifyContent:'flex-end'}}>
|
||||||
<button onClick={()=>{setResetId(u.id);setResetPw('');}}
|
<button onClick={()=>{setResetId(u.id);setResetPw('');}}
|
||||||
style={{...S.btn('#ffe66d',true),fontSize:10}}>🔑 PW</button>
|
style={{...S.btn('#ffe66d',true),fontSize:10,padding:'4px 8px'}}>🔑</button>
|
||||||
<button
|
<button
|
||||||
onClick={async ()=>{
|
onClick={async ()=>{
|
||||||
if (u.role==='admin') return;
|
if (u.role==='admin') return;
|
||||||
try {
|
try {
|
||||||
const r = await api(`/admin/users/${u.id}/hidden`,{method:'PUT'});
|
const r = await api(`/admin/users/${u.id}/hidden`,{method:'PUT'});
|
||||||
setUsers(p=>p.map(x=>x.id===u.id?{...x,hidden:r.hidden}:x));
|
setUsers(p=>p.map(x=>x.id===u.id?{...x,hidden:r.hidden}:x));
|
||||||
toast(r.hidden ? 'Benutzer ausgeblendet' : 'Benutzer wieder sichtbar');
|
toast(r.hidden ? 'Ausgeblendet' : 'Eingeblendet');
|
||||||
} catch(e){ toast(e.message,'error'); }
|
} catch(e){ toast(e.message,'error'); }
|
||||||
}}
|
}}
|
||||||
title={u.role==='admin'?'Admin kann nicht ausgeblendet werden':u.hidden?'Einblenden':'Ausblenden'}
|
|
||||||
disabled={u.role==='admin'}
|
disabled={u.role==='admin'}
|
||||||
|
title={u.hidden?'Einblenden':'Ausblenden'}
|
||||||
style={{
|
style={{
|
||||||
fontSize:10, fontFamily:'monospace', cursor: u.role==='admin'?'not-allowed':'pointer',
|
fontSize:13, cursor: u.role==='admin'?'not-allowed':'pointer',
|
||||||
padding:'3px 8px', borderRadius:6, border:'none',
|
padding:'4px 7px', borderRadius:6, border:'none',
|
||||||
background: u.hidden ? 'rgba(255,230,109,0.15)' : 'rgba(255,255,255,0.08)',
|
background: u.hidden ? 'rgba(255,230,109,0.15)' : 'rgba(255,255,255,0.08)',
|
||||||
color: u.hidden ? '#ffe66d' : 'rgba(255,255,255,0.5)',
|
color: u.hidden ? '#ffe66d' : 'rgba(255,255,255,0.4)',
|
||||||
opacity: u.role==='admin' ? 0.3 : 1,
|
opacity: u.role==='admin' ? 0.3 : 1,
|
||||||
}}>
|
}}>👁</button>
|
||||||
{u.hidden ? '👁 einblend.' : '👁 ausblend.'}
|
<button onClick={()=>del(u.id)} style={{...S.btn('#ff6b9d',true),padding:'4px 7px'}}>
|
||||||
</button>
|
|
||||||
<button onClick={()=>del(u.id)} style={{...S.btn('#ff6b9d',true)}}>
|
|
||||||
<TrashIcon size={13} color="#ff6b9d"/>
|
<TrashIcon size={13} color="#ff6b9d"/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user