[split-required] Split 700-870 LOC files across all services
backend-lehrer (11 files): - llm_gateway/routes/schools.py (867 → 5), recording_api.py (848 → 6) - messenger_api.py (840 → 5), print_generator.py (824 → 5) - unit_analytics_api.py (751 → 5), classroom/routes/context.py (726 → 4) - llm_gateway/routes/edu_search_seeds.py (710 → 4) klausur-service (12 files): - ocr_labeling_api.py (845 → 4), metrics_db.py (833 → 4) - legal_corpus_api.py (790 → 4), page_crop.py (758 → 3) - mail/ai_service.py (747 → 4), github_crawler.py (767 → 3) - trocr_service.py (730 → 4), full_compliance_pipeline.py (723 → 4) - dsfa_rag_api.py (715 → 4), ocr_pipeline_auto.py (705 → 4) website (6 pages): - audit-checklist (867 → 8), content (806 → 6) - screen-flow (790 → 4), scraper (789 → 5) - zeugnisse (776 → 5), modules (745 → 4) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
'use client'
|
||||
|
||||
import { Source, regulationTypeBadge, sourceTypeBadge } from './types'
|
||||
|
||||
export default function SourceCard({
|
||||
source,
|
||||
onScrape,
|
||||
scraping,
|
||||
}: {
|
||||
source: Source
|
||||
onScrape: (code: string, force: boolean) => void
|
||||
scraping: boolean
|
||||
}) {
|
||||
const regType = regulationTypeBadge[source.regulation_type] || regulationTypeBadge.industry_standard
|
||||
const srcType = sourceTypeBadge[source.source_type] || sourceTypeBadge.manual
|
||||
|
||||
return (
|
||||
<div className="bg-white border border-slate-200 rounded-lg p-4 hover:shadow-sm transition-shadow">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="text-2xl">{regType.icon}</span>
|
||||
<div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="font-semibold text-slate-900">{source.code}</span>
|
||||
<span className={`px-2 py-0.5 rounded text-xs font-medium ${regType.color}`}>
|
||||
{regType.label}
|
||||
</span>
|
||||
<span className={`px-2 py-0.5 rounded text-xs font-medium ${srcType.color}`}>
|
||||
{srcType.label}
|
||||
</span>
|
||||
</div>
|
||||
<div className="text-sm text-slate-500 truncate max-w-md" title={source.url}>
|
||||
{source.url.length > 60 ? source.url.substring(0, 60) + '...' : source.url}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-3">
|
||||
{source.has_data ? (
|
||||
<span className="px-3 py-1 bg-green-100 text-green-700 rounded-full text-sm font-medium">
|
||||
{source.requirement_count} Anforderungen
|
||||
</span>
|
||||
) : (
|
||||
<span className="px-3 py-1 bg-gray-100 text-gray-500 rounded-full text-sm">
|
||||
Keine Daten
|
||||
</span>
|
||||
)}
|
||||
|
||||
<div className="flex gap-1">
|
||||
<button
|
||||
onClick={() => onScrape(source.code, false)}
|
||||
disabled={scraping}
|
||||
className="px-3 py-1.5 text-sm bg-slate-100 text-slate-700 rounded hover:bg-slate-200 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
title="Scrapen (ueberspringt vorhandene)"
|
||||
>
|
||||
Scrapen
|
||||
</button>
|
||||
{source.has_data && (
|
||||
<button
|
||||
onClick={() => onScrape(source.code, true)}
|
||||
disabled={scraping}
|
||||
className="px-3 py-1.5 text-sm bg-orange-100 text-orange-700 rounded hover:bg-orange-200 transition-colors disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
title="Force: Loescht vorhandene Daten und scraped neu"
|
||||
>
|
||||
Force
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user