import { Box, Card, Chip, Divider, LinearProgress, Stack, TextField, Typography, Alert } from '@mui/material' import { MapPin, Ruler, Wallet, Clock, CheckSquare, ShieldAlert } from 'lucide-react' import type { ParsedNeedCriteria } from '../../domain/needBuilder' import { WEIGHTING_KEYS, WEIGHTING_LABELS } from '../../domain/needBuilder' import type { WeightingKey } from '../../domain/needBuilder' interface Props { criteria: ParsedNeedCriteria weights: Record confidenceByField: Record missingFields: string[] needTitle: string onNeedTitleChange: (v: string) => void } const ASSET_LABELS: Record = { OFFICE: 'Büro', LOGISTICS: 'Logistik / Lager', RETAIL: 'Retail', PRODUCTION: 'Produktion', GASTRO: 'Gastro / F&B', LIGHT_INDUSTRIAL: 'Light Industrial', } const CRITICAL_FIELDS = ['assetType', 'areaRange', 'preferredLocations', 'budgetRange', 'timing'] export function NeedCardPreview({ criteria: c, weights, confidenceByField, missingFields, needTitle, onNeedTitleChange }: Props) { const maxWeight = Math.max(...WEIGHTING_KEYS.map(k => weights[k] ?? 0), 0.01) const fieldEntries = Object.entries(confidenceByField) const overallConfidence = fieldEntries.length > 0 ? fieldEntries.reduce((sum, [, v]) => sum + v, 0) / fieldEntries.length : 0 const lowConfidenceFields = fieldEntries.filter(([, v]) => v < 0.6).map(([k]) => k) const criticalMissing = missingFields.filter(f => CRITICAL_FIELDS.some(cf => f.toLowerCase().includes(cf.toLowerCase()))) const isLowConfidence = overallConfidence < 0.6 return ( Vorschau — Neuer Bedarf {/* Need Title */} onNeedTitleChange(e.target.value)} sx={{ mb: 2 }} /> {/* Low-confidence warning */} {isLowConfidence && ( } sx={{ mb: 2 }}> Gesamtkonfidenz niedrig ({Math.round(overallConfidence * 100)}%) — Bedarf wird als Entwurf gespeichert und muss manuell geprüft werden. )} {/* Critical missing fields */} {criticalMissing.length > 0 && ( Fehlende Pflichtfelder: {criticalMissing.join(', ')}. Bitte in den Kriterien ergänzen. )} {/* Header */} {c.assetType && ( )} {c.preferredLocations && c.preferredLocations.length > 0 && ( Standort {c.preferredLocations.join(', ')} )} {c.areaRange && ( Fläche {c.areaRange.min}–{c.areaRange.max} m² )} {c.budgetRange && ( Budget max. CHF {c.budgetRange.maxPerSqm}/m² )} {c.timing && ( Verfügbarkeit ab {c.timing.earliestMoveIn} )} {c.mustHaveCriteria && c.mustHaveCriteria.length > 0 && ( Must-haves {c.mustHaveCriteria.map(m => ( ))} )} {/* Confidence Summary */} Gesamtkonfidenz = 0.7 ? '#1a7a4a' : overallConfidence >= 0.5 ? '#d97706' : '#c0392b' }} > {Math.round(overallConfidence * 100)}% = 0.7 ? '#1a7a4a' : overallConfidence >= 0.5 ? '#d97706' : '#c0392b', }, }} /> {lowConfidenceFields.length > 0 && ( Unsichere Felder: {lowConfidenceFields.join(', ')} )} {/* Weights */} Gewichtungsprofil {WEIGHTING_KEYS.map(k => { const pct = Math.round((weights[k] ?? 0) * 100) return ( {WEIGHTING_LABELS[k]} {pct}% ) })} ) }