backend-lehrer (10 files): - game/database.py (785 → 5), correction_api.py (683 → 4) - classroom_engine/antizipation.py (676 → 5) - llm_gateway schools/edu_search already done in prior batch klausur-service (12 files): - orientation_crop_api.py (694 → 5), pdf_export.py (677 → 4) - zeugnis_crawler.py (676 → 5), grid_editor_api.py (671 → 5) - eh_templates.py (658 → 5), mail/api.py (651 → 5) - qdrant_service.py (638 → 5), training_api.py (625 → 4) website (6 pages): - middleware (696 → 8), mail (733 → 6), consent (628 → 8) - compliance/risks (622 → 5), export (502 → 5), brandbook (629 → 7) studio-v2 (3 components): - B2BMigrationWizard (848 → 3), CleanupPanel (765 → 2) - dashboard-experimental (739 → 2) admin-lehrer (4 files): - uebersetzungen (769 → 4), manager (670 → 2) - ChunkBrowserQA (675 → 6), dsfa/page (674 → 5) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
129 lines
4.1 KiB
TypeScript
129 lines
4.1 KiB
TypeScript
'use client'
|
|
|
|
import { useState, useEffect } from 'react'
|
|
import type { MiddlewareConfig, RateLimitIP, MiddlewareEvent, MiddlewareStats, TabType, MiddlewareHookReturn } from './types'
|
|
|
|
const BACKEND_URL = process.env.NEXT_PUBLIC_BACKEND_URL || 'http://localhost:8000'
|
|
|
|
export function useMiddleware(): MiddlewareHookReturn {
|
|
const [activeTab, setActiveTab] = useState<TabType>('overview')
|
|
const [configs, setConfigs] = useState<MiddlewareConfig[]>([])
|
|
const [ipList, setIpList] = useState<RateLimitIP[]>([])
|
|
const [events, setEvents] = useState<MiddlewareEvent[]>([])
|
|
const [stats, setStats] = useState<MiddlewareStats[]>([])
|
|
const [loading, setLoading] = useState(true)
|
|
const [saving, setSaving] = useState(false)
|
|
const [newIP, setNewIP] = useState({ ip_address: '', list_type: 'whitelist', reason: '' })
|
|
|
|
useEffect(() => {
|
|
loadData()
|
|
}, [])
|
|
|
|
const loadData = async () => {
|
|
setLoading(true)
|
|
try {
|
|
const [configsRes, ipListRes, eventsRes, statsRes] = await Promise.all([
|
|
fetch(`${BACKEND_URL}/api/admin/middleware`),
|
|
fetch(`${BACKEND_URL}/api/admin/middleware/rate-limit/ip-list`),
|
|
fetch(`${BACKEND_URL}/api/admin/middleware/events?limit=50`),
|
|
fetch(`${BACKEND_URL}/api/admin/middleware/stats`),
|
|
])
|
|
|
|
if (configsRes.ok) setConfigs(await configsRes.json())
|
|
if (ipListRes.ok) setIpList(await ipListRes.json())
|
|
if (eventsRes.ok) setEvents(await eventsRes.json())
|
|
if (statsRes.ok) setStats(await statsRes.json())
|
|
} catch (error) {
|
|
console.error('Failed to load middleware data:', error)
|
|
} finally {
|
|
setLoading(false)
|
|
}
|
|
}
|
|
|
|
const toggleMiddleware = async (name: string, enabled: boolean) => {
|
|
setSaving(true)
|
|
try {
|
|
const res = await fetch(`${BACKEND_URL}/api/admin/middleware/${name}`, {
|
|
method: 'PUT',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ enabled }),
|
|
})
|
|
if (res.ok) {
|
|
setConfigs(configs.map(c => c.middleware_name === name ? { ...c, enabled } : c))
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to update middleware:', error)
|
|
} finally {
|
|
setSaving(false)
|
|
}
|
|
}
|
|
|
|
const updateConfig = async (name: string, config: Record<string, any>) => {
|
|
setSaving(true)
|
|
try {
|
|
const res = await fetch(`${BACKEND_URL}/api/admin/middleware/${name}`, {
|
|
method: 'PUT',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ config }),
|
|
})
|
|
if (res.ok) {
|
|
const updated = await res.json()
|
|
setConfigs(configs.map(c => c.middleware_name === name ? updated : c))
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to update config:', error)
|
|
} finally {
|
|
setSaving(false)
|
|
}
|
|
}
|
|
|
|
const addIP = async () => {
|
|
if (!newIP.ip_address) return
|
|
setSaving(true)
|
|
try {
|
|
const res = await fetch(`${BACKEND_URL}/api/admin/middleware/rate-limit/ip-list`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(newIP),
|
|
})
|
|
if (res.ok) {
|
|
const added = await res.json()
|
|
setIpList([added, ...ipList])
|
|
setNewIP({ ip_address: '', list_type: 'whitelist', reason: '' })
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to add IP:', error)
|
|
} finally {
|
|
setSaving(false)
|
|
}
|
|
}
|
|
|
|
const removeIP = async (id: string) => {
|
|
setSaving(true)
|
|
try {
|
|
const res = await fetch(`${BACKEND_URL}/api/admin/middleware/rate-limit/ip-list/${id}`, {
|
|
method: 'DELETE',
|
|
})
|
|
if (res.ok) {
|
|
setIpList(ipList.filter(ip => ip.id !== id))
|
|
}
|
|
} catch (error) {
|
|
console.error('Failed to remove IP:', error)
|
|
} finally {
|
|
setSaving(false)
|
|
}
|
|
}
|
|
|
|
const getConfig = (name: string) => configs.find(c => c.middleware_name === name)
|
|
const getStats = (name: string) => stats.find(s => s.middleware_name === name)
|
|
|
|
return {
|
|
activeTab, setActiveTab,
|
|
configs, ipList, events, stats,
|
|
loading, saving,
|
|
newIP, setNewIP,
|
|
loadData, toggleMiddleware, updateConfig, addIP, removeIP,
|
|
getConfig, getStats,
|
|
}
|
|
}
|