feat: F007 property repository & detail view
- useProperties: added usePropertyById, usePropertyMatches, usePropertySignals hooks - propertyService.getProperties(), matchService.getMatchesForProperty(), futureSignalService.getSignalsForProperty() added - PropertyFilterBar: asset type chips, availability select, sort select, search - PropertyTable: sortable columns, row selection highlight, loading skeletons, empty/error states, Eye/Plus/Bookmark actions - PropertyCard: decision-object card with header, primary, matchability, data quality and action zones; card states (selected, compareSelected, stale, low-confidence) - PropertyDetailView: 7-tab detail panel (Übersicht, Hard Facts, Soft Factors, Matchability, Datenqualität, Quelle, Signale) with low-quality banner, missing field UX, data update CTA - PropertyDetailSkeleton: loading state - Properties page: two-panel layout (table + sliding detail panel) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
import type { AssetType, AvailabilityStatus, ResultType } from '../../domain/enums'
|
||||
|
||||
export function getAssetTypeLabel(type: AssetType): string {
|
||||
const labels: Record<string, string> = {
|
||||
OFFICE: 'Büro',
|
||||
LOGISTICS: 'Logistik',
|
||||
RETAIL: 'Retail',
|
||||
GASTRO: 'Gastro',
|
||||
PRODUCTION: 'Produktion',
|
||||
MIXED: 'Gemischt',
|
||||
LIGHT_INDUSTRIAL: 'Leichtindustrie',
|
||||
UNKNOWN: 'Unbekannt',
|
||||
}
|
||||
return labels[type] ?? type
|
||||
}
|
||||
|
||||
export function getAssetTypeColor(type: AssetType): string {
|
||||
const colors: Record<string, string> = {
|
||||
OFFICE: '#1e3a5f',
|
||||
LOGISTICS: '#d97706',
|
||||
RETAIL: '#7c3aed',
|
||||
GASTRO: '#0d9488',
|
||||
PRODUCTION: '#92400e',
|
||||
MIXED: '#6b7280',
|
||||
LIGHT_INDUSTRIAL: '#b45309',
|
||||
UNKNOWN: '#9ca3af',
|
||||
}
|
||||
return colors[type] ?? '#6b7280'
|
||||
}
|
||||
|
||||
export function getAvailabilityLabel(status: AvailabilityStatus): string {
|
||||
const labels: Record<string, string> = {
|
||||
AVAILABLE_NOW: 'Verfügbar',
|
||||
AVAILABLE_SOON: 'Bald verfügbar',
|
||||
FUTURE_SIGNAL: 'Zukunftssignal',
|
||||
OCCUPIED: 'Belegt',
|
||||
UNKNOWN: 'Unbekannt',
|
||||
}
|
||||
return labels[status] ?? status
|
||||
}
|
||||
|
||||
export function getAvailabilityChipColor(status: AvailabilityStatus): 'success' | 'warning' | 'secondary' | 'error' | 'default' {
|
||||
const colors: Record<string, 'success' | 'warning' | 'secondary' | 'error' | 'default'> = {
|
||||
AVAILABLE_NOW: 'success',
|
||||
AVAILABLE_SOON: 'warning',
|
||||
FUTURE_SIGNAL: 'secondary',
|
||||
OCCUPIED: 'error',
|
||||
UNKNOWN: 'default',
|
||||
}
|
||||
return colors[status] ?? 'default'
|
||||
}
|
||||
|
||||
export function getResultTypeLabel(type: ResultType): string {
|
||||
const labels: Record<string, string> = {
|
||||
VERIFIED_PORTFOLIO: 'Portfolio',
|
||||
EXTERNAL_MARKET: 'Markt',
|
||||
FUTURE_AVAILABILITY: 'Zukunft',
|
||||
}
|
||||
return labels[type] ?? type
|
||||
}
|
||||
|
||||
export function getResultTypeColor(type: ResultType): string {
|
||||
const colors: Record<string, string> = {
|
||||
VERIFIED_PORTFOLIO: '#1e3a5f',
|
||||
EXTERNAL_MARKET: '#1a7a4a',
|
||||
FUTURE_AVAILABILITY: '#7c3aed',
|
||||
}
|
||||
return colors[type] ?? '#6b7280'
|
||||
}
|
||||
|
||||
export function qualityColor(score: number): 'success' | 'warning' | 'error' {
|
||||
if (score >= 0.8) return 'success'
|
||||
if (score >= 0.6) return 'warning'
|
||||
return 'error'
|
||||
}
|
||||
|
||||
export function confidenceColor(score: number): string {
|
||||
if (score >= 0.85) return '#1a7a4a'
|
||||
if (score >= 0.65) return '#1e3a5f'
|
||||
return '#d97706'
|
||||
}
|
||||
Reference in New Issue
Block a user