|
|
import React, { useState, useEffect, useCallback } from "react"; |
|
|
import { |
|
|
View, |
|
|
Text, |
|
|
ScrollView, |
|
|
Dimensions, |
|
|
StyleSheet, |
|
|
Pressable, |
|
|
SafeAreaView, |
|
|
StatusBar, |
|
|
LayoutAnimation, |
|
|
KeyboardAvoidingView, |
|
|
Appearance, |
|
|
} from "react-native"; |
|
|
import { connect } from "react-redux"; |
|
|
import { userProduct, userFactor } from "../../redux/actions"; |
|
|
import { Ionicons } from "@expo/vector-icons"; |
|
|
import { useNavigation } from "@react-navigation/native"; |
|
|
import { asyncAwesomeAlert } from "../../utils/AsyncWrappers"; |
|
|
import separate from "../../utils/separate"; |
|
|
|
|
|
//components |
|
|
import Product from "./components/Product"; |
|
|
import Code from "./components/Code"; |
|
|
import CustomPressable from "../../components/Pressable"; |
|
|
import Navbar from "../../components/Navbar"; |
|
|
import Drawer from "../../components/Drawer"; |
|
|
import Empty from "../../components/Empty"; |
|
|
|
|
|
//style |
|
|
import fontSize from "../../constants/fontSize"; |
|
|
import Colors from "../../constants/Colors"; |
|
|
import tw from "tailwind-rn"; |
|
|
|
|
|
const { height } = Dimensions.get("window"); |
|
|
|
|
|
const PriceStatus = ({ name, value, type, theme }) => { |
|
|
return ( |
|
|
<View style={tw("w-full flex flex-row-reverse justify-between py-2")}> |
|
|
<Text |
|
|
style={[ |
|
|
tw(""), |
|
|
{ |
|
|
fontSize: fontSize.tiny, |
|
|
color: |
|
|
theme === "light" ? Colors.theme1.gray20 : Colors.theme1.white, |
|
|
fontFamily: "bold", |
|
|
}, |
|
|
]} |
|
|
> |
|
|
{name} |
|
|
</Text> |
|
|
<View style={tw("flex flex-row-reverse items-center")}> |
|
|
<Text |
|
|
style={[ |
|
|
{ |
|
|
color: |
|
|
type === "error" |
|
|
? Colors.theme1.redFF1 |
|
|
: theme === "light" |
|
|
? Colors.theme1.green79 |
|
|
: Colors.theme1.white, |
|
|
fontSize: fontSize.xl, |
|
|
fontFamily: "bold", |
|
|
}, |
|
|
]} |
|
|
> |
|
|
{value} |
|
|
</Text> |
|
|
<Text |
|
|
style={[ |
|
|
{ |
|
|
color: |
|
|
type === "error" |
|
|
? Colors.theme1.redFF1 |
|
|
: theme === "light" |
|
|
? Colors.theme1.green79 |
|
|
: Colors.theme1.white, |
|
|
fontSize: fontSize.sm, |
|
|
fontFamily: "regular", |
|
|
marginRight: 4, |
|
|
}, |
|
|
]} |
|
|
> |
|
|
تومان |
|
|
</Text> |
|
|
</View> |
|
|
</View> |
|
|
); |
|
|
}; |
|
|
|
|
|
function ShoppingCart({ |
|
|
userId, |
|
|
list, |
|
|
factorInfo, |
|
|
getList, |
|
|
getFactorInfo, |
|
|
loading, |
|
|
payFactor, |
|
|
theme, |
|
|
}) { |
|
|
const navigation = useNavigation(); |
|
|
const [position, setPosition] = useState("100%"); |
|
|
|
|
|
const isEmpty = React.useMemo(() => { |
|
|
return list?.filter((product) => product?.condition < 2)?.length === 0; |
|
|
}, [list]); |
|
|
|
|
|
const hasPhysical = React.useMemo(() => { |
|
|
return ( |
|
|
list?.filter( |
|
|
(product) => product?.condition < 2 && product?.productType === 2 |
|
|
)?.length |
|
|
); |
|
|
}, [list]); |
|
|
|
|
|
useEffect(() => { |
|
|
getFactorInfo({ userId }); |
|
|
}, [list]); |
|
|
|
|
|
useEffect(() => { |
|
|
getList(); |
|
|
getFactorInfo({ userId }); |
|
|
}, []); |
|
|
|
|
|
const setBoxPosition = useCallback(() => { |
|
|
LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut); |
|
|
setPosition(position === "100%" ? "0%" : "100%"); |
|
|
}, [userId]); |
|
|
|
|
|
return ( |
|
|
<SafeAreaView |
|
|
style={{ |
|
|
paddingTop: Platform.OS === "android" ? StatusBar.currentHeight : 0, |
|
|
position: "relative", |
|
|
flex: 1, |
|
|
}} |
|
|
> |
|
|
<KeyboardAvoidingView behavior="padding" style={{ flex: 1 }}> |
|
|
<Navbar |
|
|
setBoxPosition={setBoxPosition} |
|
|
headerOptions={{ |
|
|
logo: false, |
|
|
menu: false, |
|
|
hamburgerMenu: false, |
|
|
title: "سبد خرید", |
|
|
bookmark: false, |
|
|
qr: false, |
|
|
back: false, |
|
|
}} |
|
|
/> |
|
|
<Drawer setBoxPosition={setBoxPosition} position={position} /> |
|
|
{list?.filter((product) => product?.condition < 2)?.length ? ( |
|
|
<ScrollView |
|
|
contentContainerStyle={styles.contentContainerStyle} |
|
|
style={styles.container} |
|
|
> |
|
|
{list |
|
|
?.sort((a, b) => a?.id - b?.id) |
|
|
?.map((product, index) => |
|
|
product?.condition < 2 ? ( |
|
|
<Product key={index} product={product} loading={loading} /> |
|
|
) : null |
|
|
)} |
|
|
<Code /> |
|
|
<View |
|
|
style={tw( |
|
|
`flex w-full border-t py-2 border-gray-300 border-b mt-6 ${ |
|
|
theme === "light" ? "" : "border-opacity-20" |
|
|
}` |
|
|
)} |
|
|
> |
|
|
<PriceStatus |
|
|
name="مبلغ سبد خرید" |
|
|
value={ |
|
|
isEmpty ? 0 : separate(Math.round(factorInfo?.sumPrice || 0)) |
|
|
} |
|
|
type="normal" |
|
|
theme={theme} |
|
|
/> |
|
|
|
|
|
<PriceStatus |
|
|
name="میزان تخفیف" |
|
|
value={ |
|
|
isEmpty ? 0 : separate(Math.round(factorInfo?.offPrice || 0)) |
|
|
} |
|
|
type="error" |
|
|
theme={theme} |
|
|
/> |
|
|
</View> |
|
|
<View |
|
|
style={tw( |
|
|
"flex flex-row-reverse justify-between items-center w-full py-3" |
|
|
)} |
|
|
> |
|
|
<Text |
|
|
style={[ |
|
|
{ |
|
|
color: |
|
|
theme === "light" |
|
|
? Colors.theme1.green79 |
|
|
: Colors.theme1.white, |
|
|
fontSize: fontSize.base, |
|
|
fontFamily: "bold", |
|
|
}, |
|
|
]} |
|
|
> |
|
|
جمع کل سبد خرید |
|
|
</Text> |
|
|
<View style={tw("flex flex-row-reverse items-center")}> |
|
|
<Text |
|
|
style={[ |
|
|
{ |
|
|
color: |
|
|
theme === "light" |
|
|
? Colors.theme1.green79 |
|
|
: Colors.theme1.white, |
|
|
fontSize: fontSize.xl, |
|
|
fontFamily: "bold", |
|
|
}, |
|
|
]} |
|
|
> |
|
|
{isEmpty ? 0 : separate(factorInfo?.payPrice - factorInfo?.transportPrice)} |
|
|
</Text> |
|
|
|
|
|
<Text |
|
|
style={[ |
|
|
{ |
|
|
color: |
|
|
theme === "light" |
|
|
? Colors.theme1.green79 |
|
|
: Colors.theme1.white, |
|
|
fontSize: fontSize.sm, |
|
|
fontFamily: "regular", |
|
|
marginRight: 4, |
|
|
}, |
|
|
]} |
|
|
> |
|
|
تومان |
|
|
</Text> |
|
|
</View> |
|
|
</View> |
|
|
<View style={tw("w-full")}> |
|
|
<Pressable |
|
|
style={[ |
|
|
tw( |
|
|
"w-full rounded-md flex flex-row justify-center items-center py-3 px-3 my-5" |
|
|
), |
|
|
{ |
|
|
backgroundColor: |
|
|
theme === "light" |
|
|
? Colors.theme1.greenC8 + "1a" |
|
|
: Colors.theme1.blue90 + "33", |
|
|
}, |
|
|
]} |
|
|
> |
|
|
<Text |
|
|
style={[ |
|
|
tw("mr-1"), |
|
|
{ |
|
|
color: |
|
|
theme === "light" |
|
|
? Colors.theme1.green79 |
|
|
: Colors.theme1.white, |
|
|
fontSize: fontSize.sm, |
|
|
fontFamily: "regular", |
|
|
}, |
|
|
]} |
|
|
> |
|
|
هزینه ارسال کالا پس از تعیین محل آدرس مشخص میشود |
|
|
</Text> |
|
|
<Ionicons |
|
|
name="alert-circle-outline" |
|
|
size={20} |
|
|
color={ |
|
|
theme === "light" |
|
|
? Colors.theme1.greenC8 |
|
|
: Colors.theme1.white |
|
|
} |
|
|
/> |
|
|
</Pressable> |
|
|
|
|
|
<CustomPressable |
|
|
title={hasPhysical ? "ادامه فرایند خرید" : "پرداخت"} |
|
|
backgroundColor={Colors.theme1.greenCF} |
|
|
color={"white"} |
|
|
border={{ color: "#196EC0", width: 0 }} |
|
|
width={"100%"} |
|
|
onPress={() => |
|
|
isEmpty |
|
|
? asyncAwesomeAlert("خطا", "سبد خرید شما خالی است.", { |
|
|
showCancelButton: false, |
|
|
}) |
|
|
: hasPhysical |
|
|
? navigation.navigate("DeliveryForm") |
|
|
: payFactor({ userId }) |
|
|
} |
|
|
/> |
|
|
</View> |
|
|
</ScrollView> |
|
|
) : ( |
|
|
<Empty |
|
|
text={"سبد خرید شما خالی است"} |
|
|
buttonText={"فروشگاه"} |
|
|
buttonAction={() => navigation.navigate("Products")} |
|
|
/> |
|
|
)} |
|
|
</KeyboardAvoidingView> |
|
|
</SafeAreaView> |
|
|
); |
|
|
} |
|
|
|
|
|
const mapStateToProps = (state) => ({ |
|
|
list: state.userProduct.list, |
|
|
payPrice: state.userProduct.sum, |
|
|
factorInfo: state.userFactor.info, |
|
|
userId: state.user.status?.id, |
|
|
hasPhysical: state.userProduct.hasPhysical, |
|
|
loading: state.userProduct.loading, |
|
|
theme: state.publicApi.theme, |
|
|
}); |
|
|
|
|
|
const mapDispatchToProps = { |
|
|
getList: userProduct.list, |
|
|
getInfo: userProduct.info, |
|
|
getFactorInfo: userFactor.info, |
|
|
payFactor: userFactor.payment, |
|
|
}; |
|
|
|
|
|
export default connect(mapStateToProps, mapDispatchToProps)(ShoppingCart); |
|
|
|
|
|
const styles = StyleSheet.create({ |
|
|
contentContainerStyle: { |
|
|
paddingBottom: 120, |
|
|
position: "relative", |
|
|
}, |
|
|
container: { |
|
|
flexDirection: "column", |
|
|
paddingVertical: 5, |
|
|
paddingHorizontal: 16, |
|
|
}, |
|
|
});
|
|
|
|