import { Box, Button, Chip, CircularProgress, Divider, Tooltip, Typography } from '@mui/material' import { Building2, FileText, Newspaper, TrendingUp, FileCheck2, HardHat, Database, CalendarClock, Search, PenLine, CheckCircle2, XCircle, Send, Link2, } from 'lucide-react' import type { LucideIcon } from 'lucide-react' import type { MarketSignal } from '../../domain/marketSignal' import { MARKET_SIGNAL_SOURCE_LABELS, SIGNAL_PROCESSING_STATUS_LABELS, SIGNAL_PROCESSING_STATUS_COLORS, SignalProcessingStatus, ExtractedEntityType, } from '../../domain/marketSignal' import { SensitivityLevel } from '../../domain/enums' import { FreshnessBadge } from '../badges/FreshnessBadge' import { SourceReliabilityBadge } from './SourceReliabilityBadge' import { SignalConfidenceBadge } from './SignalConfidenceBadge' import { SensitivityWarningPanel } from './SensitivityWarningPanel' import { SignalEvidenceList } from './SignalEvidenceList' import { SignalConversionPanel } from './SignalConversionPanel' import { MarketSignalEmptyState } from './MarketSignalEmptyState' import { FeedEligibilityBadge } from './FeedEligibilityBadge' import { useUpdateSignalStatus, useCreateReviewTask } from '../../hooks/useMarketSignals' const SOURCE_ICONS: Record = { PUBLIC_LISTING_PLATFORM: Building2, BUILDING_PERMIT_REGISTER: FileText, COMPANY_NEWS: Newspaper, JOB_GROWTH_SIGNAL: TrendingUp, COMMERCIAL_REGISTER: FileCheck2, INFRASTRUCTURE_PROJECT: HardHat, PORTFOLIO_IMPORT: Database, LEASE_EXPIRY_DATA: CalendarClock, USER_DEMAND_SIGNAL: Search, MANUAL_ANALYST_SIGNAL: PenLine, } const ENTITY_TYPE_LABELS: Record = { [ExtractedEntityType.COMPANY]: 'Unternehmen', [ExtractedEntityType.PERSON]: 'Person', [ExtractedEntityType.LOCATION]: 'Ort', [ExtractedEntityType.ASSET]: 'Objekt', [ExtractedEntityType.DATE]: 'Datum', } const SENSITIVITY_LABELS: Record = { [SensitivityLevel.PUBLIC]: 'Öffentlich', [SensitivityLevel.INTERNAL]: 'Intern', [SensitivityLevel.CONFIDENTIAL]: 'Vertraulich', [SensitivityLevel.RESTRICTED]: 'Eingeschränkt', } function formatDate(iso: string): string { return new Date(iso).toLocaleString('de-CH', { day: '2-digit', month: '2-digit', year: '2-digit', hour: '2-digit', minute: '2-digit', }) } interface MarketSignalDetailPanelProps { signal: MarketSignal | null } export function MarketSignalDetailPanel({ signal }: MarketSignalDetailPanelProps) { const { mutate: updateStatus, isPending: isUpdating } = useUpdateSignalStatus() const { mutate: sendToReview, isPending: isSending } = useCreateReviewTask() if (!signal) return const SourceIcon = SOURCE_ICONS[signal.sourceCategory] ?? Building2 const { bg, fg } = SIGNAL_PROCESSING_STATUS_COLORS[signal.processingStatus] const NON_ACTIONABLE_STATUSES: SignalProcessingStatus[] = [ SignalProcessingStatus.REJECTED, SignalProcessingStatus.ARCHIVED, SignalProcessingStatus.CONVERTED_TO_FUTURE_AVAILABILITY, ] const isActionable = !NON_ACTIONABLE_STATUSES.includes(signal.processingStatus) return ( {/* Header */} {signal.title} {MARKET_SIGNAL_SOURCE_LABELS[signal.sourceCategory]} · {signal.location} · {formatDate(signal.detectedAt)} {/* Body */} {/* Summary */} {signal.summary} {/* Evidence */} Quellenangaben & Evidenz {signal.extractedEntities.length > 0 && ( <> Extrahierte Entitäten {signal.extractedEntities.map((entity, i) => ( ))} )} {signal.analystNotes && ( <> Analyst-Notizen {signal.analystNotes} )} {/* Conversion panel */} {/* Actions */} {isActionable && ( <> Aktionen )} ) }