mirror of
https://github.com/ClaytonWWilson/CS307-Team24.git
synced 2025-12-15 18:08:46 +00:00
Liking posts with Redux and Material UI
This commit is contained in:
parent
e218708e0a
commit
e4ea325fb8
@ -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', '==')
|
||||
};
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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",
|
||||
|
||||
@ -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 =>
|
||||
<Card>
|
||||
@ -60,9 +94,21 @@ class Home extends Component {
|
||||
<br />
|
||||
<Typography variant="body2"><b>Topics:</b> {post.microBlogTopics}</Typography>
|
||||
<br />
|
||||
{/* <Typography variant="body2" color={"textSecondary"}>Likes {post.likeCount}</Typography> */}
|
||||
<Like microBlog = {post.postId} count = {post.likeCount} name = {username}></Like>
|
||||
<Quote microblog = {post.postId}></Quote>
|
||||
<Typography id={post.postId} data-likes={post.likeCount} variant="body2" color={"textSecondary"}>Likes {post.likeCount}</Typography>
|
||||
{/* <Like microBlog = {post.postId} count = {post.likeCount} name = {username}></Like> */}
|
||||
<Button
|
||||
onClick={this.handleClickLikeButton}
|
||||
data-key={post.postId}
|
||||
disabled={loading}
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
>{
|
||||
this.state.likes && this.state.likes.includes(post.postId) ? 'Unlike' : 'Like'
|
||||
}</Button>
|
||||
<Quote microblog = {post.postId}></Quote>
|
||||
|
||||
{/* <button>Quote</button> */}
|
||||
|
||||
</CardContent>
|
||||
</Card>
|
||||
)
|
||||
@ -184,14 +230,14 @@ class Quote extends Component {
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<button onClick={this.handleOpenModal}>Quote with Post</button>
|
||||
<Button variant="outlined" color="primary" onClick={this.handleOpenModal}>Quote with Post</Button>
|
||||
<ReactModal
|
||||
isOpen={this.state.showModal}
|
||||
style={{content: {height: "50%", width: "25%", marginTop: "auto", marginLeft: "auto", marginRight: "auto", marginBottom : "auto"}}}
|
||||
>
|
||||
<div style={{ width: "200px", marginLeft: "50px" }}>
|
||||
<form>
|
||||
<textarea
|
||||
<form style={{ width: "350px"}}>
|
||||
{/* <textarea
|
||||
value={this.state.value}
|
||||
required
|
||||
maxLength="250"
|
||||
@ -203,21 +249,39 @@ class Quote extends Component {
|
||||
}}
|
||||
cols={40}
|
||||
rows={20}
|
||||
/>
|
||||
/> */}
|
||||
<TextField
|
||||
style={{width: 300}}
|
||||
value={this.state.value}
|
||||
label="Write Quoted Post here..."
|
||||
required
|
||||
multiline
|
||||
color="primary"
|
||||
rows="14"
|
||||
variant="outlined"
|
||||
inputProps={{
|
||||
maxLength: 250
|
||||
}}
|
||||
onChange={e => {
|
||||
this.handleChangeforPost(e);
|
||||
this.handleChangeforCharacterCount(e);
|
||||
}}
|
||||
autoComplete='off'
|
||||
></TextField>
|
||||
|
||||
<div style={{ fontSize: "14px", marginRight: "-100px" }}>
|
||||
<p2>Characters Left: {this.state.characterCount}</p2>
|
||||
</div>
|
||||
<button onClick={this.handleSubmit}>Share Quoted Post</button>
|
||||
<Button variant="outlined" color="primary" onClick={this.handleSubmit}>Share Quoted Post</Button>
|
||||
|
||||
<button onClick={this.handleCloseModal}>Cancel</button>
|
||||
<Button variant="outlined" color="primary" onClick={this.handleCloseModal}>Cancel</Button>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
||||
|
||||
</ReactModal>
|
||||
<button onClick={this.handleSubmitWithoutPost}>Quote without Post</button>
|
||||
<Button variant="outlined" color="primary" onClick={this.handleSubmitWithoutPost}>Quote without Post</Button>
|
||||
|
||||
</div>
|
||||
)
|
||||
@ -318,11 +382,21 @@ class Like extends Component {
|
||||
}
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
user: state.user
|
||||
user: state.user,
|
||||
UI: state.UI
|
||||
})
|
||||
|
||||
const mapActionsToProps = {
|
||||
likePost,
|
||||
unlikePost,
|
||||
getLikes
|
||||
}
|
||||
|
||||
Home.propTypes = {
|
||||
user: PropTypes.object.isRequired
|
||||
user: PropTypes.object.isRequired,
|
||||
likePost: PropTypes.func.isRequired,
|
||||
unlikePost: PropTypes.func.isRequired,
|
||||
getLikes: PropTypes.func.isRequired
|
||||
}
|
||||
|
||||
Like.propTypes = {
|
||||
@ -333,4 +407,4 @@ Quote.propTypes = {
|
||||
user: PropTypes.object.isRequired
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps)(Home, Like, Quote);
|
||||
export default connect(mapStateToProps, mapActionsToProps)(Home, Like, Quote);
|
||||
@ -59,8 +59,9 @@ export class Search extends Component {
|
||||
<Grid>
|
||||
<TextField
|
||||
id="standard-required"
|
||||
label="Search"
|
||||
defaultValue="username"
|
||||
label="Username"
|
||||
// defaultValue="username"
|
||||
|
||||
margin="normal"
|
||||
value={this.state.searchPhase}
|
||||
onChange={event => this.handleInput(event)}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {SET_USER, SET_ERRORS, CLEAR_ERRORS, LOADING_UI, SET_AUTHENTICATED, SET_UNAUTHENTICATED} from '../types';
|
||||
import {SET_USER, SET_ERRORS, CLEAR_ERRORS, LOADING_UI, SET_AUTHENTICATED, SET_UNAUTHENTICATED, LIKE_POST, UNLIKE_POST, SET_LIKES} from '../types';
|
||||
import axios from 'axios';
|
||||
|
||||
|
||||
@ -81,6 +81,55 @@ export const deleteUser = () => (dispatch) => {
|
||||
dispatch({ type: SET_UNAUTHENTICATED });
|
||||
}
|
||||
|
||||
export const getLikes = () => (dispatch) => {
|
||||
axios.get('/likes')
|
||||
.then((res) => {
|
||||
dispatch({
|
||||
type: SET_LIKES,
|
||||
payload: res.data
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export const likePost = (postId, postArray) => (dispatch) => {
|
||||
postArray.push(postId);
|
||||
dispatch({
|
||||
type: LIKE_POST,
|
||||
payload: {
|
||||
likes: postArray
|
||||
}
|
||||
})
|
||||
axios.get(`/like/${postId}`)
|
||||
.then((res) => {
|
||||
getLikes();
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
export const unlikePost = (postId, postArray) => (dispatch) => {
|
||||
let i;
|
||||
for (i = 0; i < postArray.length; i++) {
|
||||
if (postArray[i] === postId) {
|
||||
postArray.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: UNLIKE_POST,
|
||||
payload: {
|
||||
likes: postArray
|
||||
}
|
||||
})
|
||||
|
||||
axios.get(`/unlike/${postId}`)
|
||||
.then((res) => {
|
||||
getLikes();
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
const setAuthorizationHeader = (token) => {
|
||||
const FBIdToken = `Bearer ${token}`;
|
||||
localStorage.setItem('FBIdToken', FBIdToken);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import {SET_USER, SET_ERRORS, CLEAR_ERRORS, LOADING_UI, SET_AUTHENTICATED, SET_UNAUTHENTICATED} from '../types';
|
||||
import {SET_USER, SET_ERRORS, CLEAR_ERRORS, LOADING_UI, SET_AUTHENTICATED, SET_UNAUTHENTICATED, LIKE_POST, UNLIKE_POST, SET_LIKES} from '../types';
|
||||
|
||||
const initialState = {
|
||||
authenticated: false,
|
||||
@ -19,9 +19,25 @@ export default function(state = initialState, action) {
|
||||
return initialState;
|
||||
case SET_USER:
|
||||
return {
|
||||
...state,
|
||||
authenticated: true,
|
||||
...action.payload,
|
||||
};
|
||||
case LIKE_POST:
|
||||
return {
|
||||
...state,
|
||||
...action.payload
|
||||
}
|
||||
case UNLIKE_POST:
|
||||
return {
|
||||
...state,
|
||||
...action.payload
|
||||
}
|
||||
case SET_LIKES:
|
||||
return {
|
||||
...state,
|
||||
...action.payload
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
||||
@ -3,6 +3,9 @@ export const SET_AUTHENTICATED = 'SET_AUTHENTICATED';
|
||||
export const SET_UNAUTHENTICATED = 'SET_UNAUTHENTICATED';
|
||||
export const SET_USER = 'SET_USER';
|
||||
export const LOADING_USER = 'LOADING_USER';
|
||||
export const LIKE_POST = 'LIKE_POST';
|
||||
export const UNLIKE_POST = 'UNLIKE_POST';
|
||||
export const SET_LIKES = 'SET_LIKES';
|
||||
|
||||
// UI reducer types
|
||||
export const SET_ERRORS = 'SET_ERRORS';
|
||||
|
||||
Loading…
Reference in New Issue
Block a user