Profile Management (Active Profiles Selection)
continuous-integration/drone/push Build is passing Details

WORK-RRE
Louison PARANT 1 year ago
parent db50b29f46
commit a73d72f1bd

@ -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) {
<View style={[styles.active, {display: props.isActive}]}>
<Text style={styles.textActive}>Activated</Text>
</View>
<View style={{flex: 0.3, display: separator}}/>
<View style={[styles.waiting, {display: waiting}]}>
<View style={{flex: 0.3, display: props.separatorDisplay}}/>
<View style={[styles.waiting, {display: props.isWaiting}]}>
<Text style={styles.textWaiting}>Waiting...</Text>
</View>
</View>

@ -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) {
<Pressable onPress={decreaseCounter}>
<Image source={bracketLeft} style={{width: 40, height: 40, resizeMode: "contain"}} tintColor={colors.carrouselText}/>
</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}>
<Image source={bracketRight} style={{width: 40, height: 40, resizeMode: "contain"}} tintColor={colors.carrouselText}/>
</Pressable>

@ -104,7 +104,7 @@ export default function RecipeElement(props: RecipeElementProps) {
<Text style={styles.text}>Description</Text>
<Image source={Union_right} style={{width: "27%", marginLeft: "3%", resizeMode: "contain"}}/>
</View>
<ScrollView style={{marginTop: "3%", overflow: "hidden"}}>
<ScrollView style={{marginTop: "3%", overflow: "hidden", maxHeight: 70}}>
<Text style={styles.smallText}>{props.recipe.description}</Text>
</ScrollView>
</View>
@ -113,6 +113,4 @@ export default function RecipeElement(props: RecipeElementProps) {
</View>
</Pressable>
);
}

@ -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

@ -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
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) {
<View style={styles.profilesSelection}>
<View style={styles.filterBar}>
<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 style={{marginTop: "3%"}}/>
<ProfileSelection listProfile={profiles} disableSelection={false}/>
<ProfileSelection listProfile={profiles} disableSelection={false} changeStatusWaiting={changeStatusWaiting}/>
<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 style={{marginTop: "6%"}}/>
<View style={styles.background}>
@ -134,7 +221,7 @@ export default function FiltersSelection(props) {
<Text style={styles.filters}>Additional Filters</Text>
<Text style={styles.nbSelected}>{dieAdd.length} available</Text>
</View>
<ListSelect title="Diets" content={dieAdd}></ListSelect>
<ListSelect title="Diets" content={dieAdd} setSelected={handleSelectedDiets}/>
<View style={{marginTop: "3%"}}/>
<ListWithoutSelect title="Allergies" content={allAdd}></ListWithoutSelect>
<View style={{marginTop: "3%"}}/>

@ -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 }) {
<Text style={styles.nbSelected}>{nbActiveProfiles()} selected</Text>
</View>
<View style={{marginTop: "3%"}}/>
<ProfileSelection listProfile={profiles} disableSelection={true}/>
<ProfileSelection listProfile={profiles} disableSelection={true} changeStatusWaiting={() => console.log("Je n'affiche RIEN")} separator="none" changeStatusWaiting={() => console.log("Ignorer")}/>
<View style={{marginTop: "4%"}}/>
<ValidateButton title="Change Active Filters" image="update.png" colour={colors.buttonDetail} backColour={colors.buttonBackground} todo={() => navigation.navigate('FiltersSelection')}/>
<View style={{marginTop: "3%"}}/>
@ -256,7 +260,7 @@ export default function HomePage({ navigation, props }) {
<View style={{marginTop: "4%"}}/>
<ValidateButton title="Change Selected Ingredients" image="cook.png" colour={colors.buttonDetail} backColour={colors.buttonBackground} todo={ () => navigation.navigate("IngredientSelection")}/>
<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 style={{marginBottom: "20%"}}/>
</LinearGradient>

@ -84,7 +84,7 @@ const loadIngredients = async () => {
<>
<View style={styles.horizontalAlignment}>
<Pressable onPress={() => RemoveIngredient(value.id)}>
<FoodElementText title={value.name} />
<FoodElementText title={value.name}/>
</Pressable>
<Pressable onPress={() => RemoveIngredient(value.id)}>
<Image source={moins} style={{ width: 20, height: 20, tintColor: colors.cardDetail }} />

@ -30,7 +30,7 @@ export default function RecipeSuggestion({ route, navigation }) {
const [colorFilters, setColorFilters] = useState(colors.cardDetail);
const [selectedRecipes, setSelectedRecipes] = useState<Recipes[]>([]);
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}/>
<ScrollView style={{ marginTop: "6%" }} horizontal={true} contentContainerStyle={{ flexDirection: 'row' }}>
{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) => (
<View style={{ marginRight: 10, marginLeft: 20}} key={recipe.id}>

Loading…
Cancel
Save