Skip to content

Commit

Permalink
FoodDetailsScreen + improve something
Browse files Browse the repository at this point in the history
  • Loading branch information
hoan7902 committed Dec 27, 2023
1 parent 3c0e7bb commit 8a57436
Show file tree
Hide file tree
Showing 25 changed files with 552 additions and 62 deletions.
6 changes: 6 additions & 0 deletions assets/Heart_Active.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions assets/Home_Indicator.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions assets/arrow-back.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@react-navigation/native-stack": "^6.9.0",
"@react-navigation/stack": "^6.3.20",
"@reduxjs/toolkit": "^1.8.5",
"@types/react-native-video": "^5.0.19",
"axios": "^1.6.2",
"expo": "~48.0.21",
"expo-blur": "~12.2.2",
Expand Down Expand Up @@ -48,6 +49,7 @@
"react-native-svg-transformer": "^1.2.0",
"react-native-svg-uri": "^1.2.3",
"react-native-tab-view": "^3.5.2",
"react-native-video": "^5.2.1",
"react-native-web": "~0.18.11",
"react-redux": "^8.0.2",
"redux-devtools-extension": "^2.13.9",
Expand Down
1 change: 0 additions & 1 deletion src/Components/Home/Category.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ const Category: React.FC = () => {
const [activeIndex, setActiveIndex] = useState<number | null>(0);

const handleTypeClick = (index: number) => {
console.log('hehe');
setActiveIndex(index === activeIndex ? null : index);
};

Expand Down
74 changes: 52 additions & 22 deletions src/Components/Home/FoodDetails.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,59 @@
import { Image, StyleSheet, View } from "react-native";
import React, { memo } from "react";
import { Image, StyleSheet, TouchableOpacity, View } from "react-native";
import React, { memo, useCallback, useMemo, useState } from "react";
import { HStack, Text } from "native-base";
import { Colors } from "@/Theme/Variables";
import SvgUri from "react-native-svg-uri";
import { useAppSelector } from "@/Hooks/redux";
import { addFavouriteDishById, getFavouriteDishIds, removeFavouriteDishById } from "@/api";
import { setListFavouriteIds } from "@/Store/reducers";
import { useDispatch } from "react-redux";

const FoodDetails = ({ item }: { item: any }) => (
<View style={styles.container}>
{item.thumbnail_url && (
<Image
source={{ uri: item.thumbnail_url }}
style={styles.image}
/>
)}
<Text style={styles.titleName}>{item.name}</Text>
<Text style={styles.textDescription}>{item.description}</Text>
<View style={styles.subInformation}>
<HStack style={{ alignItems: 'center', gap: 4 }}>
<SvgUri source={require('../../../assets/Star.svg')} />
<Text>{`Score: ${(item.user_ratings.score * 100).toFixed(2)} / 100`}</Text>
</HStack>
<Text style={styles.timeCook}>{`${item.cook_time_minutes || '20'} m`}</Text>
<SvgUri source={require('../../../assets/Heart_Inactive.svg')} />
</View>
</View>
);
const FoodDetails = ({ item, onPress }: { item: any, onPress: any }) => {
const userId = useAppSelector(state => state.user.userId);
const listFavouriteIds = useAppSelector(state => state.home.listFavouriteIds);
const isFavourite = useMemo(() => listFavouriteIds.includes(item.id), [item, listFavouriteIds]);
const [isRed, setIsRed] = useState(isFavourite);
const dispatch = useDispatch();

const handleAddToFavourite = useCallback(async () => {
setIsRed(!isRed);
if (isFavourite) {
await removeFavouriteDishById(item.id);
} else {
await addFavouriteDishById(item.id);
}
const resFavouriteIds = await getFavouriteDishIds();
dispatch(setListFavouriteIds({ listFavouriteIds: resFavouriteIds.data.ids}));
}, [userId]);


return (
<TouchableOpacity onPress={onPress} style={styles.container}>
{item.thumbnail_url && (
<Image
source={{ uri: item.thumbnail_url }}
style={styles.image}
/>
)}
<Text style={styles.titleName}>{item.name}</Text>
<Text style={styles.textDescription}>{item.description}</Text>
<View style={styles.subInformation}>
<HStack style={{ alignItems: 'center', gap: 4 }}>
<SvgUri source={require('../../../assets/Star.svg')} />
<Text>{`Score: ${(item.user_ratings.score * 100).toFixed(2)} / 100`}</Text>
</HStack>
<Text style={styles.timeCook}>{`${item.cook_time_minutes || '20'} m`}</Text>
{userId &&
<TouchableOpacity onPress={handleAddToFavourite}>
{(isRed) ?
<SvgUri source={require('../../../assets/Heart_Active.svg')} />
: <SvgUri source={require('../../../assets/Heart_Inactive.svg')} />}

</TouchableOpacity>}
</View>
</TouchableOpacity>
);
};

export default memo(FoodDetails);

Expand Down
173 changes: 173 additions & 0 deletions src/Components/Home/FoodMoreDetails.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
import { Image, StyleSheet, Text, TouchableOpacity, View } from "react-native";
import React from "react";
import { ScrollView } from "native-base";
import { Colors } from "@/Theme/Variables";
// import VideoPlayer from "../Video";
import SvgUri from "react-native-svg-uri";
import { RootScreens } from "@/Screens";

interface FoodMoreDetailsProps {
food: any;
navigation?: any,
}

interface SectionInfoProps {
title: string;
description: string;
}


const SectionInfo: React.FC<SectionInfoProps> = ({ title, description }: SectionInfoProps) => (
<View style={styles.sectionInfo}>
<Text style={styles.textTitle}>{title}</Text>
<Text style={styles.textSub}>{description}</Text>
</View>
);

const SectionStep: React.FC = ({ number, content}) => <View style={styles.stepsContainer}>
<View style={styles.number}>
<Text style={{ color: Colors.WHITE }}>{number}</Text>
</View>
<Text style={styles.textSubBold}>{content}</Text>
</View>;

const FoodMoreDetails: React.FC<FoodMoreDetailsProps> = ({ food, navigation }) => (
<View style={styles.container}>
<Image
source={{ uri: food.thumbnailUrl }}
style={styles.image}
/>
<TouchableOpacity style={styles.iconBack} onPress={() => navigation?.navigate(RootScreens.HOME)}>
<SvgUri
source={require('../../../assets/arrow-left.svg')}
/>
</TouchableOpacity>
<ScrollView style={styles.scrollView}>
<View style={styles.homeIndicator} />
<View style={styles.infoContainer}>
<SectionInfo title={food.name} description={`Food - ${food.totalTimeTier.display_tier || '30 mins'}`} />
<SectionInfo title="Description" description={food.description} />
<View style={styles.sectionInfo}>
<Text style={styles.textTitle}>Ingredients</Text>
{food.ingredients.map((ingredient, index) => (
<Text key={index} style={[styles.textSubBold, { textTransform: 'capitalize' }]}>
{ingredient}
</Text>
))}
</View>
<View style={styles.sectionInfo}>
<Text style={styles.textTitle}>Steps</Text>
{food.instructions.map((instruction, idx) => (
<SectionStep key={idx} number={idx + 1} content={instruction.display_text} />
))}
</View>
</View>
{/* Chưa import video được, hichic:< */}
{/* <VideoPlayer urlVideo={food.urlVideo} /> */}
</ScrollView>
</View>
);

export default FoodMoreDetails;

const styles = StyleSheet.create({
container: {
width: '100%',
height: '100%',
display: 'flex',
marginBottom: 230
},
image: {
width: 'auto',
height: '50%',
resizeMode: 'cover',
},
scrollView: {
flex: 1,
backgroundColor: Colors.WHITE,
borderTopLeftRadius: 30,
borderTopRightRadius: 30,
marginTop: -100,
position: 'relative',
},
homeIndicator: {
position: 'absolute',
top: 10,
left: '50%',
transform: [{ translateX: -20 }],
backgroundColor: Colors.GRAY_INDICATOR,
borderRadius: 100,
height: 5,
width: 40,
marginBottom: 10
},
infoContainer: {
marginTop: 15,
},
textTitle: {
color: Colors.NAVY,
fontSize: 17,
fontWeight: '700',
lineHeight: 27,
letterSpacing: 0.50,
wordWrap: 'break-word'
},
textSub: {
color: Colors.TEXT_SECONDARY,
fontSize: 15,
fontWeight: '500',
lineHeight: 25,
letterSpacing: 0.50,
wordWrap: 'break-word',
},
textSubBold: {
color: '#2E3E5C',
fontSize: 15,
fontWeight: '500',
lineHeight: 25,
letterSpacing: 0.50,
wordWrap: 'break-word'
},
sectionInfo: {
display: 'flex',
gap: 8,
paddingVertical: 20,
marginHorizontal: 20,
borderBottomWidth: 1,
borderBottomColor: Colors.GRAY_INDICATOR,
borderBottomStyle: 'solid',
},
number: {
backgroundColor: '#2E3E5C',
marginTop: 5,
height: 24,
width: 24,
borderRadius: 12,
color: Colors.WHITE,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
textAlign: 'center',
textAlignVertical: 'center'
},
stepsContainer: {
display: 'flex',
flexDirection: 'row',
gap: 12,
marginRight: 20
},
iconBack: {
width: 40,
height: 40,
backgroundColor: Colors.PRIMARY,
position: 'relative',
top: -280,
left: 20,
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
padding: 10,
borderRadius: 20,
zIndex: 2
}
});
Loading

0 comments on commit 8a57436

Please sign in to comment.