/** * useTrainingMetricsSSE Hook * * SSE (Server-Sent Events) hook for real-time training metrics. * Connects to the training metrics stream and provides live updates. */ 'use client' import { useState, useEffect, useCallback, useRef } from 'react' import type { TrainingStatus } from './training-metrics-types' /** * Custom hook for SSE-based training metrics */ export function useTrainingMetricsSSE( apiBase: string, jobId: string | null, onUpdate?: (status: TrainingStatus) => void ) { const [status, setStatus] = useState(null) const [connected, setConnected] = useState(false) const [error, setError] = useState(null) const eventSourceRef = useRef(null) useEffect(() => { if (!jobId) return const url = `${apiBase}/api/klausur/trocr/training/metrics/stream?job_id=${jobId}` const eventSource = new EventSource(url) eventSourceRef.current = eventSource eventSource.onopen = () => { setConnected(true) setError(null) } eventSource.onmessage = (event) => { try { const data = JSON.parse(event.data) as TrainingStatus setStatus(data) onUpdate?.(data) // Close connection when training is done if (data.status === 'completed' || data.status === 'failed' || data.status === 'cancelled') { eventSource.close() setConnected(false) } } catch (e) { console.error('Failed to parse SSE message:', e) } } eventSource.onerror = () => { setError('Verbindung zum Server verloren') setConnected(false) eventSource.close() } return () => { eventSource.close() setConnected(false) } }, [apiBase, jobId, onUpdate]) const disconnect = useCallback(() => { eventSourceRef.current?.close() setConnected(false) }, []) return { status, connected, error, disconnect } }