BrixCafe/app/components/CartItem.tsx
2025-04-18 06:09:09 +01:00

108 lines
2.6 KiB
TypeScript

import React from 'react';
import { View, Text, StyleSheet, Image } from 'react-native';
import COLORS from "@/app/constants/colors";
import { CartItem as CartItemType } from '@/app/constants/types';
import QuantityControl from '@/app/components/QuantityControl';
import Animated, {
useAnimatedStyle,
withTiming,
useSharedValue,
runOnJS
} from 'react-native-reanimated';
interface CartItemProps {
item: CartItemType;
onUpdateQuantity: (id: string, quantity: number) => void;
}
const CartItem: React.FC<CartItemProps> = ({ item, onUpdateQuantity }) => {
const opacity = useSharedValue(1);
const scale = useSharedValue(1);
const animatedStyle = useAnimatedStyle(() => {
return {
opacity: opacity.value,
transform: [{ scale: scale.value }]
};
});
const handleIncrease = () => {
scale.value = withTiming(1.02, { duration: 100 }, () => {
scale.value = withTiming(1, { duration: 100 });
});
onUpdateQuantity(item.id, item.quantity + 1);
};
const handleDecrease = () => {
if (item.quantity > 0) {
scale.value = withTiming(0.98, { duration: 100 }, () => {
scale.value = withTiming(1, { duration: 100 });
});
onUpdateQuantity(item.id, item.quantity - 1);
}
};
return (
<Animated.View style={[styles.container, animatedStyle]}>
<View style={styles.imageContainer}>
<Image source={{ uri: item.image }} style={styles.image} />
</View>
<View style={styles.contentContainer}>
<Text style={styles.name}>{item.name}</Text>
<View style={styles.controlRow}>
<QuantityControl
quantity={item.quantity}
onIncrease={handleIncrease}
onDecrease={handleDecrease}
/>
<Text style={styles.price}>{item.price}{item.priceUnit}</Text>
</View>
</View>
</Animated.View>
);
};
const styles = StyleSheet.create({
container: {
flexDirection: 'row',
backgroundColor: COLORS.secondary,
borderRadius: 12,
marginBottom: 5,
padding: 4,
},
imageContainer: {
width: 80,
height: 80,
borderRadius: 8,
overflow: 'hidden',
marginRight: 2,
},
image: {
width: '100%',
height: '100%',
},
contentContainer: {
flex: 1,
justifyContent: 'center',
},
name: {
fontSize: 16,
color: COLORS.text,
marginBottom: 5,
},
controlRow: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'space-between',
},
price: {
fontSize: 14,
color: COLORS.secondary,
},
});
export default CartItem;