You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

342 lines
9.8 KiB

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,
},
});