fix: UX polish — score formula, role badges, compare view, page titles

- Score: remove hidden dataQuality/confidence modifiers from finalScore;
  formula now correctly shows hard×60% + soft×40% = displayed total
- "Ihr Objekt" badge: only shown for PROPERTY_MANAGER/ORGANIZATION_ADMIN
  in both IntelligenceMatchCard and MatchCardHeader (DEMAND_USER sees
  Verified Portfolio as a normal listing without ownership indicator)
- Compare: fix factor lookup to use allFactors (includes mid-range 45–70
  scores) so Prestige, Erreichbarkeit etc. no longer show "Nicht verfügbar"
- Compare: richer AI summary with overallAssessment, perPropertyAssessment
  (strengths/weaknesses/bestFor/keyRisk per property), and recommendation
- Compare/Results: pb:10 so CompareTray never overlaps last row of content
- AppShell: dynamic route names for /demand/results/:id → "Match Detail"
  and /demand/property/:id → "Objekt Detail" (no more UUID in header)
- MatchDetail: remove "Match EF9" debug chip from sticky nav
- LocationIntelligencePanel: comparable listings are now clickable links
  navigating to /demand/property/:id
- Comparable links: blue text + hover highlight

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Sutter
2026-05-22 21:05:36 +02:00
parent 9f7062d137
commit 76f9927c7c
11 changed files with 180 additions and 43 deletions
@@ -3,6 +3,7 @@ import {
Activity, Building2, HardHat, MapPin, Percent,
TrendingDown, TrendingUp, Train, Users, Zap,
} from 'lucide-react'
import { useNavigate } from 'react-router'
import { useProperties } from '../../hooks/useProperties'
import { getCityIntelligence } from '../../lib/locationIntelligence'
import type { Property } from '../../domain/property'
@@ -124,6 +125,7 @@ interface Props {
}
export function LocationIntelligencePanel({ property }: Props) {
const navigate = useNavigate()
const { data: allProperties = [] } = useProperties()
if (!property) return null
@@ -332,11 +334,16 @@ export function LocationIntelligencePanel({ property }: Props) {
{comparables.map(p => (
<Box
key={p.id}
sx={{ display: 'flex', alignItems: 'center', gap: 1.5, py: 0.75, borderBottom: '1px solid #f1f5f9' }}
onClick={() => navigate(`/demand/property/${p.id}`)}
sx={{
display: 'flex', alignItems: 'center', gap: 1.5, py: 0.75,
borderBottom: '1px solid #f1f5f9', cursor: 'pointer',
'&:hover': { bgcolor: '#f8fafc', borderRadius: 0.5 },
}}
>
<Building2 size={13} color="#64748b" />
<Building2 size={13} color="#3b82f6" />
<Box sx={{ flex: 1, minWidth: 0 }}>
<Typography variant="caption" sx={{ fontWeight: 500, display: 'block', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
<Typography variant="caption" sx={{ fontWeight: 500, display: 'block', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', color: '#1d4ed8' }}>
{p.title}
</Typography>
<Typography variant="caption" color="text.secondary">