Files
breakpilot-lehrer/website/app/admin/companion/_components/FeaturesTab.tsx
Benjamin Admin 6811264756 [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>
2026-04-24 23:17:30 +02:00

77 lines
3.0 KiB
TypeScript

'use client'
import type { Feature } from './types'
import { statusColors, priorityColors } from './types'
import { roadmapPhases } from './data'
interface FeaturesTabProps {
features: Feature[]
selectedPhase: string | null
setSelectedPhase: (phase: string | null) => void
updateFeatureStatus: (id: string, status: Feature['status']) => void
}
export default function FeaturesTab({ features, selectedPhase, setSelectedPhase, updateFeatureStatus }: FeaturesTabProps) {
return (
<div>
{/* Phase Filter */}
<div className="flex gap-2 mb-4 flex-wrap">
<button
onClick={() => setSelectedPhase(null)}
className={`px-3 py-1.5 rounded-lg text-sm font-medium transition-colors ${
!selectedPhase ? 'bg-primary-600 text-white' : 'bg-slate-100 text-slate-600 hover:bg-slate-200'
}`}
>
Alle
</button>
{roadmapPhases.map(phase => (
<button
key={phase.id}
onClick={() => setSelectedPhase(phase.id)}
className={`px-3 py-1.5 rounded-lg text-sm font-medium transition-colors ${
selectedPhase === phase.id ? 'bg-primary-600 text-white' : 'bg-slate-100 text-slate-600 hover:bg-slate-200'
}`}
>
{phase.name.replace('Phase ', 'P')}
</button>
))}
</div>
{/* Features List */}
<div className="space-y-2">
{features
.filter(f => !selectedPhase || f.phase === selectedPhase)
.map(feature => (
<div key={feature.id} className="flex items-center gap-4 p-3 bg-slate-50 rounded-lg">
<span className={`px-2 py-0.5 rounded text-xs font-medium ${priorityColors[feature.priority]}`}>
{feature.priority}
</span>
<div className="flex-1 min-w-0">
<div className="font-medium text-slate-900 truncate">{feature.title}</div>
<div className="text-xs text-slate-500 truncate">{feature.description}</div>
</div>
<span className={`px-2 py-1 rounded text-xs font-medium whitespace-nowrap ${
feature.effort === 'small' ? 'bg-green-100 text-green-700' :
feature.effort === 'medium' ? 'bg-amber-100 text-amber-700' :
feature.effort === 'large' ? 'bg-orange-100 text-orange-700' :
'bg-red-100 text-red-700'
}`}>
{feature.effort}
</span>
<select
value={feature.status}
onChange={(e) => updateFeatureStatus(feature.id, e.target.value as Feature['status'])}
className={`px-2 py-1 rounded text-xs font-medium border-0 cursor-pointer ${statusColors[feature.status]}`}
>
<option value="done">Fertig</option>
<option value="in_progress">In Arbeit</option>
<option value="todo">Todo</option>
<option value="backlog">Backlog</option>
</select>
</div>
))}
</div>
</div>
)
}