import { useState } from 'react'; import { Trash2, Archive } from 'lucide-react'; import { useHaptics } from '@/hooks/use-haptics'; interface SwipeableCardProps { children: React.ReactNode; onSwipeLeft?: () => void; onSwipeRight?: () => void; leftAction?: { icon?: React.ReactNode; label?: string; color?: string }; rightAction?: { icon?: React.ReactNode; label?: string; color?: string }; } export function SwipeableCard({ children, onSwipeLeft, onSwipeRight, leftAction = { icon: , label: 'Delete', color: 'bg-red-500' }, rightAction = { icon: , label: 'Archive', color: 'bg-blue-500' } }: SwipeableCardProps) { const [offset, setOffset] = useState(0); const haptics = useHaptics(); let startX = 0; let currentX = 0; const handleTouchStart = (e: React.TouchEvent) => { startX = e.touches[0].clientX; currentX = startX; }; const handleTouchMove = (e: React.TouchEvent) => { currentX = e.touches[0].clientX; const diff = currentX - startX; if (Math.abs(diff) > 10) { setOffset(Math.max(-100, Math.min(100, diff))); } }; const handleTouchEnd = () => { if (offset < -50 && onSwipeLeft) { haptics.impact('medium'); onSwipeLeft(); } else if (offset > 50 && onSwipeRight) { haptics.impact('medium'); onSwipeRight(); } setOffset(0); }; return (
{children}
); } interface CardListProps { items: T[]; renderItem: (item: T, index: number) => React.ReactNode; onItemSwipeLeft?: (item: T, index: number) => void; onItemSwipeRight?: (item: T, index: number) => void; keyExtractor: (item: T, index: number) => string; emptyMessage?: string; } export function SwipeableCardList({ items, renderItem, onItemSwipeLeft, onItemSwipeRight, keyExtractor, emptyMessage = 'No items' }: CardListProps) { if (items.length === 0) { return
{emptyMessage}
; } return (
{items.map((item, index) => ( onItemSwipeLeft(item, index) : undefined} onSwipeRight={onItemSwipeRight ? () => onItemSwipeRight(item, index) : undefined} > {renderItem(item, index)} ))}
); }