From e4ea325fb8cc6732cc681a5b7e7d15fdea43cd5d Mon Sep 17 00:00:00 2001 From: Clayton Wilson Date: Mon, 2 Dec 2019 20:18:44 -0500 Subject: [PATCH] Liking posts with Redux and Material UI --- functions/handlers/post.js | 221 +++++++++++++----- functions/index.js | 3 +- twistter-frontend/package.json | 1 + twistter-frontend/src/pages/Home.js | 108 +++++++-- twistter-frontend/src/pages/Search.js | 5 +- .../src/redux/actions/userActions.js | 51 +++- .../src/redux/reducers/userReducer.js | 18 +- twistter-frontend/src/redux/types.js | 3 + 8 files changed, 324 insertions(+), 86 deletions(-) diff --git a/functions/handlers/post.js b/functions/handlers/post.js index af1b854..341d790 100644 --- a/functions/handlers/post.js +++ b/functions/handlers/post.js @@ -213,85 +213,178 @@ exports.checkforLikePost = (req, res) => { } exports.likePost = (req, res) => { - let postData; - const likeDoc = admin.firestore().collection('likes').where('userHandle', '==', req.user.handle) - .where('postId', '==', req.params.postId).limit(1); + const postId = req.params.postId; + let likedPostDoc; + db.doc(`/users/${req.userData.handle}`) + .get() + .then((userDoc) => { + let likes = userDoc.data().likes; + if (likes === undefined || likes === null) { + likes = []; + } - const postDoc = db.doc(`/posts/${req.params.postId}`); + if (likes.includes(postId)) { + return res.status(400).json({error: "This user has already liked this post"}); + } - postDoc.get() - .then((doc) => { - if(doc.exists) { - postData = doc.data(); - return likeDoc.get(); - } - else - { - return res.status(404).json({error: 'Post not found'}); - } - }) - .then((data) => { - if (data.empty) { - return admin.firestore().collection('likes').add({ - postId : req.params.postId, - userHandle: req.user.handle + likes.push(postId); - }) - .then(() => { - postData.likeCount++; - return postDoc.update({likeCount : postData.likeCount}) - }) - .then(() => { - return res.status(200).json(postData); - }) - } - }) - .catch((err) => { - return res.status(500).json({error: 'Something is wrong'}); - }) + return userDoc.ref.update({likes}) + }) + .then(() => { + return db.doc(`/posts/${postId}`).get() + + }) + .then((postDoc) => { + let postData = postDoc.data(); + postData.likeCount++; + likedPostDoc = postData; + return postDoc.ref.update({likeCount : postData.likeCount}) + }) + .then(() => { + return res.status(201).json(likedPostDoc); + }) + .catch((err) => { + console.log(err); + return res.status(500).json({error: err}); + }) + + // let postData; + // const likeDoc = admin.firestore().collection('likes').where('userHandle', '==', req.user.handle) + // .where('postId', '==', req.params.postId).limit(1); + + // const postDoc = db.doc(`/posts/${req.params.postId}`); + + // postDoc.get() + // .then((doc) => { + // if(doc.exists) { + // postData = doc.data(); + // return likeDoc.get(); + // } + // else + // { + // return res.status(404).json({error: 'Post not found'}); + // } + // }) + // .then((data) => { + // if (data.empty) { + // return admin.firestore().collection('likes').add({ + // postId : req.params.postId, + // userHandle: req.user.handle + + // }) + // .then(() => { + // postData.likeCount++; + // return postDoc.update({likeCount : postData.likeCount}) + // }) + // .then(() => { + // return res.status(200).json(postData); + // }) + // } + // }) + // .catch((err) => { + // return res.status(500).json({error: 'Something is wrong'}); + // }) } exports.unlikePost = (req, res) => { - let postData; - const likeDoc = admin.firestore().collection('likes').where('userHandle', '==', req.user.handle) - .where('postId', '==', req.params.postId).limit(1); + const postId = req.params.postId; + let likedPostDoc; + db.doc(`/users/${req.userData.handle}`) + .get() + .then((userDoc) => { + let likes = userDoc.data().likes; + if (likes === undefined || likes === null) { + likes = []; + } - const postDoc = db.doc(`/posts/${req.params.postId}`); + if (!likes.includes(postId)) { + return res.status(400).json({error: "This user hasn't liked this post yet"}); + } - postDoc.get() - .then((doc) => { - if(doc.exists) { - postData = doc.data(); - return likeDoc.get(); - } - else - { - return res.status(404).json({error: 'Post not found'}); - } - }) - .then((data) => { - return db - .doc(`/likes/${data.docs[0].id}`) - .delete() - .then(() => { - postData.likeCount--; - return postDoc.update({ likeCount: postData.likeCount }); - }) - .then(() => { - res.status(200).json(postData); - }); + let i; + for (i = 0; i < likes.length; i++) { + if (likes[i] === postId) { + likes.splice(i, 1); + } + } + + return userDoc.ref.update({likes}) + }) + .then(() => { + return db.doc(`/posts/${postId}`).get() + + }) + .then((postDoc) => { + let postData = postDoc.data(); + postData.likeCount--; + likedPostDoc = postData; + return postDoc.ref.update({likeCount : postData.likeCount}) + }) + .then(() => { + return res.status(201).json(likedPostDoc); + }) + .catch((err) => { + console.log(err); + return res.status(500).json({error: err}); + }) + + // let postData; + // const likeDoc = admin.firestore().collection('likes').where('userHandle', '==', req.user.handle) + // .where('postId', '==', req.params.postId).limit(1); + + // const postDoc = db.doc(`/posts/${req.params.postId}`); + + // postDoc.get() + // .then((doc) => { + // if(doc.exists) { + // postData = doc.data(); + // return likeDoc.get(); + // } + // else + // { + // return res.status(404).json({error: 'Post not found'}); + // } + // }) + // .then((data) => { + // return db + // .doc(`/likes/${data.docs[0].id}`) + // .delete() + // .then(() => { + // postData.likeCount--; + // return postDoc.update({ likeCount: postData.likeCount }); + // }) + // .then(() => { + // res.status(200).json(postData); + // }); - }) - .catch((err) => { - console.error(err); - return res.status(500).json({error: 'Something is wrong'}); - }) + // }) + // .catch((err) => { + // console.error(err); + // return res.status(500).json({error: 'Something is wrong'}); + // }) } +exports.getLikes = (req, res) => { + db.doc(`/users/${req.userData.handle}`) + .get() + .then((doc) => { + let likes = doc.data().likes; + if (likes === undefined || likes === null) { + likes = []; + } + return res.status(200).json({likes}); + }) + .catch((err) => { + console.log(err); + return res.status(500).json({error: err}); + }) +} + exports.getFilteredPosts = (req, res) => { admin.firestore().collection('posts').where('userHandle', '==', 'new user').where('microBlogTopics', '==') }; diff --git a/functions/index.js b/functions/index.js index ee203eb..16c8708 100644 --- a/functions/index.js +++ b/functions/index.js @@ -70,7 +70,7 @@ app.post("/removeSub", fbAuth, removeSub); /*------------------------------------------------------------------* * handlers/post.js * *------------------------------------------------------------------*/ -const { getallPostsforUser, getallPosts, putPost, likePost, unlikePost, quoteWithPost, quoteWithoutPost, checkforLikePost} = require("./handlers/post"); +const { getallPostsforUser, getallPosts, putPost, likePost, unlikePost, getLikes, quoteWithPost, quoteWithoutPost, checkforLikePost} = require("./handlers/post"); app.get("/getallPostsforUser", fbAuth, getallPostsforUser); @@ -79,6 +79,7 @@ app.get("/getallPosts", getallPosts); // Adds one post to the database app.post("/putPost", fbAuth, putPost); +app.get("/likes", fbAuth, getLikes); app.get("/like/:postId", fbAuth, likePost); app.get("/unlike/:postId", fbAuth, unlikePost); app.get("/checkforLikePost/:postId", fbAuth, checkforLikePost); diff --git a/twistter-frontend/package.json b/twistter-frontend/package.json index a0cec16..2fc8943 100644 --- a/twistter-frontend/package.json +++ b/twistter-frontend/package.json @@ -15,6 +15,7 @@ "node-pre-gyp": "^0.13.0", "react": "^16.9.0", "react-dom": "^16.9.0", + "react-modal": "^3.11.1", "react-redux": "^7.1.1", "react-router-dom": "^5.1.0", "react-scripts": "0.9.5", diff --git a/twistter-frontend/src/pages/Home.js b/twistter-frontend/src/pages/Home.js index 0602a3a..093feee 100644 --- a/twistter-frontend/src/pages/Home.js +++ b/twistter-frontend/src/pages/Home.js @@ -5,9 +5,11 @@ import { connect } from 'react-redux'; import axios from 'axios'; // Material UI and React Router -import Grid from '@material-ui/core/Grid'; +import Button from '@material-ui/core/Button'; import Card from '@material-ui/core/Card'; import CardContent from '@material-ui/core/CardContent'; +import Grid from '@material-ui/core/Grid'; +import TextField from '@material-ui/core/TextField'; import Typography from "@material-ui/core/Typography"; // component @@ -17,10 +19,13 @@ import noImage from '../images/no-img.png'; import Writing_Microblogs from '../Writing_Microblogs'; import ReactModal from 'react-modal'; +// Redux +import { likePost, unlikePost, getLikes } from '../redux/actions/userActions'; + class Home extends Component { state = { - + likes: [] }; @@ -34,12 +39,41 @@ class Home extends Component { }) }) .catch(err => console.log(err)); + + this.props.getLikes(); + } + + componentWillReceiveProps(nextProps) { + this.setState({ + likes: nextProps.user.likes + }) + } + + handleClickLikeButton = (event) => { + // Need the ternary if statement because the user can click on the text or body of the + // Button and they are two different html elements + let postId = event.target.dataset.key ? event.target.dataset.key : event.target.parentNode.dataset.key; + console.log(postId) + + let doc = document.getElementById(postId); + // console.log(postId); + if (this.state.likes.includes(postId)) { + this.props.unlikePost(postId, this.state.likes) + doc.dataset.likes--; + } else { + this.props.likePost(postId, this.state.likes) + doc.dataset.likes++; + } + + doc.innerHTML = "Likes " + doc.dataset.likes; + } render() { - let authenticated = this.props.user.authenticated; - let username = this.props.user.credentials.handle; + let authenticated = this.props.user.authenticated; + let username = this.props.user.credentials.handle; + const {UI: { loading }} = this.props; let postMarkup = this.state.posts ? ( this.state.posts.map(post => @@ -60,9 +94,21 @@ class Home extends Component {
Topics: {post.microBlogTopics}
- {/* Likes {post.likeCount} */} - - + Likes {post.likeCount} + {/* */} + + + + {/* */} +
) @@ -184,14 +230,14 @@ class Quote extends Component { render() { return (
- +
-
-