mirror of
https://github.com/rjNemo/meal_planner
synced 2026-06-12 13:26:45 +00:00
Routing to individual meal page
This commit is contained in:
parent
0f40ad5878
commit
a18a03181e
7 changed files with 58 additions and 52 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
68
src/App.js
68
src/App.js
|
|
@ -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 />
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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}
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
|
|
|
||||||
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -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 {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue