UNPKG

react-native-ecommerce-components

Version:

A compilation of components to optimize the development of your ecommerce

230 lines (225 loc) 6.64 kB
import React, { useState } from "react"; import { View, Text, FlatList, TouchableOpacity, StyleSheet, Alert, } from "react-native"; import { widthPercentageToDP as wp, heightPercentageToDP as hp, } from "react-native-responsive-screen"; // Traduções do componente const translations = { en: { defaultTitle: "Shopping Cart", defaultSubTitle: "Review your items", removeConfirmTitle: "Remove Item", removeConfirmMessage: "Are you sure you want to remove this item?", cancelText: "Cancel", confirmRemoveText: "Remove", emptyCartTitle: "Empty Cart", emptyCartMessage: "Please add items to your cart before checkout.", successTitle: "Success", successMessage: (total) => `Your order of $${total.toFixed(2)} has been placed!`, totalLabel: "Total:", checkoutButton: "Checkout", removeButtonText: "Remove", }, pt: { defaultTitle: "Carrinho de Compras", defaultSubTitle: "Revise seus itens", removeConfirmTitle: "Remover Item", removeConfirmMessage: "Tem certeza que deseja remover este item?", cancelText: "Cancelar", confirmRemoveText: "Remover", emptyCartTitle: "Carrinho Vazio", emptyCartMessage: "Por favor, adicione itens ao carrinho antes de finalizar.", successTitle: "Sucesso", successMessage: (total) => `Seu pedido de R$${total.toFixed(2)} foi realizado!`, totalLabel: "Total:", checkoutButton: "Finalizar Compra", removeButtonText: "Remover", }, }; const ShoppingCart = ({ items, onUpdateQuantity, onRemoveItem, onCheckout, title, subTitle, language = "en", styles: customStyles = {}, }) => { const t = translations[language] || translations.en; const [cartItems, setCartItems] = useState(items); const calculateTotal = () => cartItems.reduce((sum, item) => sum + item.price * item.quantity, 0); const handleQuantityChange = (id, change) => { const updated = cartItems.map((item) => item.id === id ? Object.assign(Object.assign({}, item), { quantity: Math.max(1, item.quantity + change), }) : item ); setCartItems(updated); onUpdateQuantity(id, updated.find((i) => i.id === id).quantity); }; const confirmRemove = (id) => { Alert.alert(t.removeConfirmTitle, t.removeConfirmMessage, [ { text: t.cancelText, style: "cancel" }, { text: t.confirmRemoveText, style: "destructive", onPress: () => { const filtered = cartItems.filter((i) => i.id !== id); setCartItems(filtered); onRemoveItem(id); }, }, ]); }; const handleCheckout = () => { const total = calculateTotal(); if (cartItems.length === 0) { Alert.alert(t.emptyCartTitle, t.emptyCartMessage); return; } onCheckout(cartItems, total); setCartItems([]); Alert.alert(t.successTitle, t.successMessage(total)); }; const renderItem = ({ item }) => ( <View style={[styles.itemContainer, customStyles.itemContainer]}> <Text style={[styles.itemText, customStyles.itemText]}> {item.name} - ${item.price.toFixed(2)} x {item.quantity} </Text> <View style={[styles.quantityContainer, customStyles.quantityContainer]}> <TouchableOpacity onPress={() => handleQuantityChange(item.id, -1)}> <Text style={[styles.quantityButton, customStyles.quantityButton]}> - </Text> </TouchableOpacity> <Text style={[styles.quantityText, customStyles.quantityText]}> {item.quantity} </Text> <TouchableOpacity onPress={() => handleQuantityChange(item.id, 1)}> <Text style={[styles.quantityButton, customStyles.quantityButton]}> + </Text> </TouchableOpacity> </View> <TouchableOpacity onPress={() => confirmRemove(item.id)}> <Text style={[styles.removeButton, customStyles.removeButton]}> {t.removeButtonText} </Text> </TouchableOpacity> </View> ); return ( <View style={[styles.container, customStyles.container]}> <Text style={[styles.title, customStyles.title]}> {title || t.defaultTitle} </Text> {(subTitle || t.defaultSubTitle) && ( <Text style={[styles.subTitle, customStyles.subTitle]}> {subTitle || t.defaultSubTitle} </Text> )} <FlatList data={cartItems} renderItem={renderItem} keyExtractor={(item) => item.id} /> <View style={[styles.totalContainer, customStyles.totalContainer]}> <Text style={[styles.totalText, customStyles.totalText]}> {t.totalLabel} ${calculateTotal().toFixed(2)} </Text> <TouchableOpacity style={[styles.button, customStyles.button]} onPress={handleCheckout} > <Text style={[styles.buttonText, customStyles.buttonText]}> {t.checkoutButton} </Text> </TouchableOpacity> </View> </View> ); }; const styles = StyleSheet.create({ container: { padding: wp("5%"), borderRadius: wp("3%"), }, itemContainer: { flexDirection: "row", alignItems: "center", marginBottom: hp("2%"), borderBottomWidth: 1, borderColor: "#ccc", paddingBottom: hp("1%"), }, itemText: { flex: 1, flexWrap: "wrap", fontSize: wp("4%"), marginRight: wp("2%"), }, quantityContainer: { flexDirection: "row", alignItems: "center", marginHorizontal: wp("2%"), }, quantityButton: { fontSize: wp("5%"), paddingHorizontal: wp("2%"), }, quantityText: { fontSize: wp("4%"), marginHorizontal: wp("2%"), }, removeButton: { color: "red", fontSize: wp("4%"), marginLeft: wp("2%"), }, totalContainer: { marginTop: hp("3%"), alignItems: "center", }, totalText: { fontSize: wp("5%"), fontWeight: "bold", }, button: { backgroundColor: "#28a745", paddingVertical: hp("2%"), paddingHorizontal: wp("5%"), marginTop: hp("2%"), borderRadius: wp("2%"), }, buttonText: { color: "#fff", fontWeight: "bold", fontSize: wp("4%"), }, title: { fontSize: wp("5%"), fontWeight: "bold", marginBottom: hp("1%"), }, subTitle: { fontSize: wp("4%"), color: "#555", marginBottom: hp("2%"), }, }); export default ShoppingCart;