diff --git a/frontend/src/app.css b/frontend/src/app.css
index 9868097..4ebd9a0 100644
--- a/frontend/src/app.css
+++ b/frontend/src/app.css
@@ -69,8 +69,42 @@ body { font-family: var(--font); background: var(--bg); color: var(--text1); -we
padding-right: max(16px, env(safe-area-inset-right, 0px));
}
}
+.app-header--mobile-stack {
+ flex-direction: column;
+ align-items: stretch;
+ gap: 0.5rem;
+ padding-bottom: 10px;
+}
+.app-header-mobile__top {
+ display: flex;
+ align-items: center;
+ min-height: var(--header-h);
+}
.app-logo { font-size: 18px; font-weight: 700; color: var(--accent); letter-spacing: -0.02em; }
+.active-club-switch {
+ display: flex;
+ flex-direction: column;
+ gap: 0.35rem;
+}
+.active-club-switch__label {
+ font-size: 0.75rem;
+ font-weight: 500;
+ color: var(--text2);
+}
+.active-club-switch__select {
+ width: 100%;
+ font-size: 0.875rem;
+ padding: 0.4rem 0.5rem;
+}
+.active-club-switch--sidebar {
+ width: 100%;
+ padding-bottom: 4px;
+}
+.active-club-switch--mobile {
+ width: 100%;
+}
+
/* === Seiten-Inhalt: volle Breite der Spalte, kein künstlicher Max-Wert auf großen Screens === */
.app-page {
width: 100%;
@@ -2198,7 +2232,14 @@ a.analysis-split__nav-item {
.desktop-sidebar__footer {
border-top: 1px solid var(--border);
- padding: 16px 12px 0;
+ padding: 16px 12px 16px;
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+ gap: 12px;
+}
+
+.desktop-sidebar__footer-row {
display: flex;
align-items: center;
gap: 8px;
diff --git a/frontend/src/components/ActiveClubSwitcher.jsx b/frontend/src/components/ActiveClubSwitcher.jsx
new file mode 100644
index 0000000..0243b79
--- /dev/null
+++ b/frontend/src/components/ActiveClubSwitcher.jsx
@@ -0,0 +1,44 @@
+import { useAuth } from '../context/AuthContext'
+
+/**
+ * Zeigt einen Vereins-Umschalter, wenn der Nutzer mehreren Vereinen zugeordnet ist.
+ * Steuert den Mandanten-Kontext (Header X-Active-Club-Id + Profilfeld active_club_id).
+ */
+export default function ActiveClubSwitcher({ variant = 'sidebar' }) {
+ const { user, setActiveClub } = useAuth()
+ const clubs = user?.clubs || []
+ if (clubs.length <= 1) return null
+
+ const selectClubId =
+ user?.active_club_id != null && clubs.some((c) => c.id === user.active_club_id)
+ ? user.active_club_id
+ : clubs[0]?.id
+
+ const isMobile = variant === 'mobile'
+
+ return (
+
+ )
+}
diff --git a/frontend/src/components/DesktopSidebar.jsx b/frontend/src/components/DesktopSidebar.jsx
index b95be31..a918e17 100644
--- a/frontend/src/components/DesktopSidebar.jsx
+++ b/frontend/src/components/DesktopSidebar.jsx
@@ -1,6 +1,7 @@
import { NavLink, useLocation } from 'react-router-dom'
import { LogOut } from 'lucide-react'
import { getMainNavItems } from '../config/appNav'
+import ActiveClubSwitcher from './ActiveClubSwitcher'
function sidebarLinkActive(pathname, item, routerIsActive) {
if (item.to.startsWith('/admin')) return pathname.startsWith('/admin')
@@ -46,40 +47,43 @@ export default function DesktopSidebar({
-
-
+
+
+
+ {(user?.name || user?.email || '?').trim().slice(0, 1).toUpperCase()}
+
+
+
+ {user?.name || user?.email || 'User'}
+
+ {tier ? (
+ {tier}
+ ) : null}
+
+
+
-
-
- {user?.name || user?.email || 'User'}
-
- {tier ? (
- {tier}
- ) : null}
-
+
+
-
)