shinkan-jinkendo/frontend/src/components/Navigation.jsx
Lars f48b573a63
Some checks failed
Deploy Development / deploy (push) Successful in 36s
Test Suite / lint-backend (push) Successful in 0s
Test Suite / build-frontend (push) Successful in 6s
Test Suite / playwright-tests (push) Failing after 43s
feat: register new club membership and join request routers
- Added club_memberships and club_join_requests routers to the backend, improving API functionality for managing club memberships and join requests.
- Bumped application version to 0.8.21 in both backend and frontend files.
- Updated changelog to reflect the new version and changes made in this release.
2026-05-05 21:15:27 +02:00

146 lines
4.1 KiB
JavaScript

import { Link, useLocation, useNavigate } from 'react-router-dom'
import { useAuth } from '../context/AuthContext'
function Navigation() {
const location = useLocation()
const navigate = useNavigate()
const { user, logout, setActiveClub } = useAuth()
const clubs = user?.clubs || []
const selectClubId =
user?.active_club_id != null && clubs.some((c) => c.id === user.active_club_id)
? user.active_club_id
: clubs[0]?.id
const handleLogout = async () => {
await logout()
navigate('/login')
}
const isActive = (path) => location.pathname === path
return (
<nav style={{
background: 'var(--surface)',
borderBottom: '1px solid var(--border)',
padding: '0 1rem',
position: 'sticky',
top: 0,
zIndex: 1000
}}>
<div style={{
width: '100%',
maxWidth: 'none',
margin: '0',
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
height: '60px'
}}>
{/* Logo/Title */}
<Link to="/" style={{
fontSize: '1.25rem',
fontWeight: 600,
color: 'var(--text1)',
textDecoration: 'none'
}}>
🥋 Shinkan
</Link>
{/* Main Navigation */}
<div style={{ display: 'flex', gap: '1rem', alignItems: 'center' }}>
<Link
to="/"
style={{
color: isActive('/') ? 'var(--accent)' : 'var(--text2)',
textDecoration: 'none',
fontWeight: isActive('/') ? 600 : 400
}}
>
Dashboard
</Link>
<Link
to="/exercises"
style={{
color: isActive('/exercises') ? 'var(--accent)' : 'var(--text2)',
textDecoration: 'none',
fontWeight: isActive('/exercises') ? 600 : 400
}}
>
Übungen
</Link>
<Link
to="/clubs"
style={{
color: isActive('/clubs') ? 'var(--accent)' : 'var(--text2)',
textDecoration: 'none',
fontWeight: isActive('/clubs') ? 600 : 400
}}
>
Vereine
</Link>
<Link
to="/profile"
style={{
color: isActive('/profile') ? 'var(--accent)' : 'var(--text2)',
textDecoration: 'none',
fontWeight: isActive('/profile') ? 600 : 400
}}
>
Profil
</Link>
{(clubs?.length ?? 0) > 1 && (
<label style={{ display: 'flex', alignItems: 'center', gap: '0.35rem', fontSize: '0.8125rem', color: 'var(--text2)' }}>
<span>Verein</span>
<select
className="form-input"
style={{ padding: '0.35rem 0.5rem', minWidth: '9rem', fontSize: '0.8125rem' }}
value={selectClubId ?? ''}
onChange={(e) => {
const v = e.target.value
if (v) setActiveClub(Number(v))
}}
>
{clubs.map((c) => (
<option key={c.id} value={c.id}>{c.name}</option>
))}
</select>
</label>
)}
{/* User Menu */}
<div style={{
borderLeft: '1px solid var(--border)',
paddingLeft: '1rem',
marginLeft: '0.5rem',
display: 'flex',
alignItems: 'center',
gap: '0.75rem'
}}>
<span style={{ color: 'var(--text2)', fontSize: '0.875rem' }}>
{user?.name || user?.email}
</span>
<button
onClick={handleLogout}
style={{
padding: '0.5rem 1rem',
background: 'transparent',
border: '1px solid var(--border)',
borderRadius: '6px',
color: 'var(--text2)',
cursor: 'pointer',
fontSize: '0.875rem'
}}
>
Abmelden
</button>
</div>
</div>
</div>
</nav>
)
}
export default Navigation