Merge branch 'master' into WORK-RHA2
continuous-integration/drone/push Build is passing Details

pull/24/head
Rayhân HASSOU 1 year ago
commit 14a0587c1b

@ -1,30 +1,41 @@
export default class Profile { export default class Profile {
private _name: string; public name: string;
private _avatar: string; public avatar: string;
private _allergy: string[]; public allergies: string[];
private _diets: string[]; public diets: string[];
public isActive: string;
public isWaiting: string
constructor( name: string, avatar: string, allergy: string[], diets: string[]) { constructor( name: string, avatar: string, allergies: string[], diets: string[], isActive: string, isWaiting: string) {
this._name = name; this.name = name;
this._avatar = avatar; this.avatar = avatar;
this._allergy = allergy; this.diets = diets;
this._diets = diets; this.allergies = allergies;
this.isActive = isActive;
this.isWaiting = isWaiting
} }
get name(): string { // get name(): string {
return this._name; // return this._name;
} // }
// get avatar(): string{
// return this._avatar;
// }
get avatar(): string{ // get allergies(): string[]{
return this._avatar; // return this._allergies;
} // }
get allergy(): string[]{ // get diets(): string[]{
return this._allergy; // return this._diets;
} // }
get diets(): string[]{ // get isActive(): string{
return this._diets; // return this._isActive;
} // }
// get isWaiting(): string{
// return this._isWaiting;
// }
} }

@ -5,4 +5,7 @@ export default interface IIngredientService {
getIngredientById(id: number): Promise<Ingredient | null>; getIngredientById(id: number): Promise<Ingredient | null>;
getIngredientByLetter(id: string): Promise<Ingredient[]>; getIngredientByLetter(id: string): Promise<Ingredient[]>;
getfilteredIngredient(prompt: string): Promise<Ingredient[]>; getfilteredIngredient(prompt: string): Promise<Ingredient[]>;
getAvailableIngredient(): Promise<Ingredient[]>,
addIngredient(newIngredient: Ingredient): Promise<boolean>,
delIngredient(idIngredient: number): Promise<boolean>
} }

@ -1,6 +1,8 @@
import AsyncStorage from "@react-native-async-storage/async-storage";
import Ingredient from "../../Models/Ingredient"; import Ingredient from "../../Models/Ingredient";
import IIngredientService from "./IIngredientService"; import IIngredientService from "./IIngredientService";
import axios from 'axios'; import axios from 'axios';
import eventEmitter from "../../screens/EventEmitter";
export default class IngredientService implements IIngredientService { export default class IngredientService implements IIngredientService {
private readonly API_URL = "http://leftovers.alwaysdata.net/ingredients"; private readonly API_URL = "http://leftovers.alwaysdata.net/ingredients";
@ -41,4 +43,36 @@ export default class IngredientService implements IIngredientService {
throw new Error('Erreur lors de la récupération des ingrédients : ' + error.message); throw new Error('Erreur lors de la récupération des ingrédients : ' + error.message);
} }
} }
async getAvailableIngredient(): Promise<Ingredient[]> {
const results = await AsyncStorage.getItem('ingredient')
const availableIngredient = JSON.parse(results)
if(availableIngredient.length == 0){
availableIngredient.push(new Ingredient(-1, "None"))
}
console.log("AvailableIngredient:", availableIngredient)
return availableIngredient;
}
async addIngredient(newIngredient: Ingredient): Promise<boolean> {
let selectedIngredients = await this.getAvailableIngredient()
const exists = selectedIngredients.find((ingredient) => ingredient.id === newIngredient.id);
if (!exists) {
let existingAvailableIngredient = await AsyncStorage.getItem('ingredient');
existingAvailableIngredient = existingAvailableIngredient ? JSON.parse(existingAvailableIngredient) : [];
const updatedAvailableIngredient = [...existingAvailableIngredient, newIngredient];
await AsyncStorage.setItem('ingredient', JSON.stringify(updatedAvailableIngredient));
eventEmitter.emit('ingredientAdded');
return true
}
return false
}
async delIngredient(idIngredient: number): Promise<boolean> {
let selectedIngredients = await this.getAvailableIngredient()
const updatedIngredients = selectedIngredients.filter((ingredient) => ingredient.id !== idIngredient);
await AsyncStorage.setItem('ingredient', JSON.stringify(updatedIngredients));
eventEmitter.emit('ingredientDeleted');
return true
}
} }

@ -1,7 +1,7 @@
import Profil from "../../Models/Profil"; import Profile from "../../Models/Profile";
export default interface IProfileService { export default interface IProfileService {
getProfiles(): Promise<Profil[]>, getProfiles(): Promise<Profile[]>,
addProfile(new_profile: Profil): Promise<boolean>, addProfile(newProfile: Profile): Promise<boolean>,
delProfile(profile_name_to_del: string): Promise<boolean> delProfile(index: number): Promise<boolean>
} }

@ -1,41 +1,32 @@
import Profil from "../../Models/Profil"; import Profile from "../../Models/Profile";
import IProfileService from "./IProfileService"; import IProfileService from "./IProfileService";
import AsyncStorage from "@react-native-async-storage/async-storage"; import AsyncStorage from "@react-native-async-storage/async-storage";
import eventEmitter from "../../screens/EventEmitter";
export default class ProfileService implements IProfileService { export default class ProfileService implements IProfileService {
async getProfiles(): Promise<Profil[]> { async getProfiles(): Promise<Profile[]> {
const results = await AsyncStorage.getItem('profiles'); const results = await AsyncStorage.getItem('profiles')
const tmp = JSON.parse(results) const existingProfiles = JSON.parse(results)
let existingProfiles: Profil[] = [] if(existingProfiles.length == 0){
for (let item of tmp) { existingProfiles.push(new Profile("None", "logo.png", [], [], "none", "none"))
existingProfiles.push(new Profil(item._name, item._avatar, item._allergy, item._diets))
} }
return existingProfiles; return existingProfiles;
} }
async addProfile(new_profile : Profil): Promise<boolean> { async addProfile(newProfile : Profile): Promise<boolean> {
const existingProfiles = await this.getProfiles() let existingProfiles = await AsyncStorage.getItem('profiles')
for (let current_profile of existingProfiles) { existingProfiles = existingProfiles ? JSON.parse(existingProfiles) : [];
if (current_profile.name == new_profile.name) { const updatedProfiles = [...existingProfiles, newProfile];
console.log("Tried to create a profil already existing !") await AsyncStorage.setItem('profiles', JSON.stringify(updatedProfiles));
return false eventEmitter.emit("profileAdded")
}
}
await AsyncStorage.setItem('profiles', JSON.stringify([...existingProfiles, new_profile]))
return true return true
} }
async delProfile(profile_name_to_del: string): Promise<boolean> { async delProfile(index: number): Promise<boolean> {
const existing_profiles = await this.getProfiles() const existingProfiles = await this.getProfiles()
let key: number = -1 const updatedProfiles = existingProfiles.filter((profile, i) => i !== index);
for (let current_profile of existing_profiles) { await AsyncStorage.setItem('profiles', JSON.stringify(updatedProfiles));
if (current_profile.name == profile_name_to_del) { eventEmitter.emit('profileDeleted');
let updated_profile = existing_profiles.splice(key, 1)
await AsyncStorage.setItem('profiles', JSON.stringify(updated_profile))
return true return true
} }
key ++
}
return false
}
} }

