'use client'
import {
Source, ScraperStatus, ScrapeResult,
PDFDocument, PDFExtractionResult,
} from './types'
import SourceCard from './SourceCard'
interface ScraperTabsProps {
activeTab: string
sources: Source[]
pdfDocuments: PDFDocument[]
status: ScraperStatus | null
scraping: boolean
extracting: boolean
results: ScrapeResult[]
pdfResult: PDFExtractionResult | null
handleScrapeAll: () => void
handleScrapeSingle: (code: string, force: boolean) => void
handleExtractPdf: (code: string, saveToDb: boolean, force: boolean) => void
}
export default function ScraperTabs(props: ScraperTabsProps) {
const { activeTab, sources, pdfDocuments, status, scraping, extracting, results, pdfResult } = props
if (activeTab === 'sources') {
return (
Regulierungsquellen
EU-Lex, BSI-TR und deutsche Gesetze
🇪🇺 EU-Regulierungen (EUR-Lex)
{sources.filter(s => s.source_type === 'eur_lex').map(source => ())}
🔒 BSI Technical Guidelines
{sources.filter(s => s.source_type === 'bsi_pdf').map(source => ())}
)
}
if (activeTab === 'pdf') {
return (
PDF-Extraktion (PyMuPDF)
Extrahiert ALLE Pruefaspekte aus BSI-TR-03161 PDFs mit Regex-Pattern-Matching
{pdfDocuments.map(doc => (
📄
{doc.code}
{doc.available ? 'Verfuegbar' : 'Nicht gefunden'}
{doc.name}
{doc.description}
Erwartete Pruefaspekte: {doc.expected_aspects}
))}
{pdfResult && (
Letztes Extraktions-Ergebnis
{pdfResult.total_aspects}
Pruefaspekte gefunden
{pdfResult.requirements_created}
Requirements erstellt
{Object.keys(pdfResult.statistics.by_category || {}).length}
Kategorien
{pdfResult.statistics.by_category && Object.keys(pdfResult.statistics.by_category).length > 0 && (
Nach Kategorie:
{Object.entries(pdfResult.statistics.by_category).map(([cat, count]) => ({cat}: {count}))}
)}
)}
Wie funktioniert die PDF-Extraktion?
- - PyMuPDF (fitz) liest den PDF-Text
- - Regex-Pattern finden Aspekte wie O.Auth_1, O.Sess_2, T.Network_1
- - Kontextanalyse extrahiert Titel, Kategorie und Anforderungsstufe (MUSS/SOLL/KANN)
- - Automatische Speicherung erstellt Requirements in der Datenbank
)
}
if (activeTab === 'status' && status) {
return (
Scraper-Status
Letzter Lauf: {status.stats.last_run ? new Date(status.stats.last_run).toLocaleString('de-DE') : 'Noch nie'}
{status.status === 'running' ? 'Laeuft' : status.status === 'error' ? 'Fehler' : status.status === 'completed' ? 'Abgeschlossen' : 'Bereit'}
{status.stats.sources_processed}
Quellen verarbeitet
{status.stats.requirements_extracted}
Anforderungen extrahiert
{status.stats.errors}
Fehler
{status.last_error && (
Letzter Fehler: {status.last_error}
)}
Wie funktioniert der Scraper?
{[{ n: '1', t: 'EUR-Lex Abruf', d: 'Holt HTML-Version der EU-Verordnung, extrahiert Artikel und Absaetze' }, { n: '2', t: 'BSI-TR Parsing', d: 'Extrahiert Pruefaspekte (O.Auth_1, O.Sess_1, etc.) aus den TR-Dokumenten' }, { n: '3', t: 'Datenbank-Speicherung', d: 'Jede Anforderung wird als Requirement in der Compliance-DB gespeichert' }].map(s => (
))}
✓
Audit-Workspace: Anforderungen koennen mit Implementierungsdetails angereichert werden
)
}
// logs tab
return (
Letzte Ergebnisse
{results.length === 0 ? (
Keine Ergebnisse vorhanden. Starte einen Scrape-Vorgang.
) : (
{results.map((result, idx) => (
{result.error ? '❌' : result.reason ? '⏭️' : '✅'}
{result.code}
{result.error || result.reason || `${result.requirements_extracted} Anforderungen`}
))}
)}
)
}