feat: F015 shortlist management

3-panel Shortlists page with left list, center detail, right decision brief panel. AddToShortlistDialog wired into result feed cards and match detail. Full DRAFT→REVIEW_READY→FINALIZED workflow, AI-generated decision brief draft, duplicate prevention, and compare-view integration.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Benjamin Sutter
2026-05-16 21:10:06 +02:00
parent 2753d1717c
commit 65130efca7
22 changed files with 1079 additions and 195 deletions
+20 -2
View File
@@ -6,6 +6,8 @@ import { propertyService } from '../../services/propertyService'
import { needService } from '../../services/needService'
import { futureSignalService } from '../../services/futureSignalService'
import { useCompareStore } from '../../stores/compareStore'
import { useShortlistStore } from '../../stores/shortlistStore'
import { AddToShortlistDialog } from '../../components/shortlist'
import { MatchReasonList } from '../../components/match-card/MatchReasonList'
import {
MatchDetailHeader,
@@ -37,6 +39,7 @@ export default function MatchDetail() {
const { matchId } = useParams<{ matchId: string }>()
const navigate = useNavigate()
const { addToCompare } = useCompareStore()
const { openAddDialog } = useShortlistStore()
const { data: match, isLoading } = useMatchDetail(matchId ?? '')
@@ -112,15 +115,30 @@ export default function MatchDetail() {
const handleBack = () => navigate(-1)
const handleShortlist = () => {
const title = property?.title ?? signal?.companyName ?? signal?.locationHint ?? match.id
openAddDialog({
resultId: match.id,
resultType: match.resultType ?? 'VERIFIED_PORTFOLIO',
title,
matchScore: match.matchScore,
confidenceScore: match.confidenceLevel,
sourceLabel: property?.sourceLabel ?? match.resultType ?? 'VERIFIED_PORTFOLIO',
addedBy: 'admin@ideal-sharing.ch',
propertyId: property?.id,
})
}
return (
<Box sx={{ px: 3, py: 2 }}>
<AddToShortlistDialog />
<MatchDetailHeader
match={match}
property={property}
signal={signal}
onBack={handleBack}
onCompare={handleCompare}
onShortlist={() => {}}
onShortlist={handleShortlist}
/>
<Box sx={{ display: 'flex', gap: 3, alignItems: 'flex-start' }}>
@@ -165,7 +183,7 @@ export default function MatchDetail() {
<NextActionsPanel
match={match}
onCompare={handleCompare}
onShortlist={() => {}}
onShortlist={handleShortlist}
onReview={() => {}}
onReject={() => {}}
/>