feat(ui): Navigation neu strukturiert (flache Topbar + Verwaltung-Menü + /settings)

Topbar nur noch täglich genutzte Punkte (Dashboard/Zeit/Abwesenheiten/Kalender);
HR/Admin-Funktionen im neuen "Verwaltung"-Dropdown. Zahnrad führt auf eigene
/settings-Seite mit Kategorie-Kacheln statt 11er-Flachliste. Zentrale navConfig.ts
für PRIMARY/MANAGEMENT/SETTINGS_GROUPS; Rollen-Gating unverändert.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-06-23 22:07:34 +02:00
co-authored by Claude Opus 4.8
parent c122ab6fd7
commit 933d369dc4
4 changed files with 219 additions and 86 deletions
+61
View File
@@ -0,0 +1,61 @@
import { useEffect, useState } from 'react'
import { Link } from 'react-router-dom'
import { api } from '../api/client'
import { Layout } from '../components/Layout'
import { SETTINGS_GROUPS, visibleFor } from '../components/navConfig'
interface UserOut {
role: string
first_name: string
last_name: string
}
export function SettingsPage() {
const [me, setMe] = useState<UserOut | null>(null)
useEffect(() => {
api.get<UserOut>('/auth/me').then(setMe).catch(() => {})
}, [])
const role = me?.role ?? ''
const groups = SETTINGS_GROUPS
.map(g => ({ ...g, items: visibleFor(g.items, role) }))
.filter(g => g.items.length > 0)
return (
<Layout userRole={role} userName={me ? `${me.first_name} ${me.last_name}` : ''}>
<div className='mb-6'>
<h1 className='text-2xl font-bold text-gray-800'>Einstellungen</h1>
<p className='text-sm text-gray-500 mt-1'>Konfiguration & Verwaltung von TimeMaster</p>
</div>
{groups.length === 0 ? (
<p className='text-gray-500'>Keine Einstellungen für deine Rolle verfügbar.</p>
) : (
<div className='space-y-8'>
{groups.map(group => (
<section key={group.title}>
<h2 className='text-xs font-semibold text-gray-400 uppercase tracking-wide mb-3'>
{group.title}
</h2>
<div className='grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3'>
{group.items.map(item => (
<Link
key={item.path}
to={item.path}
className='group bg-white rounded-xl border border-gray-200 p-4 hover:border-blue-300 hover:shadow-sm transition-all'
>
<p className='font-medium text-gray-800 group-hover:text-blue-700'>{item.label}</p>
{item.description && (
<p className='text-sm text-gray-500 mt-1 leading-snug'>{item.description}</p>
)}
</Link>
))}
</div>
</section>
))}
</div>
)}
</Layout>
)
}