# Card View: Photo Carousel and Tap-to-Detail **Date:** 2026-02-21 **Status:** Approved ## Summary Two changes to the listing card view: 1. Replace single thumbnail with a 5-photo carousel on each card 2. Fix tap behavior so tapping a card opens the detail bottom sheet (not Rightmove) ## Design ### Backend: Embed Photos in GeoJSON **File:** `api/ui_exporter.py` — `convert_row_to_geojson()` Add `photos` property (first 5 photo URLs) from `additional_info.property.images` to each GeoJSON feature. Fall back to `[photo_thumbnail]` if no photos array available. ### Frontend: Types **File:** `frontend/src/types/index.ts` Add `photos?: string[]` to `PropertyProperties` interface. ### Frontend: Card Carousel **File:** `frontend/src/components/PropertyCard.tsx` - Replace single `` in compact variant with lightweight embla-carousel - Swipeable horizontally, dot indicators overlaid at bottom - Same aspect ratio as current thumbnail - Lazy-load images - Max 5 photos ### Frontend: Click Behavior **File:** `frontend/src/components/PropertyCard.tsx` - Remove `window.open(property.url)` from `handleClick` - Tapping card only calls `onClick()` callback - This triggers `onSelectListing(id)` in App.tsx, which opens `ListingDetailSheet` - Rightmove link remains accessible via external link button in `ListingDetail` ### No Changes Needed - `ListingDetailSheet.tsx` — already wired correctly - `App.tsx` — `onSelectListing` already sets `selectedListingId` - `ListingDetail.tsx` — already has Rightmove external link - `PhotoCarousel.tsx` — used in detail view, unchanged - `SwipeablePropertyCard.tsx` — passes `onClick` through, unchanged ## Approach Decision Chose **Approach A (Minimal Fix)** over: - **Approach B (Two-Zone Card):** Two click zones add UI complexity and are hard to discover on mobile - **Approach C (Long-press):** Most users won't discover long-press behavior