app integraded :)😈
This commit is contained in:
@@ -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>}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -47,6 +47,7 @@ export const InstructionNumber = styled(Text)`
|
||||
`
|
||||
|
||||
export const StyledImage = styled(Image)`
|
||||
margin-top: -110px;
|
||||
height: 200px;
|
||||
width: 100%;
|
||||
`
|
||||
|
||||
Reference in New Issue
Block a user