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.
 
 
 
 
 

304 lines
8.6 KiB

import React, { useState, useEffect, useCallback } from "react";
import {
View,
Text,
ScrollView,
Dimensions,
StyleSheet,
Pressable,
SafeAreaView,
StatusBar,
LayoutAnimation,
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";
import * as Linking from "expo-linking";
//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 { width, height } = Dimensions.get("window");
const PriceStatus = ({ name, value, type }) => {
const colorScheme = Appearance.getColorScheme();
return (
<View style={tw("w-full flex flex-row-reverse justify-between py-2")}>
<Text
style={[
tw(""),
{
fontSize: fontSize.tiny,
color: Colors.theme1[colorScheme].gray20,
fontFamily: "bold",
},
]}
>
{name}
</Text>
<View style={tw("flex flex-row-reverse items-center")}>
<Text
style={[
{
color:
type === "error"
? Colors.theme1[colorScheme].redFF1
: Colors.theme1[colorScheme].green79,
fontSize: fontSize.xl,
fontFamily: "bold",
},
]}
>
{value}
</Text>
<Text
style={[
{
color:
type === "error"
? Colors.theme1[colorScheme].redFF1
: Colors.theme1[colorScheme].green79,
fontSize: fontSize.sm,
fontFamily: "regular",
marginRight: 4,
},
]}
>
تومان
</Text>
</View>
</View>
);
};
function ShoppingCart({
userId,
list,
factorInfo,
getList,
getFactorInfo,
loading,
payFactor,
}) {
const navigation = useNavigation();
const colorScheme = Appearance.getColorScheme();
const [position, setPosition] = useState("100%");
const isEmpty = list.filter((product) => product.condition < 2).length === 0;
const hasPhysical =
list.filter((product) => product.condition < 2 && product.productType === 2)
.length !== 0;
useEffect(() => {
if (list.length === 0) {
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",
height: height,
}}
>
<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} />
)
)}
<Code />
<View
style={tw(
"flex w-full border-t py-2 border-gray-300 border-b mt-6"
)}
>
<PriceStatus
name="مبلغ سبد خرید"
value={isEmpty ? 0 : separate(Math.round(factorInfo?.sumPrice || 0))}
type="normal"
/>
<PriceStatus
name="میزان تخفیف"
value={isEmpty ? 0 : separate(Math.round(factorInfo?.offPrice || 0))}
type="error"
/>
<PriceStatus
name="مالیات بر ارزش افزوده"
value={
isEmpty ? 0 : separate(Math.round((factorInfo?.sumPrice || 0) * 0.009))
}
type="error"
/>
</View>
<View
style={tw(
"flex flex-row-reverse justify-between items-center w-full py-3"
)}
>
<Text
style={[
{
color: Colors.theme1[colorScheme].green79,
fontSize: fontSize.base,
fontFamily: "bold",
},
]}
>
جمع کل سبد خرید
</Text>
<View style={tw("flex flex-row-reverse items-center")}>
<Text
style={[
{
color: Colors.theme1[colorScheme].green79,
fontSize: fontSize.xl,
fontFamily: "bold",
},
]}
>
{isEmpty ? 0 : separate(factorInfo?.payPrice || '')}
</Text>
<Text
style={[
{
color: Colors.theme1[colorScheme].green79,
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: Colors.theme1[colorScheme].greenC8 + "1a" },
]}
>
<Text
style={[
tw("mr-1"),
{
color: Colors.theme1[colorScheme].green79,
fontSize: fontSize.sm,
fontFamily: "regular",
},
]}
>
هزینه ارسال کالا پس از تعیین محل آدرس مشخص میشود
</Text>
<Ionicons
name="alert-circle-outline"
size={20}
color={Colors.theme1[colorScheme].greenC8}
/>
</Pressable>
<CustomPressable
title={hasPhysical ? "ادامه فرایند خرید" : "پرداخت"}
backgroundColor={Colors.theme1[colorScheme].greenCF}
color={"white"}
border={{ color: "#196EC0", width: 0 }}
width={"100%"}
onPress={() =>
isEmpty
? asyncAwesomeAlert("خطا", "سبد خرید شما خالی است.", {
showCancelButton: false,
})
: hasPhysical
? navigation.push("DeliveryForm")
: payFactor({ userId })
}
/>
</View>
</ScrollView>
) : (
<Empty
text={"سبد خرید شما خالی است"}
buttonText={"فروشگاه"}
buttonAction={() => navigation.navigate("Products")}
/>
)}
</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,
});
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: 100,
position: "relative",
},
container: {
backgroundColor: "white",
flexDirection: "column",
paddingVertical: 5,
paddingHorizontal: 16,
},
});