Skip to content
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
6 changes: 6 additions & 0 deletions Intl/localizationData/en.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ export default {
postTitle: 'Post Title',
postContent: 'Post Content',
submit: 'Submit',
cancel: 'Cancel',
deleteComment: 'Delete Comment',
showComments: 'Show Comments',
hideComments: 'Hide Comments',
editComment: 'Edit Comment',
createNewComment: 'Create New Comment',
comment: `user {name} {value, plural,
=0 {does not have any comments}
=1 {has # comment}
Expand Down
70 changes: 70 additions & 0 deletions client/modules/Comment/CommentActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import callApi from '../../util/apiCaller';

// Export Constants
export const GET_COMMENTS = 'GET_COMMENTS';
export const ADD_COMMENT = 'ADD_COMMENT';
export const DELETE_COMMENT = 'DELETE_COMMENT';
export const EDIT_COMMENT = 'EDIT_COMMENT';

// Export Actions

export function getComments(comments) {
return {
type: GET_COMMENTS,
comments,
};
}

export function fetchComments(id) {
return (dispatch) => {
return callApi(`/posts/${id}/comments`).then(res => {
dispatch(getComments(res.comments));
});
};
}

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

export function addCommentRequest(comment, id) {
return (dispatch) => {
return callApi(`posts/${id}/comment`, 'post', {
comment: {
content: comment.content,
createdBy: comment.createdBy,
},
}).then(res => dispatch(addComment(res.comment)));
};
}


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

export function editCommentRequest(id, content) {
return (dispatch) => {
return callApi(`comment/${id}`, 'put', { content }).then(() => dispatch(editComment(id, content)));
};
}

export function deleteComment(id) {
return {
type: DELETE_COMMENT,
id,
};
}

export function deleteCommentRequest(id) {
return (dispatch) => {
return callApi(`comment/${id}`, 'delete').then(() => dispatch(deleteComment(id)));
};
}
46 changes: 46 additions & 0 deletions client/modules/Comment/CommentReducer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { GET_COMMENTS, ADD_COMMENT, DELETE_COMMENT, EDIT_COMMENT } from './CommentActions';

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

const CommentReducer = (state = initialState, action) => {
switch (action.type) {
case GET_COMMENTS :
return {
comments: action.comments,
};

case ADD_COMMENT :
return {
comments: [action.comment, ...state.comments],
};

case EDIT_COMMENT :
return {
comments: state.comments.map(comment => {
if (comment._id === action.id) {
const newComment = {
content: action.content,
postId: comment.postId,
createdBy: comment.createdBy,
dateAdded: comment.dateAdded,
};

return newComment;
}
return comment;
}),
};

case DELETE_COMMENT :
return {
comments: state.comments.filter(comment => comment._id !== action.id),
};

default:
return state;
}
};

// Export Reducer
export default CommentReducer;
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
.form {
display: block;
background: #FAFAFA;
padding: 32px 0;
border: 1px solid #eee;
border-radius: 4px;
}

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

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

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

.form-field-large {
min-height: 120px;
}

.comment-button {
display: inline-block;
padding: 6px 10px;
margin-left: 10px;
font-size: 14px;
color: #FFF;
text-decoration: none;
border-radius: 4px;
}

.comment-submit-button {
background: #03A9F4;
}

.comment-cancel-button {
background: #9a533c;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';

// Import Style
import styles from './CommentCreateWidget.css';

const CommentCreateWidget = ({ addComment, closeForm }) => {
const [authorName, changeAuthor] = useState('');
const [content, changeContent] = useState('');

const addNewComment = () => {
addComment(authorName, content);
closeForm();
};

return (
<div className={styles.form}>
<div className={styles['form-content']}>
<h2 className={styles['form-title']}><FormattedMessage id="createNewComment" /></h2>
<input placeholder="Author Name" className={styles['form-field']} value={authorName} onChange={e => changeAuthor(e.target.value)} />
<textarea placeholder="Content" className={`${styles['form-field']} ${styles['form-field-large']}`} value={content} onChange={e => changeContent(e.target.value)} />
<div className={styles['comment-actions']}>
<a
className={`${styles['comment-button']} ${styles['comment-cancel-button']}`}
href="#"
onClick={() => closeForm()}
>
<FormattedMessage id="cancel" />
</a>
<a
className={`${styles['comment-button']} ${styles['comment-submit-button']}`}
href="#"
onClick={() => addNewComment()}
>
<FormattedMessage id="submit" />
</a>
</div>
</div>
</div>
);
};

CommentCreateWidget.propTypes = {
addComment: PropTypes.func.isRequired,
closeForm: PropTypes.func.isRequired,
};

export default CommentCreateWidget;
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
.single-comment {
display: flex;
flex-direction: column;
align-items: flex-end;
margin: 20px 0;
padding: 10px 25px;
border-radius: 2px;
color: #757575;
}

.single-comment div {
display: flex;
justify-content: space-between;
width: 100%;
}

.comment-date {
font-size: 16px;
}

.author-name {
font-size: 16px;
margin-bottom: 16px;
}

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

.comment-button {
display: inline-block;
padding: 6px 10px;
font-size: 14px;
color: #FFF;
text-decoration: none;
border-radius: 4px;
}

.comment-submit-button {
background: #03A9F4;
}

.comment-cancel-button {
background: #9a533c;
}

.comment-desc {
font-size: 14px;
color: #888;
margin-bottom: 8px;
}

.post-actions {
display: flex;
justify-content: space-between;
}

.comment-action a{
color: #555;
text-decoration: none;
font-size: 14px;
font-style: italic;
}

.comment-delete a:hover{
color: #EF5350;
}

.comment-edit a:hover{
color: #4db258;
}
Loading