Skip to content

Commit

Permalink
added comments feature
Browse files Browse the repository at this point in the history
  • Loading branch information
haroonbajwa committed Aug 7, 2021
1 parent 93d0bcd commit 2fa041f
Show file tree
Hide file tree
Showing 10 changed files with 113 additions and 7 deletions.
16 changes: 14 additions & 2 deletions client/src/actions/posts.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as api from '../api';
import { CREATE, UPDATE, DELETE, FETCH_ALL, FETCH_POST, FETCH_BY_SEARCH, START_LOADING, END_LOADING } from '../constants/actionTypes';
import { CREATE, UPDATE, DELETE, FETCH_ALL, FETCH_POST, FETCH_BY_SEARCH, START_LOADING, END_LOADING, COMMENT } from '../constants/actionTypes';

//Action Creators
export const getPosts = (page) => async (dispatch) => {
Expand Down Expand Up @@ -82,4 +82,16 @@ export const likePost = (id) => async (dispatch) => {
} catch (error) {
console.log(error);
}
}
}

export const commentPost = (value, id) => async (dispatch) => {
try {
const { data } = await api.comment(value, id);

dispatch({ type: COMMENT, payload: data });

return data.comments;
} catch (error) {
console.log(error);
}
};
1 change: 1 addition & 0 deletions client/src/api/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export const createPost = (newPost) => API.post('/posts', newPost);
export const updatePost = (id, updatedPost) => API.patch(`/posts/${id}`, updatedPost);
export const deletePost = (id) => API.delete(`/posts/${id}`);
export const likePost = (id) => API.patch(`/posts/${id}/likePost`);
export const comment = (value, id) => API.post(`/posts/${id}/commentPost`, { value });

export const signIn = (formData) => API.post('/user/signin', formData);
export const signUp = (formData) => API.post('/user/signup', formData);
53 changes: 53 additions & 0 deletions client/src/components/PostDetails/CommentSection.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React, { useState, useRef } from 'react';
import { Typography, TextField, Button } from '@material-ui/core/';
import { useDispatch } from 'react-redux';

import { commentPost } from '../../actions/posts';
import useStyles from './styles';

const CommentSection = ({ post }) => {
const user = JSON.parse(localStorage.getItem('profile'));
const [comment, setComment] = useState('');
const dispatch = useDispatch();
const [comments, setComments] = useState(post?.comments);
const classes = useStyles();
const commentsRef = useRef();

const handleComment = async () => {
const newComments = await dispatch(commentPost(`${user?.result?.name}: ${comment}`, post._id));

setComment('');
setComments(newComments);

commentsRef.current.scrollIntoView({ behavior: 'smooth' });
};

return (
<div>
<div className={classes.commentsOuterContainer}>
<div className={classes.commentsInnerContainer}>
<Typography gutterBottom variant="h6">Comments</Typography>
{comments?.map((c, i) => (
<Typography key={i} gutterBottom variant="subtitle1">
<strong>{c.split(': ')[0]}</strong>
{c.split(':')[1]}
</Typography>
))}
<div ref={commentsRef} />
</div>
{user?.result?.name && (
<div style={{ width: '70%' }}>
<Typography gutterBottom variant="h6">Write a comment</Typography>
<TextField fullWidth rows={4} variant="outlined" label="Comment" multiline value={comment} onChange={(e) => setComment(e.target.value)} />
<br />
<Button style={{ marginTop: '10px' }} fullWidth disabled={!comment.length} color="primary" variant="contained" onClick={handleComment}>
Comment
</Button>
</div>
)}
</div>
</div>
);
};

export default CommentSection;
3 changes: 2 additions & 1 deletion client/src/components/PostDetails/PostDetails.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Paper, Typography, CircularProgress, Divider} from '@material-ui/core';
import { useDispatch, useSelector } from 'react-redux';
import moment from 'moment';
import { useParams, useHistory } from 'react-router';
import CommentSection from './CommentSection';

import useStyles from './styles';

