app integraded :)😈

This commit is contained in:
2021-11-02 21:38:46 +01:00
parent ad391b69f6
commit e202b7a160
29 changed files with 307 additions and 228 deletions

View File

@@ -1,57 +1,66 @@
import React from 'react';
import { Text, View } from 'react-native'
import { Button, ScrollView, Text, View } from 'react-native'
import * as ImagePicker from 'expo-image-picker';
//components
import Header from "../../components/Header"
import { ArrowBack } from "../styles/page";
import { Ingredients } from "../../components/recipes/addRecipe/Inputs";
//styling
import { Wrapper, WrapperRecipe, Input, InputInstructions, IconRecipe, IconPot, IconMeal, IconImage, IconCheck } from "./styles/addRecipe"
import { Wrapper, WrapperRecipe, Input, InputInstructions, IconRecipe, IconPot, IconMeal, IconImage, IconCheck, AddImageButton, ButtonText, SubmitButton } from "./styles/addRecipe"
import { useState } from "react";
import { addRecipe, findRecipeById, updateRecipe } from "../../redux/slices/recipesSlice";
import { useDispatch, useSelector } from "react-redux";
import { StyledImage } from "./styles/recipe";
import HeaderPadding from '../../components/Header';
import { Row } from '../../components/recipes/addRecipe/styles/inputs';
import { useNavigation } from '@react-navigation/core';
const AddRecipe = (props) => {
const id = props.route.params.id
const navigation = useNavigation()
const AddRecipe = () => {
let { id } = useParams()
const foundRecipe = useSelector(state => findRecipeById(state, id))
let recipe = foundRecipe ? foundRecipe : { name: '', prepTime: '', servings: '', image: '', ingredients: [], instructions: '' }
const dispatch = useDispatch()
const [name, setName] = useState(recipe.name)
const [prepTime, setPrepTime] = useState(recipe.prepTime)
const [servings, setServings] = useState(recipe.servings)
const [prepTime, setPrepTime] = useState(recipe.prepTime && recipe.prepTime.toString())
const [servings, setServings] = useState(recipe.servings && recipe.servings.toString())
const [image, setImage] = useState(recipe.image)
const [ingredients, setIngredients] = useState(recipe.ingredients)
const [instructions, setInstructions] = useState(recipe.instructions)
const handleImageInput = (input) => {
if (input.target.files && input.target.files[0] && input.target.files[0].size < 1000000) {
let reader = new FileReader()
reader.onload = function (e) {
setImage(e.target.result)
};
reader.readAsDataURL(input.target.files[0])
const pickImage = async () => {
let result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.All,
allowsEditing: true,
aspect: [4, 3],
quality: 1,
});
console.log(result);
if (!result.cancelled) {
setImage(result.uri);
}
else {
alert("That file is too big! Choose an image with a size lower than 1MB")
}
}
};
const submitRecipe = () => {
if (name && ingredients && instructions) {
foundRecipe ? dispatch(updateRecipe({ _id: foundRecipe._id, name, prepTime: Number(prepTime), servings: Number(servings), image, ingredients, instructions }))
: dispatch(addRecipe({ name, prepTime: Number(prepTime), servings: Number(servings), image, ingredients, instructions }))
console.log(typeof (image))
navigation.goBack()
}
else {
alert("You should add a name, at least one ingredient and the instructions")
}
}
const handleInput = (event) => {
let lastChar = event.target.value.substr(-1).charCodeAt(0);
let penultimateChar = event.target.value.substr(-2).charCodeAt(0);
const handleInput = (text) => {
let lastChar = text.substr(-1).charCodeAt(0);
let penultimateChar = text.substr(-2).charCodeAt(0);
if (instructions === '') {
setInstructions("- " + event.target.value)
setInstructions("- " + text)
return
}
else if (penultimateChar === 10 && lastChar === 45) {
@@ -59,55 +68,56 @@ const AddRecipe = () => {
return
}
else if (lastChar === 10) {
setInstructions(event.target.value + "- ")
setInstructions(text + "- ")
return
}
setInstructions(event.target.value)
setInstructions(text)
}
return (
<>
<HeaderPadding/>
return (<>
<ScrollView nestedScrollEnabled={true} keyboardShouldPersistTaps={'always'}>
<HeaderPadding />
{image != "" && <StyledImage source={{ uri: image }} alt="Recipe" />}
<Wrapper >
{image && <StyledImage source={image} alt="Recipe" />}
<WrapperRecipe>
<View id="row">
<Row>
<IconRecipe />
<Input
type="text"
value={name}
onChange={(text) => setName(text.target.value)}
onChangeText={(text) => setName(text)}
placeholder="Recipe name" />
</View>
<View id="row">
</Row>
<Row>
<IconPot />
<Input
type="number"
keyboardType={"number-pad"}
value={prepTime}
onChange={(text) => setPrepTime(text.target.value)}
onChangeText={(text) => setPrepTime(text)}
placeholder="Prep time (min)" />
<IconMeal />
<Input
type="number"
keyboardType={"number-pad"}
value={servings}
onChange={(text) => setServings(text.target.value)}
onChangeText={(text) => setServings(text)}
placeholder="Servings" />
</View>
<View id="row">
<IconImage />
<Input
style={{ borderBottom: 'none' }}
type="file" accept="image/*"
onChange={input => handleImageInput(input)} />
</View>
</Row>
<AddImageButton onPress={pickImage}
style={{ borderBottom: 'none' }} >
<ButtonText>Add Image</ButtonText>
</AddImageButton>
<Ingredients ingredients={ingredients} setIngredients={setIngredients} />
<InputInstructions
type="text"
minHeight={40}
multiline={true}
value={instructions}
onChange={(text) => handleInput(text)}
onChangeText={(text) => handleInput(text)}
placeholder='Instructions' />
</WrapperRecipe>
</Wrapper>
</>
</ScrollView>
{name != "" && ingredients != "" && instructions != "" && <SubmitButton onPress={submitRecipe} >
<IconCheck />
</SubmitButton>}
</>
)
}

View File

@@ -10,8 +10,8 @@ import { OptionsButtonRecipe, AddIngredientsButton } from "../../components/reci
import { ScrollView, Text, View } from "react-native"
import HeaderPadding from "../../components/Header"
const Recipe = (props) => {
const id = props.route.params.id
const Recipe = ({route, navigation}) => {
const id = route.params.id
const recipe = useSelector(state => findRecipeById(state, id))
const IngredientList = recipe.ingredients.map((ingredient, index) => {
return (<Ingredient ingredient={ingredient} index={index} key={index} />)
@@ -25,12 +25,21 @@ const Recipe = (props) => {
<InstructionText>{instruction}</InstructionText>
</InstructionWrapper>)
})
React.useLayoutEffect(() => {
navigation.setOptions({
headerRight: () => (
<OptionsButtonRecipe id={id} />
),
});
}, [navigation]);
return (
<>
<HeaderPadding/>
{recipe.image != "" && <StyledImage source={{ uri: recipe.image }} />}
<ScrollView>
<Wrapper >
{recipe.image != "" && <StyledImage source={{ uri: recipe.image }} />}
<WrapperRecipe>
<Title>{recipe.name}</Title>
<Hr />

View File

@@ -1,8 +1,9 @@
import React from 'react';
import { Image, Text, TextInput, View } from "react-native"
import { Image, Text, TextInput, TouchableOpacity, View } from "react-native"
import styled from 'styled-components'
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
import theme from "../../../styles/theme";
import { Button } from '../../../styles/componentBlueprints';
export const Wrapper = styled(View)`
display: flex;
@@ -38,35 +39,49 @@ export const Input = styled(TextInput)`
color: ${props => props.theme.colors.textW1};
border-bottom-color: ${props => props.theme.colors.primary + 'aa'};
border-bottom-width: 1px;
font-size: ${({theme}) => theme.fontSizes.fontS}px;
font-size: ${({theme}) => theme.fontSizes.fontM}px;
width: 100%;
`
export const InputInstructions = styled(Text)`
export const InputInstructions = styled(TextInput)`
margin-top: 30px;
padding: 5px;
color: ${props => props.theme.colors.textW1};
border-bottom-color: ${props => props.theme.colors.primary + 'aa'};
border-bottom-width: 1px;
font-size: ${({theme}) => theme.fontSizes.fontS}px;
min-height: 600px;
font-size: ${({theme}) => theme.fontSizes.fontM}px;
width: 100%;
`
export const StyledImage = styled(Image)`
width: 100px;
height: 100px;
export const AddImageButton = styled(TouchableOpacity)`
justify-content: center;
align-items: center;
align-self: center;
margin: 10px;
width: 140px;
height: 40px;
background-color:${props => props.theme.colors.primary};
border-radius: 15px;
`
export const IconRecipe = () => <MaterialCommunityIcons name="pasta" color={theme.colors.primaryVar} size={theme.fontSizes.fontM} />
export const ButtonText = styled(Text)`
color: ${props => props.theme.colors.textB1};
font-weight: bold;
font-size: 20px;
`
export const SubmitButton = styled(Button)`
position: absolute;
right: 10px;
bottom: 10px;
background-color: ${({theme}) => theme.colors.primary};
`
export const IconRecipe = () => <MaterialCommunityIcons name="pasta" color={theme.colors.primaryVar} size={theme.fontSizes.fontL} />
export const IconPot = () => <MaterialCommunityIcons name="pot-steam" color={theme.colors.primaryVar} size={theme.fontSizes.fontM} />
export const IconPot = () => <MaterialCommunityIcons name="pot-steam" color={theme.colors.primaryVar} size={theme.fontSizes.fontL} />
export const IconMeal = () => <MaterialCommunityIcons name="pot-steam" color={theme.colors.primaryVar} size={theme.fontSizes.fontM} />
export const IconMeal = () => <MaterialCommunityIcons name="pot-steam" color={theme.colors.primaryVar} size={theme.fontSizes.fontL} />
export const IconImage = () => <MaterialCommunityIcons name="food" color={theme.colors.primaryVar} size={theme.fontSizes.fontM} />
const Check = () => <MaterialCommunityIcons name="check" color={theme.colors.textB3} size={theme.fontSizes.fontL} />
const Check = () => <MaterialCommunityIcons name="check" color={theme.colors.textB3} size={50} />
export const IconCheck = styled(Check)`
margin-right: 10px;

View File

@@ -47,6 +47,7 @@ export const InstructionNumber = styled(Text)`
`
export const StyledImage = styled(Image)`
margin-top: -110px;
height: 200px;
width: 100%;
`