diff --git a/src/components/match-detail/FutureAvailabilityContextPanel.tsx b/src/components/match-detail/FutureAvailabilityContextPanel.tsx
index 19c0432..7e529c8 100644
--- a/src/components/match-detail/FutureAvailabilityContextPanel.tsx
+++ b/src/components/match-detail/FutureAvailabilityContextPanel.tsx
@@ -1,11 +1,9 @@
-import { Box, Button, Chip, Divider, LinearProgress, Paper, Typography } from '@mui/material'
+import { Box, Chip, Divider, LinearProgress, Paper, Typography } from '@mui/material'
import {
AlertTriangle,
Calendar,
CheckCircle2,
Clock,
- ExternalLink,
- Globe,
ShieldCheck,
Sparkles,
TrendingUp,
@@ -14,7 +12,8 @@ import {
import type { Match } from '../../domain/match'
import type { FutureSignal } from '../../domain/futureSignal'
import { SIGNAL_TYPE_LABELS, SIGNAL_ACTION, SOURCE_META } from './futureAvailabilityConstants'
-import { CREDIBILITY_META, SENSITIVITY_META, RISK_META, ageLabel, domainLabel } from './futureAvailabilityContextUtils'
+import { CREDIBILITY_META, SENSITIVITY_META, RISK_META, ageLabel } from './futureAvailabilityContextUtils'
+import { SignalSourcesSection } from './SignalSourcesSection'
interface Props {
match: Match
@@ -197,100 +196,13 @@ export function FutureAvailabilityContextPanel({ match: _match, signal }: Props)
{/* ── 7. Quellen & Belege ───────────────────────────────────────────── */}
-
-
-
- Quellen & Belege
-
-
- {/* Primary source metadata — always shown */}
-
- {sourceMeta && (
-
- {sourceMeta.icon}
- {sourceMeta.label}
-
- )}
- {credMeta && (
-
-
- {credMeta.label}
-
- )}
- {signal.source.publishedAt && (
-
-
-
- {new Date(signal.source.publishedAt).toLocaleDateString('de-CH', { day: '2-digit', month: 'long', year: 'numeric' })}
-
-
- )}
-
-
- {/* Verified contract special box */}
- {isVerifiedContract && (
-
-
-
- Vertragsende aus internem ERP bestätigt
-
-
-
- Verwaltung hat Marktfreigabe erteilt
-
-
- )}
-
- {/* All source URLs */}
- {allSourceUrls.length > 0 ? (
-
- {allSourceUrls.map((url, i) => (
- }
- sx={{
- textTransform: 'none', justifyContent: 'flex-start',
- color: '#0369a1', borderColor: '#bae6fd',
- '&:hover': { borderColor: '#0369a1', bgcolor: '#f0f9ff' },
- fontSize: '0.78rem', fontWeight: 500,
- }}
- >
- {domainLabel(url)}
-
- ))}
-
- ) : (
-
-
- Kein direkter Quellenlink verfügbar — Signal basiert auf aggregierten {sourceMeta?.label ?? 'Marktdaten'}.
-
-
- )}
-
- {/* Evidence extraction date */}
- {signal.evidence?.extractedAt && (
-
-
-
- Daten extrahiert: {new Date(signal.evidence.extractedAt).toLocaleDateString('de-CH', { day: '2-digit', month: 'short', year: 'numeric' })}
-
-
- )}
-
- {/* Evidence summary */}
- {signal.evidence?.summary && (
-
- Evidenz-Zusammenfassung
- {signal.evidence.summary}
-
- )}
-
+
{/* ── Footer ──────────────────────────────────────────────────────────── */}
diff --git a/src/components/match-detail/SignalSourcesSection.tsx b/src/components/match-detail/SignalSourcesSection.tsx
new file mode 100644
index 0000000..4905520
--- /dev/null
+++ b/src/components/match-detail/SignalSourcesSection.tsx
@@ -0,0 +1,117 @@
+import { Box, Button, Typography } from '@mui/material'
+import { Calendar, Clock, ExternalLink, Globe, ShieldCheck } from 'lucide-react'
+import type { FutureSignal } from '../../domain/futureSignal'
+import { domainLabel } from './futureAvailabilityContextUtils'
+
+interface SignalSourcesSectionProps {
+ sourceMeta: { label: string; icon: React.ReactNode; badge?: string; description?: string } | null
+ credMeta: { label: string; color: string } | null
+ isVerifiedContract: boolean
+ allSourceUrls: string[]
+ signal: FutureSignal
+}
+
+export function SignalSourcesSection({
+ sourceMeta,
+ credMeta,
+ isVerifiedContract,
+ allSourceUrls,
+ signal,
+}: SignalSourcesSectionProps) {
+ return (
+
+
+
+ Quellen & Belege
+
+
+ {/* Primary source metadata — always shown */}
+
+ {sourceMeta && (
+
+ {sourceMeta.icon}
+ {sourceMeta.label}
+
+ )}
+ {credMeta && (
+
+
+ {credMeta.label}
+
+ )}
+ {signal.source.publishedAt && (
+
+
+
+ {new Date(signal.source.publishedAt).toLocaleDateString('de-CH', { day: '2-digit', month: 'long', year: 'numeric' })}
+
+
+ )}
+
+
+ {/* Verified contract special box */}
+ {isVerifiedContract && (
+
+
+
+ Vertragsende aus internem ERP bestätigt
+
+
+
+ Verwaltung hat Marktfreigabe erteilt
+
+
+ )}
+
+ {/* All source URLs */}
+ {allSourceUrls.length > 0 ? (
+
+ {allSourceUrls.map((url, i) => (
+ }
+ sx={{
+ textTransform: 'none', justifyContent: 'flex-start',
+ color: '#0369a1', borderColor: '#bae6fd',
+ '&:hover': { borderColor: '#0369a1', bgcolor: '#f0f9ff' },
+ fontSize: '0.78rem', fontWeight: 500,
+ }}
+ >
+ {domainLabel(url)}
+
+ ))}
+
+ ) : (
+
+
+ Kein direkter Quellenlink verfügbar — Signal basiert auf aggregierten {sourceMeta?.label ?? 'Marktdaten'}.
+
+
+ )}
+
+ {/* Evidence extraction date */}
+ {signal.evidence?.extractedAt && (
+
+
+
+ Daten extrahiert: {new Date(signal.evidence.extractedAt).toLocaleDateString('de-CH', { day: '2-digit', month: 'short', year: 'numeric' })}
+
+
+ )}
+
+ {/* Evidence summary */}
+ {signal.evidence?.summary && (
+
+ Evidenz-Zusammenfassung
+ {signal.evidence.summary}
+
+ )}
+
+ )
+}