mirror of
https://github.com/rjNemo/meal_planner
synced 2026-06-06 02:26:49 +00:00
cleanup
This commit is contained in:
parent
df80472fd7
commit
fd3362a169
28 changed files with 136 additions and 23 deletions
|
|
@ -71,6 +71,8 @@ Free meal planner for cooks short on ideas! (like me …)
|
|||
- [Materialize](https://materializecss.com) CSS librairy for styling
|
||||
- Public API: [TheMealDb](https://www.themealdb.com/api.php) and [TheCocktailDb](https://www.thecocktaildb.com/api.php)
|
||||
- Hosting: [Render](https://render.com/)
|
||||
- Analytics : Google Analytics & Mixpanel
|
||||
- Authentication : Firebase or Auth0
|
||||
|
||||
## Versions
|
||||
|
||||
|
|
@ -90,7 +92,7 @@ Free meal planner for cooks short on ideas! (like me …)
|
|||
## TO DO
|
||||
|
||||
- add sidenav on mobile
|
||||
- accounts v2
|
||||
- accounts v2 (profile page)
|
||||
- send message after contact form validation (confirm to sender and msg+info to admin)
|
||||
- code cleanup (props and refactoring)
|
||||
- put a preloader
|
||||
|
|
@ -99,3 +101,4 @@ Free meal planner for cooks short on ideas! (like me …)
|
|||
- https://www.henriksommerfeld.se/error-handling-with-fetch/
|
||||
- Use ErrorBoundaries component ?
|
||||
- Back to top button
|
||||
- Take a look at some components [here](http://react-materialize.github.io/react-materialize/?path=/story/css-grid--default)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"short_name": "Meal Planner",
|
||||
"name": "Chef's Meal Planner",
|
||||
"short_name": "Chef's",
|
||||
"name": "Chef's | Meal Planner",
|
||||
"icons": [
|
||||
{
|
||||
"src": "favicon.ico",
|
||||
|
|
@ -27,4 +27,4 @@
|
|||
"display": "standalone",
|
||||
"theme_color": "#ee6e73",
|
||||
"background_color": "#ffffff"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
10
src/App.js
10
src/App.js
|
|
@ -1,8 +1,8 @@
|
|||
import React, { useState } from "react";
|
||||
import { Router } from "./utils/router";
|
||||
import { Switch, Route, Redirect } from "react-router-dom";
|
||||
import { HomePage } from "./pages/Home";
|
||||
import { MealPage } from "./pages/Meal";
|
||||
import { Home } from "./pages/Home";
|
||||
import { Meal } from "./pages/Meal";
|
||||
import { SearchPage } from "./pages/Search";
|
||||
import { CategoryListPage } from "./pages/CategoryList";
|
||||
import { CategoryPage } from "./pages/Category";
|
||||
|
|
@ -113,10 +113,10 @@ export const App = () => {
|
|||
/>
|
||||
<Switch>
|
||||
<Route exact path="/">
|
||||
<HomePage handleClick={getRandomMeal} buttonUrl={buttonUrl} />
|
||||
<Home buttonUrl={buttonUrl} />
|
||||
</Route>
|
||||
<Route exact path={buttonUrl}>
|
||||
<MealPage meal={meal} getMeal={getRandomMeal} />
|
||||
<Meal meal={meal} getMeal={getRandomMeal} />
|
||||
</Route>
|
||||
<Route exact path="/categories">
|
||||
<CategoryListPage
|
||||
|
|
@ -145,7 +145,7 @@ export const App = () => {
|
|||
<NotFoundPage handleClick={getRandomMeal} />
|
||||
</Route>
|
||||
<Route path="/:idMeal">
|
||||
<MealPage meal={meal} getMeal={getMeal} />
|
||||
<Meal meal={meal} getMeal={getMeal} />
|
||||
</Route>
|
||||
<Route path="*">
|
||||
<Redirect to="/404" />
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ import { Link, useRouteMatch } from "react-router-dom";
|
|||
const CategoryEntry = props => {
|
||||
const {
|
||||
strCategory,
|
||||
strCategoryThumb,
|
||||
strCategoryDescription
|
||||
strCategoryThumb
|
||||
// strCategoryDescription
|
||||
} = props.category;
|
||||
|
||||
const { url } = useRouteMatch();
|
||||
|
|
@ -16,7 +16,6 @@ export const Navbar = props => {
|
|||
{links.map((link, i) => (
|
||||
<FooterLink i={i} link={link} />
|
||||
))}
|
||||
|
||||
<li>
|
||||
<RandomButton
|
||||
handleClick={props.handleClick}
|
||||
|
|
@ -1,14 +1,14 @@
|
|||
import React from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
export const RandomButton = props => {
|
||||
const classString = `waves-effect waves-light btn-${props.size}`;
|
||||
export const RandomButton = ({ url, size, handleClick }) => {
|
||||
const classString = `waves-effect waves-light btn-${size}`;
|
||||
return (
|
||||
<Link to={props.url}>
|
||||
<Link to={url}>
|
||||
<button
|
||||
// className="waves-effect waves-light btn-small"
|
||||
className={classString}
|
||||
onClick={props.handleClick}
|
||||
onClick={handleClick}
|
||||
>
|
||||
Random Recipe
|
||||
</button>
|
||||
|
|
@ -15,10 +15,10 @@ div {
|
|||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.background {
|
||||
background-image: url(./images/Chef.svg);
|
||||
/* width: 100%; */
|
||||
}
|
||||
/* .background {
|
||||
background-image: url(./images/chef.svg);
|
||||
width: 100%;
|
||||
} */
|
||||
|
||||
.logo {
|
||||
font-family: "Marck Script", cursive;
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
import React from "react";
|
||||
import { RandomButton } from "../components/RandomButton";
|
||||
|
||||
export const HomePage = props => {
|
||||
export const Home = ({ buttonUrl }) => {
|
||||
return (
|
||||
<div className="section ">
|
||||
<div className="container ">
|
||||
<div className="row">
|
||||
<div className="col s12 m6">
|
||||
<h1 className="logo">Chef's Online Cookbook</h1>
|
||||
<RandomButton url={props.buttonUrl} size="large" />
|
||||
<RandomButton url={buttonUrl} size="large" />
|
||||
</div>
|
||||
<div className="col s12 m6">
|
||||
<img
|
||||
|
|
@ -4,7 +4,7 @@ import { IngredientList } from "../components/IngredientList";
|
|||
import { Recipe } from "../components/Recipe";
|
||||
import { useParams, Redirect } from "react-router-dom";
|
||||
|
||||
export const MealPage = props => {
|
||||
export const Meal = props => {
|
||||
const { getMeal } = props;
|
||||
const { idMeal } = useParams();
|
||||
|
||||
111
src/utils/authentication.js
Normal file
111
src/utils/authentication.js
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
import React, { useState, useEffect, useContext, createContext } from "react";
|
||||
import queryString from "query-string";
|
||||
import * as firebase from "firebase/app";
|
||||
import "firebase/auth";
|
||||
|
||||
if (!firebase.apps.length) {
|
||||
// Replace with your own Firebase credentials
|
||||
firebase.initializeApp({
|
||||
apiKey: "AIzaSyBkkFF0XhNZeWuDmOfEhsgdfX1VBG7WTas",
|
||||
authDomain: "divjoy-demo.firebaseapp.com",
|
||||
projectId: "divjoy-demo",
|
||||
appID: "divjoy-demo"
|
||||
});
|
||||
}
|
||||
|
||||
const authContext = createContext();
|
||||
|
||||
// Provider component that wraps your app and makes auth object ...
|
||||
// ... available to any child component that calls useAuth().
|
||||
export function ProvideAuth({ children }) {
|
||||
const auth = useProvideAuth();
|
||||
return <authContext.Provider value={auth}>{children}</authContext.Provider>;
|
||||
}
|
||||
|
||||
// Hook for child components to get the auth object ...
|
||||
// ... update when it changes.
|
||||
export const useAuth = () => {
|
||||
return useContext(authContext);
|
||||
};
|
||||
|
||||
// Provider hook that creates auth object and handles state
|
||||
function useProvideAuth() {
|
||||
const [user, setUser] = useState(null);
|
||||
|
||||
const signin = (email, password) => {
|
||||
return firebase
|
||||
.auth()
|
||||
.signInWithEmailAndPassword(email, password)
|
||||
.then(response => {
|
||||
setUser(response.user);
|
||||
return response.user;
|
||||
});
|
||||
};
|
||||
|
||||
const signup = (email, password) => {
|
||||
return firebase
|
||||
.auth()
|
||||
.createUserWithEmailAndPassword(email, password)
|
||||
.then(response => {
|
||||
setUser(response.user);
|
||||
return response.user;
|
||||
});
|
||||
};
|
||||
|
||||
const signout = () => {
|
||||
return firebase
|
||||
.auth()
|
||||
.signOut()
|
||||
.then(() => {
|
||||
setUser(false);
|
||||
});
|
||||
};
|
||||
|
||||
const sendPasswordResetEmail = email => {
|
||||
return firebase
|
||||
.auth()
|
||||
.sendPasswordResetEmail(email)
|
||||
.then(() => {
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
||||
const confirmPasswordReset = (password, code) => {
|
||||
// Get code from query string object
|
||||
const resetCode = code || getFromQueryString("oobCode");
|
||||
|
||||
return firebase
|
||||
.auth()
|
||||
.confirmPasswordReset(resetCode, password)
|
||||
.then(() => {
|
||||
return true;
|
||||
});
|
||||
};
|
||||
|
||||
// Subscribe to user on mount
|
||||
useEffect(() => {
|
||||
const unsubscribe = firebase.auth().onAuthStateChanged(user => {
|
||||
if (user) {
|
||||
setUser(user);
|
||||
} else {
|
||||
setUser(false);
|
||||
}
|
||||
});
|
||||
|
||||
// Subscription unsubscribe function
|
||||
return () => unsubscribe();
|
||||
}, []);
|
||||
|
||||
return {
|
||||
user,
|
||||
signin,
|
||||
signup,
|
||||
signout,
|
||||
sendPasswordResetEmail,
|
||||
confirmPasswordReset
|
||||
};
|
||||
}
|
||||
|
||||
const getFromQueryString = key => {
|
||||
return queryString.parse(window.location.search)[key];
|
||||
};
|
||||
Loading…
Reference in a new issue