wrongmove: guard property cards against null backend fields (fix BUY crash)

BUY listings can come back from the API with null `total_price`, `qm`,
`qmprice`, `rooms`, and `last_seen` even though the TypeScript types
declare them non-nullable. The cards called `.toLocaleString()` and
`.split('T')` on those values, throwing TypeError and tripping the
ErrorBoundary — which is the "BUY part of the page crashes" symptom.

Coerce numeric fields via a `safeNum` helper (0 fallback), gate the
"Nd ago" line on a finite last_seen, and apply the same guards in
PropertyCard, PropertyCardCompact, SwipeCard, and the price-history
section of ListingDetail. Added regression tests asserting both card
variants render with all-null backend fields without throwing.
This commit is contained in:
Viktor Barzin 2026-05-10 21:17:41 +00:00
parent 73823bd381
commit 0b5308200e
6 changed files with 97 additions and 30 deletions

View file

@ -214,8 +214,12 @@ export function ListingDetail({ detail, onDecide, onClearDecision }: ListingDeta
<div className="space-y-2">
{detail.price_history.map((entry) => (
<div key={entry.id} className="flex justify-between items-center text-sm py-1.5 border-b last:border-0">
<span className="text-muted-foreground">{entry.last_seen.split('T')[0]}</span>
<span className="font-medium">£{entry.price.toLocaleString()}</span>
<span className="text-muted-foreground">
{typeof entry.last_seen === 'string' ? entry.last_seen.split('T')[0] : '—'}
</span>
<span className="font-medium">
£{typeof entry.price === 'number' && Number.isFinite(entry.price) ? entry.price.toLocaleString() : '—'}
</span>
</div>
))}
</div>