mirror of
https://github.com/rjNemo/meal_planner
synced 2026-06-06 02:26:49 +00:00
navbar skeleton
This commit is contained in:
parent
99e61fdd74
commit
0c1e426669
10 changed files with 263 additions and 181 deletions
|
|
@ -97,7 +97,8 @@ Free meal planner for cooks short on ideas! (like me …)
|
||||||
|
|
||||||
1. add sidenav on mobile
|
1. add sidenav on mobile
|
||||||
1. send message after contact form validation (confirm to sender and msg+info to admin)
|
1. send message after contact form validation (confirm to sender and msg+info to admin)
|
||||||
1. Breadcrumb
|
1. Design & Breadcrumb
|
||||||
|
1. Cookie bar
|
||||||
1. code cleanup (props and refactoring)
|
1. code cleanup (props and refactoring)
|
||||||
1. Back to top button
|
1. Back to top button
|
||||||
1. Take a look at some components [here](http://react-materialize.github.io/react-materialize/?path=/story/css-grid--default)
|
1. Take a look at some components [here](http://react-materialize.github.io/react-materialize/?path=/story/css-grid--default)
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
<meta name="theme-color" content="#ee6e73" />
|
<meta name="theme-color" content="#ee6e73" />
|
||||||
<meta name="description" content="Chef's | Meal Planner" />
|
<meta name="description" content="Online Meal Planner | Chef's" />
|
||||||
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
||||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
||||||
|
|
||||||
|
|
@ -28,15 +28,9 @@
|
||||||
href="https://fonts.googleapis.com/css?family=Marck+Script&display=swap"
|
href="https://fonts.googleapis.com/css?family=Marck+Script&display=swap"
|
||||||
rel="stylesheet"
|
rel="stylesheet"
|
||||||
/>
|
/>
|
||||||
<title>Chef's | Meal Planner</title>
|
<title>Online Meal Planner | Chef's</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<!-- <script>
|
|
||||||
document.addEventListener("DOMContentLoaded", function() {
|
|
||||||
var elems = document.querySelectorAll(".sidenav");
|
|
||||||
var instances = M.Sidenav.init(elems, options);
|
|
||||||
});
|
|
||||||
</script> -->
|
|
||||||
<noscript>You need to enable JavaScript to run this app.</noscript>
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
</body>
|
</body>
|
||||||
|
|
|
||||||
|
|
@ -1,39 +1,43 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
|
import { useInput } from "../utils/inputHook";
|
||||||
|
|
||||||
export const ContactForm = ({ handleSubmit }) => {
|
export const ContactForm = ({ onSubmit }) => {
|
||||||
// const fields = ["firstname", "lastname", "email", "phone", "message"];
|
// const fields = ["firstname", "lastname", "email", "phone", "message"];
|
||||||
|
|
||||||
// const [firstName, setFirstName] = useState("");
|
// const [firstName, setFirstName] = useState("");
|
||||||
|
|
||||||
const onSubmit = ev => {
|
const handleSubmit = ev => {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
handleSubmit(true);
|
onSubmit(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
// const handleChange = ev => {
|
// const handleChange = ev => {
|
||||||
// const { value } = ev.target;
|
// const { value } = ev.target;
|
||||||
// setFirstName(value);
|
// setFirstName(value);
|
||||||
// };
|
// };
|
||||||
|
|
||||||
|
// const { value, bind } = useInput("");
|
||||||
|
const { bind } = useInput("");
|
||||||
return (
|
return (
|
||||||
<form onSubmit={onSubmit}>
|
<form onSubmit={handleSubmit}>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col s12">
|
<div className="col s12">
|
||||||
<div className="col s12 m6">
|
|
||||||
<ContactFormInput id="First Name" />
|
|
||||||
</div>
|
|
||||||
<div className="col s12 m6">
|
|
||||||
<ContactFormInput id="Last Name" />
|
|
||||||
</div>
|
|
||||||
<div className="col s12 m6">
|
<div className="col s12 m6">
|
||||||
<ContactFormInput
|
<ContactFormInput
|
||||||
id="Email"
|
id="First Name"
|
||||||
type="email"
|
// value={firstName}
|
||||||
placeholder="jd@mail.com"
|
// onChange={handleChange}
|
||||||
|
{...bind}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="col s12 m6">
|
<div className="col s12 m6">
|
||||||
<ContactFormInput id="Phone" placeholder="0123456789" />
|
<ContactFormInput id="Last Name" {...bind} />
|
||||||
|
</div>
|
||||||
|
<div className="col s12 m6">
|
||||||
|
<ContactFormInput id="Email" type="email" />
|
||||||
|
</div>
|
||||||
|
<div className="col s12 m6">
|
||||||
|
<ContactFormInput id="Phone" />
|
||||||
</div>
|
</div>
|
||||||
<div className="col s12">
|
<div className="col s12">
|
||||||
<ContactFormTextArea id="Message" />
|
<ContactFormTextArea id="Message" />
|
||||||
|
|
@ -45,18 +49,18 @@ export const ContactForm = ({ handleSubmit }) => {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const ContactFormInput = ({ id, type = "text" }) => {
|
const ContactFormInput = ({ id, type = "text", value, onChange }) => {
|
||||||
return (
|
return (
|
||||||
<div className="input-field">
|
<div className="input-field">
|
||||||
{/* <i class="material-icons prefix">account_circle</i> */}
|
{/* <i class="material-icons prefix">account_circle</i> */}
|
||||||
<label for={id}>{id}</label>
|
<label htmlFor={id}>{id}</label>
|
||||||
<input
|
<input
|
||||||
className="validate"
|
className="validate"
|
||||||
type={type}
|
type={type}
|
||||||
id={id}
|
id={id}
|
||||||
name={id}
|
name={value}
|
||||||
// value={value}
|
value={value}
|
||||||
// onChange={onChange}
|
onChange={onChange}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
@ -65,7 +69,7 @@ const ContactFormInput = ({ id, type = "text" }) => {
|
||||||
const ContactFormTextArea = ({ id }) => {
|
const ContactFormTextArea = ({ id }) => {
|
||||||
return (
|
return (
|
||||||
<div className="input-field">
|
<div className="input-field">
|
||||||
<label for={id}>{id}</label>
|
<label htmlFor={id}>{id}</label>
|
||||||
<textarea
|
<textarea
|
||||||
className="materialize-textarea validate"
|
className="materialize-textarea validate"
|
||||||
rows="12"
|
rows="12"
|
||||||
|
|
@ -85,7 +89,7 @@ const ContactFormSubmit = ({ text }) => {
|
||||||
type="submit"
|
type="submit"
|
||||||
name="submit"
|
name="submit"
|
||||||
>
|
>
|
||||||
<i class="material-icons right">send</i> {text}
|
<i className="material-icons right">send</i> {text}
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,9 @@ import { LogOutButton } from "./LogOutButton";
|
||||||
export const Navbar = props => {
|
export const Navbar = props => {
|
||||||
const { isAuthenticated } = useAuth0();
|
const { isAuthenticated } = useAuth0();
|
||||||
const links = ["categories", "contact"];
|
const links = ["categories", "contact"];
|
||||||
|
const { openNavClick } = props;
|
||||||
return (
|
return (
|
||||||
<div className="row">
|
<div className="navbar-fixed">
|
||||||
<nav>
|
<nav>
|
||||||
<div className="nav-wrapper">
|
<div className="nav-wrapper">
|
||||||
<div className="container ">
|
<div className="container ">
|
||||||
|
|
@ -29,50 +30,17 @@ export const Navbar = props => {
|
||||||
</li>
|
</li>
|
||||||
<li>{!isAuthenticated ? <LogInButton /> : <LogOutButton />}</li>
|
<li>{!isAuthenticated ? <LogInButton /> : <LogOutButton />}</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<a
|
||||||
|
href="#"
|
||||||
|
data-target="slide-out"
|
||||||
|
class="sidenav-trigger "
|
||||||
|
onClick={openNavClick}
|
||||||
|
>
|
||||||
|
<i class="material-icons">menu</i>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
{/* <ul id="slide-out" class="sidenav show-on-small">
|
|
||||||
<li>
|
|
||||||
<div class="user-view">
|
|
||||||
<div class="background">
|
|
||||||
<img src="images/office.jpg" />
|
|
||||||
</div>
|
|
||||||
<a href="#user">
|
|
||||||
<img class="circle" src="images/yuna.jpg" />
|
|
||||||
</a>
|
|
||||||
<a href="#name">
|
|
||||||
<span class="white-text name">John Doe</span>
|
|
||||||
</a>
|
|
||||||
<a href="#email">
|
|
||||||
<span class="white-text email">jdandturk@gmail.com</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="#!">
|
|
||||||
<i class="material-icons">cloud</i>First Link With Icon
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a href="#!">Second Link</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<div class="divider"></div>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a class="subheader">Subheader</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a class="waves-effect" href="#!">
|
|
||||||
Third Link With Waves
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<a href="#" data-target="slide-out" class="sidenav-trigger">
|
|
||||||
<i class="material-icons">menu</i>
|
|
||||||
</a> */}
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -4,28 +4,38 @@ import { Link } from "react-router-dom";
|
||||||
export const SearchBar = props => {
|
export const SearchBar = props => {
|
||||||
return (
|
return (
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<div className="row center-align">
|
<div className=" nav-wrapper">
|
||||||
<form>
|
<div className="row center-align">
|
||||||
<input
|
<form>
|
||||||
className="input-field col s10"
|
<div className="input-field col s10">
|
||||||
type="text"
|
<input
|
||||||
name="search"
|
className=""
|
||||||
value={props.searchString}
|
id="search"
|
||||||
placeholder="Search a recipe"
|
type="search"
|
||||||
onChange={props.handleChange}
|
required
|
||||||
/>
|
name="search"
|
||||||
<Link to="/search">
|
value={props.searchString}
|
||||||
<button
|
placeholder="Search for a recipe"
|
||||||
className="btn-floating waves-effect waves-light"
|
onChange={props.handleChange}
|
||||||
type="submit"
|
/>
|
||||||
name="searchButton"
|
<label className="label-icon" htmlFor="search">
|
||||||
value="Search"
|
<i className="material-icons">search</i>
|
||||||
onClick={props.onSubmit}
|
</label>
|
||||||
>
|
<i className="material-icons">close</i>
|
||||||
<i className="material-icons right">send</i>
|
</div>
|
||||||
</button>
|
<Link to="/search">
|
||||||
</Link>
|
<button
|
||||||
</form>
|
className="btn-floating waves-effect waves-light"
|
||||||
|
type="submit"
|
||||||
|
name="searchButton"
|
||||||
|
value="Search"
|
||||||
|
onClick={props.onSubmit}
|
||||||
|
>
|
||||||
|
<i className="material-icons right">send</i>
|
||||||
|
</button>
|
||||||
|
</Link>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
59
src/components/SideNav.jsx
Normal file
59
src/components/SideNav.jsx
Normal file
|
|
@ -0,0 +1,59 @@
|
||||||
|
import React, { useState } from "react";
|
||||||
|
import { Link } from "react-router-dom";
|
||||||
|
// import { useAuth0 } from "../utils/auth0-spa";
|
||||||
|
// import { Logo } from "./Logo";
|
||||||
|
// import { RandomButton } from "./RandomButton";
|
||||||
|
// import { FooterLink } from "./FooterLink";
|
||||||
|
// import { LogInButton } from "./LogInButton";
|
||||||
|
// import { LogOutButton } from "./LogOutButton";
|
||||||
|
|
||||||
|
export const SideNav = props => {
|
||||||
|
const { showNav } = props;
|
||||||
|
|
||||||
|
let transformStyle = {
|
||||||
|
transform: showNav ? "translateX(0%)" : "translateX(-105%)"
|
||||||
|
};
|
||||||
|
// let sideNavStyle = { width: showNav ? "250px" : "0" };
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ul id="slide-out" class="sidenav" style={transformStyle}>
|
||||||
|
<li>
|
||||||
|
<div class="user-view">
|
||||||
|
<div class="background">
|
||||||
|
<img src={require("../images/chef.svg")} />
|
||||||
|
</div>
|
||||||
|
<a href="#user">
|
||||||
|
<img class="circle" src={require("../images/chef.svg")} />
|
||||||
|
</a>
|
||||||
|
<a href="#name">
|
||||||
|
<span class="white-text name">John Doe</span>
|
||||||
|
</a>
|
||||||
|
<a href="#email">
|
||||||
|
<span class="white-text email">jdandturk@gmail.com</span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#!">
|
||||||
|
<i class="material-icons">cloud</i>First Link With Icon
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="#!">Second Link</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<div class="divider"></div>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="subheader">Subheader</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="waves-effect" href="#!">
|
||||||
|
Third Link With Waves
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
import "./index.css";
|
import "./index.css";
|
||||||
import { App } from "./App";
|
import { App } from "./pages/App.jsx";
|
||||||
import * as serviceWorker from "./serviceWorker";
|
import * as serviceWorker from "./serviceWorker";
|
||||||
import { Auth0Provider } from "./utils/auth0-spa";
|
import { Auth0Provider } from "./utils/auth0-spa";
|
||||||
import history from "./utils/history";
|
import history from "./utils/history";
|
||||||
|
|
|
||||||
|
|
@ -1,23 +1,24 @@
|
||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { Router } from "./utils/router";
|
import { Router } from "../utils/router";
|
||||||
import { Switch, Route, Redirect } from "react-router-dom";
|
import { Switch, Route, Redirect } from "react-router-dom";
|
||||||
import { useAuth0 } from "./utils/auth0-spa";
|
import { useAuth0 } from "../utils/auth0-spa";
|
||||||
import { Home } from "./pages/Home";
|
import { Home } from "./Home";
|
||||||
import { Meal } from "./pages/Meal";
|
import { Meal } from "./Meal";
|
||||||
import { SearchPage } from "./pages/Search";
|
import { SearchPage } from "./Search";
|
||||||
import { CategoryListPage } from "./pages/CategoryList";
|
import { CategoryListPage } from "./CategoryList";
|
||||||
import { CategoryPage } from "./pages/Category";
|
import { CategoryPage } from "./Category";
|
||||||
import { ContactPage } from "./pages/Contact";
|
import { ContactPage } from "./Contact";
|
||||||
import { NotFoundPage } from "./pages/NotFound";
|
import { NotFoundPage } from "./NotFound";
|
||||||
import { Navbar } from "./components/Navbar";
|
import { Navbar } from "../components/Navbar";
|
||||||
import { SearchBar } from "./components/SearchBar";
|
import { SearchBar } from "../components/SearchBar";
|
||||||
import { Footer } from "./components/Footer";
|
import { Footer } from "../components/Footer";
|
||||||
import "./index.css";
|
import { getData } from "../utils/methods";
|
||||||
import { getData } from "./utils/methods";
|
import history from "../utils/history";
|
||||||
import history from "./utils/history";
|
import { Profile } from "./Profile";
|
||||||
import { Profile } from "./pages/Profile";
|
import { PrivateRoute } from "../components/PrivateRoute";
|
||||||
import { PrivateRoute } from "./components/PrivateRoute";
|
import { PreLoader } from "../components/PreLoader";
|
||||||
import { PreLoader } from "./components/PreLoader";
|
import { SideNav } from "../components/SideNav";
|
||||||
|
import "../index.css";
|
||||||
|
|
||||||
export const App = () => {
|
export const App = () => {
|
||||||
const { loading } = useAuth0();
|
const { loading } = useAuth0();
|
||||||
|
|
@ -35,7 +36,7 @@ export const App = () => {
|
||||||
strArea: "Mine",
|
strArea: "Mine",
|
||||||
strInstructions:
|
strInstructions:
|
||||||
"Cook the pasta following pack instructions.\r\n\r\nHeat the oil in a non-stick frying pan and cook the onion, garlic and chilli for 3-4 mins to soften. Stir in the tomato pur\u00e9e and cook for 1 min, then add the pilchards with their sauce. Cook, breaking up the fish with a wooden spoon, then add the olives and continue to cook for a few more mins.\r\n\r\nDrain the pasta and add to the pan with 2-3 tbsp of the cooking water. Toss everything together well, then divide between plates and serve, scattered with Parmesan.",
|
"Cook the pasta following pack instructions.\r\n\r\nHeat the oil in a non-stick frying pan and cook the onion, garlic and chilli for 3-4 mins to soften. Stir in the tomato pur\u00e9e and cook for 1 min, then add the pilchards with their sauce. Cook, breaking up the fish with a wooden spoon, then add the olives and continue to cook for a few more mins.\r\n\r\nDrain the pasta and add to the pan with 2-3 tbsp of the cooking water. Toss everything together well, then divide between plates and serve, scattered with Parmesan.",
|
||||||
strMealThumb: require("./images/breakfast.svg"),
|
strMealThumb: require("../images/breakfast.svg"),
|
||||||
// "https://www.themealdb.com/images/media/meals/vvtvtr1511180578.jpg",
|
// "https://www.themealdb.com/images/media/meals/vvtvtr1511180578.jpg",
|
||||||
strTags: null,
|
strTags: null,
|
||||||
strYoutube: "#",
|
strYoutube: "#",
|
||||||
|
|
@ -109,80 +110,108 @@ export const App = () => {
|
||||||
|
|
||||||
const buttonUrl = "/random";
|
const buttonUrl = "/random";
|
||||||
|
|
||||||
|
const [showNav, setShowNav] = useState(false);
|
||||||
|
const openNavClick = ev => {
|
||||||
|
ev.preventDefault();
|
||||||
|
setShowNav(true);
|
||||||
|
document.addEventListener("keydown", handleEscKey);
|
||||||
|
};
|
||||||
|
const closeNavClick = ev => {
|
||||||
|
ev.preventDefault();
|
||||||
|
setShowNav(false);
|
||||||
|
document.removeEventListener("keydown", handleEscKey);
|
||||||
|
};
|
||||||
|
const handleEscKey = ev => {
|
||||||
|
if (ev.key === "Escape") {
|
||||||
|
setShowNav(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return loading ? (
|
return loading ? (
|
||||||
<div className="container center-align valign-wrapper">
|
<div className="container center-align valign-wrapper">
|
||||||
<PreLoader />
|
<PreLoader />
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<Router history={history}>
|
<>
|
||||||
<header>
|
<Router history={history}>
|
||||||
<Navbar handleClick={getRandomMeal} buttonUrl={buttonUrl} />
|
<header>
|
||||||
</header>
|
<Navbar
|
||||||
<SearchBar
|
handleClick={getRandomMeal}
|
||||||
searchString={searchString}
|
buttonUrl={buttonUrl}
|
||||||
handleChange={handleChange}
|
openNavClick={openNavClick}
|
||||||
onSubmit={getSearchResults}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Switch>
|
|
||||||
<Route exact path="/">
|
|
||||||
<Home buttonUrl={buttonUrl} />
|
|
||||||
</Route>
|
|
||||||
|
|
||||||
<PrivateRoute exact path="/profile">
|
|
||||||
<Profile />
|
|
||||||
</PrivateRoute>
|
|
||||||
|
|
||||||
<Route exact path={buttonUrl}>
|
|
||||||
{meal !== undefined && meal.meals !== null ? (
|
|
||||||
<Meal meal={meal} getMeal={getRandomMeal} />
|
|
||||||
) : (
|
|
||||||
<NotFoundPage handleClick={getRandomMeal} />
|
|
||||||
)}
|
|
||||||
</Route>
|
|
||||||
|
|
||||||
<Route exact path="/categories">
|
|
||||||
<CategoryListPage items={categories} getCategories={getCategories} />
|
|
||||||
</Route>
|
|
||||||
|
|
||||||
<Route path="/categories/:strCategory/">
|
|
||||||
<CategoryPage
|
|
||||||
getData={getData}
|
|
||||||
getMeal={getMeal}
|
|
||||||
setMeal={setMeal}
|
|
||||||
meal={meal}
|
|
||||||
/>
|
/>
|
||||||
</Route>
|
|
||||||
|
|
||||||
<Route exact path="/search">
|
<SearchBar
|
||||||
<SearchPage
|
|
||||||
searchString={searchString}
|
searchString={searchString}
|
||||||
searchResults={searchResults}
|
handleChange={handleChange}
|
||||||
|
onSubmit={getSearchResults}
|
||||||
/>
|
/>
|
||||||
</Route>
|
<SideNav showNav={showNav} />
|
||||||
|
</header>
|
||||||
|
|
||||||
<Route path="/contact">
|
<Switch>
|
||||||
<ContactPage />
|
<Route exact path="/">
|
||||||
</Route>
|
<Home buttonUrl={buttonUrl} />
|
||||||
|
</Route>
|
||||||
|
|
||||||
<Route path="/404">
|
<PrivateRoute exact path="/profile">
|
||||||
<NotFoundPage handleClick={getRandomMeal} />
|
<Profile />
|
||||||
</Route>
|
</PrivateRoute>
|
||||||
|
|
||||||
<Route path="/:idMeal">
|
<Route exact path={buttonUrl}>
|
||||||
{meal !== undefined && meal.meals !== null ? (
|
{meal !== undefined && meal.meals !== null ? (
|
||||||
<Meal meal={meal} getMeal={getMeal} />
|
<Meal meal={meal} getMeal={getRandomMeal} />
|
||||||
) : (
|
) : (
|
||||||
|
<NotFoundPage handleClick={getRandomMeal} />
|
||||||
|
)}
|
||||||
|
</Route>
|
||||||
|
|
||||||
|
<Route exact path="/categories">
|
||||||
|
<CategoryListPage
|
||||||
|
items={categories}
|
||||||
|
getCategories={getCategories}
|
||||||
|
/>
|
||||||
|
</Route>
|
||||||
|
|
||||||
|
<Route path="/categories/:strCategory/">
|
||||||
|
<CategoryPage
|
||||||
|
getData={getData}
|
||||||
|
getMeal={getMeal}
|
||||||
|
setMeal={setMeal}
|
||||||
|
meal={meal}
|
||||||
|
/>
|
||||||
|
</Route>
|
||||||
|
|
||||||
|
<Route exact path="/search">
|
||||||
|
<SearchPage
|
||||||
|
searchString={searchString}
|
||||||
|
searchResults={searchResults}
|
||||||
|
/>
|
||||||
|
</Route>
|
||||||
|
|
||||||
|
<Route path="/contact">
|
||||||
|
<ContactPage />
|
||||||
|
</Route>
|
||||||
|
|
||||||
|
<Route path="/404">
|
||||||
<NotFoundPage handleClick={getRandomMeal} />
|
<NotFoundPage handleClick={getRandomMeal} />
|
||||||
)}
|
</Route>
|
||||||
</Route>
|
|
||||||
|
|
||||||
<Route path="*">
|
<Route path="/:idMeal">
|
||||||
<Redirect to="/404" />
|
{meal !== undefined && meal.meals !== null ? (
|
||||||
</Route>
|
<Meal meal={meal} getMeal={getMeal} />
|
||||||
</Switch>
|
) : (
|
||||||
|
<NotFoundPage handleClick={getRandomMeal} />
|
||||||
|
)}
|
||||||
|
</Route>
|
||||||
|
|
||||||
<Footer />
|
<Route path="*">
|
||||||
</Router>
|
<Redirect to="/404" />
|
||||||
|
</Route>
|
||||||
|
</Switch>
|
||||||
|
|
||||||
|
<Footer />
|
||||||
|
</Router>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
@ -16,8 +16,8 @@ export const ContactPage = props => {
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<h1 className="logo">Contact Us</h1>
|
<h2 className="logo">Contact Us</h2>
|
||||||
<ContactForm handleSubmit={setIsSubmitted} />
|
<ContactForm onSubmit={setIsSubmitted} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
17
src/utils/inputHook.js
Normal file
17
src/utils/inputHook.js
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { useState } from "react";
|
||||||
|
|
||||||
|
export const useInput = initialValue => {
|
||||||
|
const [value, setValue] = useState(initialValue);
|
||||||
|
|
||||||
|
return {
|
||||||
|
value,
|
||||||
|
setValue,
|
||||||
|
reset: () => setValue(""),
|
||||||
|
bind: {
|
||||||
|
value,
|
||||||
|
onChange: ev => {
|
||||||
|
setValue(ev.target.value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
Loading…
Reference in a new issue