Add tap-to-detail on swipe cards and fix color overlay alignment
- Add onTap callback to SwipeCard using useDrag's tap detection - Wire through SwipeReviewMode to open ListingDetailSheet on tap - Fix color overlay misalignment: add relative to card container so the absolute overlay positions within the rounded card, not the full-width outer wrapper
This commit is contained in:
parent
9c954c0e43
commit
eacdf24621
3 changed files with 14 additions and 4 deletions
|
|
@ -625,6 +625,7 @@ function App() {
|
|||
onDecide={decide}
|
||||
onClear={clear}
|
||||
onClose={() => setShowReviewMode(false)}
|
||||
onSelectListing={(id) => setSelectedListingId(id)}
|
||||
getDecision={getDecision}
|
||||
/>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
>
|
||||
<div className="bg-background rounded-2xl border shadow-lg overflow-hidden mx-4">
|
||||
<div className="relative bg-background rounded-2xl border shadow-lg overflow-hidden mx-4">
|
||||
{/* Color overlay */}
|
||||
{isTop && (
|
||||
<animated.div
|
||||
className="absolute inset-0 z-10 rounded-2xl pointer-events-none"
|
||||
className="absolute inset-0 z-10 pointer-events-none"
|
||||
style={{ backgroundColor: overlayColor, opacity: overlayOpacity }}
|
||||
/>
|
||||
)}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
/>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue