import { Box, Button, Card, Chip, Divider, LinearProgress, Typography, } from '@mui/material' import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query' import { Building2 } from 'lucide-react' import { useState } from 'react' import { EmptyState, ErrorState, LoadingPage } from '../../components/ui' import { matchService } from '../../services/matchService' import { propertyService } from '../../services/propertyService' import { needService } from '../../services/needService' import { MatchStrength, RiskLevel } from '../../domain/enums' function getMatchStrengthLabel(strength: MatchStrength): string { switch (strength) { case MatchStrength.STRONG: return 'Stark' case MatchStrength.MODERATE: return 'Mittel' case MatchStrength.WEAK: return 'Schwach' } } function getMatchStrengthColor(strength: MatchStrength): 'success' | 'warning' | 'error' { switch (strength) { case MatchStrength.STRONG: return 'success' case MatchStrength.MODERATE: return 'warning' case MatchStrength.WEAK: return 'error' } } function getScoreColor(strength: MatchStrength): string { switch (strength) { case MatchStrength.STRONG: return '#1a7a4a' case MatchStrength.MODERATE: return '#d97706' case MatchStrength.WEAK: return '#c0392b' } } function getConfidenceColor(score: number): 'success' | 'primary' | 'warning' { if (score >= 0.85) return 'success' if (score >= 0.65) return 'primary' return 'warning' } function getConfidenceLabel(score: number): string { if (score >= 0.85) return 'Hoch' if (score >= 0.65) return 'Mittel' return 'Niedrig' } function getRiskLabel(level: RiskLevel): string { switch (level) { case RiskLevel.LOW: return 'Niedriges Risiko' case RiskLevel.MEDIUM: return 'Mittleres Risiko' case RiskLevel.HIGH: return 'Hohes Risiko' case RiskLevel.CRITICAL: return 'Kritisches Risiko' } } function getRiskColor(level: RiskLevel): 'success' | 'warning' | 'error' { switch (level) { case RiskLevel.LOW: return 'success' case RiskLevel.MEDIUM: return 'warning' case RiskLevel.HIGH: return 'error' case RiskLevel.CRITICAL: return 'error' } } export default function MatchCenter() { const [filterStrength, setFilterStrength] = useState('ALL') const queryClient = useQueryClient() const { data: matchResp, isLoading: matchLoading, error: matchError } = useQuery({ queryKey: ['matches'], queryFn: () => matchService.getAll(), }) const { data: propResp, isLoading: propLoading, error: propError } = useQuery({ queryKey: ['properties'], queryFn: () => propertyService.getAll(), }) const { data: needResp, isLoading: needLoading, error: needError } = useQuery({ queryKey: ['needs'], queryFn: () => needService.getAll(), }) const approveMutation = useMutation({ mutationFn: (matchId: string) => matchService.approve(matchId, 'admin@ideal-sharing.ch'), onSuccess: () => queryClient.invalidateQueries({ queryKey: ['matches'] }), }) if (matchLoading || propLoading || needLoading) return if (matchError || propError || needError) return const matches = matchResp?.data ?? [] const properties = propResp?.data ?? [] const needs = needResp?.data ?? [] const filtered = filterStrength === 'ALL' ? matches : matches.filter(m => m.matchStrength === filterStrength) const sortedFiltered = [...filtered].sort((a, b) => b.matchScore - a.matchScore) const strengthFilters: { value: MatchStrength | 'ALL'; label: string }[] = [ { value: 'ALL', label: 'Alle' }, { value: MatchStrength.STRONG, label: 'Stark' }, { value: MatchStrength.MODERATE, label: 'Mittel' }, { value: MatchStrength.WEAK, label: 'Schwach' }, ] return ( {/* Page Header */} Match Center KI-gestützte Objekt-Bedarfs-Analyse {/* Content */} {/* Filter Chips */} {strengthFilters.map(f => ( setFilterStrength(f.value)} color={ f.value === MatchStrength.STRONG ? 'success' : f.value === MatchStrength.MODERATE ? 'warning' : f.value === MatchStrength.WEAK ? 'error' : 'default' } sx={{ cursor: 'pointer', fontWeight: filterStrength === f.value ? 700 : 400 }} /> ))} {/* Match Cards */} {sortedFiltered.length === 0 ? ( ) : ( {sortedFiltered.map(match => { const property = properties.find(p => p.id === match.propertyId) const need = needs.find(n => n.id === match.needId) return ( {/* Left column: score */} {match.matchScore} / 100 {/* Center column: details */} {/* Property info */} {property?.title ?? match.propertyId} {need && ( {need.companyName} — {need.assetType} )} {/* Positive factors */} {match.positiveFactors.slice(0, 3).map((f, i) => ( ✓ {f.criterion}: {Math.round(f.score)}% ))} {/* Negative factors */} {match.negativeFactors.slice(0, 2).map((f, i) => ( ✗ {f.criterion} ))} {/* Tradeoffs */} {match.tradeoffs.length > 0 && ( {match.tradeoffs.slice(0, 2).map((t, i) => ( ⚠ {t.concern} ))} )} {/* Right column: actions */} {match.isApproved ? ( ) : ( )} ) })} )} ) }