Routing to individual meal page

This commit is contained in:
Ruidy Nemausat 2020-01-27 10:06:37 +01:00
parent 0f40ad5878
commit a18a03181e
7 changed files with 58 additions and 52 deletions

View file

@ -78,3 +78,4 @@ Free meal planner for cooks short on ideas! (like me …)
## TO DO ## TO DO
- put a preloader - put a preloader
- on mealPage add link to catergory and origin

View file

@ -12,10 +12,11 @@ import Footer from "./components/Footer";
import "./index.css"; import "./index.css";
const App = () => { const App = () => {
// const [isLoading, setIsLoading] = useState(true); For Preloader // State Hooks
const [searchString, setSearchString] = useState(""); const [searchString, setSearchString] = useState("");
const [categories, setCategories] = useState({ categories: [] }); const [categories, setCategories] = useState({ categories: [] });
// Find a better alternative … // const [isLoading, setIsLoading] = useState(true); For Preloader
// Default meal object. TODO: Find a better alternative …
const mealDef = { const mealDef = {
meals: [ meals: [
{ {
@ -77,41 +78,48 @@ const App = () => {
}; };
const [meal, setMeal] = useState(mealDef); const [meal, setMeal] = useState(mealDef);
const createURI = (keyword, filter) => { // Fetch API functions
if (filter === null) { const createURI = (keyword, option) => {
const ROOT = "https://www.themealdb.com/api/json/v1/1/"; const ROOT = "https://www.themealdb.com/api/json/v1/1/";
if (option === null) {
return `${ROOT}${keyword}.php`; return `${ROOT}${keyword}.php`;
} else { } else if (option === "filter") {
const ROOT = "https://www.themealdb.com/api/json/v1/1/filter.php?c="; return `${ROOT}${option}.php?c=${keyword}`;
return `${ROOT}${keyword}`; } else if (option === "lookup") {
return `${ROOT}${option}.php?i=${keyword}`;
} }
}; };
const getFromAPI = (keyword, set, option = null) => {
const URI = createURI(keyword, option);
fetch(URI)
.then(response => response.json())
.then(data => set(data));
};
const getMeal = () => { // Fetch wrappers for each use
const getRandomMeal = () => {
// setIsLoading(true); // setIsLoading(true);
getFromAPI("random", setMeal); getFromAPI("random", setMeal);
// setIsLoading(false); // setIsLoading(false);
}; };
const getMeal = id => {
getFromAPI(id, setMeal, "lookup");
};
const getCategories = () => { const getCategories = () => {
getFromAPI("categories", setCategories); getFromAPI("categories", setCategories);
}; };
const getFromAPI = (keyword, set, filter = null) => {
const URI = createURI(keyword, filter);
fetch(URI)
.then(response => response.json())
.then(data => set(data));
};
const handleChange = ev => { const handleChange = ev => {
const { value } = ev.target; const { value } = ev.target;
setSearchString(value); setSearchString(value);
}; };
const buttonUrl = "/random";
return ( return (
<Router> <Router>
<Navbar handleClick={getMeal} /> <Navbar handleClick={getRandomMeal} buttonUrl={buttonUrl} />
<div className="container"> <div className="container">
<SearchBar searchString={searchString} handleChange={handleChange} /> <SearchBar searchString={searchString} handleChange={handleChange} />
</div> </div>
@ -119,16 +127,22 @@ const App = () => {
<Route <Route
exact exact
path="/" path="/"
render={props => <HomePage {...props} handleClick={getMeal} />} render={props => (
<HomePage
{...props}
handleClick={getRandomMeal}
buttonUrl={buttonUrl}
/>
)}
/> />
<Route <Route
exact exact
path="/meal" path={buttonUrl}
render={props => ( render={props => (
<MealPage <MealPage
{...props} {...props}
meal={meal} meal={meal}
getMeal={getMeal} getMeal={getRandomMeal}
// isLoading={isLoading} // isLoading={isLoading}
/> />
)} )}
@ -144,17 +158,21 @@ const App = () => {
/> />
)} )}
/> />
<Route path="/categories/:strCategory"> <Route path="/categories/:strCategory/">
<CategoryPage getFromAPI={getFromAPI} setMeal={setMeal} /> <CategoryPage
getFromAPI={getFromAPI}
getMeal={getMeal}
setMeal={setMeal}
meal={meal}
/>
</Route> </Route>
<Route path="/:idMeal">
<Route path="/categories/:strCategory/:strMeal">
<MealPage meal={meal} getMeal={getMeal} /> <MealPage meal={meal} getMeal={getMeal} />
</Route> </Route>
<Route exact path="/search" component={SearchPage} /> <Route exact path="/search" component={SearchPage} />
{/* We'll have to input searchResults somewhere */} {/* We'll have to input searchResults somewhere */}
<Route <Route
render={props => <NotFound {...props} handleClick={getMeal} />} render={props => <NotFound {...props} handleClick={getRandomMeal} />}
/> />
</Switch> </Switch>
<Footer /> <Footer />

View file

@ -15,7 +15,10 @@ const Navbar = props => {
<Link to="/categories">Categories</Link> <Link to="/categories">Categories</Link>
</li> </li>
<li> <li>
<RandomButton handleClick={props.handleClick} /> <RandomButton
handleClick={props.handleClick}
url={props.buttonUrl}
/>
</li> </li>
</ul> </ul>
</div> </div>

View file

@ -3,7 +3,7 @@ import { Link } from "react-router-dom";
const RandomButton = props => { const RandomButton = props => {
return ( return (
<Link to="/meal"> <Link to={props.url}>
<button <button
className="waves-effect waves-light btn-small" className="waves-effect waves-light btn-small"
onClick={props.handleClick} onClick={props.handleClick}

View file

@ -1,12 +1,5 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { import { useParams, Link, useRouteMatch } from "react-router-dom";
useParams,
Link,
useRouteMatch,
Switch,
Route
} from "react-router-dom";
import MealPage from "./Meal";
const CategoryPage = props => { const CategoryPage = props => {
const [meals, setMeals] = useState({ meals: [] }); const [meals, setMeals] = useState({ meals: [] });
@ -14,13 +7,7 @@ const CategoryPage = props => {
const { strCategory } = useParams(); const { strCategory } = useParams();
const getMeals = () => { const getMeals = () => {
getFromAPI(strCategory, setMeals, 0); getFromAPI(strCategory, setMeals, "filter");
};
const getMeal = () => {
// setIsLoading(true);
getFromAPI("random", props.setMeal);
// setIsLoading(false);
}; };
useEffect(() => { useEffect(() => {
@ -38,21 +25,16 @@ const CategoryPage = props => {
<div className="container"> <div className="container">
<h1>Chef's {strCategory} Recipes</h1> <h1>Chef's {strCategory} Recipes</h1>
{/* <img src={strCategoryThumb} alt={strCategory} /> {/* <img src={strCategoryThumb} alt={strCategory} />
<p>{strCategoryDescription}</p> */} <p>{strCategoryDescription}</p> */}
<ul> <ul>
{meals.meals.map((meal, i) => ( {meals.meals.map((meal, i) => (
<li key={i}> <li key={i}>
<Link to={`${url}/${meal.strMeal}`}> <Link to={`/${meal.idMeal}`}>
{/* <Link to="/meal"> */} {/* <Link to="/"> */}
<img src={meal.strMealThumb} alt={meal.strMeal} /> <img src={meal.strMealThumb} alt={meal.strMeal} />
<h3>{meal.strMeal}</h3> <h3>{meal.strMeal}</h3>
</Link> </Link>
<Switch>
<Route path={`${url}/${meal.strMeal}`}>
<MealPage meal={meal} getMeal={getMeal} />
</Route>
</Switch>
</li> </li>
))} ))}
</ul> </ul>

View file

@ -6,7 +6,7 @@ const HomePage = props => {
<div className="section background"> <div className="section background">
<div className="container center-align"> <div className="container center-align">
<h1>The Chef's Meal Suggestions</h1> <h1>The Chef's Meal Suggestions</h1>
<RandomButton handleClick={props.handleClick} /> <RandomButton handleClick={props.handleClick} url={props.buttonUrl} />
</div> </div>
</div> </div>
); );

View file

@ -2,14 +2,16 @@ import React, { useEffect } from "react";
import MealPresentation from "../components/MealPresentation"; import MealPresentation from "../components/MealPresentation";
import IngredientList from "../components/IngredientList"; import IngredientList from "../components/IngredientList";
import Recipe from "../components/Recipe"; import Recipe from "../components/Recipe";
import { useParams } from "react-router-dom";
// import PreLoader from "../components/PreLoader"; // import PreLoader from "../components/PreLoader";
const MealPage = props => { const MealPage = props => {
const meal = props.meal.meals[0]; const meal = props.meal.meals[0];
const { getMeal } = props; const { getMeal } = props;
const { idMeal } = useParams();
useEffect(() => { useEffect(() => {
getMeal(); idMeal === null ? getMeal() : getMeal(idMeal);
}, []); }, []);
const { const {