mirror of
https://github.com/rjNemo/meal_planner
synced 2026-06-06 02:26:49 +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!
|
||||
|
||||
## 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 SearchPage from "./pages/Search";
|
||||
import CategoryListPage from "./pages/CategoryList";
|
||||
import CategoryPage from "./pages/Category";
|
||||
import NotFound from "./pages/NotFound";
|
||||
import Navbar from "./components/Navbar";
|
||||
import SearchBar from "./components/SearchBar";
|
||||
import Footer from "./components/Footer";
|
||||
import "./index.css";
|
||||
|
||||
const App = () => {
|
||||
// const [isLoading, setIsLoading] = useState(true); For Preloader
|
||||
const [searchString, setSearchString] = useState("");
|
||||
const [categories, setCategories] = useState({ categories: [] });
|
||||
// Find a better alternative …
|
||||
|
|
@ -74,21 +77,28 @@ const App = () => {
|
|||
};
|
||||
const [meal, setMeal] = useState(mealDef);
|
||||
|
||||
const createURI = keyword => {
|
||||
const ROOT = "https://www.themealdb.com/api/json/v1/1/";
|
||||
return `${ROOT}${keyword}.php`;
|
||||
const createURI = (keyword, filter) => {
|
||||
if (filter === null) {
|
||||
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 = () => {
|
||||
// setIsLoading(true);
|
||||
getFromAPI("random", setMeal);
|
||||
// setIsLoading(false);
|
||||
};
|
||||
|
||||
const getCategories = () => {
|
||||
getFromAPI("categories", setCategories);
|
||||
};
|
||||
|
||||
const getFromAPI = (keyword, set) => {
|
||||
const URI = createURI(keyword);
|
||||
const getFromAPI = (keyword, set, filter = null) => {
|
||||
const URI = createURI(keyword, filter);
|
||||
fetch(URI)
|
||||
.then(response => response.json())
|
||||
.then(data => set(data));
|
||||
|
|
@ -101,12 +111,10 @@ const App = () => {
|
|||
|
||||
return (
|
||||
<Router>
|
||||
<Navbar
|
||||
searchString={searchString}
|
||||
handleChange={handleChange}
|
||||
handleClick={getMeal}
|
||||
getCategories={getCategories}
|
||||
/>
|
||||
<Navbar handleClick={getMeal} />
|
||||
<div className="container">
|
||||
<SearchBar searchString={searchString} handleChange={handleChange} />
|
||||
</div>
|
||||
<Switch>
|
||||
<Route
|
||||
exact
|
||||
|
|
@ -116,15 +124,33 @@ const App = () => {
|
|||
<Route
|
||||
exact
|
||||
path="/meal"
|
||||
render={props => <MealPage {...props} meal={meal} />}
|
||||
render={props => (
|
||||
<MealPage
|
||||
{...props}
|
||||
meal={meal}
|
||||
getMeal={getMeal}
|
||||
// isLoading={isLoading}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
<Route
|
||||
exact
|
||||
path="/categories"
|
||||
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} />
|
||||
{/* We'll have to input searchResults somewhere */}
|
||||
<Route
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import React from "react";
|
||||
import { Link, useRouteMatch, Switch, Route } from "react-router-dom";
|
||||
import { Link, useRouteMatch } from "react-router-dom";
|
||||
|
||||
const CategoryEntry = props => {
|
||||
const {
|
||||
|
|
@ -8,23 +8,17 @@ const CategoryEntry = props => {
|
|||
strCategoryDescription
|
||||
} = props.category;
|
||||
|
||||
const { url, path } = useRouteMatch();
|
||||
const { url } = useRouteMatch();
|
||||
|
||||
return (
|
||||
<div className="row">
|
||||
<Link to={`${url}/${strCategory}`}>
|
||||
<li key={props.key}>
|
||||
<li key={props.i}>
|
||||
<img src={strCategoryThumb} alt={strCategory} />
|
||||
<h3>{strCategory}</h3> {strCategoryDescription}
|
||||
</li>
|
||||
</Link>
|
||||
</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 = () => {
|
||||
return (
|
||||
<span>
|
||||
© 2020 - Meal's Planner - Made with{" "}
|
||||
© 2020 - Chef's - Made with{" "}
|
||||
<span role="img" aria-label="heart">
|
||||
❤️
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ const Logo = () => {
|
|||
return (
|
||||
<Link to="/" className="brand-logo">
|
||||
<span role="img" aria-label="cookie">
|
||||
🍪 Chef's Planner
|
||||
👩🍳 Chef's
|
||||
</span>
|
||||
</Link>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import React from "react";
|
||||
import Logo from "./Logo";
|
||||
import SearchBar from "./SearchBar";
|
||||
|
||||
import RandomButton from "./RandomButton";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
|
|
@ -9,25 +9,15 @@ const Navbar = props => {
|
|||
<nav>
|
||||
<div className="nav-wrapper">
|
||||
<div className="row">
|
||||
{/* <div className="col s9"> */}
|
||||
<Logo />
|
||||
{/* </div> */}
|
||||
<ul id="nav-mobile" class="right hide-on-med-and-down">
|
||||
<ul id="nav-mobile" className="right hide-on-med-and-down">
|
||||
<li>
|
||||
<Link to="/categories" onClick={props.getCategories}>
|
||||
Categories
|
||||
</Link>
|
||||
<Link to="/categories">Categories</Link>
|
||||
</li>
|
||||
<li>
|
||||
<RandomButton handleClick={props.handleClick} />
|
||||
</li>
|
||||
</ul>
|
||||
{/* <div className="col s6">
|
||||
<SearchBar
|
||||
searchString={props.searchString}
|
||||
handleChange={props.handleChange}
|
||||
/>
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
</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";
|
||||
|
||||
const CategoryListPage = props => {
|
||||
// const { categories } = props;
|
||||
const categories = props.categories.categories;
|
||||
// if (categories.length > 0) {
|
||||
const { getCategories } = props;
|
||||
|
||||
useEffect(() => {
|
||||
getCategories();
|
||||
}, []);
|
||||
|
||||
// }
|
||||
// const { strCategory } = categories;
|
||||
return (
|
||||
<div className="section">
|
||||
<div className="container">
|
||||
<h1>The Chef's meal categories</h1>
|
||||
<h1>The Chef's Meal Categories</h1>
|
||||
<ul>
|
||||
{categories.map((category, i) => (
|
||||
<CategoryEntry key={i} category={category} />
|
||||
<CategoryEntry i={i} category={category} />
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -4,14 +4,8 @@ import RandomButton from "../components/RandomButton";
|
|||
const HomePage = props => {
|
||||
return (
|
||||
<div className="section background">
|
||||
<div
|
||||
className="container center-align"
|
||||
// styles={{
|
||||
// backgroundImage: `url(require("../images/parallax1.jpg"))`
|
||||
// }}
|
||||
>
|
||||
{/* <img src={require("../images/parallax1.jpg")} alt="" /> */}
|
||||
<h1>The Chef's meal suggestions</h1>
|
||||
<div className="container center-align">
|
||||
<h1>The Chef's Meal Suggestions</h1>
|
||||
<RandomButton handleClick={props.handleClick} />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,10 +1,16 @@
|
|||
import React from "react";
|
||||
import React, { useEffect } from "react";
|
||||
import MealPresentation from "../components/MealPresentation";
|
||||
import IngredientList from "../components/IngredientList";
|
||||
import Recipe from "../components/Recipe";
|
||||
// import PreLoader from "../components/PreLoader";
|
||||
|
||||
const MealPage = props => {
|
||||
const meal = props.meal.meals[0];
|
||||
const { getMeal } = props;
|
||||
|
||||
useEffect(() => {
|
||||
getMeal();
|
||||
}, []);
|
||||
|
||||
const {
|
||||
strMeal,
|
||||
|
|
@ -33,6 +39,9 @@ const MealPage = props => {
|
|||
}
|
||||
}
|
||||
|
||||
// const page =
|
||||
|
||||
// return isLoading ? <PreLoader /> : page;
|
||||
return (
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
|
|
|
|||
Loading…
Reference in a new issue