[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:
97
website/app/admin/companion/_components/useCompanionDev.ts
Normal file
97
website/app/admin/companion/_components/useCompanionDev.ts
Normal file
@@ -0,0 +1,97 @@
|
||||
'use client'
|
||||
|
||||
import { useState, useEffect } from 'react'
|
||||
import type { Feature, TeacherFeedback } from './types'
|
||||
import { initialFeatures, initialFeedback, roadmapPhases } from './data'
|
||||
|
||||
// Data version - increment when adding new features/feedback to force refresh
|
||||
const DATA_VERSION = '8.2.0' // Phase 8e: Frontend UI-Komponenten (ContextBar, Sidebar, PathPanel)
|
||||
|
||||
export function useCompanionDev() {
|
||||
const [features, setFeatures] = useState<Feature[]>(initialFeatures)
|
||||
const [feedback, setFeedback] = useState<TeacherFeedback[]>(initialFeedback)
|
||||
const [activeTab, setActiveTab] = useState<'roadmap' | 'features' | 'feedback' | 'backlog'>('roadmap')
|
||||
const [selectedPhase, setSelectedPhase] = useState<string | null>(null)
|
||||
const [feedbackFilter, setFeedbackFilter] = useState<string>('all')
|
||||
|
||||
// Load from localStorage with version check
|
||||
useEffect(() => {
|
||||
const savedVersion = localStorage.getItem('companion-dev-version')
|
||||
const savedFeatures = localStorage.getItem('companion-dev-features')
|
||||
const savedFeedback = localStorage.getItem('companion-dev-feedback')
|
||||
|
||||
// If version mismatch or no version, use initial data and save new version
|
||||
if (savedVersion !== DATA_VERSION) {
|
||||
console.log(`Companion Dev: Data version updated from ${savedVersion} to ${DATA_VERSION}`)
|
||||
localStorage.setItem('companion-dev-version', DATA_VERSION)
|
||||
localStorage.setItem('companion-dev-features', JSON.stringify(initialFeatures))
|
||||
localStorage.setItem('companion-dev-feedback', JSON.stringify(initialFeedback))
|
||||
// State already initialized with initialFeatures/initialFeedback, no need to setFeatures
|
||||
return
|
||||
}
|
||||
|
||||
// Load saved data if version matches
|
||||
if (savedFeatures) setFeatures(JSON.parse(savedFeatures))
|
||||
if (savedFeedback) setFeedback(JSON.parse(savedFeedback))
|
||||
}, [])
|
||||
|
||||
// Save to localStorage
|
||||
useEffect(() => {
|
||||
localStorage.setItem('companion-dev-features', JSON.stringify(features))
|
||||
}, [features])
|
||||
|
||||
useEffect(() => {
|
||||
localStorage.setItem('companion-dev-feedback', JSON.stringify(feedback))
|
||||
}, [feedback])
|
||||
|
||||
const getPhaseStats = () => {
|
||||
const total = roadmapPhases.length
|
||||
const completed = roadmapPhases.filter(p => p.status === 'completed').length
|
||||
const inProgress = roadmapPhases.filter(p => p.status === 'in_progress').length
|
||||
return { total, completed, inProgress }
|
||||
}
|
||||
|
||||
const getFeatureStats = () => {
|
||||
const total = features.length
|
||||
const done = features.filter(f => f.status === 'done').length
|
||||
const inProgress = features.filter(f => f.status === 'in_progress').length
|
||||
return { total, done, inProgress, percentage: Math.round((done / total) * 100) }
|
||||
}
|
||||
|
||||
const getFeedbackStats = () => {
|
||||
const total = feedback.length
|
||||
const newCount = feedback.filter(f => f.status === 'new').length
|
||||
const bugs = feedback.filter(f => f.type === 'bug').length
|
||||
const requests = feedback.filter(f => f.type === 'feature_request').length
|
||||
return { total, newCount, bugs, requests }
|
||||
}
|
||||
|
||||
const updateFeatureStatus = (id: string, status: Feature['status']) => {
|
||||
setFeatures(features.map(f => f.id === id ? { ...f, status } : f))
|
||||
}
|
||||
|
||||
const updateFeedbackStatus = (id: string, status: TeacherFeedback['status']) => {
|
||||
setFeedback(feedback.map(f => f.id === id ? { ...f, status } : f))
|
||||
}
|
||||
|
||||
const filteredFeedback = feedbackFilter === 'all'
|
||||
? feedback
|
||||
: feedback.filter(f => f.type === feedbackFilter || f.status === feedbackFilter)
|
||||
|
||||
return {
|
||||
features,
|
||||
feedback,
|
||||
activeTab,
|
||||
setActiveTab,
|
||||
selectedPhase,
|
||||
setSelectedPhase,
|
||||
feedbackFilter,
|
||||
setFeedbackFilter,
|
||||
phaseStats: getPhaseStats(),
|
||||
featureStats: getFeatureStats(),
|
||||
feedbackStats: getFeedbackStats(),
|
||||
updateFeatureStatus,
|
||||
updateFeedbackStatus,
|
||||
filteredFeedback,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user