From 413a0964323f27d11163208f0dece8df5f919ac0 Mon Sep 17 00:00:00 2001 From: Lars Date: Tue, 5 May 2026 21:23:16 +0200 Subject: [PATCH] feat: enhance mobile and desktop sidebar with ActiveClubSwitcher component - Integrated ActiveClubSwitcher into both mobile and desktop sidebar layouts, improving club selection functionality. - Updated app header styles for better mobile responsiveness and layout. - Adjusted desktop sidebar footer styles for improved alignment and spacing. --- frontend/src/App.jsx | 8 ++- frontend/src/app.css | 43 +++++++++++- .../src/components/ActiveClubSwitcher.jsx | 44 ++++++++++++ frontend/src/components/DesktopSidebar.jsx | 68 ++++++++++--------- 4 files changed, 128 insertions(+), 35 deletions(-) create mode 100644 frontend/src/components/ActiveClubSwitcher.jsx diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 951ebf7..b545339 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -31,6 +31,7 @@ import AdminMaturityModelsPage from './pages/AdminMaturityModelsPage' import TrainerContextsPage from './pages/TrainerContextsPage' import MediaWikiImportPage from './pages/MediaWikiImportPage' import AdminUsersPage from './pages/AdminUsersPage' +import ActiveClubSwitcher from './components/ActiveClubSwitcher' import './app.css' // Bottom Navigation (Mobile) @@ -99,8 +100,11 @@ function ProtectedLayout() {
-
-
🥋 Shinkan
+
+
+
🥋 Shinkan
+
+
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} -
+ +
-
)