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 (
);
}
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)}
))}
);
}