diff --git a/client/src/actions/posts.jsx b/client/src/actions/posts.jsx
index ba1e40f..bc8e384 100644
--- a/client/src/actions/posts.jsx
+++ b/client/src/actions/posts.jsx
@@ -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) => {
@@ -82,4 +82,16 @@ export const likePost = (id) => async (dispatch) => {
} catch (error) {
console.log(error);
}
-}
\ No newline at end of file
+}
+
+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);
+ }
+ };
\ No newline at end of file
diff --git a/client/src/api/index.jsx b/client/src/api/index.jsx
index d38e6ea..ac73c20 100644
--- a/client/src/api/index.jsx
+++ b/client/src/api/index.jsx
@@ -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);
\ No newline at end of file
diff --git a/client/src/components/PostDetails/CommentSection.jsx b/client/src/components/PostDetails/CommentSection.jsx
new file mode 100644
index 0000000..0e40268
--- /dev/null
+++ b/client/src/components/PostDetails/CommentSection.jsx
@@ -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 (
+
+
+
+
Comments
+ {comments?.map((c, i) => (
+
+ {c.split(': ')[0]}
+ {c.split(':')[1]}
+
+ ))}
+
+
+ {user?.result?.name && (
+
+ Write a comment
+ setComment(e.target.value)} />
+
+
+
+ )}
+
+
+ );
+};
+
+export default CommentSection;
\ No newline at end of file
diff --git a/client/src/components/PostDetails/PostDetails.jsx b/client/src/components/PostDetails/PostDetails.jsx
index d6135d3..564438e 100644
--- a/client/src/components/PostDetails/PostDetails.jsx
+++ b/client/src/components/PostDetails/PostDetails.jsx
@@ -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';
@@ -53,7 +54,7 @@ const PostDetails = () => {
Realtime Chat - coming soon!
- Comments - coming soon!
+
diff --git a/client/src/components/PostDetails/styles.jsx b/client/src/components/PostDetails/styles.jsx
index 8b1c281..2a72e27 100644
--- a/client/src/components/PostDetails/styles.jsx
+++ b/client/src/components/PostDetails/styles.jsx
@@ -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',
+ },
}));
\ No newline at end of file
diff --git a/client/src/constants/actionTypes.jsx b/client/src/constants/actionTypes.jsx
index 4cafcb2..779268c 100644
--- a/client/src/constants/actionTypes.jsx
+++ b/client/src/constants/actionTypes.jsx
@@ -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';
diff --git a/client/src/reducers/posts.jsx b/client/src/reducers/posts.jsx
index 5afaf01..60b0d94 100644
--- a/client/src/reducers/posts.jsx
+++ b/client/src/reducers/posts.jsx
@@ -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) {
@@ -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;
}
diff --git a/server/controllers/posts.js b/server/controllers/posts.js
index a539b3e..8d7b88b 100644
--- a/server/controllers/posts.js
+++ b/server/controllers/posts.js
@@ -106,4 +106,17 @@ export const likePost = async (req, res) => {
const updatedPost = await PostMessage.findByIdAndUpdate(id, post, { new: true });
res.json(updatedPost);
-}
\ No newline at end of file
+}
+
+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);
+};
\ No newline at end of file
diff --git a/server/models/postMessage.js b/server/models/postMessage.js
index a93fe3c..d8efdf4 100644
--- a/server/models/postMessage.js
+++ b/server/models/postMessage.js
@@ -11,6 +11,10 @@ const postSchema = mongoose.Schema({
type: [String],
default: [],
},
+ comments: {
+ type: [String],
+ default: []
+ },
createdAt: {
type: Date,
default: new Date(),
diff --git a/server/routes/posts.js b/server/routes/posts.js
index fcb8f08..197ca5e 100644
--- a/server/routes/posts.js
+++ b/server/routes/posts.js
@@ -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';
@@ -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;
\ No newline at end of file