Files
breakpilot-lehrer/website/app/admin/compliance/modules/_components/useModulesPage.ts
Benjamin Admin 34da9f4cda [split-required] Split 700-870 LOC files across all services
backend-lehrer (11 files):
- llm_gateway/routes/schools.py (867 → 5), recording_api.py (848 → 6)
- messenger_api.py (840 → 5), print_generator.py (824 → 5)
- unit_analytics_api.py (751 → 5), classroom/routes/context.py (726 → 4)
- llm_gateway/routes/edu_search_seeds.py (710 → 4)

klausur-service (12 files):
- ocr_labeling_api.py (845 → 4), metrics_db.py (833 → 4)
- legal_corpus_api.py (790 → 4), page_crop.py (758 → 3)
- mail/ai_service.py (747 → 4), github_crawler.py (767 → 3)
- trocr_service.py (730 → 4), full_compliance_pipeline.py (723 → 4)
- dsfa_rag_api.py (715 → 4), ocr_pipeline_auto.py (705 → 4)

website (6 pages):
- audit-checklist (867 → 8), content (806 → 6)
- screen-flow (790 → 4), scraper (789 → 5)
- zeugnisse (776 → 5), modules (745 → 4)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-25 08:01:18 +02:00

111 lines
4.9 KiB
TypeScript

'use client'
import { useState, useEffect } from 'react'
import { ServiceModule, ModulesOverview, RiskAssessment } from './types'
const BACKEND_URL = process.env.NEXT_PUBLIC_BACKEND_URL || 'http://localhost:8000'
const API_BASE = `${BACKEND_URL}/api/v1/compliance`
export function useModulesPage() {
const [modules, setModules] = useState<ServiceModule[]>([])
const [overview, setOverview] = useState<ModulesOverview | null>(null)
const [loading, setLoading] = useState(true)
const [error, setError] = useState<string | null>(null)
const [typeFilter, setTypeFilter] = useState<string>('all')
const [criticalityFilter, setCriticalityFilter] = useState<string>('all')
const [piiFilter, setPiiFilter] = useState<boolean | null>(null)
const [aiFilter, setAiFilter] = useState<boolean | null>(null)
const [searchTerm, setSearchTerm] = useState('')
const [selectedModule, setSelectedModule] = useState<ServiceModule | null>(null)
const [loadingDetail, setLoadingDetail] = useState(false)
const [riskAssessment, setRiskAssessment] = useState<RiskAssessment | null>(null)
const [loadingRisk, setLoadingRisk] = useState(false)
const [showRiskPanel, setShowRiskPanel] = useState(false)
useEffect(() => { fetchModules(); fetchOverview() }, [])
const fetchModules = async () => {
try {
setLoading(true)
const params = new URLSearchParams()
if (typeFilter !== 'all') params.append('service_type', typeFilter)
if (criticalityFilter !== 'all') params.append('criticality', criticalityFilter)
if (piiFilter !== null) params.append('processes_pii', String(piiFilter))
if (aiFilter !== null) params.append('ai_components', String(aiFilter))
const url = `${API_BASE}/modules${params.toString() ? '?' + params.toString() : ''}`
const res = await fetch(url)
if (!res.ok) throw new Error('Failed to fetch modules')
const data = await res.json()
setModules(data.modules || [])
} catch (err) {
setError(err instanceof Error ? err.message : 'Unknown error')
} finally { setLoading(false) }
}
const fetchOverview = async () => {
try {
const res = await fetch(`${API_BASE}/modules/overview`)
if (!res.ok) throw new Error('Failed to fetch overview')
const data = await res.json()
setOverview(data)
} catch (err) { console.error('Failed to fetch overview:', err) }
}
const fetchModuleDetail = async (moduleId: string) => {
try {
setLoadingDetail(true)
const res = await fetch(`${API_BASE}/modules/${moduleId}`)
if (!res.ok) throw new Error('Failed to fetch module details')
const data = await res.json()
setSelectedModule(data)
} catch (err) { console.error('Failed to fetch module details:', err) }
finally { setLoadingDetail(false) }
}
const seedModules = async (force: boolean = false) => {
try {
const res = await fetch(`${API_BASE}/modules/seed`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ force }) })
if (!res.ok) throw new Error('Failed to seed modules')
const data = await res.json()
alert(`Seeded ${data.modules_created} modules with ${data.mappings_created} regulation mappings`)
fetchModules(); fetchOverview()
} catch (err) { alert('Failed to seed modules: ' + (err instanceof Error ? err.message : 'Unknown error')) }
}
const assessModuleRisk = async (moduleId: string) => {
setLoadingRisk(true); setShowRiskPanel(true); setRiskAssessment(null)
try {
const res = await fetch(`${API_BASE}/ai/assess-risk`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ module_id: moduleId }) })
if (res.ok) { const data = await res.json(); setRiskAssessment(data) }
else { alert('AI-Risikobewertung fehlgeschlagen') }
} catch (err) { alert('Netzwerkfehler bei AI-Risikobewertung') }
finally { setLoadingRisk(false) }
}
const filteredModules = modules.filter(m => {
if (!searchTerm) return true
const term = searchTerm.toLowerCase()
return m.name.toLowerCase().includes(term) || m.display_name.toLowerCase().includes(term) || (m.description && m.description.toLowerCase().includes(term)) || m.technology_stack.some(t => t.toLowerCase().includes(term))
})
const modulesByType = filteredModules.reduce((acc, m) => {
const type = m.service_type || 'unknown'
if (!acc[type]) acc[type] = []
acc[type].push(m)
return acc
}, {} as Record<string, ServiceModule[]>)
return {
modules, overview, loading, error,
typeFilter, setTypeFilter, criticalityFilter, setCriticalityFilter,
piiFilter, setPiiFilter, aiFilter, setAiFilter, searchTerm, setSearchTerm,
selectedModule, setSelectedModule, loadingDetail,
riskAssessment, loadingRisk, showRiskPanel, setShowRiskPanel,
filteredModules, modulesByType,
fetchModules, fetchModuleDetail, seedModules, assessModuleRisk,
}
}