Schnellzugriff Mobile: max 2 Zeilen, horizontal wischbar mit Snap
This commit is contained in:
@@ -485,20 +485,65 @@ function QuickLinks({ toast, mobile }) {
|
|||||||
{/* Link-Grid */}
|
{/* Link-Grid */}
|
||||||
{links.length === 0 && !editMode
|
{links.length === 0 && !editMode
|
||||||
? <div style={{ color:'rgba(255,255,255,0.5)', fontSize:11, fontFamily:'monospace', padding:'6px 0' }}>Links können unter Einstellungen → Dashboard hinzugefügt werden.</div>
|
? <div style={{ color:'rgba(255,255,255,0.5)', fontSize:11, fontFamily:'monospace', padding:'6px 0' }}>Links können unter Einstellungen → Dashboard hinzugefügt werden.</div>
|
||||||
|
: mobile ? (() => {
|
||||||
|
// Mobile: max 2 Zeilen, dann horizontal scrollbar
|
||||||
|
// Berechne Icons pro Zeile anhand der Viewport-Breite
|
||||||
|
const iconW = 58 + 6; // minWidth + gap
|
||||||
|
const containerW = window.innerWidth - 28 - 28; // padding links+rechts (S.card=14px*2)
|
||||||
|
const perRow = Math.max(3, Math.floor(containerW / iconW));
|
||||||
|
const maxVisible = perRow * 2;
|
||||||
|
const needsScroll = links.length > maxVisible;
|
||||||
|
const pages = needsScroll
|
||||||
|
? Math.ceil(links.length / maxVisible)
|
||||||
|
: 1;
|
||||||
|
// Gruppen zu je maxVisible Icons
|
||||||
|
const groups = [];
|
||||||
|
for (let i = 0; i < links.length; i += maxVisible) groups.push(links.slice(i, i + maxVisible));
|
||||||
|
return (
|
||||||
|
<div style={{ overflowX:'auto', scrollSnapType:'x mandatory',
|
||||||
|
display:'flex', gap:0, marginInline:-14, paddingInline:14,
|
||||||
|
scrollbarWidth:'none', WebkitOverflowScrolling:'touch' }}>
|
||||||
|
{groups.map((group, gi) => (
|
||||||
|
<div key={gi} style={{
|
||||||
|
display:'grid',
|
||||||
|
gridTemplateColumns:`repeat(${perRow}, ${iconW-6}px)`,
|
||||||
|
gridTemplateRows:'repeat(2, auto)',
|
||||||
|
gap:6,
|
||||||
|
flexShrink:0,
|
||||||
|
scrollSnapAlign:'start',
|
||||||
|
paddingRight: gi < groups.length-1 ? 14 : 0,
|
||||||
|
}}>
|
||||||
|
{group.map(l => (
|
||||||
|
<div key={l.id}>
|
||||||
|
<a href={l.url} target="_blank" rel="noopener noreferrer"
|
||||||
|
style={{ display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', gap:3,
|
||||||
|
padding:'4px 2px', background:'rgba(255,255,255,0.04)',
|
||||||
|
border:'1px solid rgba(255,255,255,0.08)', borderRadius:10,
|
||||||
|
textDecoration:'none', height:48, cursor:'pointer', width:'100%' }}>
|
||||||
|
{l.icon && l.icon.startsWith('http')
|
||||||
|
? <img src={l.icon} alt="" style={{width:16,height:16,objectFit:'contain'}} onError={e=>e.target.style.display='none'}/>
|
||||||
|
: <span style={{ fontSize:16 }}>{l.icon}</span>}
|
||||||
|
<span style={{ color:'rgba(255,255,255,0.65)', fontSize:8, fontFamily:'monospace',
|
||||||
|
maxWidth:52, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{l.title}</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})()
|
||||||
: <div style={{ display:'grid', gridTemplateColumns:'repeat(auto-fill,minmax(58px,1fr))', gap:6 }}>
|
: <div style={{ display:'grid', gridTemplateColumns:'repeat(auto-fill,minmax(58px,1fr))', gap:6 }}>
|
||||||
{links.map(l => (
|
{links.map(l => (
|
||||||
<div key={l.id} style={{ position:'relative' }}>
|
<div key={l.id} style={{ position:'relative' }}>
|
||||||
|
|
||||||
<a href={l.url} target="_blank" rel="noopener noreferrer"
|
<a href={l.url} target="_blank" rel="noopener noreferrer"
|
||||||
|
|
||||||
style={{ display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', gap:3,
|
style={{ display:'flex', flexDirection:'column', alignItems:'center', justifyContent:'center', gap:3,
|
||||||
padding: mobile?'4px 2px':'6px 4px',
|
padding:'6px 4px', background:'rgba(255,255,255,0.04)',
|
||||||
background:'rgba(255,255,255,0.04)',
|
|
||||||
border:'1px solid rgba(255,255,255,0.08)', borderRadius:10,
|
border:'1px solid rgba(255,255,255,0.08)', borderRadius:10,
|
||||||
textDecoration:'none', height: mobile?48:58, cursor:'pointer' }}>
|
textDecoration:'none', height:58, cursor:'pointer' }}>
|
||||||
{l.icon && l.icon.startsWith('http')
|
{l.icon && l.icon.startsWith('http')
|
||||||
? <img src={l.icon} alt="" style={{width:mobile?16:20,height:mobile?16:20,objectFit:'contain'}} onError={e=>e.target.style.display='none'}/>
|
? <img src={l.icon} alt="" style={{width:20,height:20,objectFit:'contain'}} onError={e=>e.target.style.display='none'}/>
|
||||||
: <span style={{ fontSize:mobile?16:18 }}>{l.icon}</span>}
|
: <span style={{ fontSize:18 }}>{l.icon}</span>}
|
||||||
<span style={{ color:'rgba(255,255,255,0.65)', fontSize:8, fontFamily:'monospace',
|
<span style={{ color:'rgba(255,255,255,0.65)', fontSize:8, fontFamily:'monospace',
|
||||||
maxWidth:52, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{l.title}</span>
|
maxWidth:52, overflow:'hidden', textOverflow:'ellipsis', whiteSpace:'nowrap' }}>{l.title}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
Reference in New Issue
Block a user