[split-required] Split final batch of monoliths >1000 LOC
Python (6 files in klausur-service): - rbac.py (1,132 → 4), admin_api.py (1,012 → 4) - routes/eh.py (1,111 → 4), ocr_pipeline_geometry.py (1,105 → 5) Python (2 files in backend-lehrer): - unit_api.py (1,226 → 6), game_api.py (1,129 → 5) Website (6 page files): - 4x klausur-korrektur pages (1,249-1,328 LOC each) → shared components in website/components/klausur-korrektur/ (17 shared files) - companion (1,057 → 10), magic-help (1,017 → 8) All re-export barrels preserve backward compatibility. Zero import errors verified. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
69
website/components/klausur-korrektur/ListTabNav.tsx
Normal file
69
website/components/klausur-korrektur/ListTabNav.tsx
Normal file
@@ -0,0 +1,69 @@
|
||||
'use client'
|
||||
|
||||
/**
|
||||
* Tab navigation bar for the Klausur-Korrektur list page.
|
||||
*/
|
||||
|
||||
import type { TabId } from './list-types'
|
||||
|
||||
interface TabDef {
|
||||
id: TabId
|
||||
name: string
|
||||
icon: JSX.Element
|
||||
hidden?: boolean
|
||||
}
|
||||
|
||||
const tabs: TabDef[] = [
|
||||
{
|
||||
id: 'willkommen', name: 'Start',
|
||||
icon: <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" /></svg>,
|
||||
},
|
||||
{
|
||||
id: 'klausuren', name: 'Klausuren',
|
||||
icon: <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" /></svg>,
|
||||
},
|
||||
{
|
||||
id: 'erstellen', name: 'Neue Klausur',
|
||||
icon: <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 4v16m8-8H4" /></svg>,
|
||||
},
|
||||
{
|
||||
id: 'direktupload', name: 'Schnellstart', hidden: true,
|
||||
icon: <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" /></svg>,
|
||||
},
|
||||
{
|
||||
id: 'statistiken', name: 'Statistiken',
|
||||
icon: <svg className="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" /></svg>,
|
||||
},
|
||||
]
|
||||
|
||||
interface ListTabNavProps {
|
||||
activeTab: TabId
|
||||
onTabChange: (tab: TabId) => void
|
||||
markAsVisited: () => void
|
||||
}
|
||||
|
||||
export default function ListTabNav({ activeTab, onTabChange, markAsVisited }: ListTabNavProps) {
|
||||
return (
|
||||
<div className="border-b border-slate-200 mb-6">
|
||||
<nav className="flex gap-4">
|
||||
{tabs.filter(tab => !tab.hidden).map((tab) => (
|
||||
<button
|
||||
key={tab.id}
|
||||
onClick={() => {
|
||||
if (tab.id !== 'willkommen') markAsVisited()
|
||||
onTabChange(tab.id)
|
||||
}}
|
||||
className={`flex items-center gap-2 px-4 py-3 text-sm font-medium border-b-2 transition-colors ${
|
||||
activeTab === tab.id
|
||||
? 'border-primary-500 text-primary-600'
|
||||
: 'border-transparent text-slate-500 hover:text-slate-700 hover:border-slate-300'
|
||||
}`}
|
||||
>
|
||||
{tab.icon}
|
||||
{tab.name}
|
||||
</button>
|
||||
))}
|
||||
</nav>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user