import { Box, Card, Typography, Alert, Stack, Chip } from '@mui/material' import type { ParseNeedResult, ParsedNeedCriteria } from '../../domain/needBuilder' import { ExtractedFieldRow } from './ExtractedFieldRow' interface Props { result: ParseNeedResult criteria: ParsedNeedCriteria onCriteriaChange: (c: ParsedNeedCriteria) => void } const ASSET_LABELS: Record = { OFFICE: 'Büro', LOGISTICS: 'Logistik / Lager', RETAIL: 'Retail', PRODUCTION: 'Produktion', GASTRO: 'Gastro / F&B', LIGHT_INDUSTRIAL: 'Light Industrial', MIXED: 'Gemischt', UNKNOWN: 'Unbekannt', } // ── Parse helpers ────────────────────────────────────────────────────────────── function parseAreaRange(s: string): ParsedNeedCriteria['areaRange'] { const m = s.match(/(\d+)\s*[–\-]\s*(\d+)/) if (m) return { min: parseInt(m[1]), max: parseInt(m[2]) } const n = s.match(/(\d+)/) if (n) { const v = parseInt(n[1]); return { min: Math.round(v * 0.8), max: Math.round(v * 1.2) } } return undefined } function parseBudget(s: string): ParsedNeedCriteria['budgetRange'] { const n = s.match(/(\d+)/) if (!n) return undefined return { maxPerSqm: parseInt(n[1]), currency: 'CHF' } } function parseList(s: string): string[] { return s.split(',').map(x => x.trim()).filter(Boolean) } function displayAreaRange(v: ParsedNeedCriteria['areaRange']): string { return v ? `${v.min}–${v.max} m²` : '' } function displayBudget(v: ParsedNeedCriteria['budgetRange']): string { return v ? `CHF ${v.maxPerSqm}/m²` : '' } function displayTiming(v: ParsedNeedCriteria['timing']): string { if (!v) return '' return `ab ${v.earliestMoveIn}${v.flexibleTiming ? ' (flexibel)' : ''}` } // ── Section wrapper ──────────────────────────────────────────────────────────── function Section({ title, children }: { title: string; children: React.ReactNode }) { return ( {title} {children} ) } // ── Main component ───────────────────────────────────────────────────────────── export function CriteriaReviewPanel({ result, criteria: c, onCriteriaChange: set }: Props) { const { confidenceByField: conf, missingFields, assumptions } = result return ( Extrahierte Kriterien {result.rawSummary} {/* ── Hard Facts ──────────────────────────────────────────────────── */}
set({ ...c, assetType: (v.toUpperCase() as ParsedNeedCriteria['assetType']) })} /> set({ ...c, areaRange: parseAreaRange(v) })} /> set({ ...c, preferredLocations: parseList(v) })} /> set({ ...c, budgetRange: parseBudget(v) })} /> set({ ...c, timing: { earliestMoveIn: v, latestMoveIn: v, flexibleTiming: v.toLowerCase().includes('flex') } })} />
{/* ── Must-haves ──────────────────────────────────────────────────── */}
set({ ...c, mustHaveCriteria: parseList(v) })} /> set({ ...c, parkingNeed: v.toLowerCase().startsWith('j') })} />
{/* ── AI Assumptions ──────────────────────────────────────────────── */} {assumptions.length > 0 && (
{assumptions.map((a, i) => ( {a} ))}
)} {/* ── Missing Information ─────────────────────────────────────────── */} {missingFields.length > 0 && (
{missingFields.map(f => ( ))}
)}
) }