added FireBase firestore

This commit is contained in:
Ruidy Nemausat 2020-04-04 13:09:51 +02:00
parent 0967f5f2ad
commit 47c9d5f4d9
13 changed files with 1157 additions and 106 deletions

26
.gitignore vendored
View file

@ -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

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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"
]
}
}
}

View file

@ -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}

View file

@ -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>

View file

@ -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 = [];

View file

@ -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 />

View file

@ -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")
);

View file

@ -0,0 +1,5 @@
import { createContext, useContext } from "react";
const FirebaseContext = createContext(null);
export const useFirebase = () => useContext(FirebaseContext);
export default FirebaseContext;

View 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();
};
}

View file

@ -0,0 +1,5 @@
import Firebase from "./firebase";
import FirebaseContext, { useFirebase } from "./context";
export default Firebase;
export { FirebaseContext, useFirebase };

View file

@ -1,4 +0,0 @@
{
"domain": "chefs-meal-planner.eu.auth0.com",
"clientId": "EXe8HCfFd0jSSfqzjAvpdk72ce0y2Hh9"
}