import { Product } from "@/utils/api"; import { Image } from "expo-image"; import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; import useCartStore from "@/store/cartStore"; import Ionicons from "@expo/vector-icons/Ionicons"; import { COLORS } from "@/utils/colors"; import { useRef } from "react"; import Reanimated, { SharedValue, useAnimatedStyle, useSharedValue, withSequence, withSpring, Easing, withTiming, } from "react-native-reanimated"; import ReanimatedSwipeable, { SwipeableMethods, } from "react-native-gesture-handler/ReanimatedSwipeable"; interface CartItemProps { item: Product & { quantity: number }; } const LeftActions = ( progress: SharedValue, dragX: SharedValue, onShouldDelete: () => void ) => { const styleAnimation = useAnimatedStyle(() => { return { transform: [{ translateX: dragX.value - 100 }], }; }); return ( ); }; const CartItem = ({ item }: CartItemProps) => { const { addProduct, reduceProduct } = useCartStore(); const reanimatedRef = useRef(null); const opacityAnim = useSharedValue(1); const scaleAnim = useSharedValue(1); const heightAnim = useSharedValue(80); const handleQuantityChanged = (type: "increment" | "decrement") => { if (type === "increment") { addProduct(item); } else { reduceProduct(item); } scaleAnim.value = withSequence( withSpring(1.2, { damping: 2, stiffness: 80 }), withSpring(1, { damping: 2, stiffness: 80 }) ); }; const onShouldDelete = async () => { opacityAnim.value = withTiming(0, { duration: 300, easing: Easing.inOut(Easing.ease), }); heightAnim.value = withTiming(0, { duration: 300, easing: Easing.inOut(Easing.ease), }); await new Promise((resolve) => setTimeout(resolve, 300)); reanimatedRef.current?.close(); for (let i = 0; i < item.quantity; i++) { reduceProduct(item); } }; const quantityAnimatedStyle = useAnimatedStyle(() => { return { transform: [{ scale: scaleAnim.value }], }; }); const animatedStyle = useAnimatedStyle(() => { return { opacity: opacityAnim.value, height: heightAnim.value, }; }); return ( LeftActions(progress, dragX, onShouldDelete) } > {item.title} Price: ${item.price} handleQuantityChanged("decrement")} style={styles.quantityButton} > {item.quantity} handleQuantityChanged("increment")} style={styles.quantityButton} > ); }; export default CartItem; const styles = StyleSheet.create({ cartItemContainer: { flexDirection: "row", alignItems: "center", gap: 20, backgroundColor: "#fff", height: 80, }, image: { width: 50, height: "100%", borderRadius: 10, resizeMode: "contain", }, itemContainer: { flex: 1, }, cartItemName: { fontSize: 16, fontWeight: "600", }, quantityContainer: { flexDirection: "row", alignItems: "center", gap: 10, }, quantityButton: { padding: 10, }, cartItemQuantity: { fontWeight: "bold", backgroundColor: COLORS.primary, fontSize: 16, padding: 5, width: 30, color: "white", textAlign: "center", }, swipeable: { height: 80, }, leftAction: { backgroundColor: "red", width: 100, height: "100%", justifyContent: "center", alignItems: "center", }, });