SearchBar & Page

This commit is contained in:
Ruidy Nemausat 2020-01-27 15:48:18 +01:00
parent 6a288f1246
commit a1462ed9e0
10 changed files with 113 additions and 87 deletions

View file

@ -2,6 +2,8 @@
Free meal planner for cooks short on ideas! (like me …)
[Available on](https://chefs-meal-planner.onrender.com/)
## Features
- Random meal suggestion
@ -52,6 +54,7 @@ Free meal planner for cooks short on ideas! (like me …)
- Notation system: know what are the most loved meals
- Suggestions based on what your personal taste
- Recipes in Video
- Get a full menu (Starter, Main, Dessert + Cocktail)
## Supports
@ -68,7 +71,7 @@ Free meal planner for cooks short on ideas! (like me …)
## Versions
### Features in V.1
### Features in V.0.1
- WebApp
- Random meal suggestion
@ -78,3 +81,4 @@ Free meal planner for cooks short on ideas! (like me …)
## TO DO
- put a preloader
- change favicon

View file

@ -5,7 +5,7 @@
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Chef's Meal Planner" />
<meta name="description" content="Chef's | Meal Planner" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
@ -25,15 +25,15 @@
href="https://fonts.googleapis.com/icon?family=Material+Icons"
/>
<title>Chef's Meal Planner</title>
<title>Chef's | Meal Planner</title>
</head>
<body>
<script>
<!-- <script>
document.addEventListener("DOMContentLoaded", function() {
var elems = document.querySelectorAll(".sidenav");
var instances = M.Sidenav.init(elems, options);
});
</script>
</script> -->
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>

View file

@ -18,7 +18,7 @@
"sizes": "512x512"
}
],
"start_url": ".",
"start_url": "/",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"

View file

@ -15,6 +15,7 @@ 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
// Default meal object. TODO: Find a better alternative …
const mealDef = {
@ -87,8 +88,11 @@ const App = () => {
return `${ROOT}${option}.php?c=${keyword}`;
} else if (option === "lookup") {
return `${ROOT}${option}.php?i=${keyword}`;
} else if (option === "search") {
return `${ROOT}${option}.php?s=${keyword}`;
}
};
const getFromAPI = (keyword, set, option = null) => {
const URI = createURI(keyword, option);
fetch(URI)
@ -111,6 +115,10 @@ const App = () => {
getFromAPI("categories", setCategories);
};
const getSearchResults = () => {
getFromAPI(searchString, setSearchResults, "search");
};
const handleChange = ev => {
const { value } = ev.target;
setSearchString(value);
@ -121,42 +129,30 @@ const App = () => {
<Router>
<Navbar handleClick={getRandomMeal} buttonUrl={buttonUrl} />
<div className="container">
<SearchBar searchString={searchString} handleChange={handleChange} />
<SearchBar
searchString={searchString}
handleChange={handleChange}
onSubmit={getSearchResults}
/>
</div>
<Switch>
<Route
exact
path="/"
render={props => (
<HomePage
{...props}
handleClick={getRandomMeal}
buttonUrl={buttonUrl}
/>
)}
<Route exact path="/">
<HomePage handleClick={getRandomMeal} buttonUrl={buttonUrl} />
</Route>
<Route exact path={buttonUrl}>
<MealPage
meal={meal}
getMeal={getRandomMeal}
// isLoading={isLoading}
/>
</Route>
/>
<Route
exact
path={buttonUrl}
render={props => (
<MealPage
{...props}
meal={meal}
getMeal={getRandomMeal}
// isLoading={isLoading}
/>
)}
/>
<Route
exact
path="/categories"
render={props => (
<CategoryListPage
{...props}
categories={categories}
getCategories={getCategories}
/>
)}
<Route exact path="/categories">
<CategoryListPage
categories={categories}
getCategories={getCategories}
/>
</Route>
/>
<Route path="/categories/:strCategory/">
<CategoryPage
@ -166,13 +162,19 @@ const App = () => {
meal={meal}
/>
</Route>
<Route exact path="/search">
<SearchPage
searchString={searchString}
searchResults={searchResults}
// getSearchResults={getSearchResults}
/>
</Route>
<Route path="/:idMeal">
<MealPage meal={meal} getMeal={getMeal} />
</Route>
<Route exact path="/search" component={SearchPage} />
{/* We'll have to input searchResults somewhere */}
<Route
render={props => <NotFound {...props} handleClick={getRandomMeal} />}
<Route>
<NotFound handleClick={getRandomMeal} />
</Route>
/>
</Switch>
<Footer />

View file

@ -1,15 +1,31 @@
import React from "react";
import { Link } from "react-router-dom";
const SearchBar = props => {
return (
<input
type="text"
name="search"
value={props.searchString}
placeholder="Search a recipe"
onChange={props.handleChange}
//{onSubmit={props.handleSubmit}
/>
<div className="row">
<input
className="input-field col s9"
type="text"
name="search"
value={props.searchString}
placeholder="Search a recipe"
onChange={props.handleChange}
/>
<Link to="/search">
<button
className="btn waves-effect waves-light right"
type="submit"
name="searchButton"
value="Search"
onClick={props.onSubmit}
>
{" "}
Search
<i class="material-icons right">send</i>
</button>
</Link>
</div>
);
};
export default SearchBar;

View file

@ -0,0 +1,20 @@
import React from "react";
import { Link } from "react-router-dom";
const SearchResult = props => {
const { meal } = props;
const { idMeal, strMeal, strMealThumb } = meal;
return (
<div className="row">
<Link to={`${idMeal}`}>
<li key={props.i}>
<img src={strMealThumb} alt={strMeal} />
<h3>{strMeal}</h3>
</li>
</Link>
</div>
);
};
export default SearchResult;

View file

@ -1,16 +0,0 @@
import React from "react";
const SearchResultList = () => {
return (
<div>
<ul>
<li>Recipe #1</li>
<li>Recipe #2</li>
<li>Recipe #</li>
<li>Recipe #N</li>
</ul>
</div>
);
};
export default SearchResultList;

View file

@ -2,7 +2,7 @@ import React, { useEffect } from "react";
import CategoryEntry from "../components/CategoryEntry";
const CategoryListPage = props => {
const categories = props.categories.categories;
const { categories } = props.categories;
const { getCategories } = props;
useEffect(() => {

View file

@ -47,10 +47,10 @@ const MealPage = props => {
return (
<div className="container">
<div className="row">
<div className="col s6">
<div className="col s12 m6">
<MealPresentation meal={item} />
</div>
<div className="col s6">
<div className="col s12 m6">
<IngredientList ingredients={ingredientList} />
<Recipe recipe={strInstructions} />
</div>

View file

@ -1,18 +1,18 @@
import React, { Component } from "react";
import SearchResultList from "../components/SearchResultList";
import React from "react";
import SearchResult from "../components/SearchResult";
export default class SearchPage extends Component {
constructor(props) {
super(props);
this.initState = {};
this.state = this.initState;
}
render() {
return (
<div>
<h1>Search Results</h1>
<SearchResultList />
</div>
);
}
}
const SearchPage = props => {
const { meals } = props.searchResults;
const { searchString } = props;
// console.log(meals[0]);
return (
<div className="container">
<h1>Search Results for: {searchString} </h1>
{meals.map((meal, i) => (
<SearchResult i={i} meal={meal} />
))}
</div>
);
};
export default SearchPage;