diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx
index 8719ccf..f2fab86 100644
--- a/frontend/src/App.jsx
+++ b/frontend/src/App.jsx
@@ -435,6 +435,112 @@ function BottomNav({ active, setActive, user, onLogout, updateInfo, onUpdateClic
// ── Dashboard Widgets ─────────────────────────────────────────────────────────
+// ── QuickLinks Carousel (Mobile) ─────────────────────────────────────────────
+function QuickLinksCarousel({ links }) {
+ const iconW = 58; const gap = 6;
+ const containerW = window.innerWidth - 28;
+ const perRow = Math.max(3, Math.floor((containerW + gap) / (iconW + gap)));
+ const pageSize = perRow * 2;
+ const pageCount = Math.ceil(links.length / pageSize);
+
+ const [page, setPage] = useState(0);
+ const scrollRef = useRef(null);
+
+ // Sync scroll position → page indicator
+ const onScroll = () => {
+ if (!scrollRef.current) return;
+ const p = Math.round(scrollRef.current.scrollLeft / containerW);
+ setPage(p);
+ };
+
+ const canLeft = page > 0;
+ const canRight = page < pageCount - 1;
+
+ const scrollTo = (p) => {
+ scrollRef.current?.scrollTo({ left: p * containerW, behavior:'smooth' });
+ };
+
+ if (pageCount <= 1) return (
+
+ {/* Scroll container – overflow hidden so nothing peeks */}
+
+ {Array.from({length: pageCount}, (_,pi) => (
+
+ {links.slice(pi*pageSize, (pi+1)*pageSize).map(l => )}
+
+ ))}
+
+
+ {/* Left arrow */}
+ {canLeft && (
+
+ )}
+
+ {/* Right arrow */}
+ {canRight && (
+
+ )}
+
+ {/* Page dots */}
+ {pageCount > 1 && (
+
+ {Array.from({length:pageCount}, (_,i) => (
+
scrollTo(i)} style={{
+ width: i===page ? 14 : 5, height:5, borderRadius:3, cursor:'pointer',
+ background: i===page ? '#4ecdc4' : 'rgba(255,255,255,0.2)',
+ transition:'all 0.2s',
+ }}/>
+ ))}
+
+ )}
+
+ );
+}
+
+function QuickLinkIcon({ l }) {
+ return (
+
+ {l.icon && l.icon.startsWith('http')
+ ?
e.target.style.display='none'}/>
+ : {l.icon}}
+ {l.title}
+
+ );
+}
+
function QuickLinks({ toast, mobile }) {
const { confirm, ConfirmDialog } = useConfirm();
const [links, setLinks] = useState([]);
@@ -485,71 +591,25 @@ function QuickLinks({ toast, mobile }) {
{/* Link-Grid */}
{links.length === 0 && !editMode
?
Links können unter Einstellungen → Dashboard hinzugefügt werden.
- : 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 (
-
- {groups.map((group, gi) => (
-
- {group.map(l => (
-
- ))}
-
- ))}
-
- );
- })()
- :
- {links.map(l => (
-
- ))}
-
+ : mobile
+ ?
+ :
+ {links.map(l => (
+
+ ))}
+
}
{/* Formular */}