Obanana_test/app/pages/home/Cart2.jsx

369 lines
9.9 KiB
JavaScript

import React, { useEffect, useReducer, useState } from "react";
import {
Dimensions,
StyleSheet,
Text,
TouchableOpacity,
View,
} from "react-native";
import MasonryList from "@react-native-seoul/masonry-list";
import CartCard from "../../components/cart/CartCard";
import Checkbox from "expo-checkbox";
import { FontAwesomeIcon } from "@fortawesome/react-native-fontawesome";
import {
faArrowLeft,
faDeleteLeft,
faTrash,
} from "@fortawesome/free-solid-svg-icons";
import DeleteConfirmationModal from "../../components/DeleteConfirmationModal";
const width = Dimensions.get("window").width;
const height = Dimensions.get("window").height;
const Cart = ({ cartList }) => {
// Reducer function to handle cart actions
const [isModalVisible, setModalVisible] = useState(false);
const toggleModal = () => {
setModalVisible(!isModalVisible);
};
const cartReducer = (state, action) => {
switch (action.type) {
case "INITIALIZE_CART":
return action.payload;
case "TOGGLE_ALL":
const all = !state.all;
const updatedCart = state.cart.map((shop) => ({
...shop,
selected: all,
cartItems: shop.cartItems.map((item) => ({
...item,
selected: all,
})),
}));
return { ...state, all, cart: updatedCart };
case "TOGGLE_SHOP":
const { shopIndex1 } = action.payload;
const updatedCartWithShopToggle = [...state.cart];
updatedCartWithShopToggle[shopIndex1].selected =
!updatedCartWithShopToggle[shopIndex1].selected;
updatedCartWithShopToggle[shopIndex1].cartItems =
updatedCartWithShopToggle[shopIndex1].cartItems.map((item) => ({
...item,
selected: updatedCartWithShopToggle[shopIndex1].selected,
}));
return { ...state, cart: updatedCartWithShopToggle };
case "TOGGLE_PRODUCT":
const { shopIndex2, prodIndex } = action.payload;
const updatedCartWithProductToggle = [...state.cart];
updatedCartWithProductToggle[shopIndex2].cartItems[prodIndex].selected =
!updatedCartWithProductToggle[shopIndex2].cartItems[prodIndex]
.selected;
updatedCartWithProductToggle[shopIndex2].selected = false;
return { ...state, cart: updatedCartWithProductToggle };
case "UPDATE_QUANTITY":
const {
shopIndex: shopIdx,
prodIndex: productIdx,
qty,
} = action.payload;
const updatedCartWithQuantity = [...state.cart];
// updatedCartWithQuantity[shopIdx].cartItems[productIdx].quantity = qty;
return { ...state, cart: updatedCartWithQuantity };
case "DELETE_ITEMS":
const updatedCartAfterDelete = state.cart
.filter((shop) => !shop.selected)
.map((shop) => ({
...shop,
cartItems: shop.cartItems.filter((item) => !item.selected),
}));
toggleModal();
const finalCartList = updatedCartAfterDelete.filter(
(shop) => shop.cartItems.length > 0
);
return { ...state, cart: finalCartList };
default:
return state;
}
};
const initialState = {
all: false,
cart: [],
};
const [state, dispatch] = useReducer(cartReducer, initialState);
const calculateTotalPrice = () => {
let total = 0;
// Iterate through the cartSort to calculate the total price
// cartSort.forEach((shop) => {
// let shopHasSelectedProducts = false; // Flag to check if the shop has selected products
// shop.cartItems.forEach((product) => {
// if (product.selected) {
// // Calculate the total price for the selected product
// let productTotal = 0;
// if (product.promo > 0) {
// // Apply promo discount if promo is greater than 0
// productTotal =
// product.price * (1 - product.promo / 100) * product.quantity; // Assuming promo is in percentage (e.g., 30%)
// } else {
// // Otherwise, calculate total without promo discount
// productTotal = product.price * product.quantity;
// }
// // Add the product total to the overall total
// total += productTotal;
// // Set the flag to true if at least one product is selected in the shop
// shopHasSelectedProducts = true;
// }
// });
// if (shopHasSelectedProducts) {
// // Add the shipping fee for the shop if it has selected products
// total += shop.shippingFee;
// }
// });
return total.toFixed(2);
};
useEffect(() => {
// Initialize the cart state when cartList changes
const cartSorted = cartList.reduce((acc, item) => {
const shopId = item.shopId;
const existingShop = acc.find((shop) => shop.shopname === shopId);
if (existingShop) {
existingShop.cartItems.push({ ...item, selected: false });
} else {
acc.push({
shopname: shopId,
cartItems: [{ ...item, selected: false }],
selected: false,
shippingFee: 50,
});
}
return acc;
}, []);
dispatch({
type: "INITIALIZE_CART",
payload: { all: false, cart: cartSorted },
});
}, [cartList]);
// Rest of your component remains the same, but use 'state' instead of 'cartSort'
return (
<View style={styles.container}>
<View style={styles.header}>
<Text style={styles.headerText}>CART</Text>
</View>
<View style={styles.actions}>
<View style={{ flexDirection: "row" }}>
<Checkbox
value={state.all}
onValueChange={() => dispatch({ type: "TOGGLE_ALL" })}
/>
<Text style={{ marginLeft: 10 }}>Select All</Text>
</View>
<TouchableOpacity
onPress={() => {
toggleModal();
}}
>
<FontAwesomeIcon icon={faTrash} />
</TouchableOpacity>
</View>
<View style={styles.wrapper}>
<MasonryList
data={state.cart}
keyExtractor={(item) => item.shopname}
style={styles.list}
numColumns={1}
showsVerticalScrollIndicator={false}
renderItem={({ item, i }) => (
<CartCard
all={state.all}
index={i}
shopLike={() =>
dispatch({ type: "TOGGLE_SHOP", payload: { shopIndex1: i } })
}
shopProdLike={(prodIndex) =>
dispatch({
type: "TOGGLE_PRODUCT",
payload: { shopIndex2: i, prodIndex },
})
}
cart={item}
quantityChange={(qty) =>
dispatch({
type: "UPDATE_QUANTITY",
payload: { shopIndex: i, prodIndex: i, qty },
})
}
/>
)}
containerStyle={styles.container1}
contentContainerStyle={styles.content}
onEndReachedThreshold={0.1}
/>
</View>
<View style={styles.bottom}>
<View style={styles.details}>
<View style={styles.detailsTop}>
<Text style={styles.detailsTopText}>Total Price : </Text>
<Text style={styles.detailsTopTextPrice}>
{" "}
{calculateTotalPrice()}
</Text>
</View>
</View>
<TouchableOpacity style={styles.checkout} >
<Text style={styles.checkoutText}>CHECKOUT</Text>
</TouchableOpacity>
</View>
<DeleteConfirmationModal
isVisible={isModalVisible}
onCancel={toggleModal}
onConfirm={() => dispatch({ type: "DELETE_ITEMS" })}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
backgroundColor: "#ffffff",
paddingTop: 10,
height: "100%",
width: width,
// height:height -70
},
header: {
width: "100%",
top: 0,
height: 40,
marginLeft: 15,
},
container1: {
width: "100%",
},
actions: {
flexDirection: "row",
justifyContent: "space-between",
alignItems: "center",
padding: 10,
paddingTop: 0,
},
content: {
width: "100%",
alignItems: "center",
justifyContent: "center",
},
list: {
width: "100%",
},
headerText: {
textAlign: "left",
width: "100%",
fontWeight: "600",
fontSize: 16,
},
footer: {
bottom: 0,
width: "100%",
},
wrapper: {
width: "100%",
height: "90%",
justifyContent: "center",
alignItems: "center",
padding: 5,
},
list: {
width: "100%",
height: "90%",
// justifyContent: "center",
// alignItems: "center",
},
card: {
width: "100%",
borderWidth: 1,
borderColor: "#dddd",
justifyContent: "center",
padding: 15,
paddingVertical: 10,
borderRadius: 10,
marginVertical: 2,
},
title: {
fontSize: 16,
fontWeight: "600",
},
body: {
fontSize: 16,
// fontWeight: "600",
marginTop: 5,
},
date: {
fontSize: 12,
// fontWeight: "600",
color: "#797979",
marginTop: 10,
},
bottom: {
position: "absolute",
bottom: 0,
backgroundColor: "#fff",
width: "100%",
justifyContent: "space-between",
alignItems: "center",
flexDirection: "row",
borderTopWidth: 1,
borderColor: "#dddd",
},
details: {
padding: 10,
},
detailsTop: {
// padding:10,
flexDirection: "row",
},
detailsTopText: {
color: "#363636",
fontWeight: "600",
fontSize: 14,
letterSpacing: 0.5,
},
detailsTopTextPrice: {
color: "#ffaa00",
fontWeight: "600",
fontSize: 16,
letterSpacing: 0.5,
},
checkout: {
backgroundColor: "#ffaa00",
width: 150,
justifyContent: "center",
alignItems: "center",
padding: 15,
},
checkoutText: {
color: "#fff",
fontWeight: "600",
fontSize: 16,
letterSpacing: 0.7,
},
});
export default Cart;