112 lines
2.9 KiB
TypeScript
112 lines
2.9 KiB
TypeScript
import React from 'react';
|
|
import {
|
|
View,
|
|
Text,
|
|
Image,
|
|
TouchableOpacity,
|
|
StyleProp,
|
|
ViewStyle,
|
|
} from 'react-native';
|
|
import { getStyles } from './productCard.styles';
|
|
import { useAppTheme } from '@theme';
|
|
import { getFullUrl } from '@utils/helper';
|
|
|
|
export interface ProductCardProps {
|
|
id: string;
|
|
name: string;
|
|
imageUrl: string;
|
|
price: string;
|
|
compareAtPrice?: string;
|
|
brand?: string | null;
|
|
currency?: string;
|
|
onPress?: () => void;
|
|
onAddPress?: () => void;
|
|
style?: StyleProp<ViewStyle>;
|
|
}
|
|
|
|
export const getDiscountPercentage = (price: string, comparePrice?: string) => {
|
|
if (!comparePrice || !price) return null;
|
|
const p = parseFloat(price);
|
|
const c = parseFloat(comparePrice);
|
|
if (c <= p || c <= 0) return null;
|
|
const discount = Math.round(((c - p) / c) * 100);
|
|
return discount > 0 ? `${discount}% OFF` : null;
|
|
};
|
|
|
|
export const formatPrice = (price: string, currency: string = '₹') => {
|
|
const num = parseFloat(price);
|
|
return isNaN(num) ? price : `${currency}${num.toFixed(0)}`;
|
|
};
|
|
|
|
export const ProductCard: React.FC<ProductCardProps> = ({
|
|
id,
|
|
name,
|
|
imageUrl,
|
|
price,
|
|
compareAtPrice,
|
|
brand,
|
|
currency = '₹',
|
|
onPress,
|
|
onAddPress,
|
|
style,
|
|
}) => {
|
|
const { colors } = useAppTheme();
|
|
const styles = getStyles(colors);
|
|
|
|
const discountText = getDiscountPercentage(price, compareAtPrice);
|
|
|
|
return (
|
|
<TouchableOpacity
|
|
style={[styles.cardContainer, style]}
|
|
activeOpacity={0.7}
|
|
onPress={onPress}
|
|
>
|
|
<View style={styles.imageContainer}>
|
|
<Image
|
|
source={{
|
|
uri: getFullUrl(imageUrl),
|
|
}}
|
|
style={styles.image}
|
|
// fallback source can be handled here if needed
|
|
/>
|
|
{discountText && (
|
|
<View style={styles.discountBadge}>
|
|
<Text style={styles.discountText}>{discountText}</Text>
|
|
</View>
|
|
)}
|
|
<TouchableOpacity style={styles.favoriteButton}>
|
|
<Text style={{ fontSize: 14 }}>🤍</Text>
|
|
</TouchableOpacity>
|
|
</View>
|
|
|
|
<View style={styles.infoContainer}>
|
|
{brand && (
|
|
<Text style={styles.brandText} numberOfLines={1}>
|
|
{brand}
|
|
</Text>
|
|
)}
|
|
<Text style={styles.titleText} numberOfLines={2}>
|
|
{name}
|
|
</Text>
|
|
|
|
<View style={styles.priceRow}>
|
|
<Text style={styles.priceText}>{formatPrice(price, currency)}</Text>
|
|
{compareAtPrice && parseFloat(compareAtPrice) > parseFloat(price) && (
|
|
<Text style={styles.comparePriceText}>
|
|
{formatPrice(compareAtPrice, currency)}
|
|
</Text>
|
|
)}
|
|
</View>
|
|
|
|
{/* <TouchableOpacity
|
|
style={styles.addButton}
|
|
onPress={onAddPress || onPress}
|
|
activeOpacity={0.7}
|
|
>
|
|
<Text style={styles.addButtonText}>+ ADD</Text>
|
|
</TouchableOpacity> */}
|
|
</View>
|
|
</TouchableOpacity>
|
|
);
|
|
};
|