@ -12,6 +12,11 @@ export default function ListWithoutSelect(props: ListProps) {
const [selected, setSelected] = React.useState([]); const [selected, setSelected] = React.useState([]);
const colors = useContext(ColorContext).colors; const colors = useContext(ColorContext).colors;
let listContent = []
props.content.forEach((val) => {
listContent.push({value: val, disabled: true})
})
const styles = StyleSheet.create({ const styles = StyleSheet.create({
titleBar: { titleBar: {
flexDirection: "row", flexDirection: "row",
@ -80,7 +85,7 @@ export default function ListWithoutSelect(props: ListProps) {
return ( return (
<MultipleSelectList <MultipleSelectList
setSelected={(val) => setSelected(val)} setSelected={(val) => setSelected(val)}
data={props.content} data={listContent}
save="value" save="value"
search={false} search={false}
arrowicon={<Image source={require("../assets/images/arrow.png")} style={styles.arrow}></Image>} arrowicon={<Image source={require("../assets/images/arrow.png")} style={styles.arrow}></Image>}
@ -98,4 +103,3 @@ export default function ListWithoutSelect(props: ListProps) {
label={props.title}/> label={props.title}/>
); );
} }

@ -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 {StyleSheet,Pressable, Text, View, Image} from 'react-native';
import ColorContext from '../theme/ColorContext'; import ColorContext from '../theme/ColorContext';
@ -6,35 +6,15 @@ type Profile = {
name: string name: string
avatar: string avatar: string
isActive: string isActive: string
isWaiting: string
disableSelection: boolean disableSelection: boolean
changeStatusWaiting: () => void
separatorDisplay: string
} }
export default function ProfileElement(props : Profile) { export default function ProfileElement(props : Profile) {
const colors = useContext(ColorContext).colors 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")
}
}
let imageSource let imageSource
if(props.avatar == ""){ if(props.avatar == ""){
imageSource=require("../assets/images/logo.png") imageSource=require("../assets/images/logo.png")
@ -102,7 +82,7 @@ export default function ProfileElement(props : Profile) {
}); });
return ( return (
<Pressable onPress={changeStatus} style={styles.button}> <Pressable onPress={props.changeStatusWaiting} style={styles.button}>
<View> <View>
<View style={styles.pseudoBar}> <View style={styles.pseudoBar}>
<Image source={imageSource} style={styles.avatar}></Image> <Image source={imageSource} style={styles.avatar}></Image>
@ -112,8 +92,8 @@ export default function ProfileElement(props : Profile) {
<View style={[styles.active, {display: props.isActive}]}> <View style={[styles.active, {display: props.isActive}]}>
<Text style={styles.textActive}>Activated</Text> <Text style={styles.textActive}>Activated</Text>
</View> </View>
<View style={{flex: 0.3, display: separator}}/> <View style={{flex: 0.3, display: props.separatorDisplay}}/>
<View style={[styles.waiting, {display: waiting}]}> <View style={[styles.waiting, {display: props.isWaiting}]}>
<Text style={styles.textWaiting}>Waiting...</Text> <Text style={styles.textWaiting}>Waiting...</Text>
</View> </View>
</View> </View>

@ -10,35 +10,61 @@ import bracketRight from '../assets/images/angle_bracket_right.png';
type ProfileSelectionProps = { type ProfileSelectionProps = {
listProfile: Profile[] listProfile: Profile[]
disableSelection: boolean disableSelection: boolean
changeStatusWaiting: (number) => void
} }
type Profile = { type Profile = {
name: string name: string
avatar: string avatar: string
isActive: string isActive: string
isWaiting: string
} }
export default function ProfileSelection(props: ProfileSelectionProps) { export default function ProfileSelection(props: ProfileSelectionProps) {
const colors = useContext(ColorContext).colors; const colors = useContext(ColorContext).colors;
const [cpt, setCpt] = useState(0); const [cpt, setCpt] = useState(0);
const [separator, setSeparator] = useState("none")
const decreaseCounter = () => { const decreaseCounter = () => {
let index = props.listProfile.length - 1
if (cpt > 0) { if (cpt > 0) {
setCpt(cpt - 1); setCpt(cpt - 1);
index = cpt - 1
} }
else { else {
setCpt(props.listProfile.length - 1); setCpt(props.listProfile.length - 1);
} }
changeSeparator(index)
}; };
const increaseCounter = () => { const increaseCounter = () => {
let index = 0
if (cpt < props.listProfile.length - 1) { if (cpt < props.listProfile.length - 1) {
setCpt(cpt + 1); setCpt(cpt + 1);
index = cpt+1
} }
else { else {
setCpt(0); 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({ const styles = StyleSheet.create({
background: { background: {
width: "92%", width: "92%",
@ -58,7 +84,7 @@ export default function ProfileSelection(props: ProfileSelectionProps) {
<Pressable onPress={decreaseCounter}> <Pressable onPress={decreaseCounter}>
<Image source={bracketLeft} style={{width: 40, height: 40, resizeMode: "contain"}} tintColor={colors.carrouselText}/> <Image source={bracketLeft} style={{width: 40, height: 40, resizeMode: "contain"}} tintColor={colors.carrouselText}/>
</Pressable> </Pressable>
<ProfileElement name={props.listProfile[cpt].name} avatar={props.listProfile[cpt].avatar} isActive={props.listProfile[cpt].isActive} disableSelection={props.disableSelection}/> <ProfileElement name={props.listProfile[cpt].name} avatar={props.listProfile[cpt].avatar} isActive={props.listProfile[cpt].isActive} isWaiting={props.listProfile[cpt].isWaiting} disableSelection={props.disableSelection} changeStatusWaiting={changeStatus} separatorDisplay={separator}/>
<Pressable onPress={increaseCounter}> <Pressable onPress={increaseCounter}>
<Image source={bracketRight} style={{width: 40, height: 40, resizeMode: "contain"}} tintColor={colors.carrouselText}/> <Image source={bracketRight} style={{width: 40, height: 40, resizeMode: "contain"}} tintColor={colors.carrouselText}/>
</Pressable> </Pressable>

@ -1,5 +1,5 @@
import React, {useContext, useState} from 'react'; import React, {useContext} from 'react';
import {StyleSheet, Pressable, Text, View, Image, ScrollView, ImageSourcePropType} from 'react-native'; import {StyleSheet, Pressable, Text, View, Image, ScrollView} from 'react-native';
import brochette from '../assets/images/brochette.png'; import brochette from '../assets/images/brochette.png';
import Union_left from '../assets/images/Union_left.png'; import Union_left from '../assets/images/Union_left.png';
import Union_right from '../assets/images/Union_right.png'; import Union_right from '../assets/images/Union_right.png';
@ -255,7 +255,7 @@ export default function RecipeElement(props: RecipeElementProps) {
<Text style={styles.text}>Description</Text> <Text style={styles.text}>Description</Text>
<Image source={Union_right} style={{width: "27%", marginLeft: "3%", resizeMode: "contain"}}/> <Image source={Union_right} style={{width: "27%", marginLeft: "3%", resizeMode: "contain"}}/>
</View> </View>
<ScrollView style={{marginTop: "3%", overflow: "hidden"}}> <ScrollView style={{marginTop: "3%", overflow: "hidden", maxHeight: 70}}>
<Text style={styles.smallText}>{props.recipe.description}</Text> <Text style={styles.smallText}>{props.recipe.description}</Text>
</ScrollView> </ScrollView>
</View> </View>
@ -264,6 +264,4 @@ export default function RecipeElement(props: RecipeElementProps) {
</View> </View>
</Pressable> </Pressable>
); );
} }

@ -1,6 +1,5 @@
import React, {useContext} from 'react'; import React, {useContext} from 'react';
import {StyleSheet, Text, View, Image} from 'react-native'; import {StyleSheet, Text, View, Image} from 'react-native';
import brochette from '../assets/images/brochette.png';
import background from '../assets/images/Background.png'; import background from '../assets/images/Background.png';
import ColorContext from '../theme/ColorContext'; import ColorContext from '../theme/ColorContext';

@ -40,7 +40,7 @@ export default function BottomBar({ state, descriptors, navigation }) {
bottom: 0, bottom: 0,
right: 0, right: 0,
left: 0, left: 0,
height: "8%", height: 60,
backgroundColor: theme === 'dark' ? "#3F3C42" : "transparent" backgroundColor: theme === 'dark' ? "#3F3C42" : "transparent"
}, },
BottomBarBlurContainer: { BottomBarBlurContainer: {

@ -37,7 +37,7 @@ export default function ProfilesStackScreen({ navigation }) {
const _handleSearch = () => { const _handleSearch = () => {
console.log('Searching'); console.log('Searching');
} }
const _handleHeaderAdd = () => navigation.navigate('ProfileCreation', { name: String }); const _handleHeaderAdd = () => navigation.navigate('ProfileCreation');
return ( return (
<ProfilesStack.Navigator> <ProfilesStack.Navigator>

@ -6,9 +6,8 @@ import ValidateButton from '../components/ValidateButton';
import ColorContext from '../theme/ColorContext'; import ColorContext from '../theme/ColorContext';
import ListWithoutSelect from '../components/ListWithoutSelect'; import ListWithoutSelect from '../components/ListWithoutSelect';
import ListSelect from '../components/ListSelect'; import ListSelect from '../components/ListSelect';
import EventEmitter from './EventEmitter';
import * as ImagePicker from 'expo-image-picker'; import * as ImagePicker from 'expo-image-picker';
import AsyncStorage from '@react-native-async-storage/async-storage'; import ProfileService from '../Services/Profiles/ProfileService';
export default function CreateProfile(props) { export default function CreateProfile(props) {
@ -19,6 +18,7 @@ export default function CreateProfile(props) {
const [avatar, setAvatar] = useState<string>(''); const [avatar, setAvatar] = useState<string>('');
const [selectedDiets, setSelectedDiets] = useState([]); const [selectedDiets, setSelectedDiets] = useState([]);
const [selectedAllergies] = useState([]) const [selectedAllergies] = useState([])
const profileService = new ProfileService()
const handleSelectedDiets = (selectedValues) => { const handleSelectedDiets = (selectedValues) => {
setSelectedDiets(selectedValues); setSelectedDiets(selectedValues);
@ -32,9 +32,6 @@ export default function CreateProfile(props) {
aspect: [4, 3], aspect: [4, 3],
quality: 1, quality: 1,
}); });
console.log(result);
if (!result.canceled) { if (!result.canceled) {
setAvatar(result.assets[0].uri); setAvatar(result.assets[0].uri);
} }
@ -42,7 +39,7 @@ export default function CreateProfile(props) {
let imageSource let imageSource
if (props.avatar == ""){ if (avatar == ""){
imageSource = require("../assets/images/logo.png") imageSource = require("../assets/images/logo.png")
} }
else{ else{
@ -51,22 +48,15 @@ export default function CreateProfile(props) {
const handleCreateProfile = async () => { const handleCreateProfile = async () => {
try { try {
// Ton code pour récupérer les profils existants et ajouter un nouveau profil
const newProfile = { const newProfile = {
name: name, name: name,
avatar: avatar, avatar: avatar,
diets: selectedDiets, diets: selectedDiets,
allergies: all, allergies: all,
isActive: "flex", isActive: "flex",
isWaiting: "none",
}; };
profileService.addProfile(newProfile)
// Mettre à jour AsyncStorage avec le nouveau profil
let existingProfiles = await AsyncStorage.getItem('profiles');
existingProfiles = existingProfiles ? JSON.parse(existingProfiles) : [];
const updatedProfiles = [...existingProfiles, newProfile];
await AsyncStorage.setItem('profiles', JSON.stringify(updatedProfiles));
EventEmitter.emit('profileAdded');
console.log('Profil créé :', newProfile);
props.navigation.goBack(); props.navigation.goBack();
} catch (error) { } catch (error) {
console.error('Erreur lors de la création du profil :', error); console.error('Erreur lors de la création du profil :', error);

@ -1,46 +1,178 @@
import React, {useContext} from 'react'; import React, {useContext, useState, useEffect} from 'react';
import {StyleSheet, View, Text, ScrollView, useWindowDimensions} from 'react-native'; import {StyleSheet, View, Text, ScrollView, useWindowDimensions} from 'react-native';
import {LinearGradient} from 'expo-linear-gradient'; import {LinearGradient} from 'expo-linear-gradient';
import {SafeAreaProvider} from 'react-native-safe-area-context'; import {SafeAreaProvider} from 'react-native-safe-area-context';
import ValidateButton from '../components/ValidateButton'; import ValidateButton from '../components/ValidateButton';
import ListSelect from '../components/ListSelect'; import ListSelect from '../components/ListSelect';
import ListWithoutSelect from '../components/ListWithoutSelect'; import ListWithoutSelect from '../components/ListWithoutSelect';
import ProfileSelection from '../components/ProfileSelection'; import ProfileSelection from '../components/ProfileSelection';
import ColorContext from '../theme/ColorContext'; import ColorContext from '../theme/ColorContext';
import eventEmitter from './EventEmitter';
import AsyncStorage from '@react-native-async-storage/async-storage';
import ProfileService from '../Services/Profiles/ProfileService';
export default function FiltersSelection(props) { export default function FiltersSelection(props) {
const {colors} = useContext(ColorContext); const {colors} = useContext(ColorContext);
const profiles = [ const profilesHand = [
{name: "Johnny Silverhand", avatar: "plus_small.png", isActive: "flex"}, {name: "None", avatar: "logo.png", diets: [], allergies: [], isActive: "none", isWaiting: "none"},
{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 die = [{value: "Dairy free"}, {value: "Gluten free"}, {value: "Porkless"}, {value: "Vegan"}, {value: "Vegetarian"}, {value: "Pescatarian"}]
const profileService = new ProfileService()
const [profiles, setProfiles] = useState(profilesHand);
const [dieProfiles, setDieProfiles] = useState([])
const [allProfiles, setAllProfiles] = useState([])
const [dieAdd, setDieAdd] = useState([])
const [allAdd, setAllAdd] = useState([])
const [selectedDiets, setSelectedDiets] = useState([])
const fetchProfiles = async () => {
setProfiles(await profileService.getProfiles())
}
const subscriptionAddProfile = eventEmitter.addListener('profileAdded', async () => {
fetchProfiles()
subscriptionAddProfile.remove()
eventEmitter.removeAllListeners('profileAdded')
eventEmitter.removeAllListeners('updateDietsAllergies')
eventEmitter.removeAllListeners('selectedProfilesUpdated')
});
const subscriptionUpdateDietsAllergies = eventEmitter.addListener('updateDietsAllergies', async() => {
setDieAdd(die.filter(isInProfileDiets))
setAllAdd([])
subscriptionUpdateDietsAllergies.remove()
subscriptionUpdateProfiles.remove();
eventEmitter.removeAllListeners('updateDietsAllergies')
})
useEffect(() => {
fetchProfiles()
}, []);
async function handleSaveSelectedProfiles(){
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));
fetchProfiles()
eventEmitter.emit("selectedProfilesUpdated")
} catch (error) {
console.error('Error occured when updating active profiles:', error, selectedDiets);
}
};
const subscriptionUpdateProfiles = eventEmitter.addListener('selectedProfilesUpdated', async () => {
updateDiets()
updateAllergies()
eventEmitter.emit("updateDietsAllergies")
subscriptionUpdateProfiles.remove();
eventEmitter.removeAllListeners('profileAdded')
eventEmitter.removeAllListeners('updateDietsAllergies')
eventEmitter.removeAllListeners('selectedProfilesUpdated')
});
const updateDiets = () => {
let dieTemp = []
let retType = true
profiles.forEach((profile) => {
if(profile.isActive == "flex"){
profile.diets.forEach((diet) => {
retType = true
dieTemp.forEach((val) => {
if(val == diet){
retType = false
}
})
if(retType){
dieTemp.push(diet)
}
})
}
})
setDieProfiles(dieTemp)
}
const updateAllergies = () => {
let allTemp = []
let retType = true
profiles.forEach((profile) => {
if(profile.isActive == "flex"){
profile.allergies.forEach((allergy) => {
retType = true
allTemp.forEach((val) => {
if(val == allergy){
retType = false
}
})
if(retType){
allTemp.push(allergy)
}
})
}
})
setAllProfiles(allTemp)
}
const changeStatusWaiting = (cpt) => {
if(profiles[cpt].isWaiting == "none"){
profiles[cpt].isWaiting = "flex"
}
else{
profiles[cpt].isWaiting = "none"
}
handleSaveWaiting()
}
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 let cptActive = 0
const updateCptActive = () => {
cptActive = 0
profiles.forEach(function (value) { profiles.forEach(function (value) {
if(value.isActive=="flex"){ if(value.isActive=="flex"){
cptActive=cptActive+1 cptActive=cptActive+1
} }
}) })}
let cptWaiting = 0
const die = [{value: "Dairy free"}, {value: "Gluten free"}, {value: "Porkless"}, {value: "Vegan"}, {value: "Vegetarian"}, {value: "Pescatarian"}] const updateCptWaiting = () => {
cptWaiting = 0
const allProfiles = [{value: "Skimmed Milk"}, {value: "Nuts"}] profiles.forEach(function (value) {
const dieProfiles = [{value: "Porkless"}, {value: "Pescatarian"}] if(value.isWaiting=="flex"){
cptWaiting=cptWaiting+1
}
})}
updateCptActive()
updateCptWaiting()
function isInProfileDiets(element, index, array) { function isInProfileDiets(element) {
let retType = true let retType = true
dieProfiles.forEach(function (diets) { dieProfiles.forEach((diet) => {
if(diets.value==element.value){ if(diet==element.value){
retType = false retType = false
} }
}) })
return retType return retType
} }
const dieAdd = die.filter(isInProfileDiets);
const allAdd = [] const handleSelectedDiets = (selectedValues) => {
setSelectedDiets(selectedValues);
};
const styles = StyleSheet.create({ const styles = StyleSheet.create({
container: { container: {
@ -112,12 +244,12 @@ export default function FiltersSelection(props) {
<View style={styles.profilesSelection}> <View style={styles.profilesSelection}>
<View style={styles.filterBar}> <View style={styles.filterBar}>
<Text style={styles.filters}>Profiles</Text> <Text style={styles.filters}>Profiles</Text>
<Text style={styles.nbSelected}>{cptActive} selected, 1 waiting</Text> <Text style={styles.nbSelected}>{cptActive} selected, {cptWaiting} waiting</Text>
</View> </View>
<View style={{marginTop: "3%"}}/> <View style={{marginTop: "3%"}}/>
<ProfileSelection listProfile={profiles} disableSelection={false}/> <ProfileSelection listProfile={profiles} disableSelection={false} changeStatusWaiting={changeStatusWaiting}/>
<View style={{marginTop: "4%"}}/> <View style={{marginTop: "4%"}}/>
<ValidateButton title="Validate Selected Profiles" image="validate.png" colour={colors.buttonDetail} backColour={colors.buttonBackground} todo={ () => console.log("change selected profile")}></ValidateButton> <ValidateButton title="Validate Selected Profiles" image="validate.png" colour={colors.buttonDetail} backColour={colors.buttonBackground} todo={handleSaveSelectedProfiles}></ValidateButton>
</View> </View>
<View style={{marginTop: "6%"}}/> <View style={{marginTop: "6%"}}/>
<View style={styles.background}> <View style={styles.background}>
@ -134,9 +266,9 @@ export default function FiltersSelection(props) {
<Text style={styles.filters}>Additional Filters</Text> <Text style={styles.filters}>Additional Filters</Text>
<Text style={styles.nbSelected}>{dieAdd.length} available</Text> <Text style={styles.nbSelected}>{dieAdd.length} available</Text>
</View> </View>
<ListSelect title="Diets" content={dieAdd}></ListSelect> <ListSelect title="Additional Diets" content={dieAdd} setSelected={handleSelectedDiets}/>
<View style={{marginTop: "3%"}}/> <View style={{marginTop: "3%"}}/>
<ListWithoutSelect title="Allergies" content={allAdd}></ListWithoutSelect> <ListWithoutSelect title="Additional Allergies" content={allAdd}></ListWithoutSelect>
<View style={{marginTop: "3%"}}/> <View style={{marginTop: "3%"}}/>
<ValidateButton title="Add Allergy" image="plus.png" colour={colors.buttonDetail} backColour={colors.buttonBackground} todo={() => props.navigation.navigate("IngredientSelection")}></ValidateButton> <ValidateButton title="Add Allergy" image="plus.png" colour={colors.buttonDetail} backColour={colors.buttonBackground} todo={() => props.navigation.navigate("IngredientSelection")}></ValidateButton>
</View> </View>

@ -2,58 +2,42 @@ import React, { useContext, useState, useEffect } from 'react';
import { StyleSheet, View, Text, Pressable, Image, ScrollView } from 'react-native'; import { StyleSheet, View, Text, Pressable, Image, ScrollView } from 'react-native';
import {LinearGradient} from 'expo-linear-gradient'; import {LinearGradient} from 'expo-linear-gradient';
import {SafeAreaProvider} from 'react-native-safe-area-context'; import {SafeAreaProvider} from 'react-native-safe-area-context';
import ValidateButton from '../components/ValidateButton'; import ValidateButton from '../components/ValidateButton';
import ProfileSelection from '../components/ProfileSelection'; import ProfileSelection from '../components/ProfileSelection';
import FoodElementText from '../components/FoodElementText'; import FoodElementText from '../components/FoodElementText';
import ColorContext from '../theme/ColorContext'; import ColorContext from '../theme/ColorContext';
import bracketLeft from '../assets/images/angle_bracket_left.png'; import bracketLeft from '../assets/images/angle_bracket_left.png';
import bracketRight from '../assets/images/angle_bracket_right.png'; import bracketRight from '../assets/images/angle_bracket_right.png';
import AsyncStorage from '@react-native-async-storage/async-storage'; import AsyncStorage from '@react-native-async-storage/async-storage';
import EventEmitter from './EventEmitter'; import eventEmitter from './EventEmitter';
import ProfileService from '../Services/Profiles/ProfileService';
export default function HomePage({ navigation, props }) { export default function HomePage({ navigation, props }) {
const colors = useContext(ColorContext).colors const colors = useContext(ColorContext).colors
const profilesHand = [ const profilesHand = [
{name: "None", avatar: "logo.png", isActive: "none"} {name: "None", avatar: "logo.png", isActive: "none", isWaiting: "none"}
] ]
const ingredientListHand = [{name: "None"}] const ingredientListHand = [{name: "None"}]
const [profiles, setProfiles] = useState(profilesHand); const [profiles, setProfiles] = useState(profilesHand);
const [ingredientList, setIngredientList] = useState(ingredientListHand) const [ingredientList, setIngredientList] = useState(ingredientListHand)
const handleGetProfiles = async () => { const profileService = new ProfileService()
try {
const existingProfiles = await AsyncStorage.getItem('profiles');
return JSON.parse(existingProfiles) || [];
} catch (error) {
console.log(error);
return [];
}
}
const handleGetAvailableIngredient = async () => { const handleGetAvailableIngredient = async () => {
try { try {
const existingAvailableIngredient = await AsyncStorage.getItem('ingredient'); const existingAvailableIngredient = await AsyncStorage.getItem('ingredient');
return JSON.parse(existingAvailableIngredient) || []; return JSON.parse(existingAvailableIngredient) || [];
} catch (error) { } catch (error) {
console.log(error); console.error(error);
return []; return [];
} }
} }
const fetchProfiles = async () => { const fetchProfiles = async () => {
const existingProfiles = await handleGetProfiles(); setProfiles(await profileService.getProfiles())
if (existingProfiles.length != 0){
setProfiles(existingProfiles);
} }
else{
setProfiles(profilesHand)
}
};
const fetchAvailableIngredient = async () => { const fetchAvailableIngredient = async () => {
const existingAvailableIngredient = await handleGetAvailableIngredient(); const existingAvailableIngredient = await handleGetAvailableIngredient();
@ -65,37 +49,71 @@ export default function HomePage({ navigation, props }) {
} }
}; };
const subscriptionAddProfile = EventEmitter.addListener('profileAdded', async () => { const subscriptionAddProfile = eventEmitter.addListener('profileAdded', async () => {
fetchProfiles(); fetchProfiles();
subscriptionAddProfile.remove();
eventEmitter.removeAllListeners('profileAdded')
eventEmitter.removeAllListeners('profileDeleted')
eventEmitter.removeAllListeners('ingredientAdded')
eventEmitter.removeAllListeners('ingredientDeleted')
eventEmitter.removeAllListeners('selectedProfilesUpdated')
}); });
const subscriptionDeleteProfile = EventEmitter.addListener('profileDeleted', async () => { const subscriptionDeleteProfile = eventEmitter.addListener('profileDeleted', async () => {
if (profiles.length == 1){ if (profiles.length == 1){
setProfiles(profilesHand) setProfiles(profilesHand)
} }
else{ else{
fetchProfiles(); fetchProfiles();
} }
subscriptionDeleteProfile.remove();
eventEmitter.removeAllListeners('profileAdded')
eventEmitter.removeAllListeners('profileDeleted')
eventEmitter.removeAllListeners('ingredientAdded')
eventEmitter.removeAllListeners('ingredientDeleted')
eventEmitter.removeAllListeners('selectedProfilesUpdated')
}); });
const subscriptionAddIngredient = EventEmitter.addListener('ingredientAdded', async () => { const subscriptionAddIngredient = eventEmitter.addListener('ingredientAdded', async () => {
fetchAvailableIngredient(); fetchAvailableIngredient();
subscriptionAddIngredient.remove();
eventEmitter.removeAllListeners('profileAdded')
eventEmitter.removeAllListeners('profileDeleted')
eventEmitter.removeAllListeners('ingredientAdded')
eventEmitter.removeAllListeners('ingredientDeleted')
eventEmitter.removeAllListeners('selectedProfilesUpdated')
}); });
const subscriptionDeleteIngredient = EventEmitter.addListener('ingredientDeleted', async () => { const subscriptionDeleteIngredient = eventEmitter.addListener('ingredientDeleted', async () => {
if (ingredientList.length == 1){ if (ingredientList.length == 1){
setIngredientList(ingredientListHand) setIngredientList(ingredientListHand)
} }
else{ else{
fetchAvailableIngredient(); fetchAvailableIngredient();
} }
subscriptionDeleteIngredient.remove();
eventEmitter.removeAllListeners('profileAdded')
eventEmitter.removeAllListeners('profileDeleted')
eventEmitter.removeAllListeners('ingredientAdded')
eventEmitter.removeAllListeners('ingredientDeleted')
eventEmitter.removeAllListeners('selectedProfilesUpdated')
});
const subscriptionUpdateSelectedProfile = eventEmitter.addListener('selectedProfilesUpdated', async () => {
fetchProfiles();
subscriptionUpdateSelectedProfile.remove();
eventEmitter.removeAllListeners('profileAdded')
eventEmitter.removeAllListeners('profileDeleted')
eventEmitter.removeAllListeners('ingredientAdded')
eventEmitter.removeAllListeners('ingredientDeleted')
eventEmitter.removeAllListeners('selectedProfilesUpdated')
}); });
useEffect(() => { useEffect(() => {
//AsyncStorage.clear() //AsyncStorage.clear()
fetchProfiles(); fetchProfiles();
if(profiles.length == 0){ if(profiles.length == 0){
setProfiles([{name: "None", avatar: "plus_small.png", isActive: "none"}]) setProfiles(profilesHand)
} }
fetchAvailableIngredient(); fetchAvailableIngredient();
}, []); }, []);
@ -229,7 +247,7 @@ export default function HomePage({ navigation, props }) {
<Text style={styles.nbSelected}>{nbActiveProfiles()} selected</Text> <Text style={styles.nbSelected}>{nbActiveProfiles()} selected</Text>
</View> </View>
<View style={{marginTop: "3%"}}/> <View style={{marginTop: "3%"}}/>
<ProfileSelection listProfile={profiles} disableSelection={true}/> <ProfileSelection listProfile={profiles} disableSelection={true} changeStatusWaiting={(val) => val += 1}/>
<View style={{marginTop: "4%"}}/> <View style={{marginTop: "4%"}}/>
<ValidateButton title="Change Active Filters" image="update.png" colour={colors.buttonDetail} backColour={colors.buttonBackground} todo={() => navigation.navigate('FiltersSelection')}/> <ValidateButton title="Change Active Filters" image="update.png" colour={colors.buttonDetail} backColour={colors.buttonBackground} todo={() => navigation.navigate('FiltersSelection')}/>
<View style={{marginTop: "3%"}}/> <View style={{marginTop: "3%"}}/>
@ -256,7 +274,7 @@ export default function HomePage({ navigation, props }) {
<View style={{marginTop: "4%"}}/> <View style={{marginTop: "4%"}}/>
<ValidateButton title="Change Selected Ingredients" image="cook.png" colour={colors.buttonDetail} backColour={colors.buttonBackground} todo={ () => navigation.navigate("IngredientSelection")}/> <ValidateButton title="Change Selected Ingredients" image="cook.png" colour={colors.buttonDetail} backColour={colors.buttonBackground} todo={ () => navigation.navigate("IngredientSelection")}/>
<View style={{marginTop: "3%"}}/> <View style={{marginTop: "3%"}}/>
<ValidateButton title="Search Recipes" image="search.png" colour={colors.buttonDetail} backColour={colors.buttonBackground} todo={ () => navigation.navigate("RecipeSuggestion")}/> <ValidateButton title="Search Recipes" image="search.png" colour={colors.buttonDetail} backColour={colors.buttonBackground} todo={() => navigation.navigate('RecipeSuggestion', {ingredients: ingredientList})}/>
</View> </View>
<View style={{marginBottom: "20%"}}/> <View style={{marginBottom: "20%"}}/>
</LinearGradient> </LinearGradient>

@ -9,7 +9,7 @@ import IngredientService from '../Services/Ingredients/IngredientsServices';
import ColorContext from '../theme/ColorContext'; import ColorContext from '../theme/ColorContext';
import ValidateButton from '../components/ValidateButton'; import ValidateButton from '../components/ValidateButton';
import AsyncStorage from '@react-native-async-storage/async-storage'; import AsyncStorage from '@react-native-async-storage/async-storage';
import EventEmitter from './EventEmitter'; import eventEmitter from './EventEmitter';
import plus from '../assets/images/plus.png'; import plus from '../assets/images/plus.png';
import moins from '../assets/images/minus.png'; import moins from '../assets/images/minus.png';
@ -37,7 +37,7 @@ export default function IngredientSelection(props) {
setResponse(filtered); setResponse(filtered);
} }
} catch (error) { } catch (error) {
console.log(error); console.error(error);
} finally { } finally {
setIsLoading(false); setIsLoading(false);
} }
@ -50,10 +50,9 @@ export default function IngredientSelection(props) {
const loadIngredients = async () => { const loadIngredients = async () => {
try { try {
const ingredients = await ingredientService.getAllIngredient(); setResponse(await ingredientService.getAllIngredient());
setResponse(ingredients);
} catch (error) { } catch (error) {
console.log(error); console.error(error);
} finally { } finally {
setIsLoading(false); setIsLoading(false);
} }
@ -80,7 +79,9 @@ const loadIngredients = async () => {
const ChooseItem = React.memo(({ value }: { value: Ingredient }) => ( const ChooseItem = React.memo(({ value }: { value: Ingredient }) => (
<> <>
<View style={styles.horizontalAlignment}> <View style={styles.horizontalAlignment}>
<FoodElementText title={value.name} /> <Pressable onPress={() => RemoveIngredient(value.id)}>
<FoodElementText title={value.name}/>
</Pressable>
<Pressable onPress={() => RemoveIngredient(value.id)}> <Pressable onPress={() => RemoveIngredient(value.id)}>
<Image source={moins} style={{ width: 20, height: 20, tintColor: colors.cardDetail }} /> <Image source={moins} style={{ width: 20, height: 20, tintColor: colors.cardDetail }} />
</Pressable> </Pressable>
@ -94,7 +95,7 @@ const loadIngredients = async () => {
const existingAvailableIngredient = await AsyncStorage.getItem('ingredient'); const existingAvailableIngredient = await AsyncStorage.getItem('ingredient');
return JSON.parse(existingAvailableIngredient) || []; return JSON.parse(existingAvailableIngredient) || [];
} catch (error) { } catch (error) {
console.log(error); console.error(error);
return []; return [];
} }
} }
@ -105,7 +106,7 @@ const fetchAvailableIngredient = async () => {
setSelectedIngredients(existingAvailableIngredient); setSelectedIngredients(existingAvailableIngredient);
} }
else{ else{
setSelectedIngredients([{value: "None"}]) setSelectedIngredients([new Ingredient(-1, "None")])
} }
}; };
@ -117,13 +118,14 @@ const fetchAvailableIngredient = async () => {
existingAvailableIngredient = existingAvailableIngredient ? JSON.parse(existingAvailableIngredient) : []; existingAvailableIngredient = existingAvailableIngredient ? JSON.parse(existingAvailableIngredient) : [];
const updatedAvailableIngredient = [...existingAvailableIngredient, newIngredient]; const updatedAvailableIngredient = [...existingAvailableIngredient, newIngredient];
await AsyncStorage.setItem('ingredient', JSON.stringify(updatedAvailableIngredient)); await AsyncStorage.setItem('ingredient', JSON.stringify(updatedAvailableIngredient));
EventEmitter.emit('ingredientAdded'); eventEmitter.emit('ingredientAdded');
fetchAvailableIngredient();
console.log('Ingredient Added:', newIngredient); console.log('Ingredient Added:', newIngredient);
ChangeAvailableSize(false) ChangeAvailableSize(false)
} }
} }
catch(error){ catch(error){
console.log("Error occured during the addition of Ingredient:", error) console.error("Error occured during the addition of Ingredient:", error)
} }
}; };
@ -131,28 +133,16 @@ const fetchAvailableIngredient = async () => {
try{ try{
const updatedIngredients = selectedIngredients.filter((ingredient) => ingredient.id !== idIngredient); const updatedIngredients = selectedIngredients.filter((ingredient) => ingredient.id !== idIngredient);
await AsyncStorage.setItem('ingredient', JSON.stringify(updatedIngredients)); await AsyncStorage.setItem('ingredient', JSON.stringify(updatedIngredients));
EventEmitter.emit('ingredientDeleted'); eventEmitter.emit('ingredientDeleted');
fetchAvailableIngredient(); fetchAvailableIngredient();
setSelectedIngredients(updatedIngredients); setSelectedIngredients(updatedIngredients);
ChangeAvailableSize(true) ChangeAvailableSize(true)
} }
catch (error){ catch (error){
console.log("Error occured during the suppression of Ingredient:", error) console.error("Error occured during the suppression of Ingredient:", error)
} }
}; };
const subscriptionAddIngredient = EventEmitter.addListener('ingredientAdded', async () => {
fetchAvailableIngredient();
});
const subscriptionDeleteIngredient = EventEmitter.addListener('ingredientDeleted', async () => {
if (selectedIngredients.length == 1){
setSelectedIngredients([{title: "None"}])
}
else{
fetchAvailableIngredient();
}
});
const ChangeAvailableSize = (remove: boolean) => { const ChangeAvailableSize = (remove: boolean) => {
if(remove){ if(remove){
if (selectedIngredients.length == 1){ if (selectedIngredients.length == 1){
@ -176,7 +166,7 @@ const fetchAvailableIngredient = async () => {
setAvailableSize(90) setAvailableSize(90)
} }
else if (selectedIngredients.length == 1){ else if (selectedIngredients.length == 1){
if(selectedIngredients[0].value == "None"){ if(selectedIngredients[0].name == "None"){
setAvailableSize(90) setAvailableSize(90)
} }
else{ else{
@ -197,7 +187,7 @@ const fetchAvailableIngredient = async () => {
const ingredientsByLetter = await ingredientService.getIngredientByLetter(letter); const ingredientsByLetter = await ingredientService.getIngredientByLetter(letter);
setResponse(ingredientsByLetter); setResponse(ingredientsByLetter);
} catch (error) { } catch (error) {
console.log(error); console.error(error);
} finally { } finally {
setIsLoading(false); setIsLoading(false);
} }

@ -15,19 +15,15 @@ export default function ModifyProfile(props) {
const [profile, setProfile] = useState(null); const [profile, setProfile] = useState(null);
const route = useRoute(); const route = useRoute();
const handleGetProfileByName = async (profileName) => { const handleGetProfileByName = async (profileName) => {
try { try {
const existingProfiles = await AsyncStorage.getItem('profiles'); const existingProfiles = await AsyncStorage.getItem('profiles');
const profiles = JSON.parse(existingProfiles) || []; const profiles = JSON.parse(existingProfiles) || [];
const matchedProfile = profiles.find(profile => profile.name === profileName); const matchedProfile = profiles.find(profile => profile.name === profileName);
console.log("Le profil choisit : " + matchedProfile);
return matchedProfile || null; return matchedProfile || null;
} catch (error) { } catch (error) {
console.log("Erreur lors de la récupération du profil :", error); console.error("Erreur lors de la récupération du profil :", error);
return null; return null;
} }
}; };
@ -35,7 +31,7 @@ export default function ModifyProfile(props) {
const fetchProfiles = async () => { const fetchProfiles = async () => {
const selectedProfil = await handleGetProfileByName(route.params); const selectedProfil = await handleGetProfileByName(route.params);
setProfile(selectedProfil); setProfile(selectedProfil);
}; };
useEffect(() => { useEffect(() => {
fetchProfiles(); fetchProfiles();
@ -48,7 +44,7 @@ useEffect(() => {
<View style={{marginTop: "6%"}}/> <View style={{marginTop: "6%"}}/>
<ProfileModification name={profile.name} avatar={profile.avatar} diets={profile.diets} allergies={profile.allergies}></ProfileModification> <ProfileModification name={profile.name} avatar={profile.avatar} diets={profile.diets} allergies={profile.allergies}></ProfileModification>
<View style={{marginTop: "3%"}}/> <View style={{marginTop: "3%"}}/>
<ValidateButton title="Update Profile" image="update.png" colour={colors.buttonMain} backColour={colors.cardBackground} todo={() => (console.log("Profile Modified"))}></ValidateButton> <ValidateButton title="Update Profile" image="update.png" colour={colors.buttonMain} backColour={colors.cardBackground} todo={() => console.log("")}></ValidateButton>
<View style={{marginTop: "20%"}}/> <View style={{marginTop: "20%"}}/>
</LinearGradient> </LinearGradient>
</ScrollView> </ScrollView>

@ -3,23 +3,21 @@ import { StyleSheet, View, Modal, Pressable, Text, Image, ScrollView, useWindowD
import { LinearGradient } from 'expo-linear-gradient'; import { LinearGradient } from 'expo-linear-gradient';
import { SafeAreaProvider } from 'react-native-safe-area-context'; import { SafeAreaProvider } from 'react-native-safe-area-context';
import ProfileService from '../Services/Profiles/ProfileService';
import ProfileDetails from '../components/ProfileDetails'; import ProfileDetails from '../components/ProfileDetails';
import ColorContext from '../theme/ColorContext'; import ColorContext from '../theme/ColorContext';
import AsyncStorage from '@react-native-async-storage/async-storage'; import eventEmitter from './EventEmitter';
import EventEmitter from './EventEmitter';
import { PaperProvider, Portal } from 'react-native-paper'; import { PaperProvider, Portal } from 'react-native-paper';
export default function Profiles({navigation, props}) { export default function Profiles({navigation, props}) {
const colors = useContext(ColorContext).colors const colors = useContext(ColorContext).colors
const profileService = new ProfileService()
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
const [profiles, setProfiles] = useState([]); const [profiles, setProfiles] = useState([]);
const [selectedProfileIndex, setSelectedProfileIndex] = useState(null); const [selectedProfileIndex, setSelectedProfileIndex] = useState(null);
const goDetails = (name: string) => navigation.navigate('ProfileCreation', name); const goDetails = (name: string) => navigation.navigate('ProfileCreation', name);
const raisePopUp = (index) => { const raisePopUp = (index) => {
setSelectedProfileIndex(index) setSelectedProfileIndex(index)
setVisible(true) setVisible(true)
@ -30,10 +28,7 @@ export default function Profiles({navigation, props}) {
const handleDeleteProfile = async (index) => { const handleDeleteProfile = async (index) => {
try { try {
const updatedProfiles = profiles.filter((profile, i) => i !== index); profileService.delProfile(index)
await AsyncStorage.setItem('profiles', JSON.stringify(updatedProfiles));
EventEmitter.emit('profileDeleted');
fetchProfiles();
setSelectedProfileIndex(index); setSelectedProfileIndex(index);
erasePopUp(); erasePopUp();
} catch (error) { } catch (error) {
@ -41,23 +36,22 @@ export default function Profiles({navigation, props}) {
} }
}; };
const handleGetProfiles = async () => { const fetchProfiles = async () => {
try { setProfiles(await profileService.getProfiles())
const existingProfiles = await AsyncStorage.getItem('profiles');
return JSON.parse(existingProfiles) || [];
} catch (error) {
console.log("Error occured during GetProfiles", error);
return [];
}
} }
const fetchProfiles = async () => { const subscription = eventEmitter.addListener('profileAdded', async () => {
const existingProfiles = await handleGetProfiles(); fetchProfiles();
setProfiles(existingProfiles); subscription.remove();
}; eventEmitter.removeAllListeners('profileAdded')
eventEmitter.removeAllListeners('profileDeleted')
});
const subscription = EventEmitter.addListener('profileAdded', async () => { const subscriptionDeletedProfile = eventEmitter.addListener('profileDeleted', async () => {
fetchProfiles(); fetchProfiles();
subscriptionDeletedProfile.remove();
eventEmitter.removeAllListeners('profileAdded')
eventEmitter.removeAllListeners('profileDeleted')
}); });
useEffect(() => { useEffect(() => {

@ -102,7 +102,6 @@ export default function RecipeDetails({ route }) {
return categories[0]; return categories[0];
} }
console.log("LA LISTE DES CATEGORY : " + categories)
let bestMatch = { category: '', similarity: 0 }; let bestMatch = { category: '', similarity: 0 };
for (const [name, categoriesList] of Object.entries(categoryMappings)) { for (const [name, categoriesList] of Object.entries(categoryMappings)) {
@ -176,7 +175,7 @@ export default function RecipeDetails({ route }) {
const recipe = await recipesService.getRecipeById(recipeId); const recipe = await recipesService.getRecipeById(recipeId);
setResponse(recipe); setResponse(recipe);
} catch (error) { } catch (error) {
console.log(error); console.error(error);
} finally{ } finally{
setIsLoading(false) setIsLoading(false)
} }

@ -30,7 +30,7 @@ export default function RecipeSuggestion({ route, navigation }) {
const [colorFilters, setColorFilters] = useState(colors.cardDetail); const [colorFilters, setColorFilters] = useState(colors.cardDetail);
const [selectedRecipes, setSelectedRecipes] = useState<Recipes[]>([]); const [selectedRecipes, setSelectedRecipes] = useState<Recipes[]>([]);
const recipeService = new RecipesServices(); const recipeService = new RecipesServices();
const { ingredients } = route.params; const {ingredients} = route.params;
const limitedList = ingredients.slice(minCpt, maxCpt); const limitedList = ingredients.slice(minCpt, maxCpt);
let selectedIngredients: string[]; let selectedIngredients: string[];
@ -99,7 +99,7 @@ export default function RecipeSuggestion({ route, navigation }) {
} }
} catch (error) { } catch (error) {
console.log(error) console.error(error)
} }
}; };
@ -114,7 +114,7 @@ export default function RecipeSuggestion({ route, navigation }) {
//padding: "2%", //padding: "2%",
paddingTop: 0, paddingTop: 0,
alignItems: "center", alignItems: "center",
justifyContent: "center" justifyContent: "center",
}, },
background: { background: {
@ -153,7 +153,7 @@ export default function RecipeSuggestion({ route, navigation }) {
height: "10%", height: "10%",
width: "100%", width: "100%",
flexDirection: 'row', flexDirection: 'row',
justifyContent: 'space-between', justifyContent: 'space-around',
alignItems: 'center', alignItems: 'center',
}, },
@ -163,6 +163,37 @@ export default function RecipeSuggestion({ route, navigation }) {
alignItems: "flex-start", alignItems: "flex-start",
justifyContent: "center", 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,
},
}); });
@ -185,11 +216,22 @@ export default function RecipeSuggestion({ route, navigation }) {
<SelectedIngredient <SelectedIngredient
ingredientList={ingredients} ingredientList={ingredients}
onEvent={handleChildEvent}/> onEvent={handleChildEvent}/>
<ScrollView style={{ marginTop: "6%" }} horizontal={true} contentContainerStyle={{ flexDirection: 'row' }}> <View style={{width: "100%", paddingHorizontal: "10%", marginTop: "6%", flexDirection: "row", alignItems: "center"}}>
<Text style={{color: colors.cardDetail, fontSize: 12, flex: 0.63}}>Scroll/Swipe to see more Recipes</Text>
<Image source={require("../assets/images/angle_bracket_right.png")} style={{tintColor: colors.cardDetail, flex: 0.1, resizeMode: "contain", height: 20}}/>
</View>
<ScrollView style={{ marginTop: "1%" }} horizontal={true} contentContainerStyle={{ flexDirection: 'row' }}>
{Array.isArray(selectedRecipes) && selectedRecipes.length === 0 ? ( {Array.isArray(selectedRecipes) && selectedRecipes.length === 0 ? (
<Text>No recipes</Text> <View style={styles.noRecipeView}>
<Text style={styles.textNoRecipe}>No recipes found with those ingredients:</Text>
<ScrollView contentContainerStyle={styles.horizontalAlignmentNoRecipe}>
{ingredients.length > 0 && ingredients.map((source, index) => (
<Text key={index} style={styles.smallText}>- {source.name} -</Text>
))}
</ScrollView>
</View>
) : ( ) : (
selectedRecipes.map((recipe, index) => ( selectedRecipes.map((recipe) => (
<View style={{ marginRight: 10, marginLeft: 20}} key={recipe.id}> <View style={{ marginRight: 10, marginLeft: 20}} key={recipe.id}>
<RecipeElement <RecipeElement
key={recipe.id} key={recipe.id}

Loading…
Cancel
Save