mirror of
https://github.com/rjNemo/meal_planner
synced 2026-06-06 02:26:49 +00:00
added FireBase firestore
This commit is contained in:
parent
0967f5f2ad
commit
47c9d5f4d9
13 changed files with 1157 additions and 106 deletions
26
.gitignore
vendored
26
.gitignore
vendored
|
|
@ -1,26 +0,0 @@
|
|||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
/src/utils/auth_config.json
|
||||
/src/utils/secret.js
|
||||
1
TODO.md
1
TODO.md
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
- [ ] send message after contact form validation (confirm to sender and msg+info to admin)
|
||||
- [ ] Local storage of prefeernces
|
||||
- [ ] Firebase
|
||||
- [ ] Breadcrumb
|
||||
- [ ] Cookie bar
|
||||
- [ ] code cleanup (props and refactoring)
|
||||
|
|
|
|||
1055
package-lock.json
generated
1055
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -7,6 +7,8 @@
|
|||
"@testing-library/jest-dom": "^4.2.4",
|
||||
"@testing-library/react": "^9.4.0",
|
||||
"@testing-library/user-event": "^7.2.1",
|
||||
"dotenv": "^8.2.0",
|
||||
"firebase": "^7.13.2",
|
||||
"react": "^16.12.0",
|
||||
"react-dom": "^16.12.0",
|
||||
"react-router-dom": "^5.1.2",
|
||||
|
|
@ -33,4 +35,4 @@
|
|||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
20
src/App.jsx
20
src/App.jsx
|
|
@ -81,13 +81,13 @@ export const App = () => {
|
|||
strMeasure19: "",
|
||||
strMeasure20: "",
|
||||
strSource: "https://www.bbcgoodfood.com/recipes/pilchard-puttanesca",
|
||||
dateModified: null
|
||||
}
|
||||
]
|
||||
dateModified: null,
|
||||
},
|
||||
],
|
||||
};
|
||||
const [meal, setMeal] = useState(mealDef);
|
||||
|
||||
const getMeal = id => {
|
||||
const getMeal = (id) => {
|
||||
getData(id, setMeal, "lookup");
|
||||
};
|
||||
|
||||
|
|
@ -95,13 +95,13 @@ export const App = () => {
|
|||
getData("random", setMeal);
|
||||
};
|
||||
|
||||
const getSearchResults = e => {
|
||||
const getSearchResults = (e) => {
|
||||
searchString === ""
|
||||
? e.preventDefault()
|
||||
: getData(searchString, setSearchResults, "search");
|
||||
};
|
||||
|
||||
const handleChange = ev => {
|
||||
const handleChange = (ev) => {
|
||||
const { value } = ev.target;
|
||||
setSearchString(value);
|
||||
};
|
||||
|
|
@ -109,18 +109,18 @@ export const App = () => {
|
|||
const buttonUrl = "/random";
|
||||
|
||||
const [showNav, setShowNav] = useState(false);
|
||||
const openNavClick = ev => {
|
||||
const openNavClick = (ev) => {
|
||||
ev.preventDefault();
|
||||
setShowNav(true);
|
||||
document.addEventListener("keydown", handleEscKey);
|
||||
// document.addEventListener("click", handleOutsideClick);
|
||||
};
|
||||
const closeNavClick = ev => {
|
||||
const closeNavClick = (ev) => {
|
||||
ev.preventDefault();
|
||||
setShowNav(false);
|
||||
document.removeEventListener("keydown", handleEscKey);
|
||||
};
|
||||
const handleEscKey = ev => {
|
||||
const handleEscKey = (ev) => {
|
||||
if (ev.key === "Escape") {
|
||||
setShowNav(false);
|
||||
}
|
||||
|
|
@ -201,7 +201,7 @@ export const App = () => {
|
|||
<NotFoundPage handleClick={getRandomMeal} />
|
||||
</Route>
|
||||
|
||||
<Route path="/:idMeal">
|
||||
<Route path="/:id">
|
||||
<MealController
|
||||
meal={meal}
|
||||
getMeal={getMeal}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import React from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
|
||||
export const MealPresentation = props => {
|
||||
export const MealPresentation = (props) => {
|
||||
const {
|
||||
mealName,
|
||||
imgAddress,
|
||||
|
|
@ -9,8 +9,9 @@ export const MealPresentation = props => {
|
|||
mealCategory,
|
||||
mealArea,
|
||||
isFav,
|
||||
setIsFav
|
||||
setIsFav,
|
||||
} = props.meal;
|
||||
|
||||
return (
|
||||
<div className="row">
|
||||
<div className="col s12">
|
||||
|
|
@ -22,40 +23,41 @@ export const MealPresentation = props => {
|
|||
<li>
|
||||
<div className="chip">
|
||||
<b>Video:</b>
|
||||
<a href={videoAddress} target="blank">
|
||||
<a href={videoAddress} target="blank" rel="noopener">
|
||||
<i className="close material-icons">video_library</i>
|
||||
</a>
|
||||
</div>
|
||||
{/* </li>
|
||||
|
||||
<li> */}
|
||||
<div className="chip">
|
||||
<b>Category: </b> {mealCategory}
|
||||
<Link to={`/categories/${mealCategory}`}>
|
||||
<i className="close material-icons">call_made</i>
|
||||
</Link>
|
||||
</div>
|
||||
{/* </li>
|
||||
<li> */}
|
||||
|
||||
<div className="chip">
|
||||
<b>Origin:</b> {mealArea}
|
||||
</div>
|
||||
|
||||
<div className="chip">
|
||||
<b>
|
||||
{isFav ? "Remove from favourites" : "Add to favourites"}:
|
||||
</b>
|
||||
|
||||
<Link to="#">
|
||||
{" "}
|
||||
<i
|
||||
className="close material-icons"
|
||||
onClick={() => setIsFav(!isFav)}
|
||||
className="material-icons tiny"
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
setIsFav(!isFav);
|
||||
}}
|
||||
>
|
||||
{isFav ? "favorite" : "favorite_border"}
|
||||
</i>
|
||||
</Link>
|
||||
</div>
|
||||
</li>
|
||||
<li></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -1,76 +1,48 @@
|
|||
import React, { useEffect, useState } from "react";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { useAuth0 } from "../utils/auth0-spa";
|
||||
import { MealPage } from "../pages/MealPage";
|
||||
import { NotFoundPage } from "../pages/NotFoundPage";
|
||||
import { useFirebase } from "../services/Firebase";
|
||||
// import Firebase from "../data/Firebase";
|
||||
|
||||
export const MealController = ({ meal, getMeal, getRandomMeal }) => {
|
||||
const { idMeal } = useParams();
|
||||
const { user, isAuthenticated } = useAuth0();
|
||||
const { id } = useParams();
|
||||
const fb = useFirebase();
|
||||
|
||||
useEffect(() => {
|
||||
idMeal === undefined ? getRandomMeal() : getMeal(idMeal);
|
||||
id === undefined ? getRandomMeal() : getMeal(id);
|
||||
// eslint-disable-next-line
|
||||
}, []);
|
||||
|
||||
const mealItem = meal.meals[0];
|
||||
|
||||
const {
|
||||
idMeal,
|
||||
strMeal,
|
||||
strMealThumb,
|
||||
strYoutube,
|
||||
strCategory,
|
||||
strArea,
|
||||
strInstructions
|
||||
strInstructions,
|
||||
} = mealItem;
|
||||
|
||||
// const setDbPromise = () => {
|
||||
// //check for support
|
||||
// if (!("indexedDB" in window)) {
|
||||
// console.log("This browser doesn't support IndexedDB");
|
||||
// return;
|
||||
// }
|
||||
|
||||
// var dbPromise = indexedDB.open("chefs-db", 1, function(upgradeDb) {
|
||||
// if (!upgradeDb.objectStoreNames.contains("favourites")) {
|
||||
// var favOS = upgradeDb.createObjectStore("favourites", {
|
||||
// keyPath: "mealName"
|
||||
// });
|
||||
// favOS.createIndex("isFav", "isFav", { unique: true });
|
||||
// }
|
||||
// });
|
||||
// return dbPromise;
|
||||
// };
|
||||
|
||||
// const [isFav, setIsFav] = useState(false);
|
||||
|
||||
// var dbPromise = setDbPromise();
|
||||
|
||||
// dbPromise
|
||||
// .then(db => {
|
||||
// var tx = db.transaction("favourites", "readwrite");
|
||||
// var store = tx.objectStore("favourites");
|
||||
// var item = {
|
||||
// mealName: strMeal,
|
||||
// isFav: isFav
|
||||
// };
|
||||
// store.add(item);
|
||||
// return tx.complete;
|
||||
// })
|
||||
// .then(function() {
|
||||
// console.log("added item to the favourite os!");
|
||||
// });
|
||||
|
||||
// const initState = Boolean(localStorage.getItem(strMeal));
|
||||
const [isFav, setIsFav] = useState(localStorage.getItem(strMeal) === "fav");
|
||||
|
||||
// console.log(isFav);
|
||||
const [isFav, setIsFav] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
isFav
|
||||
? localStorage.setItem(strMeal, "fav")
|
||||
: localStorage.removeItem(strMeal);
|
||||
// console.log(localStorage.getItem(strMeal));
|
||||
// console.log(user.email);
|
||||
// console.log(idMeal);
|
||||
// console.log(isFav);
|
||||
}, [isFav, strMeal]);
|
||||
console.log(fb);
|
||||
|
||||
// const add2Fav = async (user, idMeal, isFav) => {
|
||||
if (isAuthenticated) {
|
||||
fb.add(user.email, idMeal, isFav);
|
||||
}
|
||||
// };
|
||||
// add2Fav(user, idMeal, isFav).then((data) => console.log(data));
|
||||
}, [user, idMeal, isFav]);
|
||||
|
||||
const item = {
|
||||
mealName: strMeal,
|
||||
|
|
@ -79,7 +51,7 @@ export const MealController = ({ meal, getMeal, getRandomMeal }) => {
|
|||
mealCategory: strCategory,
|
||||
mealArea: strArea,
|
||||
isFav: isFav,
|
||||
setIsFav: setIsFav
|
||||
setIsFav: setIsFav,
|
||||
};
|
||||
|
||||
let ingredientList = [];
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import { ProfilePage } from "../pages/ProfilePage";
|
|||
export const ProfileController = () => {
|
||||
const { loading, user } = useAuth0();
|
||||
|
||||
// const fn = async () => await fire.getByEmail(user.email);
|
||||
|
||||
return loading || !user ? ( // is catched by PrivateRoute
|
||||
<div className="container center-align">
|
||||
<PreLoader />
|
||||
|
|
|
|||
|
|
@ -6,8 +6,9 @@ import * as serviceWorker from "./serviceWorker";
|
|||
import { Auth0Provider } from "./utils/auth0-spa";
|
||||
import history from "./utils/history";
|
||||
import config from "./utils/auth_config.json"; // for safety reasons this file is not tracked by git
|
||||
import Firebase, { FirebaseContext } from "./services/Firebase";
|
||||
|
||||
const onRedirectCallBack = appState => {
|
||||
const onRedirectCallBack = (appState) => {
|
||||
history.push(
|
||||
appState && appState.targetUrl
|
||||
? appState.targetUrl
|
||||
|
|
@ -22,7 +23,9 @@ ReactDOM.render(
|
|||
redirect_uri={window.location.origin}
|
||||
onRedirectCallBack={onRedirectCallBack}
|
||||
>
|
||||
<App />
|
||||
<FirebaseContext.Provider value={new Firebase()}>
|
||||
<App />
|
||||
</FirebaseContext.Provider>
|
||||
</Auth0Provider>,
|
||||
document.getElementById("root")
|
||||
);
|
||||
|
|
|
|||
5
src/services/Firebase/context.js
Normal file
5
src/services/Firebase/context.js
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import { createContext, useContext } from "react";
|
||||
|
||||
const FirebaseContext = createContext(null);
|
||||
export const useFirebase = () => useContext(FirebaseContext);
|
||||
export default FirebaseContext;
|
||||
40
src/services/Firebase/firebase.js
Normal file
40
src/services/Firebase/firebase.js
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
import app from "firebase/app";
|
||||
import "firebase/firestore";
|
||||
import config from "./config.json";
|
||||
|
||||
const CONFIG = {
|
||||
apiKey: config.apiKey,
|
||||
authDomain: config.authDomain,
|
||||
databaseURL: config.databaseURL,
|
||||
projectId: config.projectId,
|
||||
storageBucket: config.storageBucket,
|
||||
messagingSenderId: config.messagingSenderId,
|
||||
appId: config.appId,
|
||||
measurementId: config.measurementId,
|
||||
};
|
||||
|
||||
export default class Firebase {
|
||||
constructor() {
|
||||
app.initializeApp(CONFIG);
|
||||
this.db = app.firestore();
|
||||
}
|
||||
|
||||
add = async (email, id, fav) => {
|
||||
await this.db
|
||||
.collection("MealPlannerFavs")
|
||||
.add({ email: email, idMeal: id, isfav: fav })
|
||||
.then((ref) => {
|
||||
console.log("Added document with ID: ", ref.id);
|
||||
})
|
||||
.catch((error) => console.error("Error adding document: ", error));
|
||||
};
|
||||
|
||||
getByEmail = async (email) => {
|
||||
const query = await this.db
|
||||
.collection("MealPlannerFavs")
|
||||
.where("email", "==", email)
|
||||
.get();
|
||||
const snapshot = query.docs[0];
|
||||
return snapshot.data();
|
||||
};
|
||||
}
|
||||
5
src/services/Firebase/index.js
Normal file
5
src/services/Firebase/index.js
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
import Firebase from "./firebase";
|
||||
import FirebaseContext, { useFirebase } from "./context";
|
||||
|
||||
export default Firebase;
|
||||
export { FirebaseContext, useFirebase };
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
{
|
||||
"domain": "chefs-meal-planner.eu.auth0.com",
|
||||
"clientId": "EXe8HCfFd0jSSfqzjAvpdk72ce0y2Hh9"
|
||||
}
|
||||
Loading…
Reference in a new issue