Phase 1 — Python (klausur-service): 5 monoliths → 36 files - dsfa_corpus_ingestion.py (1,828 LOC → 5 files) - cv_ocr_engines.py (2,102 LOC → 7 files) - cv_layout.py (3,653 LOC → 10 files) - vocab_worksheet_api.py (2,783 LOC → 8 files) - grid_build_core.py (1,958 LOC → 6 files) Phase 2 — Go (edu-search-service, school-service): 8 monoliths → 19 files - staff_crawler.go (1,402 → 4), policy/store.go (1,168 → 3) - policy_handlers.go (700 → 2), repository.go (684 → 2) - search.go (592 → 2), ai_extraction_handlers.go (554 → 2) - seed_data.go (591 → 2), grade_service.go (646 → 2) Phase 3 — TypeScript (admin-lehrer): 45 monoliths → 220+ files - sdk/types.ts (2,108 → 16 domain files) - ai/rag/page.tsx (2,686 → 14 files) - 22 page.tsx files split into _components/ + _hooks/ - 11 component files split into sub-components - 10 SDK data catalogs added to loc-exceptions - Deleted dead backup index_original.ts (4,899 LOC) All original public APIs preserved via re-export facades. Zero new errors: Python imports verified, Go builds clean, TypeScript tsc --noEmit shows only pre-existing errors. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
62 lines
1.8 KiB
TypeScript
62 lines
1.8 KiB
TypeScript
'use client'
|
|
|
|
import { useState, useEffect, useCallback } from 'react'
|
|
import type { EmailAccount, MailStats, SyncStatus } from './types'
|
|
|
|
export interface UseMailDataReturn {
|
|
stats: MailStats | null
|
|
accounts: EmailAccount[]
|
|
syncStatus: SyncStatus | null
|
|
loading: boolean
|
|
error: string | null
|
|
fetchData: () => Promise<void>
|
|
}
|
|
|
|
export function useMailData(): UseMailDataReturn {
|
|
const [stats, setStats] = useState<MailStats | null>(null)
|
|
const [accounts, setAccounts] = useState<EmailAccount[]>([])
|
|
const [syncStatus, setSyncStatus] = useState<SyncStatus | null>(null)
|
|
const [loading, setLoading] = useState(true)
|
|
const [error, setError] = useState<string | null>(null)
|
|
|
|
const fetchData = useCallback(async () => {
|
|
try {
|
|
setLoading(true)
|
|
|
|
// Fetch stats via our proxy API (avoids CORS/mixed-content issues)
|
|
const response = await fetch('/api/admin/mail')
|
|
|
|
if (response.ok) {
|
|
const data = await response.json()
|
|
setStats(data.stats)
|
|
setAccounts(data.accounts)
|
|
setSyncStatus(data.syncStatus)
|
|
setError(null)
|
|
} else {
|
|
const errorData = await response.json().catch(() => ({}))
|
|
throw new Error(errorData.details || `API returned ${response.status}`)
|
|
}
|
|
} catch (err) {
|
|
console.error('Failed to fetch mail data:', err)
|
|
setError('Verbindung zum Mail-Service (Mailpit) fehlgeschlagen. Laeuft Mailpit auf Port 8025?')
|
|
} finally {
|
|
setLoading(false)
|
|
}
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
fetchData()
|
|
|
|
// Refresh every 10 seconds if syncing
|
|
const interval = setInterval(() => {
|
|
if (syncStatus?.running) {
|
|
fetchData()
|
|
}
|
|
}, 10000)
|
|
|
|
return () => clearInterval(interval)
|
|
}, [fetchData, syncStatus?.running])
|
|
|
|
return { stats, accounts, syncStatus, loading, error, fetchData }
|
|
}
|