mirror of
https://github.com/rjNemo/meal_planner
synced 2026-06-06 02:26:49 +00:00
error Handling
This commit is contained in:
parent
b624122f13
commit
162857407d
9 changed files with 101 additions and 90 deletions
|
|
@ -83,6 +83,6 @@ Free meal planner for cooks short on ideas! (like me …)
|
|||
## TO DO
|
||||
|
||||
- put a preloader
|
||||
- visual styling
|
||||
- route bad request to notFOund (exple: /categories/string, when search results is null)
|
||||
- add sidenav on mobile
|
||||
- contact form
|
||||
|
|
|
|||
28
src/App.js
28
src/App.js
|
|
@ -1,5 +1,10 @@
|
|||
import React, { useState } from "react";
|
||||
import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
|
||||
import {
|
||||
BrowserRouter as Router,
|
||||
Switch,
|
||||
Route,
|
||||
Redirect
|
||||
} from "react-router-dom";
|
||||
import HomePage from "./pages/Home";
|
||||
import MealPage from "./pages/Meal";
|
||||
import SearchPage from "./pages/Search";
|
||||
|
|
@ -12,11 +17,10 @@ import Footer from "./components/Footer";
|
|||
import "./index.css";
|
||||
|
||||
const App = () => {
|
||||
// State Hooks
|
||||
const [searchString, setSearchString] = useState("");
|
||||
const [categories, setCategories] = useState({ categories: [] });
|
||||
const [searchResults, setSearchResults] = useState({ meals: [] });
|
||||
// const [isLoading, setIsLoading] = useState(true); For Preloader
|
||||
// const [isLoading, setIsLoading] = useState(true); //For Preloader
|
||||
// Default meal object. TODO: Find a better alternative …
|
||||
const mealDef = {
|
||||
meals: [
|
||||
|
|
@ -79,7 +83,6 @@ const App = () => {
|
|||
};
|
||||
const [meal, setMeal] = useState(mealDef);
|
||||
|
||||
// Fetch API functions
|
||||
const createURI = (keyword, option) => {
|
||||
const ROOT = "https://www.themealdb.com/api/json/v1/1/";
|
||||
if (option === null) {
|
||||
|
|
@ -100,11 +103,8 @@ const App = () => {
|
|||
.then(data => set(data));
|
||||
};
|
||||
|
||||
// Fetch wrappers for each use
|
||||
const getRandomMeal = () => {
|
||||
// setIsLoading(true);
|
||||
getData("random", setMeal);
|
||||
// setIsLoading(false);
|
||||
};
|
||||
|
||||
const getMeal = id => {
|
||||
|
|
@ -123,6 +123,7 @@ const App = () => {
|
|||
const { value } = ev.target;
|
||||
setSearchString(value);
|
||||
};
|
||||
|
||||
const buttonUrl = "/random";
|
||||
|
||||
return (
|
||||
|
|
@ -146,14 +147,14 @@ const App = () => {
|
|||
// isLoading={isLoading}
|
||||
/>
|
||||
</Route>
|
||||
/>
|
||||
|
||||
<Route exact path="/categories">
|
||||
<CategoryListPage
|
||||
categories={categories}
|
||||
getCategories={getCategories}
|
||||
/>
|
||||
</Route>
|
||||
/>
|
||||
|
||||
<Route path="/categories/:strCategory/">
|
||||
<CategoryPage
|
||||
getData={getData}
|
||||
|
|
@ -168,13 +169,16 @@ const App = () => {
|
|||
searchResults={searchResults}
|
||||
/>
|
||||
</Route>
|
||||
|
||||
<Route path="/404">
|
||||
<NotFound handleClick={getRandomMeal} />
|
||||
</Route>
|
||||
<Route path="/:idMeal">
|
||||
<MealPage meal={meal} getMeal={getMeal} />
|
||||
</Route>
|
||||
<Route>
|
||||
<NotFound handleClick={getRandomMeal} />
|
||||
<Route path="*">
|
||||
<Redirect to="/404" />
|
||||
</Route>
|
||||
/>
|
||||
</Switch>
|
||||
<Footer />
|
||||
</Router>
|
||||
|
|
|
|||
|
|
@ -3,13 +3,13 @@ import { Link } from "react-router-dom";
|
|||
|
||||
const Logo = () => {
|
||||
return (
|
||||
<logo>
|
||||
<div className="logo">
|
||||
<Link to="/" className="brand-logo">
|
||||
<span role="img" aria-label="cookie">
|
||||
👩🍳 Chef's
|
||||
</span>
|
||||
</Link>
|
||||
</logo>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,6 @@ div {
|
|||
/* width: 100%; */
|
||||
}
|
||||
|
||||
logo {
|
||||
.logo {
|
||||
font-family: "Marck Script", cursive;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,4 +6,4 @@ import * as serviceWorker from "./serviceWorker";
|
|||
|
||||
ReactDOM.render(<App />, document.getElementById("root"));
|
||||
|
||||
serviceWorker.unregister();
|
||||
serviceWorker.register();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import { useParams, Link, useRouteMatch } from "react-router-dom";
|
||||
import CardEntry from "../components/CardEntry";
|
||||
import { useParams, Link, Redirect } from "react-router-dom";
|
||||
|
||||
const CategoryPage = props => {
|
||||
const [meals, setMeals] = useState({ meals: [] });
|
||||
|
|
@ -15,33 +14,34 @@ const CategoryPage = props => {
|
|||
getMeals();
|
||||
}, []);
|
||||
|
||||
const { url } = useRouteMatch();
|
||||
|
||||
return (
|
||||
<div className="container">
|
||||
<h1>Chef's {strCategory} Recipes</h1>
|
||||
|
||||
<ul>
|
||||
{meals.meals.map((meal, i) => (
|
||||
<li key={i}>
|
||||
{/* <CardEntry item={meal} /> */}
|
||||
<Link to={`/${meal.idMeal}`}>
|
||||
<div className="row">
|
||||
<div className="col s12 m6">
|
||||
<div className="card ">
|
||||
<div className="card-image">
|
||||
<img src={meal.strMealThumb} alt={meal.strMeal} />
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<h4>{meal.strMeal}</h4>
|
||||
{meals.meals === null ? (
|
||||
<Redirect to="/404" />
|
||||
) : (
|
||||
<ul>
|
||||
{meals.meals.map((meal, i) => (
|
||||
<li key={i}>
|
||||
{/* <CardEntry item={meal} /> */}
|
||||
<Link to={`/meal/${meal.idMeal}`}>
|
||||
<div className="row">
|
||||
<div className="col s12 m6">
|
||||
<div className="card ">
|
||||
<div className="card-image">
|
||||
<img src={meal.strMealThumb} alt={meal.strMeal} />
|
||||
</div>
|
||||
<div className="card-content">
|
||||
<h4>{meal.strMeal}</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -8,11 +8,7 @@ const HomePage = props => {
|
|||
<div className="row">
|
||||
<div className="col s12 m6">
|
||||
<h1>The Chef's Meal Suggestions</h1>
|
||||
<RandomButton
|
||||
handleClick={props.handleClick}
|
||||
url={props.buttonUrl}
|
||||
size="large"
|
||||
/>
|
||||
<RandomButton url={props.buttonUrl} size="large" />
|
||||
</div>
|
||||
<div className="col s12 m6">
|
||||
<img
|
||||
|
|
|
|||
|
|
@ -2,11 +2,10 @@ import React, { useEffect } from "react";
|
|||
import MealPresentation from "../components/MealPresentation";
|
||||
import IngredientList from "../components/IngredientList";
|
||||
import Recipe from "../components/Recipe";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useParams, Redirect } from "react-router-dom";
|
||||
// import PreLoader from "../components/PreLoader";
|
||||
|
||||
const MealPage = props => {
|
||||
const meal = props.meal.meals[0];
|
||||
const { getMeal } = props;
|
||||
const { idMeal } = useParams();
|
||||
|
||||
|
|
@ -14,48 +13,53 @@ const MealPage = props => {
|
|||
idMeal === null ? getMeal() : getMeal(idMeal);
|
||||
}, []);
|
||||
|
||||
const {
|
||||
strMeal,
|
||||
strMealThumb,
|
||||
strYoutube,
|
||||
strCategory,
|
||||
strArea,
|
||||
strInstructions
|
||||
} = meal;
|
||||
if (props.meal.meals !== null) {
|
||||
const meal = props.meal.meals[0];
|
||||
|
||||
const item = {
|
||||
mealName: strMeal,
|
||||
imgAddress: strMealThumb,
|
||||
videoAddress: strYoutube,
|
||||
mealCategory: strCategory,
|
||||
mealArea: strArea
|
||||
};
|
||||
const {
|
||||
strMeal,
|
||||
strMealThumb,
|
||||
strYoutube,
|
||||
strCategory,
|
||||
strArea,
|
||||
strInstructions
|
||||
} = meal;
|
||||
|
||||
let ingredientList = [];
|
||||
var i;
|
||||
for (i = 1; i <= 20; i++) {
|
||||
var strIng = `strIngredient${i}`;
|
||||
var strMes = `strMeasure${i}`;
|
||||
if (meal[strIng] !== "" && meal[strIng] !== null) {
|
||||
ingredientList.push([meal[strIng], meal[strMes]]);
|
||||
const item = {
|
||||
mealName: strMeal,
|
||||
imgAddress: strMealThumb,
|
||||
videoAddress: strYoutube,
|
||||
mealCategory: strCategory,
|
||||
mealArea: strArea
|
||||
};
|
||||
|
||||
let ingredientList = [];
|
||||
var i;
|
||||
for (i = 1; i <= 20; i++) {
|
||||
var strIng = `strIngredient${i}`;
|
||||
var strMes = `strMeasure${i}`;
|
||||
if (meal[strIng] !== "" && meal[strIng] !== null) {
|
||||
ingredientList.push([meal[strIng], meal[strMes]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// const page =
|
||||
|
||||
// return isLoading ? <PreLoader /> : page;
|
||||
return (
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
<div className="col s12 m6">
|
||||
<MealPresentation meal={item} />
|
||||
</div>
|
||||
<div className="col s12 m6">
|
||||
<IngredientList ingredients={ingredientList} />
|
||||
<Recipe recipe={strInstructions} />
|
||||
// return isLoading ? <PreLoader /> : page;
|
||||
return (
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
<div className="col s12 m6">
|
||||
<MealPresentation meal={item} />
|
||||
</div>
|
||||
<div className="col s12 m6">
|
||||
<IngredientList ingredients={ingredientList} />
|
||||
<Recipe recipe={strInstructions} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
);
|
||||
} else {
|
||||
return <Redirect to="/404" />;
|
||||
}
|
||||
};
|
||||
|
||||
export default MealPage;
|
||||
|
|
|
|||
|
|
@ -2,17 +2,24 @@ import React from "react";
|
|||
import SearchResult from "../components/SearchResult";
|
||||
|
||||
const SearchPage = props => {
|
||||
const { meals } = props.searchResults;
|
||||
let { meals } = props.searchResults;
|
||||
const { searchString } = props;
|
||||
if (meals === null) {
|
||||
meals = [];
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="container">
|
||||
<h1>Search Results for: {searchString} </h1>
|
||||
<ul>
|
||||
{meals.map((meal, i) => (
|
||||
<SearchResult key={i} meal={meal} />
|
||||
))}
|
||||
</ul>
|
||||
{meals[0] === undefined ? (
|
||||
<p> Nothing ! Create a component to illustrate emptiness</p>
|
||||
) : (
|
||||
<ul>
|
||||
{meals.map((meal, i) => (
|
||||
<SearchResult key={i} meal={meal} />
|
||||
))}
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue