247 lines
No EOL
7.7 KiB
TypeScript
247 lines
No EOL
7.7 KiB
TypeScript
import { View, Text, ScrollView, StyleSheet, Pressable, Dimensions} from 'react-native'
|
|
import React, { useState } from 'react'
|
|
import { useStore } from '../store/store';
|
|
import { useBottomTabBarHeight } from '@react-navigation/bottom-tabs';
|
|
import { FlatList, TextInput } from 'react-native-gesture-handler';
|
|
import { AntDesign, MaterialIcons} from '@expo/vector-icons';
|
|
import MenuCard from "../components/MenuCard";
|
|
import DrinkCard from "../components/DrinkCard";
|
|
|
|
const getCategoriesFromData = (data: any) => {
|
|
let temp: any = {};
|
|
for (let i = 0; i < data.length; i++) {
|
|
if (temp[data[i].name] == undefined) {
|
|
temp[data[i].name] = 1;
|
|
} else {
|
|
temp[data[i].name]++;
|
|
}
|
|
}
|
|
let categories = Object.keys(temp);
|
|
categories.unshift('All');
|
|
return categories;
|
|
};
|
|
|
|
const getDonutList = (category: string, data: any) => {
|
|
if (category == 'All') {
|
|
return data;
|
|
} else {
|
|
let donutlist = data.filter((item: any) => item.name == category);
|
|
return donutlist;
|
|
}
|
|
};
|
|
|
|
|
|
const Menu = ({navigation}: any) => {
|
|
const DonutList = useStore((state: any) => state.AllDonutMenu);
|
|
const DrinkList = useStore((state: any) => state.AllDrinkMenu);
|
|
|
|
const [categories, setCategories] = useState(getCategoriesFromData(DonutList));
|
|
const [searchMenu, setSearchMenu] = useState('');
|
|
const [categoryIndex, setCategoryIndex] = useState({index: 0, category: categories[0]});
|
|
const [sortItem, setSortItem] = useState(getDonutList(categoryIndex.category, DonutList));
|
|
|
|
|
|
const tabBar = useBottomTabBarHeight();
|
|
//console.log(sortItem.length)
|
|
const searchMenuItem = (search:string) => {
|
|
if(search != ''){
|
|
setCategoryIndex({index: 0, category: categories[0]});
|
|
setSortItem([...DonutList.filter((item: any) =>
|
|
item.donutname.toLowerCase().includes(search.toLocaleLowerCase()),),]
|
|
);
|
|
}
|
|
};
|
|
|
|
const resetSearch = () => {
|
|
setCategoryIndex({index: 0, category: categories[0]});
|
|
setSortItem([...DonutList]);
|
|
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 (
|
|
<View style={{flex: 1, backgroundColor: 'white'}}>
|
|
<ScrollView showsVerticalScrollIndicator={false} contentContainerStyle={styles.ScrollViewFlex}>
|
|
<View style={{marginTop: 20, paddingHorizontal: 20, paddingVertical: 10}}>
|
|
<Text style={{fontSize: 30, fontWeight: 600}}>Menu</Text>
|
|
{/*===== search =====*/}
|
|
<View style={{marginTop: 20, marginBottom: 10, backgroundColor: '#EEEEEE', padding: 10, borderRadius: 10, flexDirection: 'row', justifyContent: 'space-between'}}>
|
|
{searchMenu.length == 0 ? (
|
|
<Pressable onPress={() => {searchMenuItem(searchMenu)}}>
|
|
<AntDesign name="search1" size={24} color="gray" />
|
|
</Pressable>
|
|
) : (
|
|
<Pressable onPress={() => {resetSearch()}}>
|
|
<MaterialIcons name="close" size={24} color="black" />
|
|
</Pressable>
|
|
)}
|
|
|
|
<TextInput value={searchMenu} onChangeText={text => {setSearchMenu(text); searchMenuItem(text)}} placeholder='Search...' style={{fontSize: 18, flex:1, marginLeft: 5}}/>
|
|
|
|
{searchMenu.length > 0 ? (
|
|
<Pressable onPress={() => {searchMenuItem(searchMenu)}}>
|
|
<AntDesign name="search1" size={24} color="gray" />
|
|
</Pressable>
|
|
) : (
|
|
<></>
|
|
)}
|
|
</View>
|
|
</View>
|
|
{/*===== Tab category =====*/}
|
|
<Text style={{fontSize: 26, fontWeight: 600, color: '#EF5A6F', paddingHorizontal: 20, marginBottom: 20}}>Donuts</Text>
|
|
|
|
<ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={styles.CategoryView}>
|
|
{categories.map((item, index) => (
|
|
<View key={index.toString()} style={styles.CategoryScroll}>
|
|
<Pressable onPress={() => {setCategoryIndex({index:index, category:categories[index]}); setSortItem([...getDonutList(categories[index], DonutList)])}}>
|
|
<Text style={[styles.catText,
|
|
categoryIndex.index == index ? {color: '#DA7297'} : {}, ]}>
|
|
{item}
|
|
</Text>
|
|
{categoryIndex.index == index ? (
|
|
<View style={styles.activeCategory}/>
|
|
) : (
|
|
<></>
|
|
)}
|
|
</Pressable>
|
|
</View>
|
|
))}
|
|
</ScrollView>
|
|
|
|
{/*===== donuts=====*/}
|
|
<FlatList
|
|
horizontal
|
|
showsHorizontalScrollIndicator={false}
|
|
data={sortItem}
|
|
contentContainerStyle={styles.MenuListContainer}
|
|
keyExtractor={item => item.id}
|
|
ListEmptyComponent={
|
|
<View style={{width: Dimensions.get('window').width - 20*2, alignItems: 'center', justifyContent: 'center'}}>
|
|
<Text style={{fontWeight: 500, flex: 1,}}>Sorry, this item is not on our menu</Text>
|
|
</View>
|
|
}
|
|
renderItem={({item}) => {
|
|
return <Pressable onPress={() => {
|
|
navigation.push('detail', {
|
|
index: item.index,
|
|
id: item.id,
|
|
type: item.type,
|
|
});
|
|
}}>
|
|
<MenuCard
|
|
id={item.id}
|
|
index={item.index}
|
|
type={item.type}
|
|
name={item.name}
|
|
donutname={item.donutname}
|
|
image_item={item.image_item}
|
|
average_rating={item.average_rating}
|
|
price={item.prices[0]}
|
|
buttonPressHandler={DonutCardAddToCart}
|
|
/>
|
|
</Pressable>
|
|
}}/>
|
|
{/*===== drinks =====*/}
|
|
<View>
|
|
<Text style={{fontSize: 26, fontWeight: 600, color: '#EF5A6F' ,marginTop: 20, paddingHorizontal: 20}}>Drinks</Text>
|
|
<FlatList
|
|
horizontal
|
|
showsHorizontalScrollIndicator={false}
|
|
data={DrinkList}
|
|
contentContainerStyle={[styles.MenuListContainer, {marginBottom: tabBar}]}
|
|
keyExtractor={item => item.id}
|
|
renderItem={({item}) => {
|
|
return <Pressable onPress={() => {
|
|
navigation.push('detailDrink', {
|
|
index: item.index,
|
|
id: item.id,
|
|
type: item.type,
|
|
});
|
|
}}>
|
|
<DrinkCard
|
|
id={item.id}
|
|
index={item.index}
|
|
type={item.type}
|
|
name={item.name}
|
|
image_item={item.image_item}
|
|
average_rating={item.average_rating}
|
|
price={item.prices[0]}
|
|
buttonPressHandler={drinkCardAddToCart}
|
|
/>
|
|
</Pressable>
|
|
}}/>
|
|
</View>
|
|
</ScrollView>
|
|
</View>
|
|
)
|
|
}
|
|
|
|
export default Menu
|
|
|
|
const styles = StyleSheet.create({
|
|
ScrollViewFlex:{
|
|
flexGrow: 1,
|
|
},
|
|
CategoryView:{
|
|
paddingHorizontal: 5
|
|
},
|
|
CategoryScroll:{
|
|
paddingHorizontal: 20
|
|
},
|
|
catText:{
|
|
fontSize: 16,
|
|
fontWeight: 600,
|
|
color: 'gray'
|
|
},
|
|
activeCategory:{
|
|
backgroundColor: '#DA7297',
|
|
padding: 1
|
|
},
|
|
MenuListContainer:{
|
|
gap: 20,
|
|
paddingVertical: 20,
|
|
paddingHorizontal: 20
|
|
}
|
|
}) |