diff --git a/README.md b/README.md index d1cfb1a..b461e5f 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ Free meal planner for cooks short on ideas! (like me …) - Unknown - Vietnamese - Cocktail selection -- Create a profile and save your favourite meals +- Create a profile and save your favourite meals ✓ - Notation system: know what are the most loved meals - Share recipe with your friends and family - Suggestions based on what your personal taste @@ -79,6 +79,7 @@ The application is hosted on [Render](https://render.com/) at the following addr - [TheMealDb](https://www.themealdb.com/api.php) - An open, crowd-sourced database of Recipes from around the world - [Auth0](https://auth0.com/) - Rapidly integrate authentication and authorization +- [Firebase](https://firebase.google.com/) - Firebase helps mobile and web app teams succeed - [Render](https://render.com/) - The Easiest Cloud For All Your Apps and Websites diff --git a/src/components/MealPresentation.jsx b/src/components/MealPresentation.jsx index 1b40125..cb09b3d 100644 --- a/src/components/MealPresentation.jsx +++ b/src/components/MealPresentation.jsx @@ -9,7 +9,7 @@ export const MealPresentation = ({ meal }) => { mealCategory, mealArea, isFav, - setIsFav, + handleFavChange, } = meal; return ( @@ -48,10 +48,7 @@ export const MealPresentation = ({ meal }) => { {" "} { - e.preventDefault(); - setIsFav(!isFav); - }} + onClick={handleFavChange} > {isFav ? "favorite" : "favorite_border"} diff --git a/src/controllers/MainRouter.jsx b/src/controllers/MainRouter.jsx index 26d87df..523e312 100644 --- a/src/controllers/MainRouter.jsx +++ b/src/controllers/MainRouter.jsx @@ -1,18 +1,14 @@ import React from "react"; import { Switch, Route, Redirect } from "react-router-dom"; - import { SearchController } from "../controllers/SearchController"; import { HomeController } from "../controllers/HomeController"; import { MealController } from "../controllers/MealController"; import { CategoryController } from "../controllers/CategoryController"; import { CategoryListController } from "../controllers/CategoryListController"; import { ProfileController } from "../controllers/ProfileController"; - import { ContactPage } from "../pages/Contact"; import { NotFoundPage } from "../pages/NotFoundPage"; - import { PrivateRoute } from "../components/PrivateRoute"; -import TestPage from "../pages/TestPage"; const MainRouter = ({ buttonUrl, diff --git a/src/controllers/MealController.jsx b/src/controllers/MealController.jsx index 5ba8fc2..a47c1dc 100644 --- a/src/controllers/MealController.jsx +++ b/src/controllers/MealController.jsx @@ -27,14 +27,24 @@ export const MealController = ({ meal, getMeal, getRandomMeal }) => { strInstructions, } = mealItem; - const [isFav, setIsFav] = useState(false); + const [isFav, setIsFav] = useState(); + + /** + * Updates fav status in db + */ + const handleFavChange = (e) => { + e.preventDefault(); + setIsFav(!isFav); + // Send !isFav because state is not yet updated + fb.addToFavs(user.email, idMeal, strMeal, strMealThumb, !isFav); + }; useEffect(() => { // Not update fav status of the placeholder recipe. TODO: it's ugly... if (idMeal !== "52837" && isAuthenticated) { - fb.addToFavs(user.email, idMeal, strMeal, strMealThumb, isFav); + fb.isFav(user.email, idMeal).then((res) => setIsFav(res)); } - }, [user, idMeal, strMeal, strMealThumb, isFav, fb, isAuthenticated]); + }, [user.email, fb, idMeal, isAuthenticated]); const item = { mealName: strMeal, @@ -42,15 +52,15 @@ export const MealController = ({ meal, getMeal, getRandomMeal }) => { videoAddress: strYoutube, mealCategory: strCategory, mealArea: strArea, - isFav: isFav, - setIsFav: setIsFav, + isFav, + handleFavChange, }; let ingredientList = []; var i; for (i = 1; i <= 20; i++) { - var strIng = `strIngredient${i}`; - var strMes = `strMeasure${i}`; + let strIng = `strIngredient${i}`; + let strMes = `strMeasure${i}`; if (mealItem[strIng] !== "" && mealItem[strIng] !== null) { ingredientList.push([mealItem[strIng], mealItem[strMes]]); } diff --git a/src/pages/ProfilePage.jsx b/src/pages/ProfilePage.jsx index bf2b5cb..1d9885e 100644 --- a/src/pages/ProfilePage.jsx +++ b/src/pages/ProfilePage.jsx @@ -16,7 +16,7 @@ export const ProfilePage = ({ user, data }) => {
Email: {user.email} -
+

Favourites meals

diff --git a/src/services/Firebase/firebase.js b/src/services/Firebase/firebase.js index 89d9c7e..edfc3b0 100644 --- a/src/services/Firebase/firebase.js +++ b/src/services/Firebase/firebase.js @@ -1,16 +1,15 @@ 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, + apiKey: process.env.API_KEY, + authDomain: process.env.AUTH_DOMAIN, + databaseURL: process.env.DB_URL, + projectId: process.env.PROJECT_ID, + storageBucket: process.env.STORAGE_BUCKET, + messagingSenderId: process.env.MSG_SENDER_ID, + appId: process.env.APP_ID, + measurementId: process.env.MEASUREMENT_ID, }; const FAVS = "favs"; @@ -48,6 +47,7 @@ export default class Firebase { const query = await this.collection .doc(email) .collection(FAVS) + .where("isFav", "==", true) // .orderBy("timestamp", "desc") .limit(10) .get(); @@ -57,6 +57,19 @@ export default class Firebase { return favs; }; + isFav = async (email, idMeal) => { + const query = await this.collection + .doc(email) + .collection(FAVS) + .doc(idMeal) + .get(); + + const obj = query.data(); + return obj && !!obj.isFav; + // .where("isFav", "==", true); + // return !!query; + }; + /** * Create or update favourite status for an authenticated user. */ @@ -73,7 +86,7 @@ export default class Firebase { isFav, // timestamp: app.FieldValue.serverTimestamp(), }) - // .then(() => console.log("Fav object created.")) + // .then(() => console.log("Fav object created.", isFav)) .catch((err) => console.error("Error adding favs to database", err)); }; }