diff --git a/src/mock-data/matches.ts b/src/mock-data/matches.ts index 35c8a85..4630f8b 100644 --- a/src/mock-data/matches.ts +++ b/src/mock-data/matches.ts @@ -42,10 +42,10 @@ export const mockMatches: Match[] = [ id: 'match-002', propertyId: 'prop-004', needId: 'need-001', - matchScore: 64, - matchStrength: MatchStrength.MODERATE, - status: MatchStatus.PENDING_REVIEW, - scoreBreakdown: { hardMatchScore: 78, softFactorScore: 62, confidenceModifier: 0.68, dataQualityModifier: 0.55, totalScore: 64 }, + matchScore: 93, + matchStrength: MatchStrength.STRONG, + status: MatchStatus.SHORTLISTED, + scoreBreakdown: { hardMatchScore: 95, softFactorScore: 91, confidenceModifier: 0.82, dataQualityModifier: 0.75, totalScore: 93 }, positiveFactors: [ { criterion: 'Fläche', weight: 0.20, score: 88, contribution: 17.6, explanation: '1150m² liegt im erweiterten Korridor' }, { criterion: 'Standort', weight: 0.20, score: 80, contribution: 16, explanation: 'Zürich Kreis 4 nahe bevorzugten Lagen' }, @@ -181,10 +181,10 @@ export const mockMatches: Match[] = [ id: 'match-009', propertyId: 'prop-015', needId: 'need-001', - matchScore: 51, - matchStrength: MatchStrength.WEAK, - status: MatchStatus.PENDING_REVIEW, - scoreBreakdown: { hardMatchScore: 65, softFactorScore: 53, confidenceModifier: 0.70, dataQualityModifier: 0.60, totalScore: 51 }, + matchScore: 86, + matchStrength: MatchStrength.STRONG, + status: MatchStatus.SHORTLISTED, + scoreBreakdown: { hardMatchScore: 90, softFactorScore: 84, confidenceModifier: 0.76, dataQualityModifier: 0.72, totalScore: 86 }, positiveFactors: [ { criterion: 'Fläche', weight: 0.20, score: 88, contribution: 17.6, explanation: '650m² im Zielkorridor' }, { criterion: 'Budget', weight: 0.15, score: 90, contribution: 13.5, explanation: 'CHF 38/m² unter Maximum' }, @@ -296,10 +296,10 @@ export const mockMatches: Match[] = [ id: 'match-011', propertyId: 'prop-016', needId: 'need-002', - matchScore: 76, - matchStrength: MatchStrength.MODERATE, + matchScore: 93, + matchStrength: MatchStrength.STRONG, status: MatchStatus.APPROVED, - scoreBreakdown: { hardMatchScore: 90, softFactorScore: 74, confidenceModifier: 0.69, dataQualityModifier: 0.58, totalScore: 76 }, + scoreBreakdown: { hardMatchScore: 95, softFactorScore: 92, confidenceModifier: 0.83, dataQualityModifier: 0.76, totalScore: 93 }, positiveFactors: [ { criterion: 'Fläche', weight: 0.25, score: 92, contribution: 23, explanation: '2200m² im Zielkorridor' }, { criterion: 'Standort', weight: 0.20, score: 78, contribution: 15.6, explanation: 'Muttenz BL – gleicher Kanton, gute Lage' }, @@ -466,10 +466,10 @@ export const mockMatches: Match[] = [ id: 'match-017', propertyId: 'prop-018', needId: 'need-003', - matchScore: 44, - matchStrength: MatchStrength.WEAK, - status: MatchStatus.PENDING_REVIEW, - scoreBreakdown: { hardMatchScore: 58, softFactorScore: 46, confidenceModifier: 0.68, dataQualityModifier: 0.57, totalScore: 44 }, + matchScore: 87, + matchStrength: MatchStrength.STRONG, + status: MatchStatus.SHORTLISTED, + scoreBreakdown: { hardMatchScore: 92, softFactorScore: 85, confidenceModifier: 0.78, dataQualityModifier: 0.70, totalScore: 87 }, positiveFactors: [ { criterion: 'Budget', weight: 0.20, score: 95, contribution: 19, explanation: 'CHF 31/m² deutlich unter Maximum' }, { criterion: 'Fläche', weight: 0.20, score: 88, contribution: 17.6, explanation: '780m² nahe am Zielkorridor' }, @@ -579,10 +579,10 @@ export const mockMatches: Match[] = [ id: 'match-021', propertyId: 'prop-017', needId: 'need-004', - matchScore: 79, - matchStrength: MatchStrength.MODERATE, + matchScore: 91, + matchStrength: MatchStrength.STRONG, status: MatchStatus.SHORTLISTED, - scoreBreakdown: { hardMatchScore: 93, softFactorScore: 77, confidenceModifier: 0.71, dataQualityModifier: 0.61, totalScore: 79 }, + scoreBreakdown: { hardMatchScore: 94, softFactorScore: 90, confidenceModifier: 0.81, dataQualityModifier: 0.74, totalScore: 91 }, positiveFactors: [ { criterion: 'Standort', weight: 0.35, score: 94, contribution: 32.9, explanation: 'Zürich Löwenstrasse – Innenstadtlage' }, { criterion: 'Budget', weight: 0.15, score: 95, contribution: 14.25, explanation: 'CHF 95/m² unter Maximum' }, @@ -634,10 +634,10 @@ export const mockMatches: Match[] = [ id: 'match-023', propertyId: 'prop-003', needId: 'need-004', - matchScore: 44, - matchStrength: MatchStrength.WEAK, - status: MatchStatus.PENDING_REVIEW, - scoreBreakdown: { hardMatchScore: 58, softFactorScore: 46, confidenceModifier: 0.71, dataQualityModifier: 0.62, totalScore: 44 }, + matchScore: 84, + matchStrength: MatchStrength.STRONG, + status: MatchStatus.SHORTLISTED, + scoreBreakdown: { hardMatchScore: 89, softFactorScore: 82, confidenceModifier: 0.77, dataQualityModifier: 0.69, totalScore: 84 }, positiveFactors: [ { criterion: 'Budget', weight: 0.15, score: 95, contribution: 14.25, explanation: 'CHF 95/m² unter Maximum CHF 100/m²' }, { criterion: 'Prestige', weight: 0.15, score: 92, contribution: 13.8, explanation: 'Berner Bahnhofstrasse – Top-Prestige' }, @@ -661,10 +661,10 @@ export const mockMatches: Match[] = [ id: 'match-024', propertyId: 'prop-021', needId: 'need-004', - matchScore: 33, - matchStrength: MatchStrength.WEAK, - status: MatchStatus.REJECTED, - scoreBreakdown: { hardMatchScore: 47, softFactorScore: 35, confidenceModifier: 0.70, dataQualityModifier: 0.59, totalScore: 33 }, + matchScore: 72, + matchStrength: MatchStrength.MODERATE, + status: MatchStatus.PENDING_REVIEW, + scoreBreakdown: { hardMatchScore: 81, softFactorScore: 70, confidenceModifier: 0.72, dataQualityModifier: 0.62, totalScore: 72 }, positiveFactors: [ { criterion: 'Prestige', weight: 0.15, score: 94, contribution: 14.1, explanation: 'Rue du Rhône Genf – sehr hoher Prestige-Score' }, ], @@ -827,10 +827,10 @@ export const mockMatches: Match[] = [ id: 'match-030', propertyId: 'prop-022', needId: 'need-005', - matchScore: 43, - matchStrength: MatchStrength.WEAK, + matchScore: 73, + matchStrength: MatchStrength.MODERATE, status: MatchStatus.PENDING_REVIEW, - scoreBreakdown: { hardMatchScore: 57, softFactorScore: 45, confidenceModifier: 0.69, dataQualityModifier: 0.58, totalScore: 43 }, + scoreBreakdown: { hardMatchScore: 82, softFactorScore: 71, confidenceModifier: 0.71, dataQualityModifier: 0.62, totalScore: 73 }, positiveFactors: [ { criterion: 'Budget', weight: 0.20, score: 100, contribution: 20, explanation: 'CHF 28/m² deutlich unter Maximum' }, { criterion: 'Fläche', weight: 0.20, score: 88, contribution: 17.6, explanation: '700m² exakt an der Obergrenze' }, @@ -936,10 +936,10 @@ export const mockMatches: Match[] = [ id: 'match-034', propertyId: 'prop-016', needId: 'need-006', - matchScore: 50, - matchStrength: MatchStrength.WEAK, - status: MatchStatus.PENDING_REVIEW, - scoreBreakdown: { hardMatchScore: 64, softFactorScore: 50, confidenceModifier: 0.69, dataQualityModifier: 0.58, totalScore: 50 }, + matchScore: 88, + matchStrength: MatchStrength.STRONG, + status: MatchStatus.SHORTLISTED, + scoreBreakdown: { hardMatchScore: 92, softFactorScore: 87, confidenceModifier: 0.79, dataQualityModifier: 0.73, totalScore: 88 }, positiveFactors: [ { criterion: 'Fläche', weight: 0.30, score: 88, contribution: 26.4, explanation: '2200m² im Zielkorridor' }, { criterion: 'Budget', weight: 0.20, score: 85, contribution: 17, explanation: 'CHF 16/m² exakt im Maximum' }, @@ -1162,10 +1162,10 @@ export const mockMatches: Match[] = [ id: 'match-042', propertyId: 'prop-019', needId: 'need-008', - matchScore: 47, - matchStrength: MatchStrength.WEAK, - status: MatchStatus.PENDING_REVIEW, - scoreBreakdown: { hardMatchScore: 61, softFactorScore: 47, confidenceModifier: 0.68, dataQualityModifier: 0.56, totalScore: 47 }, + matchScore: 85, + matchStrength: MatchStrength.STRONG, + status: MatchStatus.SHORTLISTED, + scoreBreakdown: { hardMatchScore: 90, softFactorScore: 83, confidenceModifier: 0.77, dataQualityModifier: 0.71, totalScore: 85 }, positiveFactors: [ { criterion: 'Budget', weight: 0.20, score: 95, contribution: 19, explanation: 'CHF 13/m² unter Maximum CHF 14/m²' }, ], @@ -1248,10 +1248,10 @@ export const mockMatches: Match[] = [ id: 'match-045', propertyId: 'prop-017', needId: 'need-009', - matchScore: 38, - matchStrength: MatchStrength.WEAK, + matchScore: 76, + matchStrength: MatchStrength.MODERATE, status: MatchStatus.PENDING_REVIEW, - scoreBreakdown: { hardMatchScore: 52, softFactorScore: 40, confidenceModifier: 0.71, dataQualityModifier: 0.61, totalScore: 38 }, + scoreBreakdown: { hardMatchScore: 85, softFactorScore: 74, confidenceModifier: 0.73, dataQualityModifier: 0.64, totalScore: 76 }, positiveFactors: [ { criterion: 'Budget', weight: 0.15, score: 100, contribution: 15, explanation: 'CHF 95/m² unter Maximum CHF 120/m²' }, ], @@ -1278,10 +1278,10 @@ export const mockMatches: Match[] = [ id: 'match-046', propertyId: 'prop-022', needId: 'need-010', - matchScore: 79, - matchStrength: MatchStrength.MODERATE, + matchScore: 92, + matchStrength: MatchStrength.STRONG, status: MatchStatus.APPROVED, - scoreBreakdown: { hardMatchScore: 93, softFactorScore: 77, confidenceModifier: 0.69, dataQualityModifier: 0.58, totalScore: 79 }, + scoreBreakdown: { hardMatchScore: 95, softFactorScore: 91, confidenceModifier: 0.82, dataQualityModifier: 0.74, totalScore: 92 }, positiveFactors: [ { criterion: 'Standort', weight: 0.28, score: 100, contribution: 28, explanation: 'St. Gallen Centrum – exakter Standortwunsch' }, { criterion: 'Budget', weight: 0.20, score: 95, contribution: 19, explanation: 'CHF 28/m² deutlich unter Maximum CHF 35/m²' }, diff --git a/src/pages/demand/Results.tsx b/src/pages/demand/Results.tsx index 27d785c..174560c 100644 --- a/src/pages/demand/Results.tsx +++ b/src/pages/demand/Results.tsx @@ -71,11 +71,12 @@ export default function Results() { const { data: results = [], isLoading } = useUnifiedResults(activeNeed?.id) - const filtered = results - // Exclude VERIFIED_PORTFOLIO by default; include only when toggled on by Property Manager - .filter(r => r.resultType !== 'VERIFIED_PORTFOLIO' || showOwnProperties) - .filter(r => filterSource === 'ALL' || r.resultType === filterSource) - .filter(r => showSchattenmarkt || r.resultType !== 'FUTURE_AVAILABILITY') + const filtered = results.filter(r => { + if (r.resultType === 'VERIFIED_PORTFOLIO') return showOwnProperties + // Schattenmarkt toggle is independent of the source filter + if (r.resultType === 'FUTURE_AVAILABILITY') return showSchattenmarkt + return filterSource === 'ALL' || r.resultType === filterSource + }) const sorted = sortResults(filtered, sortBy)