diff --git a/src/components/Card.tsx b/src/components/Card.tsx index 4c6a046..8e492cb 100644 --- a/src/components/Card.tsx +++ b/src/components/Card.tsx @@ -7,6 +7,7 @@ import { truncateString } from '../utils/commons'; import { useCart } from '../hooks/useCart'; import { Product } from '../types/Product'; import { useRouter } from 'expo-router'; +import { formatPrice } from '../utils/formatPrice'; const ProductCard: React.FC = ({ id, @@ -15,13 +16,17 @@ const ProductCard: React.FC = ({ imageUrl, name, category, - //originalPrice, - //discount, + originalPrice, + discount, finalPrice, getQuantity, }) => { - const { getItemQuantity, updateCartQuantity } = useCart(); + const { getItemQuantity, addToCart } = useCart(); const router = useRouter(); + const computedFinalPrice = discount + ? (finalPrice * (100 - discount)) / 100 + : finalPrice; + return ( @@ -57,7 +62,15 @@ const ProductCard: React.FC = ({ { if (getQuantity) getQuantity(quantity); - updateCartQuantity(id, quantity); + // Asegura que price siempre sea number + addToCart({ + id, + name, + price: originalPrice ?? 0, + quantity, + image: imageUrl, + discount: discount ?? 0, + }); }} initialValue={getItemQuantity(id)} /> @@ -66,22 +79,18 @@ const ProductCard: React.FC = ({ {truncateString(name)} - {/** {discount && ( - ${originalPrice} + ${formatPrice(originalPrice ?? 0)} - {discount}% // Comentado + {discount}% - )}*/} + )} - ${finalPrice} + ${formatPrice(computedFinalPrice)} diff --git a/src/components/CardButton.tsx b/src/components/CardButton.tsx index db632b2..ea62541 100644 --- a/src/components/CardButton.tsx +++ b/src/components/CardButton.tsx @@ -19,15 +19,16 @@ const CardButton: React.FC = ({ }) => { const [count, setCount] = useState(initialValue); const [showCounter, setShowCounter] = useState(false); + const [hasInteracted, setHasInteracted] = useState(false); const toggleCounter = () => setShowCounter(count > 0); useEffect(toggleCounter, [count]); useEffect(() => { - if (getValue) { + if (hasInteracted && getValue) { getValue(count); } - if (syncQuantity) { + if (hasInteracted && syncQuantity) { syncQuantity(count); } }, [count]); @@ -37,11 +38,13 @@ const CardButton: React.FC = ({ }, [initialValue]); const incrementCount = () => { + setHasInteracted(true); setCount((prev) => prev + 1); }; const decrementCount = () => { if (count > 0) { + setHasInteracted(true); setCount((prev) => prev - 1); } }; diff --git a/src/components/OrderSummary.tsx b/src/components/OrderSummary.tsx index 978f236..5b441a0 100644 --- a/src/components/OrderSummary.tsx +++ b/src/components/OrderSummary.tsx @@ -5,6 +5,7 @@ import PoppinsText from './PoppinsText'; import { Colors, FontSizes } from '../styles/theme'; import type { CartItem } from '../redux/slices/cartSlice'; import { ChevronDownIcon, ChevronUpIcon } from 'react-native-heroicons/outline'; +import { formatPrice } from '../utils/formatPrice'; const OrderSummary = () => { const { cartItems } = useCart(); @@ -14,26 +15,29 @@ const OrderSummary = () => { (sum, item) => sum + item.price * item.quantity, 0, ); - // const totalDiscount = cartItems.reduce( - // (sum, item) => sum + item.price * (item.quantity * 0.1), // Comentado - // 0, - // ); + const totalDiscount = cartItems.reduce( + (sum, item) => + sum + item.price * item.quantity * ((item.discount ?? 0) / 100), + 0, + ); + const total = subtotal - totalDiscount; const renderItem = ({ item }: { item: CartItem }) => { - // const discount = 10; // Comentado - // const discountedPrice = item.price * (1 - discount / 100); // Comentado - // const totalDiscountedPrice = discountedPrice * item.quantity; // Comentado + const discount = item.discount ?? 0; + const discountedPrice = item.price * (1 - discount / 100); + const totalDiscountedPrice = discountedPrice * item.quantity; const totalOriginalPrice = item.price * item.quantity; return ( - {/** - - - -10% - - */} + {discount > 0 && ( + + + -{discount}% + + + )} { {item.name} - ${totalOriginalPrice.toFixed(2)} + ${formatPrice(totalDiscountedPrice)} - {/** - ${totalOriginalPrice.toFixed(2)} - */} + ${formatPrice(totalOriginalPrice)} + - (${item.price} c/u) + (${formatPrice(discountedPrice)} c/u) Cantidad: {item.quantity} @@ -102,12 +105,20 @@ const OrderSummary = () => { Subtotal - ${subtotal.toFixed(2)} + ${formatPrice(subtotal)} Descuentos - -$0.00 + + -${formatPrice(totalDiscount)} + + + + Total + + ${formatPrice(total)} + diff --git a/src/components/SearchInput.tsx b/src/components/SearchInput.tsx index 63ffa96..20fc96c 100644 --- a/src/components/SearchInput.tsx +++ b/src/components/SearchInput.tsx @@ -17,6 +17,7 @@ import PoppinsText from './PoppinsText'; import { router } from 'expo-router'; import { ProductService } from '../services/products'; import { ProductPresentation } from '@pharmatech/sdk'; +import { formatPrice } from '../utils/formatPrice'; interface SearchInputProps { placeholder?: string; @@ -195,7 +196,7 @@ const SearchInput: React.FC = ({ color: Colors.primary, }} > - $ {p?.price} + $ {formatPrice(p?.price)} diff --git a/src/hooks/useCart.ts b/src/hooks/useCart.ts index 05eae89..6fd2a91 100644 --- a/src/hooks/useCart.ts +++ b/src/hooks/useCart.ts @@ -15,6 +15,8 @@ export const useCart = () => { const userId = useSelector((state: RootState) => state.cart.userId); const addToCart = (item: CartItem) => { + if (item.quantity <= 0) return; // <-- NO agregar si cantidad es 0 + console.log('[addToCart] Item añadido al carrito:', item); // <-- LOG dispatch(addItem(item)); }; @@ -22,8 +24,22 @@ export const useCart = () => { dispatch(removeItem(id)); }; - const updateCartQuantity = (id: string, quantity: number) => { - dispatch(updateQuantity({ id, quantity })); + const updateCartQuantity = ( + id: string, + quantity: number, + discount?: number, + price?: number, + ) => { + // Busca el item actual en el carrito + const item = cartItems.find((item) => item.id === id); + dispatch( + updateQuantity({ + id, + quantity, + discount: typeof discount === 'number' ? discount : item?.discount, + price: typeof price === 'number' ? price : item?.price, + }), + ); }; const getItemQuantity = (id: string) => { diff --git a/src/redux/slices/cartSlice.ts b/src/redux/slices/cartSlice.ts index 26183bc..017b1d9 100644 --- a/src/redux/slices/cartSlice.ts +++ b/src/redux/slices/cartSlice.ts @@ -6,6 +6,7 @@ export type CartItem = { price: number; quantity: number; image: string; + discount?: number; }; type CartState = { @@ -35,13 +36,16 @@ const cartSlice = createSlice({ } }, addItem: (state, action: PayloadAction) => { - const existingItem = state.items.find( + const existing = state.items.find( (item) => item.id === action.payload.id, ); - if (existingItem) { - existingItem.quantity = action.payload.quantity; + if (existing) { + // Si ya existe, actualiza cantidad y descuento correctamente + existing.quantity = action.payload.quantity; + existing.price = action.payload.price; + existing.discount = action.payload.discount; // <-- ¡Asegúrate de actualizar el descuento! } else { - state.items.push(action.payload); + state.items.push({ ...action.payload }); } state.total = calculateTotal(state.items); }, @@ -51,11 +55,22 @@ const cartSlice = createSlice({ }, updateQuantity: ( state, - action: PayloadAction<{ id: string; quantity: number }>, + action: PayloadAction<{ + id: string; + quantity: number; + discount?: number; + price?: number; + }>, ) => { const item = state.items.find((item) => item.id === action.payload.id); if (item) { item.quantity = action.payload.quantity; + if (typeof action.payload.discount === 'number') { + item.discount = action.payload.discount; + } + if (typeof action.payload.price === 'number') { + item.price = action.payload.price; + } } state.total = calculateTotal(state.items); }, diff --git a/src/screens/CartListScreen.tsx b/src/screens/CartListScreen.tsx index c2151aa..89beb9f 100644 --- a/src/screens/CartListScreen.tsx +++ b/src/screens/CartListScreen.tsx @@ -14,6 +14,7 @@ import type { CartItem } from '../redux/slices/cartSlice'; import Button from '../components/Button'; import { TrashIcon } from 'react-native-heroicons/outline'; import { useRouter } from 'expo-router'; +import { formatPrice } from '../utils/formatPrice'; const CartListScreen = () => { const router = useRouter(); @@ -22,28 +23,34 @@ const CartListScreen = () => { const subtotal = cartItems.reduce( (sum, item) => sum + item.price * item.quantity, 0, - ); // Total price sum - // const totalDiscount = cartItems.reduce( - // (sum, item) => sum + item.price * (item.quantity * 0.1), // Comentado - // 0, - // ); // Discount sum - const total = subtotal; // Subtotal without discount + ); + // Total price sum + const totalDiscount = cartItems.reduce( + (sum, item) => + sum + item.price * item.quantity * ((item.discount ?? 0) / 100), + 0, + ); // Discount sum + const total = subtotal - totalDiscount; // Subtotal with discount const renderItem = ({ item }: { item: CartItem }) => { - // const discount = 10; // Comentado - // const discountedPrice = item.price * (1 - discount / 100); // Comentado - // const totalDiscountedPrice = discountedPrice * item.quantity; // Comentado - const totalOriginalPrice = item.price * item.quantity; // Original total price + console.log('[CartListScreen] Renderizando item:', item); // <-- LOG + // Usar el descuento del item, si existe, si no 0 + const discount = item.discount ?? 0; + const discountedPrice = item.price * (1 - discount / 100); + const totalDiscountedPrice = discountedPrice * item.quantity; + const totalOriginalPrice = item.price * item.quantity; return ( {/* Discount badge */} - {/* - - -{discount}% - - */} + {discount > 0 && ( + + + -{discount}% + + + )} { {item.name} - - ${totalOriginalPrice.toFixed(2)} - {/* Original total price */} - + + + ${formatPrice(totalDiscountedPrice)} + + {discount > 0 && ( + + ${formatPrice(totalOriginalPrice)} + + )} + - (${item.price} c/u) + (${formatPrice(discountedPrice)} c/u) updateCartQuantity(item.id, quantity)} + getValue={(quantity) => + updateCartQuantity(item.id, quantity, item.discount ?? 0) + } initialValue={item.quantity > 0 ? item.quantity : 0} - syncQuantity={(quantity) => updateCartQuantity(item.id, quantity)} + syncQuantity={(quantity) => + updateCartQuantity(item.id, quantity, item.discount ?? 0) + } /> removeFromCart(item.id)} @@ -118,19 +135,19 @@ const CartListScreen = () => { Subtotal - ${subtotal.toFixed(2)} + ${formatPrice(subtotal)} - {/* + Descuentos - -${totalDiscount.toFixed(2)} + -${formatPrice(totalDiscount)} - */} + Total - ${total.toFixed(2)} + ${formatPrice(total)}