Skip to content

Commit

Permalink
Merge 8e2a197 into 79f1def
Browse files Browse the repository at this point in the history
  • Loading branch information
ezrogha committed May 21, 2019
2 parents 79f1def + 8e2a197 commit 5e22619
Show file tree
Hide file tree
Showing 26 changed files with 855 additions and 19 deletions.
76 changes: 76 additions & 0 deletions src/actions/commentActions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import { notify } from 'react-notify-toast';
import axios from '../helpers/axiosInstance';
import * as types from './types';

export const fetchCommentsAction = slug => (dispatch) => {
axios
.get(`${process.env.baseURL}/articles/${slug}/comments`)
.then((response) => {
dispatch({
type: types.FETCH_COMMENTS,
payload: response.data.comments,
});
});
};


export const replyToCommentAction = (slug, commentId, commentReply) => () => {
const data = {
comment: {
body: commentReply,
},
};

axios
.post(`${process.env.baseURL}/articles/${slug}/comments/${commentId}/reply`, data)
.then(() => {
location.reload();
})
.catch(() => {
location.reload();
});
};

export const addCommentToArticleAction = (slug, comment) => () => {
const data = {
comment: {
body: comment,
},
};
axios
.post(`${process.env.baseURL}/articles/${slug}/comments/`, data)
.then(() => {
location.reload();
})
.catch(() => {
location.reload();
});
};

export const deleteArticleCommentAction = (slug, id) => {
axios
.delete(`${process.env.baseURL}/articles/${slug}/comments/${id}`)
.then(() => {
notify.show('Comment deleted', 'success', 2000);
setTimeout(() => {
location.reload();
}, 3000);
});
};

export const updateArticleCommentAction = (slug, id, updtateComment) => {
const data = {
comment: {
body: updtateComment,
},
};

axios
.put(`${process.env.baseURL}/articles/${slug}/comments/${id}`, data)
.then(() => {
notify.show('Comment updated', 'success', 1000);
setTimeout(() => {
location.reload();
}, 2000);
});
};
2 changes: 2 additions & 0 deletions src/actions/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './commentActions';
export * from './articlesActions';
1 change: 1 addition & 0 deletions src/actions/types.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ export const DELETE_AN_ARTICLE_SUCCESS = 'DELETE_AN_ARTICLE_SUCCESS';
export const DELETE_AN_ARTICLE_FAILURE = 'DELETE_AN_ARTICLE_FAILURE';
export const EDIT_AN_ARTICLE_SUCCESS = 'EDIT_AN_ARTICLE_SUCCESS';
export const EDIT_AN_ARTICLE_FAILURE = 'EDIT_AN_ARTICLE_FAILURE';
export const FETCH_COMMENTS = 'FETCH_COMMENTS';
18 changes: 16 additions & 2 deletions src/components/Articles/ArticleDetail.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,24 @@ import React from 'react';
import PropTypes, { shape } from 'prop-types';
import moment from 'moment';
import { Link } from 'react-router-dom';
import Comments from '../../pages/Comments';
import DeleteArticleComponentModel from './DeleteArticleModel';
import avartaImage from '../../assets/images/avarta.png';
import './article.scss';

const ArticleDetail = ({ article, deleteAnArticle }) => (
const ArticleDetail = ({
article,
deleteAnArticle,
comments,
showReplies,
replyDisplayState,
postReplyToComment,
onCommentChanged,
postComment,
deleteComment,
updateComment,
onChangeComment,
}) => (
<div className="container article-detail-container">
<div className="row">
<div className="col-md-12">
Expand Down Expand Up @@ -86,14 +99,15 @@ const ArticleDetail = ({ article, deleteAnArticle }) => (
)
: ''

}
}
<DeleteArticleComponentModel
title={article.title}
slug={article.slug}
username={
article.author && article.author.username}
deleteAnArticle={deleteAnArticle}
/>
<Comments comments={comments} showReplies={showReplies} replyDisplayState={replyDisplayState} slug={article.slug} postReplyToComment={postReplyToComment} onCommentChanged={onCommentChanged} postComment={postComment} deleteComment={deleteComment} updateComment={updateComment} onChangeComment={onChangeComment} />
</div>
</div>
</div>
Expand Down
46 changes: 46 additions & 0 deletions src/components/Comment/Comment.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
@import '../../assets/scss/shared.scss';

.commectCard {
margin-bottom: rem(15);

.commentHeader {
display: flex;
flex-direction: row;
justify-content: space-between;

.authorDataContainer {
display: flex;
flex-direction: row;
}
}

.imagePlaceholder {
width: rem(50);
height: rem(50);
border-radius: rem(50);
background-color: #ddd;
display: inline-block;
}

.authorData {
margin-left: rem(10);

.commentDate {
font-size: rem(12);
}
}

.commentFooter {
background-color: transparent;
border-top-color: #eee;
border-top-width: rem(1);

.replyComment {
float: right;

.replyButton {
cursor: pointer;
}
}
}
}
55 changes: 55 additions & 0 deletions src/components/Comment/Comment.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React from 'react';
import renderer from 'react-test-renderer';
import { shallow } from 'enzyme';
import Comment from './index';

