import { Box, CircularProgress, Paper, Typography } from '@mui/material' import { useNavigate, useParams } from 'react-router' import { useQuery } from '@tanstack/react-query' import { useMatchDetail } from '../../hooks/useMatches' import { propertyService } from '../../services/propertyService' import { needService } from '../../services/needService' import { futureSignalService } from '../../services/futureSignalService' import { useCompareStore } from '../../stores/compareStore' import { MatchReasonList } from '../../components/match-card/MatchReasonList' import { MatchDetailHeader, ExecutiveSummaryPanel, PropertyOverviewPanel, NeedAlignmentPanel, ScoreBreakdownPanel, TradeoffPanel, RiskPanel, MissingInformationPanel, SourceProvenancePanel, FutureAvailabilityContextPanel, NextActionsPanel, } from '../../components/match-detail' import type { MatchCardReason } from '../../components/match-card/MatchCardViewModel' const HARD_CRITERIA = new Set(['area', 'location', 'budget', 'timing']) function buildReasons(match: NonNullable['data']>): MatchCardReason[] { return match.positiveFactors.slice(0, 3).map(f => ({ type: (HARD_CRITERIA.has(f.criterion) ? 'HARD_FACT' : 'SOFT_FACTOR') as MatchCardReason['type'], label: f.criterion.charAt(0).toUpperCase() + f.criterion.slice(1), explanation: f.explanation, score: f.score, })) } export default function MatchDetail() { const { matchId } = useParams<{ matchId: string }>() const navigate = useNavigate() const { addToCompare } = useCompareStore() const { data: match, isLoading } = useMatchDetail(matchId ?? '') const isFuture = match?.resultType === 'FUTURE_AVAILABILITY' const { data: property = null } = useQuery({ queryKey: ['property', match?.propertyId], queryFn: () => propertyService.getById(match!.propertyId), enabled: !!match && !isFuture, select: r => r.data ?? null, }) const { data: need = null } = useQuery({ queryKey: ['need', match?.needId], queryFn: () => needService.getById(match!.needId), enabled: !!match?.needId, select: r => r.data ?? null, }) const { data: signal = null } = useQuery({ queryKey: ['signal', match?.resultId], queryFn: () => futureSignalService.getById(match!.resultId!), enabled: !!match && isFuture && !!match.resultId, select: r => r.data ?? null, }) if (isLoading) { return ( ) } if (!match) { return ( Match nicht gefunden Das gesuchte Match existiert nicht oder wurde entfernt. ) } const reasons = buildReasons(match) const compareId = property?.id ?? '' const handleCompare = () => { if (compareId) addToCompare(compareId) navigate('/demand/compare') } const handleBack = () => navigate(-1) return ( {}} /> {/* Main column */} {/* Why It Matches — structured from scoreFactors */} {reasons.length > 0 && ( Warum dieses Match {match.negativeFactors.length > 0 && ( Schwächere Faktoren {match.negativeFactors.slice(0, 3).map((f, i) => ( · {f.criterion}: {f.explanation} ))} )} )} {isFuture && } {/* Sidebar — sticky */} {}} onReview={() => {}} onReject={() => {}} /> ) }