refactor: split large page components + taxonomy/HeatBadge/FutureAvailability improvements
- Taxonomy: merge VERIFIED_PORTFOLIO + EXTERNAL_MARKET display → 'Plattform' (dark blue) across all surfaces - HeatBadge: new flame indicator for hot properties (grid, list, pipeline views) - FutureAvailabilityContextPanel: richer detail page with AI summary, strategic assessment, sources - Refactor Pipeline.tsx (630→152 lines) → pipeline/PipelineCard, PipelineColumn, PipelineDetailPanel, pipelineConstants, pipelineUtils - Refactor IntelligenceMatchCard.tsx (483→179 lines) → FutureAvailabilityCard extracted - Refactor MatchDetail.tsx (559→464 lines) → useMatchDetailData hook, MatchDetailPropertyDetails - Refactor Compare.tsx (638→485 lines) → compareUtils, CompareCriteriaCard extracted Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -66,9 +66,9 @@ export const ASSET_TYPE_LABELS: Record<string, string> = {
|
||||
|
||||
// Result type display labels
|
||||
export const RESULT_TYPE_LABELS: Record<string, string> = {
|
||||
VERIFIED_PORTFOLIO: 'Verified Portfolio',
|
||||
EXTERNAL_MARKET: 'Direktinserat',
|
||||
MAISON_WORK: 'Maison Work',
|
||||
VERIFIED_PORTFOLIO: 'Plattform',
|
||||
EXTERNAL_MARKET: 'Plattform',
|
||||
MAISON_WORK: 'Maison Work',
|
||||
FUTURE_AVAILABILITY: 'Zukunftssignal',
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@ import { CONF_HIGH, CONF_MEDIUM, DQ_HIGH, DQ_MEDIUM } from './constants'
|
||||
export const DS_COLORS = {
|
||||
resultType: {
|
||||
VERIFIED_PORTFOLIO: { bg: 'rgba(30,58,95,0.10)', fg: '#1e3a5f' },
|
||||
EXTERNAL_MARKET: { bg: 'rgba(180,83,9,0.10)', fg: '#b45309' },
|
||||
EXTERNAL_MARKET: { bg: 'rgba(30,58,95,0.10)', fg: '#1e3a5f' },
|
||||
MAISON_WORK: { bg: 'rgba(3,105,161,0.10)', fg: '#0369a1' },
|
||||
FUTURE_AVAILABILITY: { bg: 'rgba(109,40,217,0.10)', fg: '#6d28d9' },
|
||||
},
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
// Mock demand-heat data per property.
|
||||
// In production: aggregated from cross-user pipeline additions, search impressions, and view counts.
|
||||
|
||||
export interface PropertyHeat {
|
||||
searchCount: number // distinct active needs that matched this property
|
||||
pipelineCount: number // pipeline entries across all users
|
||||
viewCount: number // total detail-page opens
|
||||
}
|
||||
|
||||
export const PROPERTY_HEAT: Record<string, PropertyHeat> = {
|
||||
'prop-001': { searchCount: 7, pipelineCount: 4, viewCount: 52 },
|
||||
'prop-007': { searchCount: 5, pipelineCount: 3, viewCount: 38 },
|
||||
'prop-043': { searchCount: 9, pipelineCount: 2, viewCount: 61 },
|
||||
'prop-012': { searchCount: 4, pipelineCount: 3, viewCount: 29 },
|
||||
'prop-015': { searchCount: 6, pipelineCount: 2, viewCount: 44 },
|
||||
'prop-003': { searchCount: 3, pipelineCount: 2, viewCount: 21 },
|
||||
'prop-042': { searchCount: 4, pipelineCount: 1, viewCount: 33 },
|
||||
'prop-044': { searchCount: 8, pipelineCount: 2, viewCount: 57 },
|
||||
'prop-040': { searchCount: 5, pipelineCount: 2, viewCount: 31 },
|
||||
'prop-002': { searchCount: 3, pipelineCount: 2, viewCount: 18 },
|
||||
}
|
||||
|
||||
export type HeatLevel = 'HOT' | 'VERY_HOT' | null
|
||||
|
||||
export function getHeatLevel(propertyId: string | undefined): HeatLevel {
|
||||
if (!propertyId) return null
|
||||
const h = PROPERTY_HEAT[propertyId]
|
||||
if (!h) return null
|
||||
if (h.pipelineCount >= 3 || h.searchCount >= 7) return 'VERY_HOT'
|
||||
if (h.pipelineCount >= 2 || h.searchCount >= 4) return 'HOT'
|
||||
return null
|
||||
}
|
||||
|
||||
export function heatTooltip(propertyId: string): string {
|
||||
const h = PROPERTY_HEAT[propertyId]
|
||||
if (!h) return ''
|
||||
const parts: string[] = []
|
||||
if (h.searchCount > 0) parts.push(`${h.searchCount} aktive Suchen`)
|
||||
if (h.pipelineCount > 0) parts.push(`${h.pipelineCount}× in Pipeline`)
|
||||
if (h.viewCount > 0) parts.push(`${h.viewCount} Aufrufe`)
|
||||
return parts.join(' · ')
|
||||
}
|
||||
Reference in New Issue
Block a user