diff --git a/LeftOvers/components/ProfileElement.tsx b/LeftOvers/components/ProfileElement.tsx index 2f4f0d9..5c34428 100644 --- a/LeftOvers/components/ProfileElement.tsx +++ b/LeftOvers/components/ProfileElement.tsx @@ -1,4 +1,4 @@ -import React, { useContext, useState } from 'react'; +import React, { useContext } from 'react'; import {StyleSheet,Pressable, Text, View, Image} from 'react-native'; import ColorContext from '../theme/ColorContext'; @@ -6,33 +6,17 @@ type Profile = { name: string avatar: string isActive: string + isWaiting: string disableSelection: boolean + changeStatusWaiting: () => void + separatorDisplay: string } export default function ProfileElement(props : Profile) { const colors = useContext(ColorContext).colors - const [waiting, setWaiting] = useState("none") - const [separator, setSeparator] = useState("none") const changeStatus = () => { - if (props.disableSelection){ - setWaiting("none") - } - else if (waiting == "flex"){ - setWaiting("none") - } - else{ - setWaiting("flex") - } - if (props.disableSelection){ - setSeparator("none") - } - else if (props.isActive == "flex" && waiting == "none"){ - setSeparator("flex") - } - else{ - setSeparator("none") - } + props.changeStatusWaiting() } let imageSource @@ -112,8 +96,8 @@ export default function ProfileElement(props : Profile) { Activated - - + + Waiting... diff --git a/LeftOvers/components/ProfileSelection.tsx b/LeftOvers/components/ProfileSelection.tsx index daf409e..7111c3a 100644 --- a/LeftOvers/components/ProfileSelection.tsx +++ b/LeftOvers/components/ProfileSelection.tsx @@ -6,39 +6,66 @@ import ColorContext from '../theme/ColorContext'; import bracketLeft from '../assets/images/angle_bracket_left.png'; import bracketRight from '../assets/images/angle_bracket_right.png'; +import EventEmitter from "../screens/EventEmitter"; type ProfileSelectionProps = { listProfile: Profile[] disableSelection: boolean + changeStatusWaiting: (number) => void } type Profile = { name: string avatar: string isActive: string + isWaiting: string } export default function ProfileSelection(props: ProfileSelectionProps) { const colors = useContext(ColorContext).colors; - const [cpt, setCpt] = useState(0); + const [separator, setSeparator] = useState("none") + const decreaseCounter = () => { + let index = props.listProfile.length - 1 if (cpt > 0) { setCpt(cpt - 1); + index = cpt - 1 } else { setCpt(props.listProfile.length - 1); } + changeSeparator(index) }; const increaseCounter = () => { + let index = 0 if (cpt < props.listProfile.length - 1) { setCpt(cpt + 1); + index = cpt+1 } else { setCpt(0); } + changeSeparator(index) }; + const changeSeparator = (index) => { + if (props.disableSelection){ + setSeparator("none") + } + else if (props.listProfile[index].isActive == "flex" && props.listProfile[index].isWaiting == "flex"){ + setSeparator("flex") + } + else{ + setSeparator("none") + } + } + + const changeStatus = () => { + props.changeStatusWaiting(cpt) + changeSeparator(cpt) + } + const styles = StyleSheet.create({ background: { width: "92%", @@ -58,7 +85,7 @@ export default function ProfileSelection(props: ProfileSelectionProps) { - + diff --git a/LeftOvers/components/RecipeElement.tsx b/LeftOvers/components/RecipeElement.tsx index 4152ea1..e9aeda4 100644 --- a/LeftOvers/components/RecipeElement.tsx +++ b/LeftOvers/components/RecipeElement.tsx @@ -104,7 +104,7 @@ export default function RecipeElement(props: RecipeElementProps) { Description - + {props.recipe.description} @@ -112,7 +112,5 @@ export default function RecipeElement(props: RecipeElementProps) { {convertToHoursMinutes(props.recipe.time_to_cook)} - ); - - + ); } \ No newline at end of file diff --git a/LeftOvers/screens/CreateProfile.tsx b/LeftOvers/screens/CreateProfile.tsx index 72a37c7..e69a2a2 100644 --- a/LeftOvers/screens/CreateProfile.tsx +++ b/LeftOvers/screens/CreateProfile.tsx @@ -32,9 +32,6 @@ export default function CreateProfile(props) { aspect: [4, 3], quality: 1, }); - - console.log(result); - if (!result.canceled) { setAvatar(result.assets[0].uri); } @@ -42,7 +39,7 @@ export default function CreateProfile(props) { let imageSource - if (props.avatar == ""){ + if (avatar == ""){ imageSource = require("../assets/images/logo.png") } else{ @@ -58,6 +55,7 @@ export default function CreateProfile(props) { diets: selectedDiets, allergies: all, isActive: "flex", + isWaiting: "none", }; // Mettre à jour AsyncStorage avec le nouveau profil diff --git a/LeftOvers/screens/FiltersSelection.tsx b/LeftOvers/screens/FiltersSelection.tsx index bc43c42..9a60d86 100644 --- a/LeftOvers/screens/FiltersSelection.tsx +++ b/LeftOvers/screens/FiltersSelection.tsx @@ -1,4 +1,4 @@ -import React, {useContext} from 'react'; +import React, {useContext, useState, useEffect} from 'react'; import {StyleSheet, View, Text, ScrollView, useWindowDimensions} from 'react-native'; import {LinearGradient} from 'expo-linear-gradient'; import {SafeAreaProvider} from 'react-native-safe-area-context'; @@ -8,22 +8,103 @@ import ListSelect from '../components/ListSelect'; import ListWithoutSelect from '../components/ListWithoutSelect'; import ProfileSelection from '../components/ProfileSelection'; import ColorContext from '../theme/ColorContext'; +import EventEmitter from './EventEmitter'; +import AsyncStorage from '@react-native-async-storage/async-storage'; export default function FiltersSelection(props) { const {colors} = useContext(ColorContext); - const profiles = [ - {name: "Johnny Silverhand", avatar: "plus_small.png", isActive: "flex"}, - {name: "Panam Palmer", avatar: "plus_small.png", isActive: "none"}, - {name: "Goro Takemura", avatar: "plus_small.png", isActive: "none"}, - {name: "David Martinez", avatar: "plus_small.png", isActive: "flex"}, + const profilesHand = [ + {name: "None", avatar: "logo.png", isActive: "none", isWaiting: "none"}, ] + const [profiles, setProfiles] = useState(profilesHand); + + const handleGetProfiles = async () => { + try { + const existingProfiles = await AsyncStorage.getItem('profiles'); + return JSON.parse(existingProfiles) || []; + } catch (error) { + console.log("Error occured during GetProfiles", error); + return []; + } + } + + const fetchProfiles = async () => { + const existingProfiles = await handleGetProfiles(); + setProfiles(existingProfiles); + }; + + const subscription = EventEmitter.addListener('profileAdded', async () => { + fetchProfiles(); + }); + + useEffect(() => { + fetchProfiles(); + }, []); + + const handleSaveSelectedProfiles = async () => { + try { + profiles.forEach((val) => { + if(val.isWaiting == "flex"){ + if(val.isActive == "none"){ + val.isActive = "flex" + } + else{ + val.isActive = "none" + } + } + val.isWaiting = "none" + }) + await AsyncStorage.setItem('profiles', JSON.stringify(profiles)); + EventEmitter.emit('selectedProfilesUpdated'); + fetchProfiles(); + } catch (error) { + console.error('Error occured when updating active profiles:', error); + } + }; + + const subscriptionUpdateSelectedProfiles = EventEmitter.addListener('selectedProfilesUpdated', async () => { + fetchProfiles(); + }); + + const changeStatusWaiting = (cpt) => { + if(profiles[cpt].isWaiting == "none"){ + profiles[cpt].isWaiting = "flex" + } + else{ + profiles[cpt].isWaiting = "none" + } + handleSaveWaiting() + EventEmitter.emit("changeSeparatorStatus") + } + + const handleSaveWaiting = async () => { + try { + await AsyncStorage.setItem('profiles', JSON.stringify(profiles)); + fetchProfiles(); + } catch (error) { + console.error('Error occured when updating waiting profiles:', error); + } + }; + let cptActive = 0 - profiles.forEach(function (value) { + const updateCptActive = () => { + cptActive = 0 + profiles.forEach(function (value) { if(value.isActive=="flex"){ cptActive=cptActive+1 } - }) + })} + let cptWaiting = 0 + const updateCptWaiting = () => { + cptWaiting = 0 + profiles.forEach(function (value) { + if(value.isWaiting=="flex"){ + cptWaiting=cptWaiting+1 + } + })} + updateCptActive() + updateCptWaiting() const die = [{value: "Dairy free"}, {value: "Gluten free"}, {value: "Porkless"}, {value: "Vegan"}, {value: "Vegetarian"}, {value: "Pescatarian"}] @@ -42,6 +123,12 @@ export default function FiltersSelection(props) { const dieAdd = die.filter(isInProfileDiets); const allAdd = [] + const [selectedDiets, setSelectedDiets] = useState([]); + + const handleSelectedDiets = (selectedValues) => { + setSelectedDiets(selectedValues); + }; + const styles = StyleSheet.create({ container: { height: "100%", @@ -112,12 +199,12 @@ export default function FiltersSelection(props) { Profiles - {cptActive} selected, 1 waiting + {cptActive} selected, {cptWaiting} waiting - + - console.log("change selected profile")}> + @@ -134,7 +221,7 @@ export default function FiltersSelection(props) { Additional Filters {dieAdd.length} available - + diff --git a/LeftOvers/screens/HomePage.tsx b/LeftOvers/screens/HomePage.tsx index 697dd82..0dacb69 100644 --- a/LeftOvers/screens/HomePage.tsx +++ b/LeftOvers/screens/HomePage.tsx @@ -18,7 +18,7 @@ export default function HomePage({ navigation, props }) { const colors = useContext(ColorContext).colors const profilesHand = [ - {name: "None", avatar: "logo.png", isActive: "none"} + {name: "None", avatar: "logo.png", isActive: "none", isWaiting: "none"} ] const ingredientListHand = [{name: "None"}] @@ -91,11 +91,15 @@ export default function HomePage({ navigation, props }) { } }); + const subscriptionUpdateSelectedProfile = EventEmitter.addListener('selectedProfilesUpdated', async () => { + fetchProfiles(); + }); + useEffect(() => { //AsyncStorage.clear() fetchProfiles(); if(profiles.length == 0){ - setProfiles([{name: "None", avatar: "plus_small.png", isActive: "none"}]) + setProfiles(profilesHand) } fetchAvailableIngredient(); }, []); @@ -229,7 +233,7 @@ export default function HomePage({ navigation, props }) { {nbActiveProfiles()} selected - + console.log("Je n'affiche RIEN")} separator="none" changeStatusWaiting={() => console.log("Ignorer")}/> navigation.navigate('FiltersSelection')}/> @@ -256,7 +260,7 @@ export default function HomePage({ navigation, props }) { navigation.navigate("IngredientSelection")}/> - navigation.navigate("RecipeSuggestion")}/> + navigation.navigate('RecipeSuggestion', {ingredients: ingredientList})}/> diff --git a/LeftOvers/screens/IngredientSelection.tsx b/LeftOvers/screens/IngredientSelection.tsx index e3ca9b9..658dbcc 100644 --- a/LeftOvers/screens/IngredientSelection.tsx +++ b/LeftOvers/screens/IngredientSelection.tsx @@ -84,7 +84,7 @@ const loadIngredients = async () => { <> RemoveIngredient(value.id)}> - + RemoveIngredient(value.id)}> diff --git a/LeftOvers/screens/RecipeSuggestion.tsx b/LeftOvers/screens/RecipeSuggestion.tsx index 537ec20..a15d712 100644 --- a/LeftOvers/screens/RecipeSuggestion.tsx +++ b/LeftOvers/screens/RecipeSuggestion.tsx @@ -30,7 +30,7 @@ export default function RecipeSuggestion({ route, navigation }) { const [colorFilters, setColorFilters] = useState(colors.cardDetail); const [selectedRecipes, setSelectedRecipes] = useState([]); const recipeService = new RecipesServices(); - const { ingredients } = route.params; + const {ingredients} = route.params; const limitedList = ingredients.slice(minCpt, maxCpt); let selectedIngredients: string[]; @@ -114,7 +114,7 @@ export default function RecipeSuggestion({ route, navigation }) { //padding: "2%", paddingTop: 0, alignItems: "center", - justifyContent: "center" + justifyContent: "center", }, background: { @@ -153,7 +153,7 @@ export default function RecipeSuggestion({ route, navigation }) { height: "10%", width: "100%", flexDirection: 'row', - justifyContent: 'space-between', + justifyContent: 'space-around', alignItems: 'center', }, @@ -163,6 +163,37 @@ export default function RecipeSuggestion({ route, navigation }) { alignItems: "flex-start", justifyContent: "center", }, + + noRecipeView: { + width: "90%", + padding: "5%", + borderRadius: 15, + borderWidth: 1, + borderColor: colors.blocBorder, + backgroundColor: colors.buttonBackground, + alignItems: "center", + justifyContent: "center", + height: "40%", + marginLeft: 12, + }, + textNoRecipe: { + color: colors.cardElementBorder, + fontSize: 20, + textAlign: "center", + }, + smallText: { + color: colors.cardDetail, + fontSize: 15, + alignItems: "center", + justifyContent: "center", + }, + horizontalAlignmentNoRecipe: { + width: "100%", + flexDirection: 'row', + justifyContent: 'space-evenly', + alignItems: 'center', + flex: 0.9, + }, }); @@ -187,7 +218,14 @@ export default function RecipeSuggestion({ route, navigation }) { onEvent={handleChildEvent}/> {Array.isArray(selectedRecipes) && selectedRecipes.length === 0 ? ( - No recipes + + No recipes found with those ingredients: + + {ingredients.length > 0 && ingredients.map((source, index) => ( + - {source.name} - + ))} + + ) : ( selectedRecipes.map((recipe, index) => (