fix: BerichtDialog, images, and add property number + floor/unit structure

- BerichtDialog: conditionally mount instead of always-mounted with
  open prop; starts in 'generating' state immediately on open
- Images: fix all 6 wrong VERIFIED_PORTFOLIO and EXTERNAL_MARKET photos
  to match spec per assetType (OFFICE/RETAIL/LOGISTICS/PRODUCTION/MIXED)
- Domain: add PropertyUnit interface + propertyNumber field to Property
- Mock data: propertyNumber + units[] for prop-001/007/012/013
- UI: Stockwerkstruktur section in Übersicht tab (floor/unit table with
  availability, tenant, area); Objekt-Nr. shown below key metrics

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Sutter
2026-05-19 16:14:22 +02:00
parent 0651333030
commit 7800d127fe
4 changed files with 104 additions and 27 deletions
@@ -98,33 +98,29 @@ function SignalCard({ signal }: { signal: PropertyMarketSignal }) {
type PdfState = 'idle' | 'generating' | 'ready'
interface BerichtDialogProps {
open: boolean
onClose: () => void
report: MarketReport | null
propertyId: string
}
function BerichtDialog({ open, onClose, report, propertyId }: BerichtDialogProps) {
const [state, setState] = useState<PdfState>('idle')
function BerichtDialog({ onClose, report, propertyId }: Omit<BerichtDialogProps, 'open'>) {
const [state, setState] = useState<PdfState>('generating')
const [progress, setProgress] = useState(0)
const timerRef = useRef<ReturnType<typeof setInterval> | null>(null)
useEffect(() => {
if (!open) { setState('idle'); setProgress(0); return }
setState('generating')
setProgress(0)
let p = 0
timerRef.current = setInterval(() => {
p += Math.random() * 18 + 8
if (p >= 100) {
p = 100
clearInterval(timerRef.current!)
setTimeout(() => setState('ready'), 300)
setState('ready')
}
setProgress(Math.min(100, p))
}, 200)
return () => { if (timerRef.current) clearInterval(timerRef.current) }
}, [open])
}, [])
function handleDownload() {
const signals = report?.signals ?? []
@@ -152,7 +148,7 @@ function BerichtDialog({ open, onClose, report, propertyId }: BerichtDialogProps
}
return (
<Dialog open={open} onClose={state === 'generating' ? undefined : onClose} maxWidth="xs" fullWidth>
<Dialog open onClose={state === 'generating' ? undefined : onClose} maxWidth="xs" fullWidth>
<DialogTitle sx={{ fontWeight: 700, fontSize: '1rem', pb: 1 }}>
Bericht erstellen
</DialogTitle>
@@ -289,12 +285,13 @@ export function PropertyMarketSignalsTab({ propertyId }: Props) {
})
)}
<BerichtDialog
open={dialogOpen}
onClose={() => setDialogOpen(false)}
report={report}
propertyId={propertyId}
/>
{dialogOpen && (
<BerichtDialog
onClose={() => setDialogOpen(false)}
report={report}
propertyId={propertyId}
/>
)}
</Box>
)
}