describe('Comment Component test', () => {
const props = {
commentObject: {
author: 'alex',
body: 'this is alex',
createdAt: '1133',
id: 1,
replies: ['hi'],
},
showReplies: jest.fn(),
replyDisplayState: {},
slug: 'hi',
postReplyToComment: jest.fn(),
deleteComment: jest.fn(),
updateComment: jest.fn(),
onChangeComment: jest.fn(),
};

const wrapper = shallow(<Comment {...props} />);

it('replyButton test', () => {
wrapper.find('#deleteButton').simulate('click');
wrapper.find('.replyButton').simulate('click');
wrapper.setProps({
commentObject: { ...props.commentObject, replies: ['li', 'hey'] },
});
wrapper.find('.replyButton').simulate('click');
wrapper.setProps({
commentObject: { ...props.commentObject, replies: [] },
});
wrapper.find('.replyButton').simulate('click');
expect(props.deleteComment).toHaveBeenCalled();
});

it('replies map function test', () => {
const replyProps = {
key: 1,
reply: {},
slug: 'article-slug',
id: 1,
deleteComment: jest.fn(),
updateComment: jest.fn(),
onChangeComment: jest.fn(),
};
wrapper.setProps({ repliesDisplayState: { repliesDisplayState1: true } });
wrapper.setProps({
commentObject: { ...props.commentObject, replies: [] },
});
});
});
101 changes: 101 additions & 0 deletions src/components/Comment/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import React from 'react';
import moment from 'moment';
import CommentReplies from '../CommentReplies';
import ReplyToComment from '../ReplyToComment';
import EditCommentDialog from '../EditCommentDialog';

import './Comment.scss';

const Comment = ({
commentObject: {
author, body, createdAt, id, replies,
},
showReplies,
replyDisplayState,
slug,
postReplyToComment,
deleteComment,
updateComment,
onChangeComment,
}) => (
<div className="fullComment">
<div className="card commectCard">
<div className="card-header commentHeader">
<div className="authorDataContainer">
{author.image ? (
<img
className="imagePlaceholder"
src={author.image}
alt="Commenter"
/>
) : (
<div className="imagePlaceholder" />
)}
<div className="authorData">
<b>{author.username}</b>
<div className="text-muted commentDate">
{moment(createdAt.slice(0, 10)).format('LL')}
</div>
</div>
</div>
<div className="dropdown commentMenu">
<button
className="btn dropdown-toggle"
type="button"
id="dropdownMenuButton"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="false"
/>
<div className="dropdown-menu" aria-labelledby="dropdownMenuButton">
<button
type="button"
className="dropdown-item"
data-toggle="modal"
data-target="#exampleModalCenter"
>
Edit
</button>
<button
id="deleteButton"
type="button"
className="dropdown-item"
onClick={() => deleteComment(slug, id)}
>
Delete
</button>
</div>
</div>
</div>
<div className="card-body">
{body}
</div>
<div className="card-footer text-muted commentFooter">
<div className="replyComment">
{replies.length === 0
? <span className="replyButton" onClick={() => showReplies(id)}>Reply</span>
: replies.length === 1
? <span className="replyButton" onClick={() => showReplies(id)}> 1 Reply</span>
: (
<span className="replyButton" onClick={() => showReplies(id)}>
{replies.length}
{' '}
Replies
</span>
)}
</div>
</div>
</div>
{replyDisplayState[`repliesDisplayState${id}`]
? (
<div>
{replies.map(reply => <CommentReplies key={reply.id} reply={reply} slug={slug} id={id} deleteComment={deleteComment} updateComment={updateComment} onChangeComment={onChangeComment} />)}
<ReplyToComment commentId={id} slug={slug} postReplyToComment={postReplyToComment} />
</div>
)
: <div />}
<EditCommentDialog comment={body} updateComment={updateComment} onChangeComment={onChangeComment} id={id} />
</div>
);

export default Comment;
8 changes: 8 additions & 0 deletions src/components/CommentReplies/CommentReplies.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@import '../../assets/scss/shared.scss';

.commentDate {
font-size: rem(12);
}
.replyCard-header {
background-color: transparent;
}
22 changes: 22 additions & 0 deletions src/components/CommentReplies/CommentReplies.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from 'react';
import renderer from 'react-test-renderer';
import { shallow } from 'enzyme';
import CommentReplies from './index';

test('CommentReplies snapshot test', () => {
const props = {
reply: {
id: 1,
body: 'Hi',
author: 'Rogha',
createdAt: '12:35',
},
slug: 'comment-slug',
deleteComment: jest.fn(),
updateComment: jest.fn(),
onChangeComment: jest.fn(),
};
const wrapper = shallow(<CommentReplies {...props} />);
wrapper.find('#deleteButton').simulate('click');
expect(wrapper).toMatchSnapshot();
});
Loading

0 comments on commit 5e22619

Please sign in to comment.