From 1ccc195036b3b41f60503af8f604b82601544dd9 Mon Sep 17 00:00:00 2001 From: Aditya Sankaran Date: Tue, 19 Nov 2019 21:09:07 -0500 Subject: [PATCH 1/3] liking and unliking work --- functions/handlers/post.js | 93 +++++++++++++++++++++++++++-- functions/index.js | 5 +- twistter-frontend/package.json | 2 +- twistter-frontend/src/pages/Home.js | 63 ++++++++++++++++++- 4 files changed, 152 insertions(+), 11 deletions(-) diff --git a/functions/handlers/post.js b/functions/handlers/post.js index a57cfe1..b431e0a 100644 --- a/functions/handlers/post.js +++ b/functions/handlers/post.js @@ -1,6 +1,8 @@ /* eslint-disable prefer-arrow-callback */ /* eslint-disable promise/always-return */ const admin = require('firebase-admin'); +const { db } = require('../util/admin'); + exports.putPost = (req, res) => { const newPost = { @@ -39,11 +41,11 @@ exports.getallPostsforUser = (req, res) => { return res.status(200).json(posts); }) .then(function() { - res.status(200).send("Successfully retrieved all user's posts from database."); - return; + return res.status(200).json("Successfully retrieved all user's posts from database."); + }) .catch(function(err) { - res.status(500).send("Failed to retrieve user's posts from database.", err); + return res.status(500).json("Failed to retrieve user's posts from database.", err); }); }; @@ -58,14 +60,93 @@ exports.getallPosts = (req, res) => { return res.status(200).json(posts); }) .then(function() { - res.status(200).send("Successfully retrieved every post from database."); - return; + return res.status(200).json("Successfully retrieved every post from database."); }) .catch(function(err) { - res.status(500).send("Failed to retrieve posts from database.", err); + return res.status(500).json("Failed to retrieve posts from database.", err); }); }; +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 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 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'}); + }) + +} + + 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 f05c7b8..2dd66ae 100644 --- a/functions/index.js +++ b/functions/index.js @@ -58,7 +58,7 @@ app.get("/getUserHandles", fbAuth, getUserHandles); /*------------------------------------------------------------------* * handlers/post.js * *------------------------------------------------------------------*/ -const { getallPostsforUser, getallPosts, putPost } = require("./handlers/post"); +const { getallPostsforUser, getallPosts, putPost, likePost, unlikePost} = require("./handlers/post"); app.get("/getallPostsforUser", fbAuth, getallPostsforUser); @@ -67,6 +67,9 @@ app.get("/getallPosts", getallPosts); // Adds one post to the database app.post("/putPost", fbAuth, putPost); +app.get("/like/:postId", fbAuth, likePost); +app.get("/unlike/:postId", fbAuth, unlikePost); + /*------------------------------------------------------------------* * handlers/topic.js * *------------------------------------------------------------------*/ diff --git a/twistter-frontend/package.json b/twistter-frontend/package.json index f7dd12f..a0cec16 100644 --- a/twistter-frontend/package.json +++ b/twistter-frontend/package.json @@ -41,5 +41,5 @@ "last 1 safari version" ] }, - "proxy": "https://us-central1-twistter-e4649.cloudfunctions.net/api" + "proxy": "http://localhost:5001/twistter-e4649/us-central1/api" } diff --git a/twistter-frontend/src/pages/Home.js b/twistter-frontend/src/pages/Home.js index cee0a93..fb28409 100644 --- a/twistter-frontend/src/pages/Home.js +++ b/twistter-frontend/src/pages/Home.js @@ -17,7 +17,10 @@ import noImage from '../images/no-img.png'; import Writing_Microblogs from '../Writing_Microblogs'; class Home extends Component { - state = {}; + state = { + + }; + componentDidMount() { axios @@ -31,8 +34,9 @@ class Home extends Component { .catch(err => console.log(err)); } + render() { - let authenticated = this.props.user.authenticated; + let authenticated = this.props.user.authenticated; let postMarkup = this.state.posts ? ( this.state.posts.map(post => @@ -50,9 +54,10 @@ class Home extends Component { {post.microBlogTitle} {post.body}
- Topics: {post.microBlogTopics} + Topics: {post.microBlogTopics}
Likes {post.likeCount} Comments {post.commentCount} + ) @@ -96,6 +101,7 @@ class Home extends Component { } } + const mapStateToProps = (state) => ({ user: state.user }) @@ -104,4 +110,55 @@ Home.propTypes = { user: PropTypes.object.isRequired } +class Like extends Component { + + constructor(props) { + super(props) + this.state = { + like: false + } + + this.handleClick = this.handleClick.bind(this); + } + + handleClick(){ + + this.setState({ + like: !this.state.like + }); + + if(this.state.like == false) + { + + axios.get(`/like/${this.props.microBlog}`) + .then((res) => { + console.log(res.data); + }) + .catch((err) => { + console.log(err); + }) + } + else + { + axios.get(`/unlike/${this.props.microBlog}`) + .then((res) => { + console.log(res.data); + }) + .catch((err) => { + console.log(err); + }) + } + + } + render() { + const label = this.state.like ? 'Unlike' : 'Like' + return( +
+ +
+ ) + } + +} + export default connect(mapStateToProps)(Home); \ No newline at end of file From e8110d643feaae370be1bef3e4f8f4c61abf6752 Mon Sep 17 00:00:00 2001 From: Aditya Sankaran Date: Thu, 21 Nov 2019 15:42:43 -0500 Subject: [PATCH 2/3] finished quoting microblogs --- functions/handlers/post.js | 97 ++++++++++++++++++++++- functions/index.js | 7 +- twistter-frontend/src/pages/Home.js | 115 ++++++++++++++++++++++++++++ 3 files changed, 217 insertions(+), 2 deletions(-) diff --git a/functions/handlers/post.js b/functions/handlers/post.js index b431e0a..407a85c 100644 --- a/functions/handlers/post.js +++ b/functions/handlers/post.js @@ -67,6 +67,102 @@ exports.getallPosts = (req, res) => { }); }; +exports.quoteWithPost = (req, res) => { + + let quoteData; + const quoteDoc = admin.firestore().collection('quote'). + 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) { + quoteData = doc.data(); + return quoteDoc.get(); + } + else + { + return res.status(404).json({error: 'Post not found'}); + } + }) + .then((data) => { + if(data.empty) { + return admin.firestore().collection('quote').add({ + postId : req.params.postId, + userHandle : req.user.handle, + quotePost : req.body.quotePost + }) + .then(() => { + return admin.firestore().collection('posts').add({ + quoteData, + quoteUser : req.user.handle, + quotePost : req.body.quotePost, + quotedAt : new Date().toISOString() + + }) + }) + } + else { + console.log("Post has already been quoted."); + return res.status(400).json({ error: 'Post has already been quoted.' }); + } + }) + .catch((err) => { + return res.status(500).json({error: 'Something is wrong'}); + + }) + +} + +exports.quoteWithoutPost = (req, res) => { + let quoteData; + const quoteDoc = admin.firestore().collection('quote'). + 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) { + quoteData = doc.data(); + return quoteDoc.get(); + } + else + { + return res.status(404).json({error: 'Post not found'}); + } + }) + .then((data) => { + if(data.empty) { + return admin.firestore().collection('quote').add({ + postId : req.params.postId, + userHandle : req.user.handle, + }) + .then(() => { + return admin.firestore().collection('posts').add({ + quoteData, + quoteUser : req.user.handle, + quotedAt : new Date().toISOString() + + }) + }) + } + else { + console.log("Post has already been quoted."); + return res.status(400).json({ error: 'Post has already been quoted.' }); + } + }) + .catch((err) => { + return res.status(500).json({error: 'Something is wrong'}); + + }) + +} + + exports.likePost = (req, res) => { let postData; const likeDoc = admin.firestore().collection('likes').where('userHandle', '==', req.user.handle) @@ -146,7 +242,6 @@ exports.unlikePost = (req, res) => { } - 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 2dd66ae..cdea2d1 100644 --- a/functions/index.js +++ b/functions/index.js @@ -58,7 +58,7 @@ app.get("/getUserHandles", fbAuth, getUserHandles); /*------------------------------------------------------------------* * handlers/post.js * *------------------------------------------------------------------*/ -const { getallPostsforUser, getallPosts, putPost, likePost, unlikePost} = require("./handlers/post"); +const { getallPostsforUser, getallPosts, putPost, likePost, unlikePost, quoteWithPost, quoteWithoutPost} = require("./handlers/post"); app.get("/getallPostsforUser", fbAuth, getallPostsforUser); @@ -70,6 +70,11 @@ app.post("/putPost", fbAuth, putPost); app.get("/like/:postId", fbAuth, likePost); app.get("/unlike/:postId", fbAuth, unlikePost); +app.post("/quoteWithPost/:postId", fbAuth, quoteWithPost); +app.post("/quoteWithoutPost/:postId", fbAuth, quoteWithoutPost); + + + /*------------------------------------------------------------------* * handlers/topic.js * *------------------------------------------------------------------*/ diff --git a/twistter-frontend/src/pages/Home.js b/twistter-frontend/src/pages/Home.js index fb28409..ff90580 100644 --- a/twistter-frontend/src/pages/Home.js +++ b/twistter-frontend/src/pages/Home.js @@ -15,6 +15,8 @@ import '../App.css'; import logo from '../images/twistter-logo.png'; import noImage from '../images/no-img.png'; import Writing_Microblogs from '../Writing_Microblogs'; +import ReactModal from 'react-modal'; + class Home extends Component { state = { @@ -58,6 +60,7 @@ class Home extends Component {
Likes {post.likeCount} Comments {post.commentCount} + ) @@ -110,6 +113,118 @@ Home.propTypes = { user: PropTypes.object.isRequired } +class Quote extends Component { + constructor(props) { + super(props); + this.state = { + characterCount: 250, + showModal: false, + value: "" + } + + this.handleSubmitWithoutPost = this.handleSubmitWithoutPost.bind(this); + this.handleOpenModal = this.handleOpenModal.bind(this); + this.handleCloseModal = this.handleCloseModal.bind(this); + this.handleSubmit = this.handleSubmit.bind(this); + } + + handleSubmitWithoutPost(event) { + const headers = { + headers: { "Content-Type": "application/json" } + }; + axios.post(`/quoteWithoutPost/${this.props.microblog}`, headers) + .then((res) => { + + console.log(res.data); + }) + .catch(err => { + + console.error(err); + }); + event.preventDefault(); + } + + handleOpenModal() { + this.setState({ showModal: true }); + } + + handleCloseModal() { + this.setState({ showModal: false }); + } + + handleChangeforPost(event) { + this.setState({ value: event.target.value }); + } + + handleChangeforCharacterCount(event) { + const charCount = event.target.value.length; + const charRemaining = 250 - charCount; + this.setState({ characterCount: charRemaining }); + } + + handleSubmit(event) { + const quotedPost = { + quotePost: this.state.value, + }; + const headers = { + headers: { "Content-Type": "application/json" } + }; + axios.post(`/quoteWithPost/${this.props.microblog}`, quotedPost, headers) + .then((res) => { + + console.log(res.data); + }) + .catch(err => { + + console.error(err); + }); + event.preventDefault(); + this.setState({ showModal: false, characterCount: 250, value: "" }); + } + + render() { + return ( +
+ + +
+
+