fix: resolve all TypeScript errors and refactor oversized components
- Fix MUI v9 API: PaperProps/InputLabelProps/inputProps → slotProps in 6 components - Add ExternalMarketResult alias, PropertyUnit import, OPERATIONS workspace config - Fix TradeOff.description → .concern, ScoreFactor.label → .criterion - Make schattenmarktRelease.leadTimeMonths optional, fix mock-data enum values - Fix useMatchDetailData query typing, weightingService missing WeightProfile keys - Split Pipeline/Compare/MatchDetail/IntelligenceMatchCard into sub-components - Fix all test fixtures (CreateNeedInput, CreatePropertyInput, TradeOffInput, etc.) - Add vercel.json for deployment, zero tsc errors Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@ import { ResultType } from '../../domain/enums'
|
||||
import type { Property } from '../../domain/property'
|
||||
import { FLOOR_LABEL, ASSET_LABELS, RISK_LABELS, SOURCE_LABELS, PASSERBY_LABELS, KeyFactRow, UnitRow } from './MatchDetailPropertyDetails'
|
||||
import { FloorPlanSection } from './FloorPlanSection'
|
||||
import { DS_TEXT, DS_BG, DS_SURFACE, DS_BORDER, DS_MARKET_SIGNAL, DS_PRE_MARKET } from '../../lib/ds'
|
||||
import { DS_TEXT, DS_BG, DS_SURFACE, DS_BORDER, DS_MARKET_SIGNAL } from '../../lib/ds'
|
||||
|
||||
type Match = NonNullable<ReturnType<typeof useMatchDetail>['data']>
|
||||
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
import { memo, useState } from 'react'
|
||||
import { Box, Button, Paper, Typography } from '@mui/material'
|
||||
import { ChevronDown, ChevronUp } from 'lucide-react'
|
||||
import { PropertyMap } from '../shared'
|
||||
import {
|
||||
ExecutiveSummaryPanel,
|
||||
NeedAlignmentPanel,
|
||||
LocationIntelligencePanel,
|
||||
TradeoffPanel,
|
||||
RiskPanel,
|
||||
MissingInformationPanel,
|
||||
FutureAvailabilityContextPanel,
|
||||
ScoreBreakdownPanel,
|
||||
} from '.'
|
||||
import { MatchDetailPropertySections } from './MatchDetailPropertySections'
|
||||
import { useMatchDetail } from '../../hooks/useMatches'
|
||||
import type { Property } from '../../domain/property'
|
||||
import type { Need } from '../../domain/need'
|
||||
import type { FutureSignal } from '../../domain/futureSignal'
|
||||
import { DS_TEXT, DS_BORDER, DS_BG } from '../../lib/ds'
|
||||
|
||||
type Match = NonNullable<ReturnType<typeof useMatchDetail>['data']>
|
||||
|
||||
interface Props {
|
||||
match: Match
|
||||
property: Property | null
|
||||
need: Need | null
|
||||
signal: FutureSignal | null
|
||||
isFuture: boolean
|
||||
taxCalculatorUrl?: string
|
||||
}
|
||||
|
||||
export const MatchDetailScoreBreakdown = memo(function MatchDetailScoreBreakdown({
|
||||
match,
|
||||
property,
|
||||
need,
|
||||
signal,
|
||||
isFuture,
|
||||
taxCalculatorUrl,
|
||||
}: Props) {
|
||||
const [showFullAnalysis, setShowFullAnalysis] = useState(false)
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* ── Full analysis toggle ── */}
|
||||
<Button
|
||||
variant="outlined"
|
||||
onClick={() => setShowFullAnalysis(v => !v)}
|
||||
fullWidth
|
||||
endIcon={showFullAnalysis ? <ChevronUp size={15} /> : <ChevronDown size={15} />}
|
||||
sx={{
|
||||
borderStyle: 'dashed', color: DS_TEXT.muted, borderColor: DS_BORDER.strong,
|
||||
textTransform: 'none', fontWeight: 500,
|
||||
'&:hover': { borderColor: DS_TEXT.muted, bgcolor: DS_BG.subtle },
|
||||
}}
|
||||
>
|
||||
{showFullAnalysis ? 'Weniger anzeigen' : 'Vollständige Analyse anzeigen'}
|
||||
</Button>
|
||||
|
||||
{/* ── Full analysis (hidden by default) ── */}
|
||||
{showFullAnalysis && (
|
||||
<>
|
||||
<ExecutiveSummaryPanel match={match} />
|
||||
<NeedAlignmentPanel match={match} need={need} property={property} />
|
||||
{!isFuture && property && <MatchDetailPropertySections property={property} match={match} />}
|
||||
<LocationIntelligencePanel property={property} />
|
||||
{!isFuture && property?.images?.[0] && property?.location?.coordinates && (
|
||||
<Paper sx={{ overflow: 'hidden', p: 0 }}>
|
||||
<Box sx={{ px: 2.5, pt: 2, pb: 1 }}>
|
||||
<Typography variant="h6" sx={{ fontWeight: 700 }}>Standort</Typography>
|
||||
<Typography variant="caption" color="text.secondary">
|
||||
{property.address.street} {property.address.houseNumber}, {property.address.postalCode} {property.address.city}
|
||||
</Typography>
|
||||
</Box>
|
||||
<PropertyMap
|
||||
lat={property.location.coordinates.lat}
|
||||
lng={property.location.coordinates.lng}
|
||||
label={property.title}
|
||||
height={220}
|
||||
/>
|
||||
</Paper>
|
||||
)}
|
||||
<TradeoffPanel match={match} />
|
||||
<RiskPanel match={match} />
|
||||
<MissingInformationPanel match={match} />
|
||||
{isFuture && <FutureAvailabilityContextPanel match={match} signal={signal} />}
|
||||
<ScoreBreakdownPanel match={match} taxCalculatorUrl={taxCalculatorUrl} isFuture={isFuture} signal={signal} />
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
)
|
||||
})
|
||||
@@ -11,7 +11,6 @@ import {
|
||||
ExternalLink,
|
||||
Info,
|
||||
Layers,
|
||||
ShieldCheck,
|
||||
Tag,
|
||||
Train,
|
||||
TrendingUp,
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
export { LocationIntelligencePanel } from './LocationIntelligencePanel'
|
||||
export { MatchDetailHeader } from './MatchDetailHeader'
|
||||
export { MatchDetailHero } from './MatchDetailHero'
|
||||
export { MatchDetailScoreBreakdown } from './MatchDetailScoreBreakdown'
|
||||
export { ExecutiveSummaryPanel } from './ExecutiveSummaryPanel'
|
||||
export { PropertyOverviewPanel } from './PropertyOverviewPanel'
|
||||
export { NeedAlignmentPanel } from './NeedAlignmentPanel'
|
||||
|
||||
Reference in New Issue
Block a user