import React, { useState, useEffect } from 'react'
import { Eye, Play, History } from 'lucide-react'
import api from '../utils/api'
import AdminPageNav from '../components/AdminPageNav'
import PageSectionNav from '../components/PageSectionNav'
const WIKI_IMPORT_TABS = [
{ id: 'preview', label: 'Vorschau', icon: Eye },
{ id: 'execute', label: 'Ausführen', icon: Play },
{ id: 'history', label: 'Historie', icon: History },
]
export default function MediaWikiImportPage() {
const [activeTab, setActiveTab] = useState('preview')
const [loading, setLoading] = useState(false)
const [error, setError] = useState(null)
// Preview Tab State
const [previewCategory, setPreviewCategory] = useState('Übungen')
const [previewType, setPreviewType] = useState('exercise')
const [previewLimit, setPreviewLimit] = useState(10)
const [previewData, setPreviewData] = useState(null)
// Execute Tab State
const [executeCategory, setExecuteCategory] = useState('Übungen')
const [executeType, setExecuteType] = useState('exercise')
const [executeReimport, setExecuteReimport] = useState(false)
const [executeDryRun, setExecuteDryRun] = useState(false)
const [executeLimit, setExecuteLimit] = useState(null)
const [currentImport, setCurrentImport] = useState(null)
const [pollingInterval, setPollingInterval] = useState(null)
// History Tab State
const [logs, setLogs] = useState([])
// Load logs on mount and tab switch
useEffect(() => {
if (activeTab === 'history') {
loadLogs()
}
}, [activeTab])
// Polling cleanup
useEffect(() => {
return () => {
if (pollingInterval) {
clearInterval(pollingInterval)
}
}
}, [pollingInterval])
const loadLogs = async () => {
try {
setLoading(true)
const data = await api.listMediaWikiImportLogs()
setLogs(data)
} catch (err) {
setError(err.message)
} finally {
setLoading(false)
}
}
const handlePreview = async () => {
try {
setLoading(true)
setError(null)
const data = await api.previewMediaWikiImport(previewCategory, previewType, previewLimit)
setPreviewData(data)
} catch (err) {
setError(err.message)
} finally {
setLoading(false)
}
}
const handleExecute = async () => {
try {
setLoading(true)
setError(null)
const result = await api.executeMediaWikiImport({
category: executeCategory,
import_type: executeType,
reimport_existing: executeReimport,
dry_run: executeDryRun,
limit: executeLimit || null
})
setCurrentImport(result)
// Start polling
const interval = setInterval(async () => {
try {
const status = await api.getMediaWikiImportStatus(result.log_id)
setCurrentImport(status)
if (status.import_status === 'completed' || status.import_status === 'failed') {
clearInterval(interval)
setPollingInterval(null)
setLoading(false)
}
} catch (err) {
console.error('Polling error:', err)
}
}, 2000)
setPollingInterval(interval)
} catch (err) {
setError(err.message)
setLoading(false)
}
}
return (
MediaWiki Import (Semantic MediaWiki)
Importiere Übungen, Fähigkeiten und Methoden aus karatetrainer.net
{/* Error Display */}
{error && (
Fehler: {error}
)}
{/* Preview Tab */}
{activeTab === 'preview' && (
Import-Vorschau
setPreviewCategory(e.target.value)}
placeholder="Übungen"
style={{
width: '100%',
padding: '12px',
fontSize: '16px',
border: '1px solid var(--border)',
borderRadius: '8px'
}}
/>
setPreviewLimit(Math.min(500, Math.max(1, parseInt(e.target.value) || 10)))}
min="1"
max="500"
style={{
width: '100%',
padding: '12px',
fontSize: '16px',
border: '1px solid var(--border)',
borderRadius: '8px'
}}
/>
{/* Preview Results */}
{previewData && (
{previewData.total_found} Einträge gefunden in Kategorie "{previewData.category}"
{previewData.preview.map((item, idx) => (
0 ? '#C00' : item.warnings.length > 0 ? '#F90' : 'var(--border)'}`
}}
>
{item.already_imported && '✅ '}
{item.wiki_page_title}
{item.errors.length > 0 && ' ❌'}
{item.warnings.length > 0 && ' ⚠️'}
{item.already_imported && (
Bereits importiert: {new Date(item.last_imported_at).toLocaleString('de-DE')}
)}
{item.warnings.length > 0 && (
Warnungen:
{item.warnings.map((w, i) => - {w}
)}
)}
{item.errors.length > 0 && (
Fehler:
{item.errors.map((e, i) => - {e}
)}
)}
Gemappte Felder anzeigen
{JSON.stringify(item.mapped_fields, null, 2)}
))}
)}
)}
{/* Execute Tab */}
{activeTab === 'execute' && (
Import ausführen
setExecuteCategory(e.target.value)}
placeholder="Übungen"
style={{
width: '100%',
padding: '12px',
fontSize: '16px',
border: '1px solid var(--border)',
borderRadius: '8px'
}}
/>
{
const val = e.target.value ? parseInt(e.target.value) : null
setExecuteLimit(val ? Math.min(500, Math.max(1, val)) : null)
}}
placeholder="Kein Limit (max 500)"
min="1"
max="500"
style={{
width: '100%',
padding: '12px',
fontSize: '16px',
border: '1px solid var(--border)',
borderRadius: '8px'
}}
/>
{/* Import Status */}
{currentImport && (
{currentImport.import_status === 'running' && '⏳ Import läuft...'}
{currentImport.import_status === 'completed' && '✅ Import abgeschlossen'}
{currentImport.import_status === 'failed' && '❌ Import fehlgeschlagen'}
Log ID: {currentImport.id}
Kategorie: {currentImport.category}
Typ: {currentImport.import_type}
Total: {currentImport.items_total}
✅ Importiert: {currentImport.items_imported}
⏭️ Übersprungen: {currentImport.items_skipped}
❌ Fehlgeschlagen: {currentImport.items_failed}
{currentImport.started_at && (
Gestartet: {new Date(currentImport.started_at).toLocaleString('de-DE')}
)}
{currentImport.finished_at && (
Beendet: {new Date(currentImport.finished_at).toLocaleString('de-DE')}
)}
{currentImport.error_log && currentImport.error_log.length > 0 && (
❌ Fehler anzeigen ({currentImport.error_log.length})
{currentImport.error_log.map((err, idx) => (
{err.item}: {err.error}
))}
)}
)}
)}
{/* History Tab */}
{activeTab === 'history' && (
Import-Historie
{logs.length === 0 && !loading && (
Noch keine Imports durchgeführt
)}
{logs.map((log) => (
{log.import_status === 'completed' && '✅ '}
{log.import_status === 'failed' && '❌ '}
{log.import_status === 'running' && '⏳ '}
{log.category} ({log.import_type})
{log.dry_run && ' [Dry-Run]'}
{new Date(log.started_at).toLocaleString('de-DE')}
✅ {log.items_imported}
{' | '}
⏭️ {log.items_skipped}
{' | '}
❌ {log.items_failed}
{' | '}
Total: {log.items_total}
))}
)}
)
}