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
+54 -30
View File
@@ -1,11 +1,12 @@
import type { Inquiry } from '../domain/inquiry'
export const mockInquiries: Inquiry[] = [
// 1 — NEW
// 1 — UNREAD
{
id: 'inq-001',
organizationId: 'org-wincasa',
propertyId: 'prop-001',
needId: 'need-001',
tenantName: 'Sandra Meier',
tenantCompany: 'Innovatech AG',
tenantEmail: 'sandra.meier@innovatech.ch',
@@ -13,6 +14,8 @@ export const mockInquiries: Inquiry[] = [
message:
'Guten Tag\n\nWir interessieren uns für die Bürofläche an der Zollstrasse 12 in Zürich-West. Könnten wir bitte einen Besichtigungstermin in der kommenden Woche vereinbaren?\n\nFreundliche Grüsse\nSandra Meier',
status: 'new',
unreadCount: 1,
isRead: false,
matchScore: 91,
createdAt: '2026-05-17T08:32:00Z',
updatedAt: '2026-05-17T08:32:00Z',
@@ -31,21 +34,24 @@ export const mockInquiries: Inquiry[] = [
],
},
// 2 — NEW
// 2 — UNREAD
{
id: 'inq-002',
organizationId: 'org-wincasa',
propertyId: 'prop-009',
tenantName: 'Markus Frei',
tenantCompany: 'Frei Logistik AG',
tenantEmail: 'm.frei@frei-logistik.ch',
subject: 'Lagerfläche Winterthur — Verfügbarkeit?',
id: inq-002,
organizationId: org-wincasa,
propertyId: prop-009,
needId: need-002,
tenantName: Markus Frei,
tenantCompany: Frei Logistik AG,
tenantEmail: m.frei@frei-logistik.ch,
subject: Lagerfläche Winterthur Verfügbarkeit?,
message:
'Sehr geehrte Damen und Herren\n\nIst Ihre Logistikfläche in Winterthur noch verfügbar? Wir benötigen ab September ca. 3000 m² mit Rampe und Hochregalmöglichkeit.\n\nMit freundlichen Grüssen\nMarkus Frei',
status: 'new',
Sehr geehrte Damen und Herren\n\nIst Ihre Logistikfläche in Winterthur noch verfügbar? Wir benötigen ab September ca. 3000 m² mit Rampe und Hochregalmöglichkeit.\n\nMit freundlichen Grüssen\nMarkus Frei,
status: new,
unreadCount: 1,
isRead: false,
matchScore: 85,
createdAt: '2026-05-17T11:14:00Z',
updatedAt: '2026-05-17T11:14:00Z',
createdAt: 2026-05-17T11:14:00Z,
updatedAt: 2026-05-17T11:14:00Z,
thread: [
{
id: 'msg-002-1',
@@ -61,7 +67,7 @@ export const mockInquiries: Inquiry[] = [
],
},
// 3 — NEW
// 3 — READ
{
id: 'inq-003',
organizationId: 'org-wincasa',
@@ -73,6 +79,9 @@ export const mockInquiries: Inquiry[] = [
message:
'Guten Tag\n\nKönnten Sie uns bitte Detailunterlagen sowie einen Grundriss der Retailfläche am Löwenplatz zukommen lassen? Wir planen die Eröffnung unseres neuen Flagship-Stores im Frühjahr 2026.\n\nBesten Dank\nLaura Bianchi',
status: 'new',
unreadCount: 0,
isRead: true,
lastReadAt: '2026-05-16T16:10:00Z',
matchScore: 88,
createdAt: '2026-05-16T15:50:00Z',
updatedAt: '2026-05-16T15:50:00Z',
@@ -91,11 +100,12 @@ export const mockInquiries: Inquiry[] = [
],
},
// 4 — IN_PROGRESS
// 4 — UNREAD (3 messages)
{
id: 'inq-004',
organizationId: 'org-wincasa',
propertyId: 'prop-012',
needId: 'need-004',
tenantName: 'Daniel Hofer',
tenantCompany: 'Hofer Treuhand AG',
tenantEmail: 'd.hofer@hofer-treuhand.ch',
@@ -103,6 +113,8 @@ export const mockInquiries: Inquiry[] = [
message:
'Sehr geehrte Damen und Herren\n\nDie Büroflächen in Zug entsprechen genau unserem Profil. Bitte senden Sie uns die detaillierten Mietkonditionen sowie Informationen zu Nebenkosten und Mindestmietdauer.\n\nFreundliche Grüsse\nDaniel Hofer',
status: 'in_progress',
unreadCount: 3,
isRead: false,
matchScore: 93,
createdAt: '2026-05-14T09:20:00Z',
updatedAt: '2026-05-15T14:00:00Z',
@@ -134,7 +146,7 @@ export const mockInquiries: Inquiry[] = [
],
},
// 5 — IN_PROGRESS
// 5 — READ
{
id: 'inq-005',
organizationId: 'org-wincasa',
@@ -146,6 +158,9 @@ export const mockInquiries: Inquiry[] = [
message:
'Guten Tag\n\nDie Bürofläche an der Thurgauerstrasse interessiert uns sehr. Könnten Sie uns einen aktuellen Grundriss sowie Angaben zum Ausbaustand zukommen lassen?\n\nFreundliche Grüsse\nPetra Wyss',
status: 'in_progress',
unreadCount: 0,
isRead: true,
lastReadAt: '2026-05-14T17:00:00Z',
matchScore: 79,
createdAt: '2026-05-13T13:10:00Z',
updatedAt: '2026-05-14T16:20:00Z',
@@ -186,21 +201,24 @@ export const mockInquiries: Inquiry[] = [
],
},
// 6 — ANSWERED
// 6 — READ
{
id: 'inq-006',
organizationId: 'org-wincasa',
propertyId: 'prop-002',
tenantName: 'Thomas Brun',
tenantCompany: 'Schweizer Logistik GmbH',
tenantEmail: 't.brun@swisslogistik.ch',
subject: 'Lagerfläche Hardstrasse Basel',
id: inq-006,
organizationId: org-wincasa,
propertyId: prop-002,
tenantName: Thomas Brun,
tenantCompany: Schweizer Logistik GmbH,
tenantEmail: t.brun@swisslogistik.ch,
subject: Lagerfläche Hardstrasse Basel,
message:
'Guten Tag\n\nWir suchen ab Juli eine Lagerfläche in Basel mit ca. 2500 m². Ihre Liegenschaft an der Hardstrasse entspricht unserem Profil. Können wir besichtigen?\n\nThomas Brun',
status: 'answered',
Guten Tag\n\nWir suchen ab Juli eine Lagerfläche in Basel mit ca. 2500 m². Ihre Liegenschaft an der Hardstrasse entspricht unserem Profil. Können wir besichtigen?\n\nThomas Brun,
status: answered,
unreadCount: 0,
isRead: true,
lastReadAt: 2026-05-10T10:00:00Z,
matchScore: 87,
createdAt: '2026-05-08T10:00:00Z',
updatedAt: '2026-05-10T09:30:00Z',
createdAt: 2026-05-08T10:00:00Z,
updatedAt: 2026-05-10T09:30:00Z,
thread: [
{
id: 'msg-006-1',
@@ -236,7 +254,7 @@ export const mockInquiries: Inquiry[] = [
],
},
// 7 — ANSWERED
// 7 — READ
{
id: 'inq-007',
organizationId: 'org-wincasa',
@@ -248,6 +266,9 @@ export const mockInquiries: Inquiry[] = [
message:
'Guten Tag\n\nWir würden gerne einen Mietvertrag für die Bürofläche im Dreispitz aufsetzen. Bitte senden Sie uns die Vertragsvorlage.\n\nCaroline Roth',
status: 'answered',
unreadCount: 0,
isRead: true,
lastReadAt: '2026-05-06T12:00:00Z',
matchScore: 82,
createdAt: '2026-05-05T09:00:00Z',
updatedAt: '2026-05-06T11:00:00Z',
@@ -279,7 +300,7 @@ export const mockInquiries: Inquiry[] = [
],
},
// 8 — ARCHIVED
// 8 — READ (archived)
{
id: 'inq-008',
organizationId: 'org-wincasa',
@@ -291,6 +312,9 @@ export const mockInquiries: Inquiry[] = [
message:
'Guten Tag\n\nWir suchen eine Produktionsfläche im Raum Bern. Ihre Liegenschaft erscheint passend, jedoch ist die Hallenhöhe etwas niedrig. Können Sie hier mehr Details geben?\n\nJonas Keller',
status: 'archived',
unreadCount: 0,
isRead: true,
lastReadAt: '2026-04-25T11:00:00Z',
matchScore: 64,
createdAt: '2026-04-20T14:30:00Z',
updatedAt: '2026-04-25T10:00:00Z',