updated donut detail and drink detail page, cretaed cart page and their functionality

This commit is contained in:
Juthatip McDevitt 2024-07-24 22:19:07 -05:00
parent 6dea060eed
commit e2c67c021f
8 changed files with 360 additions and 38 deletions

View file

@ -0,0 +1,98 @@
import { Image, ImageProps, Pressable, StyleSheet, Text, View } from 'react-native'
import React from 'react'
import { AntDesign } from '@expo/vector-icons';
interface CartItemProps{
id: string;
name: string;
donutname: string;
prices: any;
type: string;
image_item: ImageProps;
addCartItemQuantityHandler: any;
removeCartItemQuantityHandler: any;
}
const CartItem:React.FC<CartItemProps> = ({
id,
name,
donutname,
prices,
type,
image_item,
addCartItemQuantityHandler,
removeCartItemQuantityHandler,
}) => {
return (
<View>
{prices.length != 1 ? (
<View style={{flex: 1, gap: 10, padding: 10, borderRadius: 10, borderColor: '#DA7297', borderWidth: 1}}>
<View style={{flex:1, flexDirection: 'row', gap: 10}}>
<Image source={image_item} style={{height: 80, width: 80}}/>
<View style={{flex:1, paddingVertical: 5, justifyContent: 'space-between'}}>
<View>
<Text style={{fontSize: 16, color: '#EF5A6F', fontWeight: 500, marginBottom: 10}}>{name || donutname}</Text>
</View>
{prices.map((data: any, index: any) => (
<View key={index.toString()} style={{flex: 1, justifyContent: 'center', alignItems: 'center', flexDirection: 'row', gap: 20}}>
<View style={{flex: 1, justifyContent: 'space-between', alignItems: 'center', flexDirection: 'row'}}>
<View style={{padding: 10, justifyContent: 'center', alignItems: 'center'}}>
<Text style={{fontSize: type == 'Drink' ? 16 : 18}}>{data.size}</Text>
</View>
<Text style={{fontSize: 16, color: '#EF5A6F'}}>{data.currency}{data.price}</Text>
</View>
<View style={{flex: 1, justifyContent: 'space-between', alignItems: 'center', flexDirection: 'row'}}>
<Pressable onPress={() => {removeCartItemQuantityHandler(id, data.size)}}>
<AntDesign name="minussquare" size={30} color="#DA7297" />
</Pressable>
<View style={{padding: 2, borderColor: '#DA7297', borderWidth: 2, width: 30, alignItems: 'center'}}>
<Text>{data.quantity}</Text>
</View>
<Pressable onPress={() => {addCartItemQuantityHandler(id, data.size)}}>
<AntDesign name="plussquare" size={30} color="#DA7297" />
</Pressable>
</View>
</View>
))}
</View>
</View>
</View>
) : (
<View style={{flexDirection: 'row', gap: 10, padding: 10, borderRadius: 10, borderColor: '#DA7297', borderWidth: 1}}>
<View>
<Image source={image_item} style={{height: 80, width: 80}}/>
</View>
<View style={{flex: 1}}>
<Text style={{fontSize: 16, color: '#EF5A6F', fontWeight: 500, marginBottom: 10}}>{name || donutname}</Text>
<View style={{flex: 1, justifyContent: 'center', alignItems: 'center', flexDirection: 'row', gap: 20}}>
<View style={{flex: 1, justifyContent: 'space-between', alignItems: 'center', flexDirection: 'row'}}>
<View style={{padding: 10, justifyContent: 'center', alignItems: 'center'}}>
<Text style={{fontSize: type == 'Drink' ? 14 : 16}}>{prices[0].size}</Text>
</View>
<Text style={{fontSize: 16, color: '#EF5A6F'}}>{prices[0].currency}{prices[0].price}</Text>
</View>
<View style={{flex: 1, justifyContent: 'space-between', alignItems: 'center', flexDirection: 'row'}}>
<Pressable onPress={() => {removeCartItemQuantityHandler(id, prices[0].size)}}>
<AntDesign name="minussquare" size={30} color="#DA7297" />
</Pressable>
<View style={{padding: 2, borderColor: '#DA7297', borderWidth: 2, width: 30, alignItems: 'center'}}>
<Text>{prices[0].quantity}</Text>
</View>
<Pressable onPress={() => {addCartItemQuantityHandler(id, prices[0].size)}}>
<AntDesign name="plussquare" size={30} color="#DA7297" />
</Pressable>
</View>
</View>
</View>
</View>
)}
</View>
)
}
export default CartItem
const styles = StyleSheet.create({})

