Skip to content

Mherkarapetyan comments feature #439

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Intl/localizationData/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export default {
=1 {has # comment}
other {has # comments}
}`,
commentContent: 'Comment Content',
HTMLComment: `user <b style='font-weight: bold'>{name} </b> {value, plural,
=0 {does not have <i style='font-style: italic'>any</i> comments}
=1 {has <i style='font-style: italic'>#</i> comment}
Expand Down
69 changes: 68 additions & 1 deletion client/modules/Post/PostActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import callApi from '../../util/apiCaller';
export const ADD_POST = 'ADD_POST';
export const ADD_POSTS = 'ADD_POSTS';
export const DELETE_POST = 'DELETE_POST';

export const ADD_COMMENT = 'ADD_COMMENT';
export const ADD_COMMENTS = 'ADD_COMMENTS';
export const DELETE_COMMENT = 'DELETE_COMMENT';
export const EDIT_COMMENT = 'EDIT_COMMENT';
// Export Actions
export function addPost(post) {
return {
Expand All @@ -25,6 +28,25 @@ export function addPostRequest(post) {
};
}

export function addComment(comment) {
return {
type: ADD_COMMENT,
comment,
};
}

export function addCommentRequest(comment) {
return (dispatch) => {
return callApi('comments', 'post', {
comment: {
name: comment.name,
content: comment.content,
postId: comment.postId,
},
}).then(res => dispatch(addComment(res.comment)));
};
}

export function addPosts(posts) {
return {
type: ADD_POSTS,
Expand All @@ -40,12 +62,27 @@ export function fetchPosts() {
};
}

export function addComments(comments) {
return {
type: ADD_COMMENTS,
comments,
};
}
export function fetchComments(postId) {
return (dispatch) => {
return callApi(`comments/${postId}`).then(res => {
dispatch(addComments(res.comments));
});
};
}

export function fetchPost(cuid) {
return (dispatch) => {
return callApi(`posts/${cuid}`).then(res => dispatch(addPost(res.post)));
};
}


export function deletePost(cuid) {
return {
type: DELETE_POST,
Expand All @@ -58,3 +95,33 @@ export function deletePostRequest(cuid) {
return callApi(`posts/${cuid}`, 'delete').then(() => dispatch(deletePost(cuid)));
};
}

export function deleteComment(cuid) {
return {
type: DELETE_COMMENT,
cuid,
};
}
export function deleteCommentRequest(cuid) {
return (dispatch) => {
return callApi(`comments/${cuid}`, 'delete').then(() => dispatch(deleteComment(cuid)));
};
}

export function editComment(comment) {
return {
type: EDIT_COMMENT,
comment,
};
}

export function editCommentRequest(comment) {
return (dispatch) => {
return callApi(`comments/${comment.postId}`, 'post', {
comment: {
name: comment.name,
content: comment.content,
},
}).then(res => dispatch(editComment(res.comment)));
};
}
28 changes: 25 additions & 3 deletions client/modules/Post/PostReducer.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,47 @@
import { ADD_POST, ADD_POSTS, DELETE_POST } from './PostActions';
import { ADD_COMMENT, ADD_COMMENTS, ADD_POST, ADD_POSTS, DELETE_COMMENT, DELETE_POST, EDIT_COMMENT } from './PostActions';

// Initial State
const initialState = { data: [] };
const initialState = { data: [], comments: [] };

const PostReducer = (state = initialState, action) => {
switch (action.type) {
case ADD_POST :
return {
...state,
data: [action.post, ...state.data],
};

case ADD_POSTS :
return {
...state,
data: action.posts,
};
case ADD_COMMENT :
return {
...state,
comments: [action.comment, ...state.comments],
};
case ADD_COMMENTS :
return {
...state,
comments: action.comments,
};

case DELETE_POST :
return {
...state,
data: state.data.filter(post => post.cuid !== action.cuid),
};

case DELETE_COMMENT :
return {
...state,
comments: state.comments.filter(comment => comment.cuid !== action.cuid),
};
case EDIT_COMMENT :
return {
...state,
comments: state.comments.map((comment) => (comment.cuid === action.comment.cuid ? action.comment : comment)),
};
default:
return state;
}
Expand Down
41 changes: 41 additions & 0 deletions client/modules/Post/components/PostCommentItem/PostCommentItem.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
.root {
border: 1px solid #ccc;
border-radius: 5px;
padding: 10px;
box-sizing: border-box;
-webkit-box-shadow: 0px 5px 5px -4px rgba(0,0,0,0.39);
-moz-box-shadow: 0px 5px 5px -4px rgba(0,0,0,0.39);
box-shadow: 0px 5px 5px -4px rgba(0,0,0,0.39);
margin-bottom: 10px;
}

.header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
}
.headerActions {
display: flex;
justify-content: space-between;
align-items: center;
}

.headerActions p {
cursor: pointer;
margin-left: 10px;
transition: 0.3s;
}
.headerActions p:hover {
color: #212121;

}

.name {
font-size: 16px;
color: darkgray;
}

.content {
font-style: italic;
}
34 changes: 34 additions & 0 deletions client/modules/Post/components/PostCommentItem/PostCommentItem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';

import styles from './PostCommentItem.css';

export class PostCommentItem extends PureComponent {
render() {
const { name, content, deleteComment, editComment, cuid } = this.props;
return (
<div className={styles.root}>
<div className={styles.header}>
<p className={styles.name}>{name}</p>
<div className={styles.headerActions}>
<p onClick={() => editComment(cuid)}>edit</p>
<p onClick={() => deleteComment(cuid)}>delete</p>
</div>
</div>
<p className={styles.content}>{content}</p>
</div>
);
}
}

PostCommentItem.propTypes = {
name: PropTypes.string,
content: PropTypes.string,
deleteComment: PropTypes.func,
editComment: PropTypes.func,
};

PostCommentItem.defaultProps = {
name: '',
content: '',
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
.form {
display: none;
background: #FAFAFA;
padding: 32px 0;
border: 1px solid #eee;
border-radius: 4px;
}

.form-content{
width: 100%;
max-width: 600px;
margin: auto;
font-size: 14px;
}

.form-title{
font-size: 16px;
font-weight: 700;
margin-bottom: 16px;
color: #757575;
}

.form-field{
width: 100%;
margin-bottom: 16px;
font-family: 'Lato', sans-serif;
font-size: 16px;
line-height: normal;
padding: 12px 16px;
border-radius: 4px;
border: 1px solid #ddd;
outline: none;
color: #212121;
}

textarea {
min-height: 200px;
}

.post-submit-button {
display: inline-block;
padding: 8px 16px;
font-size: 18px;
color: #FFF;
background: #03A9F4;
text-decoration: none;
border-radius: 4px;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';

import styles from './PostCommentWidget.css';
import { FormattedMessage, injectIntl } from 'react-intl';
import { PostCreateWidget } from '../PostCreateWidget/PostCreateWidget';

export const isEmpty = obj => !Object.keys(obj).length;

export class PostCommentWidget extends PureComponent {
componentDidUpdate() {
const comment = this.props.edit;
if (!isEmpty(comment)) {
this.refs.name.value = comment.name;
this.refs.content.value = comment.content;
}
}

addComment = () => {
const nameRef = this.refs.name;
const contentRef = this.refs.content;
if (nameRef.value && contentRef.value) {
this.props.addComment(nameRef.value, contentRef.value, !isEmpty(this.props.edit));
nameRef.value = contentRef.value = '';
}
};

render() {
return (
<div>
<input placeholder={this.props.intl.messages.authorName} className={styles['form-field']} ref="name" />

<textarea placeholder={this.props.intl.messages.commentContent} className={styles['form-field']} ref="content" />
<a className={styles['post-submit-button']} href="#" onClick={this.addComment}><FormattedMessage id="submit" /></a>
</div>
);
}
}

PostCreateWidget.propTypes = {
addComment: PropTypes.func.isRequired,
edit: PropTypes.object,
// showAddPost: PropTypes.bool.isRequired,
// intl: intlShape.isRequired,
};


export default injectIntl(PostCommentWidget);
Loading