import React, { useState, useEffect } from 'react' import api from '../utils/api' import AdminPageNav from '../components/AdminPageNav' 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

{/* Tabs */}
{['preview', 'execute', 'history'].map(tab => ( ))}
{/* 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(parseInt(e.target.value) || 10)} min="1" max="100" 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' }} />
setExecuteLimit(e.target.value ? parseInt(e.target.value) : null)} placeholder="Kein Limit" min="1" 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}
))}
)}
) }