feat: Anfragencenter Parts A–E — read/unread, prep wizard, offer flow, report preview

- Part A: Replace InquiryStatus badges with WhatsApp-style unread indicators
  (isRead, unreadCount, lastReadAt on Inquiry; markThreadAsRead in service + hook)
- Part B: RelatedPropertyCardPanel — reposition "Objekt ansehen", add "Weitere
  Matches" section via matchService.getAdditionalMatchesForInquiry
- Part C: PreparationWizard 4-step dialog — property selection, report generation
  progress, field editing + ReportObjectFieldSelector, PDF preview + finalize
- Part D: OfferCreationWizard 4-step dialog triggered from first tenant message —
  data capture, field editing, viewing appointments, PDF generation + attach to reply
- Part E: LatentInquiryReportPreview (2-page A4 doc), ReportObjectFieldSelector
  (5 accordion groups, 35+ optional fields), mapImageUrl on Property domain

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Sutter
2026-05-19 19:20:13 +02:00
parent 279b55d70e
commit b4d398270f
26 changed files with 1874 additions and 188 deletions
+32 -4
View File
@@ -1,7 +1,6 @@
import { Box, Paper, Typography } from '@mui/material'
import { Building2 } from 'lucide-react'
import type { Inquiry } from '../../domain/inquiry'
import { InquiryStatusBadge } from './InquiryStatusBadge'
import { formatInquiryDate, propertyLabelFromId } from './inquiryUtils'
interface InquiryCardProps {
@@ -11,6 +10,8 @@ interface InquiryCardProps {
}
export function InquiryCard({ inquiry, selected, onClick }: InquiryCardProps) {
const hasUnread = !inquiry.isRead && inquiry.unreadCount > 0
return (
<Paper
onClick={onClick}
@@ -34,17 +35,44 @@ export function InquiryCard({ inquiry, selected, onClick }: InquiryCardProps) {
}}
>
<Box sx={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 1 }}>
<Typography variant="body2" sx={{ fontWeight: 600, color: '#0f172a', fontSize: '0.85rem', lineHeight: 1.3 }}>
<Typography
variant="body2"
sx={{
fontWeight: hasUnread ? 700 : 600,
color: '#0f172a',
fontSize: '0.85rem',
lineHeight: 1.3,
}}
>
{inquiry.tenantName}
{inquiry.tenantCompany ? ` · ${inquiry.tenantCompany}` : ''}
</Typography>
<InquiryStatusBadge status={inquiry.status} />
{hasUnread && (
<Box
sx={{
minWidth: 20,
height: 20,
borderRadius: '50%',
bgcolor: '#2563eb',
color: 'white',
fontSize: '0.65rem',
fontWeight: 700,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
flexShrink: 0,
px: inquiry.unreadCount > 9 ? 0.75 : 0,
}}
>
{inquiry.unreadCount}
</Box>
)}
</Box>
<Typography
variant="body2"
sx={{
fontWeight: 500,
fontWeight: hasUnread ? 600 : 500,
color: '#1e293b',
fontSize: '0.85rem',
display: '-webkit-box',