Files
property-match/src/components/anfragencenter/EditableOfferFieldList.tsx
T
Benjamin Sutter c4c29ef7d3 feat: F030 Anfragencenter — Aktive & Latente Anfragen + Angebot-Wizard
Neuer Menüpunkt «Anfragencenter» (ehemals «Eingehende Bedarfe»):

Aktive Anfragen:
- Split-View: Anfrageliste (Liste/Grid-Toggle) + Chat-Detailansicht
- Chat-Verlauf mit Sender-Styling (Mieter links, Supply rechts)
- Antwortformular mit Betreff, Nachricht, Anhänge, Statuswechsel
- Zugehörige Property Card neben dem Chat

Latente Anfragen:
- Drei-Spalten-Layout: Need-Liste | Need-Detail | Eigene Objekte
- Need Cards mit AI-Zusammenfassung, Must-Haves, Präferenzen
- Eigene Portfolio-Objekte sortiert nach deterministischem Match-Score
- Checkbox-Selektion für Angebotsauswahl

Angebot-Wizard (4 Schritte):
- Schritt 1: Objekte auswählen (mit Score-Vorschau)
- Schritt 2: PDF-Vorschau + editierbare Textfelder
- Schritt 3: Angebot prüfen & bestätigen
- Schritt 4: Nachricht an Suchenden mit KI-generierter Mail

Architektur:
- Domain: Inquiry, LatentNeed, OfferDraft Types
- Provider: IInquiryProvider, ILatentNeedProvider, IOfferProvider + Mockups
- Services: inquiryService, latentNeedService, offerService
- Hooks: useInquiries, useLatentNeeds, useOffers (TanStack Query)
- Store: offerWizardStore (Zustand, lokaler Wizard-State)
- 27 neue Komponenten, alle Loading/Empty/Error States

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-18 18:03:05 +02:00

48 lines
1.4 KiB
TypeScript

import { Box, TextField, Typography } from '@mui/material'
import type { OfferEditableField } from '../../domain/offer'
interface EditableOfferFieldListProps {
fields: OfferEditableField[]
values: Record<string, string>
onChange: (id: string, value: string) => void
}
export function EditableOfferFieldList({ fields, values, onChange }: EditableOfferFieldListProps) {
return (
<Box sx={{ display: 'flex', flexDirection: 'column', gap: 1.5 }}>
{fields.map(f => {
const value = values[f.id] !== undefined ? values[f.id] : f.value
return (
<Box key={f.id}>
<Typography
variant="caption"
sx={{
color: '#64748b',
fontWeight: 600,
fontSize: '0.7rem',
textTransform: 'uppercase',
letterSpacing: 0.5,
mb: 0.5,
display: 'block',
}}
>
{f.label}
</Typography>
<TextField
fullWidth
size="small"
value={value}
onChange={e => onChange(f.id, e.target.value)}
multiline={f.fieldType === 'textarea'}
rows={f.fieldType === 'textarea' ? 3 : undefined}
sx={{
'& .MuiInputBase-input': { fontSize: '0.85rem' },
}}
/>
</Box>
)
})}
</Box>
)
}