a825672197
- Properties page: collapsible decision/filter strip (localStorage state), slim single-row Datenpflege status bar (chips + button), 4-column card grid - PropertyIntelligenceCard: reduced image height (160→120px), tighter body padding - OfferWizard (latente Anfragen): new "Felder wählen" step between property selection and PDF preview; uses ReportObjectFieldSelector per property - MockPdfPreview: adds second PDF page showing selected properties side by side with photo, title, location and all chosen hard/soft fact fields - offerWizardStore: adds select_fields step type and fieldSelections state Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
88 lines
3.5 KiB
TypeScript
88 lines
3.5 KiB
TypeScript
import { useEffect } from 'react'
|
|
import { Box, Button, Stack, Typography } from '@mui/material'
|
|
import { ArrowLeft } from 'lucide-react'
|
|
import { useOfferWizardStore } from '../../stores/offerWizardStore'
|
|
import { useProperties } from '../../hooks/useProperties'
|
|
import { ReportObjectFieldSelector } from './ReportObjectFieldSelector'
|
|
import type { ReportObjectFieldKey, ReportObjectFieldSelection } from '../../domain/inquiryReport'
|
|
|
|
const DEFAULT_FIELDS: ReportObjectFieldKey[] = ['areaSqm', 'rentPricePerSqm', 'availabilityDate']
|
|
const MANDATORY_FIELDS: ReportObjectFieldKey[] = ['title', 'location', 'mapImageUrl', 'images']
|
|
|
|
export function OfferFieldSelectionStep() {
|
|
const propertyIds = useOfferWizardStore(s => s.selectedPropertyIds)
|
|
const fieldSelections = useOfferWizardStore(s => s.fieldSelections)
|
|
const setFieldSelections = useOfferWizardStore(s => s.setFieldSelections)
|
|
const updateFieldSelection = useOfferWizardStore(s => s.updateFieldSelection)
|
|
const setStep = useOfferWizardStore(s => s.setStep)
|
|
|
|
const { data: allProperties = [] } = useProperties()
|
|
const selectedProperties = allProperties.filter(p => propertyIds.includes(p.id))
|
|
|
|
// Initialise selections when properties are loaded or change
|
|
useEffect(() => {
|
|
if (selectedProperties.length === 0) return
|
|
const existing = new Set(fieldSelections.map(fs => fs.propertyId))
|
|
const missing = selectedProperties.filter(p => !existing.has(p.id))
|
|
if (missing.length > 0) {
|
|
setFieldSelections([
|
|
...fieldSelections,
|
|
...missing.map(p => ({
|
|
propertyId: p.id,
|
|
mandatoryFields: MANDATORY_FIELDS,
|
|
selectedOptionalFields: DEFAULT_FIELDS,
|
|
})),
|
|
])
|
|
}
|
|
// run only when property list or selections change length
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [selectedProperties.length, fieldSelections.length])
|
|
|
|
return (
|
|
<Box sx={{ display: 'flex', flexDirection: 'column', height: '100%', overflow: 'hidden' }}>
|
|
<Box sx={{ flex: 1, overflowY: 'auto', p: 3 }}>
|
|
<Typography variant="body2" sx={{ color: '#64748b', mb: 2.5 }}>
|
|
Wählen Sie die Datenfelder, die auf der Objektseite des Angebots angezeigt werden sollen.
|
|
Pflichtfelder (Titel, Standort, Foto) sind immer enthalten.
|
|
</Typography>
|
|
|
|
<Stack spacing={2}>
|
|
{selectedProperties.map(p => {
|
|
const selection: ReportObjectFieldSelection =
|
|
fieldSelections.find(fs => fs.propertyId === p.id) ?? {
|
|
propertyId: p.id,
|
|
mandatoryFields: MANDATORY_FIELDS,
|
|
selectedOptionalFields: DEFAULT_FIELDS,
|
|
}
|
|
return (
|
|
<ReportObjectFieldSelector
|
|
key={p.id}
|
|
propertyTitle={p.title}
|
|
value={selection}
|
|
onChange={v => updateFieldSelection(p.id, v)}
|
|
/>
|
|
)
|
|
})}
|
|
</Stack>
|
|
</Box>
|
|
|
|
<Box sx={{ px: 3, py: 2, borderTop: '1px solid #e2e8f0', bgcolor: 'white', display: 'flex', justifyContent: 'space-between', flexShrink: 0 }}>
|
|
<Button
|
|
startIcon={<ArrowLeft size={14} />}
|
|
onClick={() => setStep('select_properties')}
|
|
sx={{ textTransform: 'none' }}
|
|
>
|
|
Zurück
|
|
</Button>
|
|
<Button
|
|
variant="contained"
|
|
onClick={() => setStep('pdf_review')}
|
|
sx={{ textTransform: 'none', bgcolor: '#1e3a5f', '&:hover': { bgcolor: '#16304d' } }}
|
|
>
|
|
Weiter
|
|
</Button>
|
|
</Box>
|
|
</Box>
|
|
)
|
|
}
|