Expand Down Expand Up @@ -53,7 +54,7 @@ const PostDetails = () => {
<Divider style={{ margin: '20px 0' }} />
<Typography variant="body1"><strong>Realtime Chat - coming soon!</strong></Typography>
<Divider style={{ margin: '20px 0' }} />
<Typography variant="body1"><strong>Comments - coming soon!</strong></Typography>
<CommentSection post={post} />
<Divider style={{ margin: '20px 0' }} />
</div>
<div className={classes.imageSection}>
Expand Down
9 changes: 9 additions & 0 deletions client/src/components/PostDetails/styles.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,13 @@ export default makeStyles((theme) => ({
loadingPaper: {
display: 'flex', justifyContent: 'center', alignItems: 'center', padding: '20px', borderRadius: '15px', height: '39vh',
},
commentsOuterContainer: {
display: 'flex',
justifyContent: 'space-between',
},
commentsInnerContainer: {
height: '200px',
overflowY: 'auto',
marginRight: '30px',
},
}));
1 change: 1 addition & 0 deletions client/src/constants/actionTypes.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export const DELETE = 'DELETE';
export const FETCH_ALL = 'FETCH_ALL';
export const FETCH_POST = 'FETCH_POST';
export const FETCH_BY_SEARCH = 'FETCH_BY_SEARCH';
export const COMMENT = 'COMMENT';

export const START_LOADING = 'START_LOADING';
export const END_LOADING = 'END_LOADING';
Expand Down
15 changes: 13 additions & 2 deletions client/src/reducers/posts.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CREATE, UPDATE, DELETE, FETCH_ALL, FETCH_POST, FETCH_BY_SEARCH, START_LOADING, END_LOADING } from '../constants/actionTypes';
import { CREATE, UPDATE, DELETE, FETCH_ALL, FETCH_POST, FETCH_BY_SEARCH, COMMENT, START_LOADING, END_LOADING } from '../constants/actionTypes';

const posts = (state = { isLoading: true, posts: [] }, action) => {
switch (action.type) {
Expand Down Expand Up @@ -32,7 +32,18 @@ const posts = (state = { isLoading: true, posts: [] }, action) => {

case DELETE:
return { ...state, posts: state.posts.filter((post) => post._id !== action.payload) };


case COMMENT:
return {
...state,
posts: state.posts.map((post) => {
if (post._id === action.payload._id) {
return action.payload;
}
return post;
}),
};

default:
return state;
}
Expand Down
15 changes: 14 additions & 1 deletion server/controllers/posts.js
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,17 @@ export const likePost = async (req, res) => {
const updatedPost = await PostMessage.findByIdAndUpdate(id, post, { new: true });

res.json(updatedPost);
}
}

export const commentPost = async (req, res) => {
const { id } = req.params;
const { value } = req.body;

const post = await PostMessage.findById(id);

post.comments.push(value);

const updatedPost = await PostMessage.findByIdAndUpdate(id, post, { new: true });

res.json(updatedPost);
};
4 changes: 4 additions & 0 deletions server/models/postMessage.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ const postSchema = mongoose.Schema({
type: [String],
default: [],
},
comments: {
type: [String],
default: []
},
createdAt: {
type: Date,
default: new Date(),
Expand Down
3 changes: 2 additions & 1 deletion server/routes/posts.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import express from 'express';

import { getPost, getPosts, getPostsBySearch, createPost, updatePost, deletePost, likePost } from '../controllers/posts.js';
import { getPost, getPosts, getPostsBySearch, createPost, updatePost, deletePost, likePost, commentPost } from '../controllers/posts.js';

import auth from '../middleware/auth.js';

Expand All @@ -13,5 +13,6 @@ router.post('/', auth, createPost);
router.patch('/:id', auth, updatePost);
router.delete('/:id', auth, deletePost);
router.patch('/:id/likePost', auth, likePost);
router.post('/:id/commentPost', commentPost);

export default router;

0 comments on commit 2fa041f

Please sign in to comment.