From 8a5743665f594f3dd06e0cd3f338249545806704 Mon Sep 17 00:00:00 2001 From: hoan7902 Date: Thu, 28 Dec 2023 02:51:07 +0700 Subject: [PATCH] FoodDetailsScreen + improve something --- assets/Heart_Active.svg | 6 + assets/Home_Indicator.svg | 3 + assets/arrow-back.svg | 14 ++ package.json | 2 + src/Components/Home/Category.tsx | 1 - src/Components/Home/FoodDetails.tsx | 74 +++++++--- src/Components/Home/FoodMoreDetails.tsx | 173 ++++++++++++++++++++++++ src/Components/Home/ListFood.tsx | 88 ++++++++++-- src/Components/Profile/index.tsx | 32 ++++- src/Components/Scan/Item.tsx | 2 - src/Components/SignIn/index.tsx | 10 +- src/Components/Video/index.tsx | 14 ++ src/Hooks/useProcessedFood.ts | 48 +++++++ src/Navigation/Main/index.tsx | 25 +++- src/Screens/EditProfile/index.tsx | 1 - src/Screens/FoodMoreDetails/index.tsx | 31 +++++ src/Screens/Home/index.tsx | 2 +- src/Screens/Scan/index.tsx | 1 - src/Screens/index.ts | 3 +- src/Store/index.ts | 5 +- src/Store/reducers/home.ts | 15 +- src/Store/reducers/index.ts | 1 + src/Store/reducers/user.ts | 15 ++ src/Theme/Variables.ts | 3 +- src/api/index.ts | 45 +++++- 25 files changed, 552 insertions(+), 62 deletions(-) create mode 100644 assets/Heart_Active.svg create mode 100644 assets/Home_Indicator.svg create mode 100644 assets/arrow-back.svg create mode 100644 src/Components/Home/FoodMoreDetails.tsx create mode 100644 src/Components/Video/index.tsx create mode 100644 src/Hooks/useProcessedFood.ts create mode 100644 src/Screens/FoodMoreDetails/index.tsx create mode 100644 src/Store/reducers/user.ts diff --git a/assets/Heart_Active.svg b/assets/Heart_Active.svg new file mode 100644 index 0000000..4939bf9 --- /dev/null +++ b/assets/Heart_Active.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/Home_Indicator.svg b/assets/Home_Indicator.svg new file mode 100644 index 0000000..0228ebc --- /dev/null +++ b/assets/Home_Indicator.svg @@ -0,0 +1,3 @@ + + + diff --git a/assets/arrow-back.svg b/assets/arrow-back.svg new file mode 100644 index 0000000..d5c13e8 --- /dev/null +++ b/assets/arrow-back.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/package.json b/package.json index d24853c..060e6f2 100644 --- a/package.json +++ b/package.json @@ -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", @@ -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", diff --git a/src/Components/Home/Category.tsx b/src/Components/Home/Category.tsx index 073076f..98542d5 100644 --- a/src/Components/Home/Category.tsx +++ b/src/Components/Home/Category.tsx @@ -38,7 +38,6 @@ const Category: React.FC = () => { const [activeIndex, setActiveIndex] = useState(0); const handleTypeClick = (index: number) => { - console.log('hehe'); setActiveIndex(index === activeIndex ? null : index); }; diff --git a/src/Components/Home/FoodDetails.tsx b/src/Components/Home/FoodDetails.tsx index 0297445..443d099 100644 --- a/src/Components/Home/FoodDetails.tsx +++ b/src/Components/Home/FoodDetails.tsx @@ -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 }) => ( - - {item.thumbnail_url && ( - - )} - {item.name} - {item.description} - - - - {`Score: ${(item.user_ratings.score * 100).toFixed(2)} / 100`} - - {`${item.cook_time_minutes || '20'} m`} - - - -); +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 ( + + {item.thumbnail_url && ( + + )} + {item.name} + {item.description} + + + + {`Score: ${(item.user_ratings.score * 100).toFixed(2)} / 100`} + + {`${item.cook_time_minutes || '20'} m`} + {userId && + + {(isRed) ? + + : } + + } + + + ); +}; export default memo(FoodDetails); diff --git a/src/Components/Home/FoodMoreDetails.tsx b/src/Components/Home/FoodMoreDetails.tsx new file mode 100644 index 0000000..0f9035a --- /dev/null +++ b/src/Components/Home/FoodMoreDetails.tsx @@ -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 = ({ title, description }: SectionInfoProps) => ( + + {title} + {description} + +); + +const SectionStep: React.FC = ({ number, content}) => + + {number} + + {content} +; + +const FoodMoreDetails: React.FC = ({ food, navigation }) => ( + + + navigation?.navigate(RootScreens.HOME)}> + + + + + + + + + Ingredients + {food.ingredients.map((ingredient, index) => ( + + {ingredient} + + ))} + + + Steps + {food.instructions.map((instruction, idx) => ( + + ))} + + + {/* Chưa import video được, hichic:< */} + {/* */} + + +); + +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 + } +}); diff --git a/src/Components/Home/ListFood.tsx b/src/Components/Home/ListFood.tsx index de9ba44..cd74b6a 100644 --- a/src/Components/Home/ListFood.tsx +++ b/src/Components/Home/ListFood.tsx @@ -1,37 +1,99 @@ import { useAppSelector } from '@/Hooks/redux'; import { Colors } from '@/Theme/Variables'; import { ScrollView, Text } from 'native-base'; -import React, { memo } from 'react'; +import React, { memo, useCallback, useEffect, useMemo, useState } from 'react'; import { View, Dimensions, StyleSheet } from 'react-native'; -import { TabView, SceneMap, Route, TabBar } from 'react-native-tab-view'; +import { TabView, Route, TabBar } from 'react-native-tab-view'; import FoodDetails from './FoodDetails'; +import BaseButton from '../BaseButton'; +import { StackNavigationProp } from '@react-navigation/stack'; +import { RootScreens } from '@/Screens'; +import { getDishById } from '@/api'; -const FirstRoute: React.FC = () => { +interface ListFoodProps { + navigation?: StackNavigationProp; +} + +interface FirstRouteProps { + navigation?: StackNavigationProp; +} + +interface SecondRouteProps { + navigation?: StackNavigationProp; +} + +const FirstRoute: React.FC = ({ navigation }) => { const listFood = useAppSelector(state => state.home.listFood); return ( - {Object.values(listFood || {})?.map((food: any) => )} + {Object.values(listFood || {})?.map((food: any) => navigation?.navigate(RootScreens.FOOD_DETAILS, { food })}/>)} ); }; -const SecondRoute: React.FC = () => { - const listFood = useAppSelector(state => state.home.listFood); +const SecondRoute: React.FC = ({ navigation }) => { + const userId = useAppSelector(state => state.user.userId); + const listFavouriteIds = useAppSelector(state => state.home.listFavouriteIds); + const [listFoodFavourite, setListFoodFavourite] = useState([]); + const fetchFavouriteFood = useCallback(async () => { + try { + for (const id of listFavouriteIds) { + const res = await getDishById(id); + setListFoodFavourite(prevList => { + if (!prevList.some(item => item.id === res.id)) { + return [...prevList, res]; + } + return prevList; // Nếu id đã tồn tại, không thêm vào mảng + }); + console.log('check res getDishById: ', res); + } + } catch (error) { + console.error('Error fetching favourite food:', error); + } + }, [listFavouriteIds]); + + useEffect(() => { + fetchFavouriteFood(); + }, [userId, listFavouriteIds]); + + if (!userId) { + return + navigation?.navigate(RootScreens.SIGNIN)} + width={250} + /> + ; + } + return ( - {Object.values(listFood || {})?.map((food: any) => )} + {listFoodFavourite?.map((food: any) => + navigation?.navigate(RootScreens.FOOD_DETAILS, { food })} + />)} ); }; -const renderScene = SceneMap({ - popular: FirstRoute, - favourite: SecondRoute, -}); +const renderScene = ({ route, navigation }: { route: Route; navigation: StackNavigationProp; }) => { + switch (route.key) { + case 'popular': + return ; + case 'favourite': + return ; + default: + return null; + } +}; const initialLayout = { width: Dimensions.get('window').width }; -const ListFood: React.FC = () => { +const ListFood: React.FC = ({ navigation }) => { const [index, setIndex] = React.useState(0); const [routes] = React.useState([ { key: 'popular', title: 'Popular' }, @@ -65,7 +127,7 @@ const ListFood: React.FC = () => { renderScene({ ...props, navigation })} // Pass navigation prop here onIndexChange={handleIndexChange} initialLayout={initialLayout} renderTabBar={renderTabBar} diff --git a/src/Components/Profile/index.tsx b/src/Components/Profile/index.tsx index f744e53..ce93a93 100644 --- a/src/Components/Profile/index.tsx +++ b/src/Components/Profile/index.tsx @@ -1,11 +1,16 @@ +import { useAppSelector } from '@/Hooks/redux'; import { RootScreens } from '@/Screens'; import { Colors } from '@/Theme/Variables'; import { getUserProfile } from '@/api'; +import AsyncStorage from '@react-native-async-storage/async-storage'; import { StackNavigationProp } from '@react-navigation/stack'; import { Button, HStack, VStack } from 'native-base'; import React, { memo, useCallback, useEffect, useState } from 'react'; -import { View, Text, StyleSheet, Image } from 'react-native'; +import { View, Text, StyleSheet, Image, TouchableOpacity } from 'react-native'; import SvgUri from 'react-native-svg-uri'; +import BaseButton from '../BaseButton'; +import { setUserId } from '@/Store/reducers'; +import { useDispatch } from 'react-redux'; interface ProfileProps { navigation?: StackNavigationProp; @@ -13,7 +18,9 @@ interface ProfileProps { } const Profile:React.FC = ({ navigation }) => { + const userId = useAppSelector(state => state.user.userId); const [userInfo, setUserInfo] = useState(); + const dispatch = useDispatch(); const fetchUserProfile = useCallback(async () => { const res = await getUserProfile(); @@ -24,6 +31,25 @@ const Profile:React.FC = ({ navigation }) => { fetchUserProfile(); }, []); + const handleLogout = useCallback(async () => { + await AsyncStorage.removeItem('token'); + await AsyncStorage.removeItem('userId'); + dispatch(setUserId({ userId: null })); + navigation?.navigate(RootScreens.HOME); + }, []); + + if (!userId) { + return + navigation?.navigate(RootScreens.SIGNIN)} + width={250} + /> + ; + } + return ( @@ -73,10 +99,10 @@ const Profile:React.FC = ({ navigation }) => { Change password - + Logout - + diff --git a/src/Components/Scan/Item.tsx b/src/Components/Scan/Item.tsx index 8557ab8..82b01c5 100644 --- a/src/Components/Scan/Item.tsx +++ b/src/Components/Scan/Item.tsx @@ -31,7 +31,6 @@ const Item = () => { duration: 500, // Adjust duration as needed useNativeDriver: false, }).start(); - console.log('Tick button released'); }, }); @@ -60,7 +59,6 @@ const Item = () => { duration: 500, // Adjust duration as needed useNativeDriver: false, }).start(); - console.log('Tick button released'); }, }); diff --git a/src/Components/SignIn/index.tsx b/src/Components/SignIn/index.tsx index 6119163..bab2602 100644 --- a/src/Components/SignIn/index.tsx +++ b/src/Components/SignIn/index.tsx @@ -9,6 +9,8 @@ import { View, Text, TextInput, TouchableOpacity } from 'react-native'; import SvgUri from 'react-native-svg-uri'; import BaseModal from '../BaseModal'; import BaseButton from '../BaseButton'; +import { setUserId } from '@/Store/reducers'; +import { useDispatch } from 'react-redux'; interface SignInProps { navigation?: StackNavigationProp; @@ -36,11 +38,16 @@ const SignIn:React.FC = ({ navigation, isSignUp }) => { const toggleShowPassword = () => setIsHidePassword(!isHidePassword); + const dispatch = useDispatch(); + const handleSignIn = async () => { if (isSignUp) { // Đăng ký const res = await signUp(email, password); if (!res) setIsShowMessageError(true); else setIsShowMessageError(false); + await AsyncStorage.setItem('token', res.data.token); + await AsyncStorage.setItem('userId', res.data.user.userId); + dispatch(setUserId({ userId: res.data.user.userId })); setIsModalVisible(true); } else { // Đăng nhập const res = await signIn(email, password); @@ -48,6 +55,7 @@ const SignIn:React.FC = ({ navigation, isSignUp }) => { else setIsShowMessageError(false); await AsyncStorage.setItem('token', res.data.token); await AsyncStorage.setItem('userId', res.data.user.userId); + dispatch(setUserId({ userId: res.data.user.userId })); navigation?.navigate(RootScreens.HOME); } }; @@ -117,7 +125,7 @@ const SignIn:React.FC = ({ navigation, isSignUp }) => { {isSignUp && navigation?.navigate(RootScreens.SIGNIN)} + onPressButton={() => navigation?.navigate(RootScreens.WELCOME)} />} {isSignUp ? diff --git a/src/Components/Video/index.tsx b/src/Components/Video/index.tsx new file mode 100644 index 0000000..a72eab7 --- /dev/null +++ b/src/Components/Video/index.tsx @@ -0,0 +1,14 @@ +// import Video from 'react-native-video'; +import Video from 'react-native-video'; +import React, { memo } from 'react'; +import { View } from 'react-native'; + +const VideoPlayer = ({ urlVideo } : { urlVideo: string}) => ( + + +); + +export default memo(VideoPlayer); diff --git a/src/Hooks/useProcessedFood.ts b/src/Hooks/useProcessedFood.ts new file mode 100644 index 0000000..2574983 --- /dev/null +++ b/src/Hooks/useProcessedFood.ts @@ -0,0 +1,48 @@ +import { useMemo } from 'react'; + +interface ProcessedFood { + thumbnail_url: string; + name: string; + total_time_tier: { display_tier: string }; + description: string; + sections?: { + components?: { + ingredient: { name: string }[]; + }[]; + }[]; + instructions: { display_text: string }[]; + // Add more properties if required based on your 'food' object structure +} + +const useProcessedFood = (food: any): ProcessedFood => { + const processedFood = useMemo(() => { + // Perform your processing logic here + const thumbnailUrl = food.thumbnail_url || ''; // Example processing + const name = food.name || ''; + const totalTimeTier = food.total_time_tier || { display_tier: '30 mins' }; + const description = food.description || ''; + const sections = food.sections || []; + const instructions = food.instructions || []; + const urlVideo = food.video_url; + // Map ingredients and instructions to a simpler format + const processedIngredients = sections.flatMap(section => section.components. + filter(component => component.measurements[0].quantity != 0 && component.measurements[0].unit.name !== "") + .map(component => `${component.ingredient.name} (${component.measurements[0].quantity} ${component.measurements[0].unit.name})`) || []); + const processedInstructions = instructions.map(instruction => ({ display_text: instruction.display_text || '' })); + + return { + thumbnailUrl, + name, + totalTimeTier, + description, + ingredients: processedIngredients, + instructions: processedInstructions, + urlVideo, + // Add more processed properties as needed based on your 'food' object structure + }; + }, [food]); + + return processedFood; +}; + +export default useProcessedFood; diff --git a/src/Navigation/Main/index.tsx b/src/Navigation/Main/index.tsx index 54e6158..4df83ba 100644 --- a/src/Navigation/Main/index.tsx +++ b/src/Navigation/Main/index.tsx @@ -8,24 +8,33 @@ import Scanned from "@/Screens/ScannedDetail"; import Welcome from "@/Screens/Welcome"; import Profile from "@/Screens/Profile"; import { VStack } from "native-base"; -import { getListFood } from "@/api"; +import { getFavouriteDishIds, getListFood } from "@/api"; import { useDispatch } from "react-redux"; -import { setListFood } from "@/Store/reducers"; +import { setListFavouriteIds, setListFood, setUserId } from "@/Store/reducers"; import SignIn from "@/Screens/SignIn"; import SignUp from "@/Screens/SignUp"; import EditProfile from "@/Screens/EditProfile"; +import FoodMoreDetails from "@/Screens/FoodMoreDetails"; +import AsyncStorage from "@react-native-async-storage/async-storage"; +import { useAppSelector } from "@/Hooks/redux"; const Stack = createNativeStackNavigator(); export const MainNavigator: React.FC = () => { const dispatch = useDispatch(); - const fetchDishes = async () => { + const userId = useAppSelector(state => state.user.userId); + const fetchInitialData = async () => { + const userId = await AsyncStorage.getItem('userId'); + dispatch(setUserId({ userId })); const listFood: any = await getListFood(); - dispatch(setListFood({ ...listFood })); + const resFavouriteIds = await getFavouriteDishIds(); + dispatch(setListFavouriteIds({ listFavouriteIds: resFavouriteIds.data.ids})); + dispatch(setListFood({ listFood })); }; useEffect(() => { - fetchDishes(); - }, []); + fetchInitialData(); + }, [userId]); + return ( { name={RootScreens.SIGNUP} component={SignUp} /> + ); diff --git a/src/Screens/EditProfile/index.tsx b/src/Screens/EditProfile/index.tsx index 3752db8..6cd27ad 100644 --- a/src/Screens/EditProfile/index.tsx +++ b/src/Screens/EditProfile/index.tsx @@ -3,7 +3,6 @@ import { View, StyleSheet } from 'react-native'; import { StackNavigationProp } from '@react-navigation/stack'; import { RootScreens } from '..'; import BottomBar from '@/Components/BottomBar'; -import Profile from '@/Components/Profile'; import EditProfile from '@/Components/EditProfile'; type HomeScreenProps = { diff --git a/src/Screens/FoodMoreDetails/index.tsx b/src/Screens/FoodMoreDetails/index.tsx new file mode 100644 index 0000000..fae2705 --- /dev/null +++ b/src/Screens/FoodMoreDetails/index.tsx @@ -0,0 +1,31 @@ +import React, { memo } from 'react'; +import { View, StyleSheet } from 'react-native'; +import { StackNavigationProp } from '@react-navigation/stack'; +import BottomBar from '@/Components/BottomBar'; +import FoodMoreDetails from '@/Components/Home/FoodMoreDetails'; +import useProcessedFood from '@/Hooks/useProcessedFood'; + +type FoodMoreDetailsScreenProps = { + navigation: StackNavigationProp; + route: any; +}; + +const FoodMoreDetailsScreen: React.FC = ({ navigation, route }) => { + const processedFood = useProcessedFood(route.params.food); + return ( + + + + + ); +}; + +const styles = StyleSheet.create({ + container: { + flex: 1, + alignItems: 'center', + justifyContent: 'center', + }, +}); + +export default memo(FoodMoreDetailsScreen); diff --git a/src/Screens/Home/index.tsx b/src/Screens/Home/index.tsx index 09d4be5..008b91c 100644 --- a/src/Screens/Home/index.tsx +++ b/src/Screens/Home/index.tsx @@ -33,7 +33,7 @@ const HomeScreen: React.FC = ({ navigation }) => { /> - + ); diff --git a/src/Screens/Scan/index.tsx b/src/Screens/Scan/index.tsx index 8d21b5b..213c0c8 100644 --- a/src/Screens/Scan/index.tsx +++ b/src/Screens/Scan/index.tsx @@ -40,7 +40,6 @@ const ScanScreen: React.FC = ({ navigation }) => { const photo = await cameraRef.takePictureAsync(); setCapturedImage(photo?.uri); navigation.navigate(RootScreens.SCANNEDDETAIL); - console.log(photo?.uri); } catch (error) { console.error('Error taking picture:', error); } diff --git a/src/Screens/index.ts b/src/Screens/index.ts index 3cc0706..af7e75a 100644 --- a/src/Screens/index.ts +++ b/src/Screens/index.ts @@ -6,5 +6,6 @@ export enum RootScreens { SCANNEDDETAIL = "Scanned", SIGNIN = "SignIn", SIGNUP = "SignUp", - EDIT_PROFILE = "EditProfile" + EDIT_PROFILE = "EditProfile", + FOOD_DETAILS = "FoodDetails" } diff --git a/src/Store/index.ts b/src/Store/index.ts index 36fb32a..c832944 100644 --- a/src/Store/index.ts +++ b/src/Store/index.ts @@ -12,12 +12,13 @@ import { PURGE, REGISTER, } from "redux-persist"; -import { homeReducers, themeReducers } from "./reducers"; +import { homeReducer, themeReducers, userReducer } from "./reducers"; const reducers = combineReducers({ api: API.reducer, theme: themeReducers, - home: homeReducers, + home: homeReducer, + user: userReducer, }); const persistConfig = { diff --git a/src/Store/reducers/home.ts b/src/Store/reducers/home.ts index b893657..b6fa9ea 100644 --- a/src/Store/reducers/home.ts +++ b/src/Store/reducers/home.ts @@ -2,14 +2,17 @@ import { createSlice } from "@reduxjs/toolkit"; const slice = createSlice({ name: "home", - initialState: { theme: null, darkMode: null, listFood: null }, + initialState: { theme: null, darkMode: null, listFood: null, listFavouriteIds: null }, reducers: { - setListFood: (state, { payload: listFood }) => { - state.listFood = listFood; - } + setListFood: (state, { payload }) => { + state.listFood = payload.listFood; + }, + setListFavouriteIds: (state, { payload }) => { + state.listFavouriteIds = payload.listFavouriteIds; + }, }, }); -export const { setListFood } = slice.actions; +export const { setListFood, setListFavouriteIds } = slice.actions; -export const homeReducers = slice.reducer; +export const homeReducer = slice.reducer; diff --git a/src/Store/reducers/index.ts b/src/Store/reducers/index.ts index 913fad8..e0b8b5b 100644 --- a/src/Store/reducers/index.ts +++ b/src/Store/reducers/index.ts @@ -1,2 +1,3 @@ export * from "./home"; export * from "./theme"; +export * from "./user"; diff --git a/src/Store/reducers/user.ts b/src/Store/reducers/user.ts new file mode 100644 index 0000000..1b0fe0a --- /dev/null +++ b/src/Store/reducers/user.ts @@ -0,0 +1,15 @@ +import { createSlice } from "@reduxjs/toolkit"; + +const slice = createSlice({ + name: "user", + initialState: { userId: null }, + reducers: { + setUserId: (state, { payload }) => { + state.userId = payload.userId; + } + }, +}); + +export const { setUserId } = slice.actions; + +export const userReducer = slice.reducer; diff --git a/src/Theme/Variables.ts b/src/Theme/Variables.ts index c4ff4e7..d7c34ea 100644 --- a/src/Theme/Variables.ts +++ b/src/Theme/Variables.ts @@ -22,7 +22,8 @@ export enum Colors { TEXT_SECONDARY = "#9FA5C0", FORM = "#F4F5F7", TEXT_DARK = "#000", - TEXT_DESCRIPTION = "#3D3D3D" + TEXT_DESCRIPTION = "#3D3D3D", + GRAY_INDICATOR = "#D0DBEA" } export enum NavigationColors { diff --git a/src/api/index.ts b/src/api/index.ts index a7268e7..5036f4c 100644 --- a/src/api/index.ts +++ b/src/api/index.ts @@ -57,7 +57,6 @@ export const getUserProfile = async () => { export const updateUserProfile = async (payload: any) => { try { - console.log('check payload: ', payload); const res = await axios.patch('user/edit-profile', payload); console.log('check res: ', res); return res.data; @@ -66,3 +65,47 @@ export const updateUserProfile = async (payload: any) => { throw error; } }; + +export const getFavouriteDishIds = async () => { + try { + const res = await axios.get('my-favorite-dish-ids'); + console.log('check res: ', res); + return res.data; + } catch (error) { + console.error('Error getFavouriteDishIds in:', error); + throw error; + } +}; + +export const addFavouriteDishById = async (id: any) => { + try { + const res = await axios.post(`dish/favorite/${id}`); + console.log('check res: ', res); + return res.data; + } catch (error) { + console.error('Error addFavouriteDishById in:', error); + throw error; + } +}; + +export const removeFavouriteDishById = async (id: any) => { + try { + const res = await axios.delete(`dish/favorite/${id}`); + console.log('check res: ', res); + return res.data; + } catch (error) { + console.error('Error removeFavouriteDishById in:', error); + throw error; + } +}; + +export const getDishById = async (id: any) => { + try { + const res = await axios.get(`dish/${id}`); + console.log('check res: ', res); + return res.data; + } catch (error) { + console.error('Error getFavouriteDishIds in:', error); + throw error; + } +};