refactor: consolidate duplicated UI score/color/badge logic into lib/
- Add matchScoreHex(), criterionScoreColor(), criterionScoreTextColor() to lib/utils.ts
- Add RESULT_TYPE_META (labels + colors) to lib/ds.ts as single source of truth
- Remove 5 local scoreColor() functions: StrongMatchMiniCard, MatchListCard,
pipelineUtils (re-exported as matchScoreHex), CriterionRow, ScoreBreakdownPanel,
ScoreInlineBreakdown
- Remove local RESULT_TYPE_META/TYPE_META from MatchCardHeader, ResultTypeBadge;
remove RESULT_TYPE_LABEL/COLOR from pipelineConstants — all now use lib/ds.ts
- Replace local confidenceColor() in MatchCardHeader, ConfidenceFieldBadge,
ReliabilityScorePanel with confidenceHex() from lib/utils.ts
- Replace local qualityColor() in propertyHelpers, DataQualityWidget with
dataQualityColor() from lib/utils.ts
- Fix FUTURE_AVAILABILITY label inconsistency ('Future'/'Zukunft' → 'Zukunftssignal')
- Fix EXTERNAL_MARKET label inconsistency ('Direktinserat' → 'Plattform')
- tsc --noEmit passes with zero errors
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { Box, Divider, LinearProgress, Typography } from '@mui/material'
|
||||
import type { ScoreFactor } from '../../domain/match'
|
||||
import { criterionScoreColor, criterionScoreTextColor } from '../../lib/utils'
|
||||
|
||||
interface ScoreBreakdownData {
|
||||
hardMatchScore: number
|
||||
@@ -22,14 +23,6 @@ const CRITERION_LABEL: Record<string, string> = {
|
||||
|
||||
const HARD_KEYS = new Set(['area', 'location', 'budget', 'timing'])
|
||||
|
||||
function scoreColor(v: number): 'success' | 'warning' | 'error' {
|
||||
return v >= 70 ? 'success' : v >= 50 ? 'warning' : 'error'
|
||||
}
|
||||
|
||||
function scoreTextColor(v: number): string {
|
||||
return v >= 70 ? '#1a7a4a' : v >= 50 ? '#d97706' : '#c0392b'
|
||||
}
|
||||
|
||||
function importanceLabel(weight: number, maxWeight: number): { label: string; color: string } {
|
||||
const ratio = maxWeight > 0 ? weight / maxWeight : 0
|
||||
if (ratio >= 0.85) return { label: 'Entscheidend', color: '#1e3a5f' }
|
||||
@@ -43,7 +36,7 @@ function FactorRow({ factor, maxWeight }: { factor: ScoreFactor; maxWeight: numb
|
||||
const label = CRITERION_LABEL[factor.criterion] ?? factor.criterion
|
||||
const pct = Math.round(factor.weight * 100)
|
||||
const imp = importanceLabel(factor.weight, maxWeight)
|
||||
const color = scoreColor(factor.score)
|
||||
const color = criterionScoreColor(factor.score)
|
||||
|
||||
return (
|
||||
<Box sx={{ mb: 1.25 }}>
|
||||
@@ -54,7 +47,7 @@ function FactorRow({ factor, maxWeight }: { factor: ScoreFactor; maxWeight: numb
|
||||
<Typography variant="caption" sx={{ color: '#cbd5e1', fontSize: '0.65rem' }}>{pct}%</Typography>
|
||||
</Box>
|
||||
<Box sx={{ display: 'flex', alignItems: 'baseline', gap: 0.75 }}>
|
||||
<Typography variant="caption" sx={{ fontWeight: 700, color: scoreTextColor(factor.score) }}>
|
||||
<Typography variant="caption" sx={{ fontWeight: 700, color: criterionScoreTextColor(factor.score) }}>
|
||||
{factor.score}/100
|
||||
</Typography>
|
||||
<Typography variant="caption" sx={{ color: '#94a3b8', fontSize: '0.68rem', minWidth: 40, textAlign: 'right' }}>
|
||||
@@ -82,7 +75,7 @@ export function ScoreInlineBreakdown({ scoreBreakdown: sb, allFactors, compact =
|
||||
<Typography variant="caption" sx={{ fontFamily: 'monospace', color: '#1e293b', display: 'block', lineHeight: 1.5 }}>
|
||||
Hart {sb.hardMatchScore} × 60% + Soft {sb.softFactorScore} × 40%
|
||||
{' = '}{hardContrib} + {softContrib}{' = '}
|
||||
<span style={{ fontWeight: 800, color: scoreTextColor(sb.totalScore) }}>{sb.totalScore}</span>
|
||||
<span style={{ fontWeight: 800, color: criterionScoreTextColor(sb.totalScore) }}>{sb.totalScore}</span>
|
||||
</Typography>
|
||||
</Box>
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user