diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 017ab98..5731189 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -625,6 +625,7 @@ function App() { onDecide={decide} onClear={clear} onClose={() => setShowReviewMode(false)} + onSelectListing={(id) => setSelectedListingId(id)} getDecision={getDecision} /> )} diff --git a/frontend/src/components/SwipeCard.tsx b/frontend/src/components/SwipeCard.tsx index 5fe7248..74c4850 100644 --- a/frontend/src/components/SwipeCard.tsx +++ b/frontend/src/components/SwipeCard.tsx @@ -7,13 +7,14 @@ import type { PropertyFeature } from '@/types'; interface SwipeCardProps { feature: PropertyFeature; onSwipe: (direction: 'left' | 'right' | 'up') => void; + onTap?: () => void; isTop: boolean; stackIndex: number; } const SWIPE_THRESHOLD = 100; -export function SwipeCard({ feature, onSwipe, isTop, stackIndex }: SwipeCardProps) { +export function SwipeCard({ feature, onSwipe, onTap, isTop, stackIndex }: SwipeCardProps) { const hasSwiped = useRef(false); const p = feature.properties; @@ -27,9 +28,14 @@ export function SwipeCard({ feature, onSwipe, isTop, stackIndex }: SwipeCardProp })); const bind = useDrag( - ({ active, movement: [mx, my], velocity: [vx, vy], direction: [dx, dy] }) => { + ({ active, movement: [mx, my], velocity: [vx, vy], direction: [dx, dy], tap }) => { if (!isTop || hasSwiped.current) return; + if (tap) { + onTap?.(); + return; + } + if (!active) { const isSwipeRight = mx > SWIPE_THRESHOLD || (vx > 0.5 && dx > 0); const isSwipeLeft = mx < -SWIPE_THRESHOLD || (vx > 0.5 && dx < 0); @@ -81,11 +87,11 @@ export function SwipeCard({ feature, onSwipe, isTop, stackIndex }: SwipeCardProp }} className="cursor-grab active:cursor-grabbing" > -
+
{/* Color overlay */} {isTop && ( )} diff --git a/frontend/src/components/SwipeReviewMode.tsx b/frontend/src/components/SwipeReviewMode.tsx index d739f08..0339f0a 100644 --- a/frontend/src/components/SwipeReviewMode.tsx +++ b/frontend/src/components/SwipeReviewMode.tsx @@ -9,6 +9,7 @@ interface SwipeReviewModeProps { onDecide: (listingId: number, decision: DecisionType, listingType?: 'RENT' | 'BUY') => void; onClear: (listingId: number, listingType?: 'RENT' | 'BUY') => void; onClose: () => void; + onSelectListing?: (listingId: number) => void; getDecision: (listingId: number, listingType?: string) => DecisionType | undefined; } @@ -33,6 +34,7 @@ export function SwipeReviewMode({ onDecide, onClear, onClose, + onSelectListing, getDecision, }: SwipeReviewModeProps) { // Filter to only undecided features @@ -128,6 +130,7 @@ export function SwipeReviewMode({ key={feature.properties.url} feature={feature} onSwipe={handleSwipe} + onTap={() => onSelectListing?.(getListingId(feature))} isTop={i === 0} stackIndex={i} />