mirror of
https://github.com/rjNemo/meal_planner
synced 2026-06-12 13:26:45 +00:00
recipe page
This commit is contained in:
parent
9d7db746cd
commit
0f40ad5878
11 changed files with 152 additions and 53 deletions
|
|
@ -76,3 +76,5 @@ Free meal planner for cooks short on ideas! (like me …)
|
||||||
- Search by name: you're looking for a recipe? Ours are easy to make and yummy!
|
- Search by name: you're looking for a recipe? Ours are easy to make and yummy!
|
||||||
|
|
||||||
## TO DO
|
## TO DO
|
||||||
|
|
||||||
|
- put a preloader
|
||||||
|
|
|
||||||
52
src/App.js
52
src/App.js
|
|
@ -4,12 +4,15 @@ import HomePage from "./pages/Home";
|
||||||
import MealPage from "./pages/Meal";
|
import MealPage from "./pages/Meal";
|
||||||
import SearchPage from "./pages/Search";
|
import SearchPage from "./pages/Search";
|
||||||
import CategoryListPage from "./pages/CategoryList";
|
import CategoryListPage from "./pages/CategoryList";
|
||||||
|
import CategoryPage from "./pages/Category";
|
||||||
import NotFound from "./pages/NotFound";
|
import NotFound from "./pages/NotFound";
|
||||||
import Navbar from "./components/Navbar";
|
import Navbar from "./components/Navbar";
|
||||||
|
import SearchBar from "./components/SearchBar";
|
||||||
import Footer from "./components/Footer";
|
import Footer from "./components/Footer";
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
|
|
||||||
const App = () => {
|
const App = () => {
|
||||||
|
// const [isLoading, setIsLoading] = useState(true); For Preloader
|
||||||
const [searchString, setSearchString] = useState("");
|
const [searchString, setSearchString] = useState("");
|
||||||
const [categories, setCategories] = useState({ categories: [] });
|
const [categories, setCategories] = useState({ categories: [] });
|
||||||
// Find a better alternative …
|
// Find a better alternative …
|
||||||
|
|
@ -74,21 +77,28 @@ const App = () => {
|
||||||
};
|
};
|
||||||
const [meal, setMeal] = useState(mealDef);
|
const [meal, setMeal] = useState(mealDef);
|
||||||
|
|
||||||
const createURI = keyword => {
|
const createURI = (keyword, filter) => {
|
||||||
const ROOT = "https://www.themealdb.com/api/json/v1/1/";
|
if (filter === null) {
|
||||||
return `${ROOT}${keyword}.php`;
|
const ROOT = "https://www.themealdb.com/api/json/v1/1/";
|
||||||
|
return `${ROOT}${keyword}.php`;
|
||||||
|
} else {
|
||||||
|
const ROOT = "https://www.themealdb.com/api/json/v1/1/filter.php?c=";
|
||||||
|
return `${ROOT}${keyword}`;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getMeal = () => {
|
const getMeal = () => {
|
||||||
|
// setIsLoading(true);
|
||||||
getFromAPI("random", setMeal);
|
getFromAPI("random", setMeal);
|
||||||
|
// setIsLoading(false);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getCategories = () => {
|
const getCategories = () => {
|
||||||
getFromAPI("categories", setCategories);
|
getFromAPI("categories", setCategories);
|
||||||
};
|
};
|
||||||
|
|
||||||
const getFromAPI = (keyword, set) => {
|
const getFromAPI = (keyword, set, filter = null) => {
|
||||||
const URI = createURI(keyword);
|
const URI = createURI(keyword, filter);
|
||||||
fetch(URI)
|
fetch(URI)
|
||||||
.then(response => response.json())
|
.then(response => response.json())
|
||||||
.then(data => set(data));
|
.then(data => set(data));
|
||||||
|
|
@ -101,12 +111,10 @@ const App = () => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Router>
|
<Router>
|
||||||
<Navbar
|
<Navbar handleClick={getMeal} />
|
||||||
searchString={searchString}
|
<div className="container">
|
||||||
handleChange={handleChange}
|
<SearchBar searchString={searchString} handleChange={handleChange} />
|
||||||
handleClick={getMeal}
|
</div>
|
||||||
getCategories={getCategories}
|
|
||||||
/>
|
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route
|
<Route
|
||||||
exact
|
exact
|
||||||
|
|
@ -116,15 +124,33 @@ const App = () => {
|
||||||
<Route
|
<Route
|
||||||
exact
|
exact
|
||||||
path="/meal"
|
path="/meal"
|
||||||
render={props => <MealPage {...props} meal={meal} />}
|
render={props => (
|
||||||
|
<MealPage
|
||||||
|
{...props}
|
||||||
|
meal={meal}
|
||||||
|
getMeal={getMeal}
|
||||||
|
// isLoading={isLoading}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
exact
|
exact
|
||||||
path="/categories"
|
path="/categories"
|
||||||
render={props => (
|
render={props => (
|
||||||
<CategoryListPage {...props} categories={categories} />
|
<CategoryListPage
|
||||||
|
{...props}
|
||||||
|
categories={categories}
|
||||||
|
getCategories={getCategories}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
<Route path="/categories/:strCategory">
|
||||||
|
<CategoryPage getFromAPI={getFromAPI} setMeal={setMeal} />
|
||||||
|
</Route>
|
||||||
|
|
||||||
|
<Route path="/categories/:strCategory/:strMeal">
|
||||||
|
<MealPage meal={meal} getMeal={getMeal} />
|
||||||
|
</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
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import { Link, useRouteMatch, Switch, Route } from "react-router-dom";
|
import { Link, useRouteMatch } from "react-router-dom";
|
||||||
|
|
||||||
const CategoryEntry = props => {
|
const CategoryEntry = props => {
|
||||||
const {
|
const {
|
||||||
|
|
@ -8,23 +8,17 @@ const CategoryEntry = props => {
|
||||||
strCategoryDescription
|
strCategoryDescription
|
||||||
} = props.category;
|
} = props.category;
|
||||||
|
|
||||||
const { url, path } = useRouteMatch();
|
const { url } = useRouteMatch();
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<Link to={`${url}/${strCategory}`}>
|
<Link to={`${url}/${strCategory}`}>
|
||||||
<li key={props.key}>
|
<li key={props.i}>
|
||||||
<img src={strCategoryThumb} alt={strCategory} />
|
<img src={strCategoryThumb} alt={strCategory} />
|
||||||
<h3>{strCategory}</h3> {strCategoryDescription}
|
<h3>{strCategory}</h3> {strCategoryDescription}
|
||||||
</li>
|
</li>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
// <Switch>
|
|
||||||
// <Route path={`${match.path}/${strCategory}`}>
|
|
||||||
// <h3>Please select a topic.</h3>
|
|
||||||
// </Route>
|
|
||||||
// </Switch>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import React from "react";
|
||||||
const CopyrightText = () => {
|
const CopyrightText = () => {
|
||||||
return (
|
return (
|
||||||
<span>
|
<span>
|
||||||
© 2020 - Meal's Planner - Made with{" "}
|
© 2020 - Chef's - Made with{" "}
|
||||||
<span role="img" aria-label="heart">
|
<span role="img" aria-label="heart">
|
||||||
❤️
|
❤️
|
||||||
</span>
|
</span>
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ const Logo = () => {
|
||||||
return (
|
return (
|
||||||
<Link to="/" className="brand-logo">
|
<Link to="/" className="brand-logo">
|
||||||
<span role="img" aria-label="cookie">
|
<span role="img" aria-label="cookie">
|
||||||
🍪 Chef's Planner
|
👩🍳 Chef's
|
||||||
</span>
|
</span>
|
||||||
</Link>
|
</Link>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import Logo from "./Logo";
|
import Logo from "./Logo";
|
||||||
import SearchBar from "./SearchBar";
|
|
||||||
import RandomButton from "./RandomButton";
|
import RandomButton from "./RandomButton";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
|
|
@ -9,25 +9,15 @@ const Navbar = props => {
|
||||||
<nav>
|
<nav>
|
||||||
<div className="nav-wrapper">
|
<div className="nav-wrapper">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
{/* <div className="col s9"> */}
|
|
||||||
<Logo />
|
<Logo />
|
||||||
{/* </div> */}
|
<ul id="nav-mobile" className="right hide-on-med-and-down">
|
||||||
<ul id="nav-mobile" class="right hide-on-med-and-down">
|
|
||||||
<li>
|
<li>
|
||||||
<Link to="/categories" onClick={props.getCategories}>
|
<Link to="/categories">Categories</Link>
|
||||||
Categories
|
|
||||||
</Link>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<RandomButton handleClick={props.handleClick} />
|
<RandomButton handleClick={props.handleClick} />
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
{/* <div className="col s6">
|
|
||||||
<SearchBar
|
|
||||||
searchString={props.searchString}
|
|
||||||
handleChange={props.handleChange}
|
|
||||||
/>
|
|
||||||
</div> */}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
|
||||||
21
src/components/PreLoader.js
Normal file
21
src/components/PreLoader.js
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
const PreLoader = () => {
|
||||||
|
return (
|
||||||
|
<div className="preloader-wrapper active">
|
||||||
|
<div className="spinner-layer spinner-red-only">
|
||||||
|
<div className="circle-clipper left">
|
||||||
|
<div className="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div className="gap-patch">
|
||||||
|
<div className="circle"></div>
|
||||||
|
</div>
|
||||||
|
<div className="circle-clipper right">
|
||||||
|
<div className="circle"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default PreLoader;
|
||||||
62
src/pages/Category.js
Normal file
62
src/pages/Category.js
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import {
|
||||||
|
useParams,
|
||||||
|
Link,
|
||||||
|
useRouteMatch,
|
||||||
|
Switch,
|
||||||
|
Route
|
||||||
|
} from "react-router-dom";
|
||||||
|
import MealPage from "./Meal";
|
||||||
|
|
||||||
|
const CategoryPage = props => {
|
||||||
|
const [meals, setMeals] = useState({ meals: [] });
|
||||||
|
const { getFromAPI } = props;
|
||||||
|
const { strCategory } = useParams();
|
||||||
|
|
||||||
|
const getMeals = () => {
|
||||||
|
getFromAPI(strCategory, setMeals, 0);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getMeal = () => {
|
||||||
|
// setIsLoading(true);
|
||||||
|
getFromAPI("random", props.setMeal);
|
||||||
|
// setIsLoading(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getMeals();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const { url } = useRouteMatch();
|
||||||
|
// const {
|
||||||
|
// strCategory,
|
||||||
|
// strCategoryThumb,
|
||||||
|
// strCategoryDescription
|
||||||
|
// } = props.category;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="container">
|
||||||
|
<h1>Chef's {strCategory} Recipes</h1>
|
||||||
|
{/* <img src={strCategoryThumb} alt={strCategory} />
|
||||||
|
<p>{strCategoryDescription}</p> */}
|
||||||
|
|
||||||
|
<ul>
|
||||||
|
{meals.meals.map((meal, i) => (
|
||||||
|
<li key={i}>
|
||||||
|
<Link to={`${url}/${meal.strMeal}`}>
|
||||||
|
{/* <Link to="/meal"> */}
|
||||||
|
<img src={meal.strMealThumb} alt={meal.strMeal} />
|
||||||
|
<h3>{meal.strMeal}</h3>
|
||||||
|
</Link>
|
||||||
|
<Switch>
|
||||||
|
<Route path={`${url}/${meal.strMeal}`}>
|
||||||
|
<MealPage meal={meal} getMeal={getMeal} />
|
||||||
|
</Route>
|
||||||
|
</Switch>
|
||||||
|
</li>
|
||||||
|
))}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export default CategoryPage;
|
||||||
|
|
@ -1,20 +1,21 @@
|
||||||
import React from "react";
|
import React, { useEffect } from "react";
|
||||||
import CategoryEntry from "../components/CategoryEntry";
|
import CategoryEntry from "../components/CategoryEntry";
|
||||||
|
|
||||||
const CategoryListPage = props => {
|
const CategoryListPage = props => {
|
||||||
// const { categories } = props;
|
|
||||||
const categories = props.categories.categories;
|
const categories = props.categories.categories;
|
||||||
// if (categories.length > 0) {
|
const { getCategories } = props;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getCategories();
|
||||||
|
}, []);
|
||||||
|
|
||||||
// }
|
|
||||||
// const { strCategory } = categories;
|
|
||||||
return (
|
return (
|
||||||
<div className="section">
|
<div className="section">
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<h1>The Chef's meal categories</h1>
|
<h1>The Chef's Meal Categories</h1>
|
||||||
<ul>
|
<ul>
|
||||||
{categories.map((category, i) => (
|
{categories.map((category, i) => (
|
||||||
<CategoryEntry key={i} category={category} />
|
<CategoryEntry i={i} category={category} />
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -4,14 +4,8 @@ import RandomButton from "../components/RandomButton";
|
||||||
const HomePage = props => {
|
const HomePage = props => {
|
||||||
return (
|
return (
|
||||||
<div className="section background">
|
<div className="section background">
|
||||||
<div
|
<div className="container center-align">
|
||||||
className="container center-align"
|
<h1>The Chef's Meal Suggestions</h1>
|
||||||
// styles={{
|
|
||||||
// backgroundImage: `url(require("../images/parallax1.jpg"))`
|
|
||||||
// }}
|
|
||||||
>
|
|
||||||
{/* <img src={require("../images/parallax1.jpg")} alt="" /> */}
|
|
||||||
<h1>The Chef's meal suggestions</h1>
|
|
||||||
<RandomButton handleClick={props.handleClick} />
|
<RandomButton handleClick={props.handleClick} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,16 @@
|
||||||
import React from "react";
|
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 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;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
getMeal();
|
||||||
|
}, []);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
strMeal,
|
strMeal,
|
||||||
|
|
@ -33,6 +39,9 @@ const MealPage = props => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// const page =
|
||||||
|
|
||||||
|
// return isLoading ? <PreLoader /> : page;
|
||||||
return (
|
return (
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue