diff --git a/.gitignore b/.gitignore index d8e35bc..0ad5f05 100644 --- a/.gitignore +++ b/.gitignore @@ -11,6 +11,7 @@ # misc .idea +.env .DS_Store .env.local .env.development.local diff --git a/src/App.js b/src/App.js index 203067e..7eddf11 100644 --- a/src/App.js +++ b/src/App.js @@ -1,18 +1,73 @@ import React, { Component } from 'react'; -import logo from './logo.svg'; -import './App.css'; +import './styles/App.css'; +import { RecipeList } from './RecipeList.js'; +import SearchBar from './SearchBar.js'; +import { Error } from './Error.js'; + +const app_id = process.env.REACT_APP_APP_ID; +const app_key = process.env.REACT_APP_APP_KEY; class App extends Component { + constructor(props) { + super(props); + this.state = { + error: null, + isLoading: false, + recipes: [] + }; + } + + fetchRecipes = (foodItem = 'cake') => { + let recipeUrl = `https://api.edamam.com/search?&app_id=${app_id}&app_key=${app_key}&q=${foodItem}`; + return new Promise((res, rej) => { + return fetch(recipeUrl) + .then(res => res.json()) + .then( + value => { + if (value.hits.length === 0) { + rej('No recipe found!'); + } else { + const recipes = value.hits.map(foodItem => ({ + name: foodItem.recipe.label, + calories: Math.round(foodItem.recipe.calories) + })); + res(recipes); + } + }, + error => { + rej('Oops, something went wrong!'); + throw error; + } + ); + }); + }; + + componentDidMount() { + this.fetchRecipes() + .then(recipes => { + this.setState({ recipes }); + }) + .catch(e => this.setState({ error: e })); + } + + updateError = error => { + this.setState({ error }); + }; + + updateRecipes = recipes => { + this.setState({ recipes }); + }; + render() { return (
-
- logo -

Welcome to React

-
-

- To get started, edit src/App.js and save to reload. -

+ {this.state.error && } + +
); } diff --git a/src/EachRecipe.js b/src/EachRecipe.js new file mode 100644 index 0000000..2968e3e --- /dev/null +++ b/src/EachRecipe.js @@ -0,0 +1,9 @@ +import React from 'react'; + +export const EachRecipe = ({ recipe }) => { + return ( +
  • + {recipe.name} {recipe.calories} +
  • + ); +}; diff --git a/src/Error.js b/src/Error.js new file mode 100644 index 0000000..fb9d7d2 --- /dev/null +++ b/src/Error.js @@ -0,0 +1,5 @@ +import React from 'react'; + +export const Error = ({ error }) => { + return

    {error}

    ; +}; diff --git a/src/RecipeList.js b/src/RecipeList.js new file mode 100644 index 0000000..d0d6411 --- /dev/null +++ b/src/RecipeList.js @@ -0,0 +1,12 @@ +import React from 'react'; +import { EachRecipe } from './EachRecipe.js'; + +export const RecipeList = ({ recipes }) => { + return ( + + ); +}; diff --git a/src/SearchBar.js b/src/SearchBar.js new file mode 100644 index 0000000..2ec3606 --- /dev/null +++ b/src/SearchBar.js @@ -0,0 +1,32 @@ +import React, { Component } from 'react'; + +class SearchBar extends Component { + handleKeyPress = event => { + let value = this.textInput.value; + if (event.key === 'Enter' && value) { + this.props + .fetchRecipes(value) + .then(recipes => this.props.updateRecipes(recipes)) + .catch(e => this.props.updateError(e)); + this.textInput.value = ''; + } + }; + + render() { + return ( + { + this.textInput = input; + }} + type="text" + placeholder="Type to search for recipe" + required + /> + ); + } +} + +export default SearchBar; diff --git a/src/index.js b/src/index.js index fae3e35..f2402cd 100644 --- a/src/index.js +++ b/src/index.js @@ -1,6 +1,6 @@ import React from 'react'; import ReactDOM from 'react-dom'; -import './index.css'; +import './styles/index.css'; import App from './App'; import registerServiceWorker from './registerServiceWorker'; diff --git a/src/logo.svg b/src/logo.svg deleted file mode 100644 index 6b60c10..0000000 --- a/src/logo.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/App.css b/src/styles/App.css similarity index 100% rename from src/App.css rename to src/styles/App.css diff --git a/src/index.css b/src/styles/index.css similarity index 100% rename from src/index.css rename to src/styles/index.css