2026-09-16 14:17:25 +02:00
|
|
|
import { useEffect } from 'react'
|
|
|
|
|
import { Routes, Route, NavLink, Navigate, useLocation } from 'react-router-dom'
|
2026-07-02 10:10:06 +02:00
|
|
|
import Dashboard from './pages/Dashboard'
|
|
|
|
|
import Configuration from './pages/Configuration'
|
|
|
|
|
import Consultants from './pages/Consultants'
|
|
|
|
|
import AssignmentCreate from './pages/AssignmentCreate'
|
|
|
|
|
import AssignmentDetail from './pages/AssignmentDetail'
|
|
|
|
|
import AssignmentEdit from './pages/AssignmentEdit'
|
2026-07-13 12:45:35 +02:00
|
|
|
import AssignmentTrash from './pages/AssignmentTrash'
|
|
|
|
|
import AssignmentArchive from './pages/AssignmentArchive'
|
|
|
|
|
import MeetingHistory from './pages/MeetingHistory'
|
2026-07-02 10:30:46 +02:00
|
|
|
import MeetingView from './pages/meeting/MeetingView'
|
2026-07-02 10:10:06 +02:00
|
|
|
import FeedbackDraftPage from './pages/FeedbackDraftPage'
|
|
|
|
|
import AssignmentFeedbackPage from './pages/AssignmentFeedbackPage'
|
|
|
|
|
import Evaluation from './pages/Evaluation'
|
2026-09-16 14:17:25 +02:00
|
|
|
import ConsultantDetailPage from './pages/ConsultantDetail'
|
|
|
|
|
|
|
|
|
|
function headerContext(pathname: string): string {
|
|
|
|
|
if (pathname.startsWith('/config')) return 'Einstellungen'
|
|
|
|
|
if (pathname.startsWith('/consultants')) return 'Personen'
|
|
|
|
|
if (pathname.startsWith('/evaluation') || pathname.startsWith('/feedbacks')) return 'Feedbacks'
|
|
|
|
|
if (pathname.startsWith('/assignments/trash')) return 'Papierkorb'
|
|
|
|
|
if (pathname.startsWith('/assignments/archive')) return 'Archiv'
|
|
|
|
|
if (/\/meeting\//.test(pathname)) return 'Meeting'
|
|
|
|
|
if (/\/history$/.test(pathname)) return 'Gesamtprotokoll'
|
|
|
|
|
if (/\/feedback/.test(pathname)) return 'Feedback'
|
|
|
|
|
if (pathname.startsWith('/assignment')) return 'Assignment'
|
|
|
|
|
return 'Assignments'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const NAV = [
|
|
|
|
|
{ to: '/', label: 'Assignments', end: true },
|
|
|
|
|
{ to: '/feedbacks', label: 'Feedbacks', end: false },
|
|
|
|
|
{ to: '/consultants', label: 'Personen', end: false },
|
|
|
|
|
{ to: '/config', label: 'Einstellungen', end: false },
|
|
|
|
|
] as const
|
2026-07-02 10:10:06 +02:00
|
|
|
|
|
|
|
|
export default function App() {
|
2026-09-16 14:17:25 +02:00
|
|
|
const { pathname } = useLocation()
|
|
|
|
|
const wideLayout =
|
|
|
|
|
pathname === '/' ||
|
|
|
|
|
pathname.startsWith('/feedbacks') ||
|
|
|
|
|
pathname.startsWith('/evaluation') ||
|
|
|
|
|
pathname.startsWith('/consultants') ||
|
|
|
|
|
/\/meeting\/|\/history$/.test(pathname)
|
|
|
|
|
const context = headerContext(pathname)
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
document.title = context === 'Assignments'
|
|
|
|
|
? 'Assignment Monitor'
|
|
|
|
|
: `${context} · Assignment Monitor`
|
|
|
|
|
}, [context])
|
|
|
|
|
|
2026-07-02 10:10:06 +02:00
|
|
|
return (
|
2026-09-16 14:17:25 +02:00
|
|
|
<div className="min-h-dvh bg-app flex flex-col font-sans text-ink">
|
|
|
|
|
<header className="bg-brand text-white px-4 py-3 flex items-center gap-3 shrink-0 shadow-[var(--shadow-header)]">
|
|
|
|
|
<div className="min-w-0 flex-1">
|
|
|
|
|
<div className="font-bold text-lg tracking-tight leading-tight truncate">
|
|
|
|
|
Assignment Monitor
|
|
|
|
|
</div>
|
|
|
|
|
<div className="text-xs text-white/80 mt-0.5 truncate">{context}</div>
|
|
|
|
|
</div>
|
2026-07-02 10:10:06 +02:00
|
|
|
</header>
|
2026-09-16 14:17:25 +02:00
|
|
|
|
|
|
|
|
<main
|
|
|
|
|
className={`flex-1 w-full mx-auto px-4 pt-4 pb-24 ${
|
|
|
|
|
wideLayout ? 'max-w-6xl' : 'max-w-2xl'
|
|
|
|
|
}`}
|
|
|
|
|
>
|
2026-07-02 10:10:06 +02:00
|
|
|
<Routes>
|
|
|
|
|
<Route path="/" element={<Dashboard />} />
|
|
|
|
|
<Route path="/assignment/new" element={<AssignmentCreate />} />
|
2026-07-13 12:45:35 +02:00
|
|
|
<Route path="/assignments/trash" element={<AssignmentTrash />} />
|
|
|
|
|
<Route path="/assignments/archive" element={<AssignmentArchive />} />
|
2026-07-02 10:10:06 +02:00
|
|
|
<Route path="/assignment/:id" element={<AssignmentDetail />} />
|
|
|
|
|
<Route path="/assignment/:id/edit" element={<AssignmentEdit />} />
|
2026-07-13 12:45:35 +02:00
|
|
|
<Route path="/assignment/:id/history" element={<MeetingHistory />} />
|
2026-07-02 10:10:06 +02:00
|
|
|
<Route path="/assignment/:id/meeting/:meetingId" element={<MeetingView />} />
|
|
|
|
|
<Route path="/assignment/:id/feedback/:instituteeId" element={<AssignmentFeedbackPage />} />
|
|
|
|
|
<Route path="/assignment/:id/feedback-draft/:instituteeId" element={<FeedbackDraftPage />} />
|
2026-09-16 14:17:25 +02:00
|
|
|
<Route path="/feedbacks" element={<Evaluation />} />
|
|
|
|
|
<Route path="/evaluation" element={<Navigate to="/feedbacks" replace />} />
|
2026-07-02 10:10:06 +02:00
|
|
|
<Route path="/consultants" element={<Consultants />} />
|
2026-09-16 14:17:25 +02:00
|
|
|
<Route path="/consultants/:id" element={<ConsultantDetailPage />} />
|
2026-07-02 10:10:06 +02:00
|
|
|
<Route path="/config" element={<Configuration />} />
|
|
|
|
|
</Routes>
|
|
|
|
|
</main>
|
2026-09-16 14:17:25 +02:00
|
|
|
|
|
|
|
|
<nav
|
|
|
|
|
className="fixed bottom-0 inset-x-0 z-20 bg-surface border-t border-line shadow-[var(--shadow-nav)]"
|
|
|
|
|
aria-label="Hauptnavigation"
|
|
|
|
|
>
|
|
|
|
|
<div className={`mx-auto flex justify-around px-1 pt-1 pb-[max(0.35rem,env(safe-area-inset-bottom))] ${
|
|
|
|
|
wideLayout ? 'max-w-6xl' : 'max-w-2xl'
|
|
|
|
|
}`}>
|
|
|
|
|
{NAV.map(({ to, label, end }) => (
|
|
|
|
|
<NavLink
|
|
|
|
|
key={to}
|
|
|
|
|
to={to}
|
|
|
|
|
end={end}
|
|
|
|
|
className={({ isActive }) =>
|
|
|
|
|
[
|
|
|
|
|
'flex-1 min-h-11 max-w-[7.5rem] mx-0.5 flex items-center justify-center',
|
|
|
|
|
'rounded-[var(--radius-control)] px-2 text-[11px] sm:text-xs font-medium leading-tight text-center',
|
|
|
|
|
'transition-colors',
|
|
|
|
|
isActive
|
|
|
|
|
? 'bg-brand-soft text-brand font-semibold'
|
|
|
|
|
: 'text-ink-muted hover:text-ink hover:bg-app',
|
|
|
|
|
].join(' ')
|
|
|
|
|
}
|
|
|
|
|
>
|
|
|
|
|
{label}
|
|
|
|
|
</NavLink>
|
|
|
|
|
))}
|
|
|
|
|
</div>
|
2026-07-02 10:10:06 +02:00
|
|
|
</nav>
|
|
|
|
|
</div>
|
|
|
|
|
)
|
|
|
|
|
}
|