feat: merge Merkliste into Pipeline (SAVED stage) + Anfragen chat page

- Remove standalone Merkliste/Shortlists nav item; pipeline now covers the full funnel
- Add SAVED as first PipelineStage — 'Merken' on result cards lands here
- pipelineStore (Zustand) holds shared items; AddToPipelineDialog replaces AddToShortlistDialog in demand workspace
- New /demand/anfragen split-panel: searchable inquiry list + chat thread with compose
- Pipeline detail panel: KI insight, stage actions, editable notes, mock documents
- ShortlistItemCard: cards clickable → property detail, Anfrage button with inline dialog
- Supply workspace (FutureAvailability, Anfragencenter) unchanged

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Sutter
2026-05-22 21:31:30 +02:00
parent 76f9927c7c
commit de00f758e9
13 changed files with 1275 additions and 265 deletions
+5 -7
View File
@@ -3,7 +3,7 @@ import { MatchCardCompact } from '../match-card/MatchCardCompact'
import { IntelligenceMatchCard } from '../match-card/IntelligenceMatchCard'
import { buildMatchCardViewModel } from '../../features/matching/matchCardAdapter'
import { useCompareStore } from '../../stores/compareStore'
import { useShortlistStore } from '../../stores/shortlistStore'
import { usePipelineStore } from '../../stores/pipelineStore'
import type { UnifiedMatchResult } from '../../domain/unifiedResult'
import type { MatchCardAction } from '../match-card/MatchCardViewModel'
@@ -22,7 +22,7 @@ function getResultTitle(result: UnifiedMatchResult): string {
export function UnifiedResultCard({ result, view = 'list' }: Props) {
const navigate = useNavigate()
const { addToCompare, removeFromCompare, isInCompare, isFull } = useCompareStore()
const { openAddDialog } = useShortlistStore()
const { openSavedDialog } = usePipelineStore()
const inCompare = isInCompare(result.matchId)
const isPortfolio = result.resultType === 'VERIFIED_PORTFOLIO'
@@ -30,17 +30,15 @@ export function UnifiedResultCard({ result, view = 'list' }: Props) {
const actions: MatchCardAction[] = [
{
id: 'shortlist',
label: 'Shortlist',
label: 'Merken',
actionType: 'SAVE_SHORTLIST',
variant: 'secondary',
onClick: () => openAddDialog({
onClick: () => openSavedDialog({
resultId: result.matchId,
resultType: result.resultType,
title: getResultTitle(result),
matchScore: result.matchScore,
confidenceScore: result.match.confidenceLevel,
sourceLabel: result.resultType,
addedBy: 'admin@ideal-sharing.ch',
location: result.resultType !== 'FUTURE_AVAILABILITY' ? result.property.location?.city : undefined,
}),
},
{