diff --git a/src/pages/demand/Results.tsx b/src/pages/demand/Results.tsx index c3a5c55..70eb18e 100644 --- a/src/pages/demand/Results.tsx +++ b/src/pages/demand/Results.tsx @@ -44,6 +44,8 @@ export default function Results() { (localStorage.getItem('view-results') as 'list' | 'grid') ?? 'list' ) + const [selectedNeedId, setSelectedNeedId] = useState(undefined) + // When coming from NeedBuilder, invalidate so the freshly created need is included const activeNeedIdFromNav = (location.state as { activeNeedId?: string } | null)?.activeNeedId @@ -55,14 +57,12 @@ export default function Results() { gcTime: 0, }) - // Prefer the ID passed from NeedBuilder; fall back to most-recently-created - const activeNeed = needResp?.data - ? activeNeedIdFromNav - ? (needResp.data.find(n => n.id === activeNeedIdFromNav) ?? needResp.data[0]) - : [...needResp.data].sort((a, b) => - new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime() - )[0] - : undefined + const allNeeds = needResp?.data ?? [] + + // Priority: explicit user selection → nav (just came from NeedBuilder) → first need in list + const effectiveNeedId = selectedNeedId ?? activeNeedIdFromNav ?? allNeeds[0]?.id + + const activeNeed = allNeeds.find(n => n.id === effectiveNeedId) ?? allNeeds[0] // Ensure query cache is invalidated when a new need was just created if (activeNeedIdFromNav) { @@ -127,6 +127,25 @@ export default function Results() { {activeNeed && ( + {/* Need selector — all saved searches as chips */} + {allNeeds.length > 1 && ( + + {allNeeds.map(n => ( + setSelectedNeedId(n.id)} + sx={n.id === activeNeed.id + ? { fontSize: '0.68rem', height: 22, bgcolor: '#1e3a5f', color: 'white', cursor: 'pointer' } + : { fontSize: '0.68rem', height: 22, color: '#64748b', borderColor: '#cbd5e1', cursor: 'pointer' } + } + /> + ))} + + )} + diff --git a/src/services/aiService.ts b/src/services/aiService.ts index beeaea4..318a416 100644 --- a/src/services/aiService.ts +++ b/src/services/aiService.ts @@ -177,14 +177,16 @@ function mockParseNeed(input: string): ParseNeedResult { const budgetMaxMatch = input.match(/(?:max\.?|bis|höchstens)\s*(?:CHF\s*)?(\d+)/i) let budgetRange: { maxPerSqm: number; currency: string } | undefined let budgetConfidence = 0.20 + // Monthly-to-annual threshold: Swiss retail quotes monthly (150/m²/mon → 1800/year), + // office/logistics quote monthly too but at lower values (45/m²/mon → 540/year). + const monthlyThreshold = assetType === 'RETAIL' ? 500 : 150 if (budgetPerSqmMatch) { const raw = parseInt(budgetPerSqmMatch[1]) - // Values < 100 are monthly (e.g. CHF 45/m²/month); convert to annual - budgetRange = { maxPerSqm: raw < 100 ? raw * 12 : raw, currency: 'CHF' } + budgetRange = { maxPerSqm: raw < monthlyThreshold ? raw * 12 : raw, currency: 'CHF' } budgetConfidence = 0.92 } else if (budgetMaxMatch) { const raw = parseInt(budgetMaxMatch[1]) - budgetRange = { maxPerSqm: raw < 100 ? raw * 12 : raw, currency: 'CHF' } + budgetRange = { maxPerSqm: raw < monthlyThreshold ? raw * 12 : raw, currency: 'CHF' } budgetConfidence = 0.60 }