View file

@ -12,7 +12,7 @@ interface DrinkCardProps {
name: string; name: string;
image_item: ImageProps; image_item: ImageProps;
average_rating: number; average_rating: number;
prices: any; price: any;
buttonPressHandler: any; buttonPressHandler: any;
} }
@ -24,7 +24,7 @@ const DrinkCard:React.FC<DrinkCardProps> = ({
name, name,
image_item, image_item,
average_rating, average_rating,
prices, price,
buttonPressHandler, buttonPressHandler,
}) => { }) => {
@ -42,8 +42,8 @@ const DrinkCard:React.FC<DrinkCardProps> = ({
</View> </View>
</View> </View>
<View style={{flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between'}}> <View style={{flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between'}}>
<Text style={{fontWeight: 600, color: '#EF5A6F'}}>$<Text>{prices.price}</Text></Text> <Text style={{fontWeight: 600, color: '#EF5A6F'}}>$<Text>{price.price}</Text></Text>
<Pressable onPress={() => {}}> <Pressable onPress={() => {buttonPressHandler({id, index, type, image_item, name, prices:[{...price, quantity:1}]})}}>
<MaterialIcons name="add-circle" size={24} color="#EF5A6F" /> <MaterialIcons name="add-circle" size={24} color="#EF5A6F" />
</Pressable> </Pressable>
</View> </View>

View file

@ -13,7 +13,7 @@ interface donutCardProps {
name: string; name: string;
image_item: ImageProps; image_item: ImageProps;
average_rating: number; average_rating: number;
prices: any; price: any;
buttonPressHandler: any; buttonPressHandler: any;
} }
@ -25,7 +25,7 @@ const MenuCard:React.FC<donutCardProps> = ({
donutname, donutname,
image_item, image_item,
average_rating, average_rating,
prices, price,
buttonPressHandler, buttonPressHandler,
}) => { }) => {
@ -43,8 +43,8 @@ const MenuCard:React.FC<donutCardProps> = ({
</View> </View>
</View> </View>
<View style={{flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between'}}> <View style={{flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between'}}>
<Text style={{fontWeight: 600, color: '#EF5A6F'}}>$<Text>{prices.price}</Text></Text> <Text style={{fontWeight: 600, color: '#EF5A6F'}}>$<Text>{price.price}</Text></Text>
<Pressable onPress={() => {}}> <Pressable onPress={() => {buttonPressHandler({id, index, type, image_item, donutname, prices:[{...price, quantity:1}]})}}>
<MaterialIcons name="add-circle" size={24} color="#EF5A6F" /> <MaterialIcons name="add-circle" size={24} color="#EF5A6F" />
</Pressable> </Pressable>
</View> </View>

View file

@ -0,0 +1,42 @@
import { Pressable, StyleSheet, Text, View } from 'react-native'
import React from 'react'
interface PriceProps{
price: string;
currency: string;
}
interface PaymentProps{
price: PriceProps;
buttonPressHandler: any;
buttonTitle: string;
}
const Payment: React.FC<PaymentProps> = ({
price,
buttonPressHandler,
buttonTitle,
}) => {
return (
<View style={{padding: 10, marginHorizontal: 10, marginVertical: 10, flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between'}}>
<View style={{flex: 1, marginHorizontal: 10}}>
<Text style={{color: 'gray', marginBottom: 3}}>Price</Text>
<Text style={{fontSize: 22, color: '#EF5A6F', fontWeight: 500}}>{price.currency}{price.price}</Text>
</View>
<View style={{flex: 2, backgroundColor: '#DA7297', padding: 15, alignItems: 'center', borderRadius: 5}}>
<Pressable onPress={() => buttonPressHandler()}>
<Text style={{color: 'white', fontSize: 16, fontWeight: 500}}>{buttonTitle}</Text>
</Pressable>
</View>
</View>
)
}
export default Payment
const styles = StyleSheet.create({})

View file

@ -1,10 +1,65 @@
import { View, Text } from 'react-native' import { View, Text, ScrollView, Image, Pressable} from 'react-native'
import React from 'react' import React from 'react'
import { useStore } from '../store/store';
import {useBottomTabBarHeight} from '@react-navigation/bottom-tabs';
import Payment from '../components/Payment';
import CartItem from '../components/CartItem';
const Cart = ({navigation, route}: any) => {
const CartList = useStore((state: any) => state.CartList);
const CartPrice = useStore((state: any) => state.CartPrice);
const addCartItemQuantity = useStore((state: any) => state.addCartItemQuantity);
const removeCartItemQuantity = useStore((state: any) => state.removeCartItemQuantity);
const calculateCartPrice = useStore((state: any) => state.calculateCartPrice);
const tabBarHeight = useBottomTabBarHeight();
//console.log("CartList =", CartList.length)
const buttonPressHandler = () => {
navigation.push('payment');
}
const Cart = () => {
return ( return (
<View> <View style={{flex: 1, backgroundColor: 'white'}}>
<Text>Cart</Text> <ScrollView showsVerticalScrollIndicator={false} contentContainerStyle={{flexGrow: 1}}>
<View style={{flex: 1, justifyContent: 'space-between'}}>
<View style={{marginTop: 20, paddingVertical: 10, paddingHorizontal: 20}}>
<Text style={{fontSize: 30, fontWeight: 600}}>Cart</Text>
{CartList.length == 0 ? (
<View style={{marginVertical: 50, alignItems: 'center'}}>
<Image source={require('../../assets/images/misc/empty_bag.png')} style={{ width: 200, height: 200, resizeMode: "contain"}} />
<Text style={{marginTop: 30, fontSize: 16, fontWeight: 500}}>You bag is empty!</Text>
</View>
):(
<View style={{gap: 10, marginTop: 20}}>
{CartList.map((data: any)=> (
<Pressable key={data.id} onPress={() => {}}>
<CartItem
id = {data.id}
name = {data.name}
donutname= {data.donutname}
prices = {data.prices}
type = {data.type}
image_item = {data.image_item}
addCartItemQuantityHandler = {() => {}}
removeCartItemQuantityHandler = {() => {}}
/>
</Pressable>
))}
</View>
)}
</View>
{CartList.length != 0 ? (
<Payment buttonTitle='Pay' price={{price:CartPrice, currency: '$'}} buttonPressHandler={buttonPressHandler}/>
) : (
<></>
)}
</View>
</ScrollView>
</View> </View>
) )
} }

View file

@ -3,13 +3,14 @@ import React, { useState } from 'react';
import { useStore } from '../store/store'; import { useStore } from '../store/store';
import { StatusBar } from 'expo-status-bar'; import { StatusBar } from 'expo-status-bar';
import BackgroundInfo from "../components/BackgroundInfo"; import BackgroundInfo from "../components/BackgroundInfo";
import Payment from "../components/Payment";
import { TouchableWithoutFeedback } from 'react-native-gesture-handler'; import { TouchableWithoutFeedback } from 'react-native-gesture-handler';
const Detail = ({navigation, route}: any) => { const Detail = ({navigation, route}: any) => {
const ItemOfIndex = useStore((state: any) => const ItemOfIndex = useStore((state: any) =>
route.params.type == 'Donut' ? state.AllDonutList1 : state.AllDrinkList1, route.params.type == 'Donut' ? state.AllDonutList2 : state.AllDrinkList2,
)[route.params.index]; )[route.params.index];
const addToFavoriteList = useStore((state: any) => state.addToFavoriteList); const addToFavoriteList = useStore((state: any) => state.addToFavoriteList);
@ -20,6 +21,30 @@ const Detail = ({navigation, route}: any) => {
favourite ? deleteFromFavoriteList(type, id) : addToFavoriteList(type, id) favourite ? deleteFromFavoriteList(type, id) : addToFavoriteList(type, id)
} }
//add to cart
const addToCart = useStore((state: any) => state.addToCart);
const calculateCartPrice = useStore((state: any) => state.calculateCartPrice);
const addtoCartHandler = ({
id,
index,
donutname,
image_item,
type,
price
}: any) => {
addToCart({
id,
index,
donutname,
image_item,
type,
prices:[{...price, quantity:1}],
})
calculateCartPrice();
navigation.navigate('cart');
}
//backhandler functionality //backhandler functionality
const BackHandler = () => { const BackHandler = () => {
navigation.pop(); navigation.pop();
@ -28,11 +53,14 @@ const Detail = ({navigation, route}: any) => {
//desc //desc
const [descriptionDrink, setDescriptionDrink] = useState(false); const [descriptionDrink, setDescriptionDrink] = useState(false);
//set prices
const [price, setPrice] = useState(ItemOfIndex.prices[0]);
return ( return (
<View style={{flex: 1, backgroundColor: 'white'}}> <View style={{flex: 1, backgroundColor: 'white'}}>
<StatusBar backgroundColor='dark'/> <StatusBar backgroundColor='dark'/>
<ScrollView showsVerticalScrollIndicator={false} contentContainerStyle={{flexGrow: 1}}> <ScrollView showsVerticalScrollIndicator={false} contentContainerStyle={{flexGrow: 1, justifyContent: 'space-between'}}>
<BackgroundInfo <BackgroundInfo
EnableBackHandler={true} EnableBackHandler={true}
type={ItemOfIndex.type} type={ItemOfIndex.type}
@ -49,14 +77,28 @@ const Detail = ({navigation, route}: any) => {
<View style={{padding: 10, marginHorizontal: 10, marginVertical: 10}}> <View style={{padding: 10, marginHorizontal: 10, marginVertical: 10}}>
{descriptionDrink? ( {descriptionDrink? (
<TouchableWithoutFeedback onPress={() => {setDescriptionDrink(prev => !prev)}}> <TouchableWithoutFeedback onPress={() => {setDescriptionDrink(prev => !prev)}}>
<Text style={{color: 'gray', fontSize: 16}}>{ItemOfIndex.description}</Text> <Text style={{color: 'gray', fontSize: 16, marginTop: 10}}>{ItemOfIndex.description}</Text>
</TouchableWithoutFeedback> </TouchableWithoutFeedback>
) : ( ) : (
<TouchableWithoutFeedback onPress={() => {setDescriptionDrink(prev => !prev)}}> <TouchableWithoutFeedback onPress={() => {setDescriptionDrink(prev => !prev)}}>
<Text style={{color: 'gray', fontSize: 16}} numberOfLines={3}>{ItemOfIndex.description}</Text> <Text style={{color: 'gray', fontSize: 16, marginTop: 10}} numberOfLines={3}>{ItemOfIndex.description}</Text>
</TouchableWithoutFeedback> </TouchableWithoutFeedback>
)} )}
</View> </View>
<Payment
price={price}
buttonTitle = 'Add to cart'
buttonPressHandler={() => {
addtoCartHandler({
id: ItemOfIndex.id,
index: ItemOfIndex.index,
donutname: ItemOfIndex.donutname,
image_item: ItemOfIndex.image_item,
type: ItemOfIndex.type,
price: price,
})
}}
/>
</ScrollView> </ScrollView>
</View> </View>
) )

View file

@ -4,11 +4,12 @@ import { useStore } from '../store/store'
import { StatusBar } from 'expo-status-bar'; import { StatusBar } from 'expo-status-bar';
import { ScrollView, TouchableWithoutFeedback } from 'react-native-gesture-handler'; import { ScrollView, TouchableWithoutFeedback } from 'react-native-gesture-handler';
import BackgroundDrinkInfo from "../components/BackgroundDrinkInfo"; import BackgroundDrinkInfo from "../components/BackgroundDrinkInfo";
import Payment from "../components/Payment";
const DetailDrink = ({navigation, route}: any) => { const DetailDrink = ({navigation, route}: any) => {
const ItemOfIndex = useStore((state: any) => const ItemOfIndex = useStore((state: any) =>
route.params.type == 'Donut' ? state.AllDonutList1 : state.AllDrinkList1, route.params.type == 'Donut' ? state.AllDonutList2 : state.AllDrinkList2,
)[route.params.index]; )[route.params.index];
const addToFavoriteList = useStore((state: any) => state.addToFavoriteList); const addToFavoriteList = useStore((state: any) => state.addToFavoriteList);
@ -19,6 +20,30 @@ const DetailDrink = ({navigation, route}: any) => {
favourite ? deleteFromFavoriteList(type, id) : addToFavoriteList(type, id) favourite ? deleteFromFavoriteList(type, id) : addToFavoriteList(type, id)
} }
//add to cart
const addToCart = useStore((state: any) => state.addToCart);
const calculateCartPrice = useStore((state: any) => state.calculateCartPrice);
const addtoCartHandler = ({
id,
index,
name,
image_item,
type,
price
}: any) => {
addToCart({
id,
index,
name,
image_item,
type,
prices:[{...price, quantity:1}],
});
calculateCartPrice();
navigation.navigate('cart')
}
//backhandler functionality //backhandler functionality
const BackHandler = () => { const BackHandler = () => {
navigation.pop(); navigation.pop();
@ -26,13 +51,16 @@ const DetailDrink = ({navigation, route}: any) => {
//desc //desc
const [descriptionDrink, setDescriptionDrink] = useState(false); const [descriptionDrink, setDescriptionDrink] = useState(false);
//set prices //set prices
const [price, setPrice] = useState(ItemOfIndex.prices[0]) const [price, setPrice] = useState(ItemOfIndex.prices[0]);
return ( return (
<View style={{flex: 1, backgroundColor: 'white'}}> <View style={{flex: 1, backgroundColor: 'white'}}>
<StatusBar backgroundColor='dark'/> <StatusBar backgroundColor='dark'/>
<ScrollView showsVerticalScrollIndicator={false} contentContainerStyle={{flexGrow: 1}}> <ScrollView showsVerticalScrollIndicator={false} contentContainerStyle={{flexGrow: 1, justifyContent: 'space-between'}}>
<BackgroundDrinkInfo <BackgroundDrinkInfo
EnableBackHandler={true} EnableBackHandler={true}
type={ItemOfIndex.type} type={ItemOfIndex.type}
@ -62,7 +90,7 @@ const DetailDrink = ({navigation, route}: any) => {
<Text style={{fontSize: 18, fontWeight: 500, color: '#EF5A6F'}}>Size</Text> <Text style={{fontSize: 18, fontWeight: 500, color: '#EF5A6F'}}>Size</Text>
<View style={{flex: 1, flexDirection: 'row', justifyContent: 'space-between', gap: 10}}> <View style={{flex: 1, flexDirection: 'row', justifyContent: 'space-between', gap: 10}}>
{ItemOfIndex.prices.map((data: any) => ( {ItemOfIndex.prices.map((data: any) => (
<Pressable key={data.size} style={[styles.sizeBox, {borderColor: data.size == price.size ? '#DA7297' : 'gray', backgroundColor: data.size == price.size ? '#DA7297' : 'white'}]}> <Pressable onPress={() => {setPrice(data)}} key={data.size} style={[styles.sizeBox, {borderColor: data.size == price.size ? '#DA7297' : 'gray', backgroundColor: data.size == price.size ? '#DA7297' : 'white'}]}>
<Text style={{fontSize: ItemOfIndex.type == 'Drink'? 14: 16, color: data.size == price.size ? 'white' : 'gray'}}>{data.size}</Text> <Text style={{fontSize: ItemOfIndex.type == 'Drink'? 14: 16, color: data.size == price.size ? 'white' : 'gray'}}>{data.size}</Text>
</Pressable> </Pressable>
))} ))}
@ -70,6 +98,20 @@ const DetailDrink = ({navigation, route}: any) => {
</View> </View>
</View> </View>
<Payment
price={price}
buttonTitle = 'Add to cart'
buttonPressHandler={() => {
addtoCartHandler({
id: ItemOfIndex.id,
index: ItemOfIndex.index,
name: ItemOfIndex.name,
image_item: ItemOfIndex.image_item,
type: ItemOfIndex.type,
price: price,
})
}}
/>
</ScrollView> </ScrollView>
</View> </View>
) )

View file

@ -1,4 +1,4 @@
import { View, Text, ScrollView, StyleSheet, Pressable, Dimensions} from 'react-native' import { View, Text, ScrollView, StyleSheet, Pressable, Dimensions, ToastAndroid} from 'react-native'
import React, { useState } from 'react' import React, { useState } from 'react'
import { useStore } from '../store/store'; import { useStore } from '../store/store';
import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs'; import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs';
@ -32,8 +32,8 @@ const getDonutList = (category: string, data: any) => {
const Menu = ({navigation}: any) => { const Menu = ({navigation}: any) => {
const DonutList = useStore((state: any) => state.AllDonutList1); const DonutList = useStore((state: any) => state.AllDonutList2);
const DrinkList = useStore((state: any) => state.AllDrinkList1); const DrinkList = useStore((state: any) => state.AllDrinkList2);
const [categories, setCategories] = useState(getCategoriesFromData(DonutList)); const [categories, setCategories] = useState(getCategoriesFromData(DonutList));
const [searchMenu, setSearchMenu] = useState(''); const [searchMenu, setSearchMenu] = useState('');
@ -57,6 +57,49 @@ const Menu = ({navigation}: any) => {
setSortItem([...DonutList]); setSortItem([...DonutList]);
setSearchMenu(''); setSearchMenu('');
} }
//add to cart
const addToCart = useStore((state: any) => state.addToCart);
const calculateCartPrice = useStore((state: any) => state.calculateCartPrice);
const drinkCardAddToCart = ({
id,
index,
name,
image_item,
type,
prices
}: any) => {
addToCart({
id,
index,
name,
image_item,
type,
prices,
});
calculateCartPrice();
}
const DonutCardAddToCart = ({
id,
index,
donutname,
image_item,
type,
prices
}: any) => {
addToCart({
id,
index,
donutname,
image_item,
type,
prices,
});
calculateCartPrice();
}
return ( return (
<View style={{flex: 1, backgroundColor: 'white'}}> <View style={{flex: 1, backgroundColor: 'white'}}>
@ -135,8 +178,8 @@ const Menu = ({navigation}: any) => {
donutname={item.donutname} donutname={item.donutname}
image_item={item.image_item} image_item={item.image_item}
average_rating={item.average_rating} average_rating={item.average_rating}
prices={item.prices[0]} price={item.prices[0]}
buttonPressHandler={() => {}} buttonPressHandler={DonutCardAddToCart}
/> />
</Pressable> </Pressable>
}}/> }}/>
@ -164,8 +207,8 @@ const Menu = ({navigation}: any) => {
name={item.name} name={item.name}
image_item={item.image_item} image_item={item.image_item}
average_rating={item.average_rating} average_rating={item.average_rating}
prices={item.prices[0]} price={item.prices[0]}
buttonPressHandler={() => {}} buttonPressHandler={drinkCardAddToCart}
/> />
</Pressable> </Pressable>
}}/> }}/>