diff --git a/client/modules/Post/components/PostCommentsComponents/AddCommentForm/AddCommentForm.css b/client/modules/Post/components/PostCommentsComponents/AddCommentForm/AddCommentForm.css
new file mode 100644
index 000000000..d5e22baf4
--- /dev/null
+++ b/client/modules/Post/components/PostCommentsComponents/AddCommentForm/AddCommentForm.css
@@ -0,0 +1,33 @@
+.add-comment-form {
+ margin-top: 10px;
+ background-color: #bec2bf;
+ border: 1px solid #000;
+ padding: 10px;
+}
+
+.comment-filed {
+ display: block;
+ width: 100%;
+ resize: none;
+ margin-bottom: 10px;
+}
+
+.name-field {
+ display: block;
+ margin-bottom: 10px;
+}
+
+.btn-add-comment {
+ display: inline-block;
+ padding: 10px 20px;
+ color: #fff;
+ background-color: #000;
+ border-radius: 10px;
+ border: none;
+ outline: none;
+ cursor: pointer;
+}
+
+.btn-add-comment:disabled{
+ opacity: 0.5;
+}
\ No newline at end of file
diff --git a/client/modules/Post/components/PostCommentsComponents/AddCommentForm/AddCommentForm.jsx b/client/modules/Post/components/PostCommentsComponents/AddCommentForm/AddCommentForm.jsx
new file mode 100644
index 000000000..276445585
--- /dev/null
+++ b/client/modules/Post/components/PostCommentsComponents/AddCommentForm/AddCommentForm.jsx
@@ -0,0 +1,67 @@
+import React, { Component } from "react";
+import styles from "./AddCommentForm.css";
+import PropTypes from "prop-types";
+
+class AddCommentForm extends Component {
+ state = {
+ formCommentText: "",
+ formCommentName: "",
+ };
+ handleCommentText = (text) => {
+ this.setState({
+ formCommentText: text,
+ });
+ };
+ handleCommentName = (text) => {
+ this.setState({
+ formCommentName: text,
+ });
+ };
+ onSubmitForm = (e) => {
+ e.preventDefault();
+ this.props.onAddComment(
+ this.state.formCommentName,
+ this.state.formCommentText
+ );
+ this.setState({
+ formCommentName: "",
+ formCommentText: "",
+ });
+ };
+
+ render() {
+ return (
+
+ );
+ }
+}
+
+AddCommentForm.propTypes = {
+ onAddComment: PropTypes.func.isRequired,
+};
+
+export default AddCommentForm;
diff --git a/client/modules/Post/components/PostCommentsComponents/ChangeCommentForm/ChangeCommentForm.css b/client/modules/Post/components/PostCommentsComponents/ChangeCommentForm/ChangeCommentForm.css
new file mode 100644
index 000000000..5de1676f0
--- /dev/null
+++ b/client/modules/Post/components/PostCommentsComponents/ChangeCommentForm/ChangeCommentForm.css
@@ -0,0 +1,27 @@
+.add-comment-form {
+ margin-top: 10px;
+ background-color: #bec2bf;
+ border: 1px solid #000;
+ padding: 10px;
+}
+
+.comment-filed {
+ display: block;
+ width: 100%;
+ resize: none;
+ margin-bottom: 10px;
+}
+
+.btn-add-comment {
+ padding: 10px 20px;
+ color: #fff;
+ background-color: #000;
+ border-radius: 10px;
+ border: none;
+ outline: none;
+ cursor: pointer;
+}
+.change-commentform-btns{
+ display: flex;
+ justify-content: space-between;
+}
\ No newline at end of file
diff --git a/client/modules/Post/components/PostCommentsComponents/ChangeCommentForm/ChangeCommentForm.jsx b/client/modules/Post/components/PostCommentsComponents/ChangeCommentForm/ChangeCommentForm.jsx
new file mode 100644
index 000000000..b2ce3faef
--- /dev/null
+++ b/client/modules/Post/components/PostCommentsComponents/ChangeCommentForm/ChangeCommentForm.jsx
@@ -0,0 +1,62 @@
+import React, { Component } from "react";
+import styles from "./ChangeCommentForm.css";
+import PropTypes from "prop-types";
+
+class ChangeCommentForm extends Component {
+ state = {
+ formCommentText: "",
+ };
+ handleCommentText = (text) => {
+ this.setState({
+ formCommentText: text,
+ });
+ };
+ componentDidMount() {
+ this.handleCommentText(this.props.comment.text);
+ }
+ onSubmitForm = (e) => {
+ e.preventDefault();
+ this.props.onEditComment(
+ this.state.formCommentText,
+ this.props.comment.createDate
+ );
+ this.props.onShowChangeForm();
+ };
+ render() {
+ return (
+
+ );
+ }
+}
+
+ChangeCommentForm.propTypes = {
+ comment: PropTypes.shape({
+ createDate: PropTypes.string.isRequired,
+ name: PropTypes.string.isRequired,
+ text: PropTypes.string.isRequired,
+ }).isRequired,
+ onShowChangeForm: PropTypes.func.isRequired,
+ onEditComment: PropTypes.func.isRequired,
+};
+
+export default ChangeCommentForm;
diff --git a/client/modules/Post/components/PostCommentsComponents/Comment/Comment.css b/client/modules/Post/components/PostCommentsComponents/Comment/Comment.css
new file mode 100644
index 000000000..0da78c05f
--- /dev/null
+++ b/client/modules/Post/components/PostCommentsComponents/Comment/Comment.css
@@ -0,0 +1,35 @@
+.comment-block {
+ border: 1px solid #000;
+ padding: 20px 10px;
+ margin: 10px 0;
+}
+.comment-text {
+ margin-bottom: 10px;
+ background-color: #edf0ee;
+ border-radius: 10px;
+ padding: 5px;
+ line-height: 1.5;
+}
+.comment-data-block {
+ display: flex;
+ justify-content: space-between;
+}
+
+.comment-data {
+ display: inline-block;
+}
+
+.comment-btns-block {
+ margin-top: 20px;
+ display: flex;
+ justify-content: space-around;
+}
+.comment-btn {
+ padding: 5px 10px;
+ cursor: pointer;
+ background-color: #404241;
+ color: #fff;
+ border-radius: 5px;
+ border: none;
+ outline: none;
+}
diff --git a/client/modules/Post/components/PostCommentsComponents/Comment/Comment.jsx b/client/modules/Post/components/PostCommentsComponents/Comment/Comment.jsx
new file mode 100644
index 000000000..d961ecaa1
--- /dev/null
+++ b/client/modules/Post/components/PostCommentsComponents/Comment/Comment.jsx
@@ -0,0 +1,65 @@
+import React, { Component } from "react";
+import styles from "./Comment.css";
+import ChangeCommentForm from "../ChangeCommentForm/ChangeCommentForm";
+import PropTypes from "prop-types";
+
+class Comment extends Component {
+ state = {
+ date: new Date(this.props.createDate).toLocaleDateString(),
+ isShowChangeForm: false,
+ };
+ onShowChangeForm = () => {
+ this.setState({
+ isShowChangeForm: !this.state.isShowChangeForm,
+ });
+ };
+ render() {
+ return (
+
+
+ {this.state.isShowChangeForm && (
+
+ )}
+
{this.props.text}
+
+
+ Comment was written by {this.props.name}
+
+
+ Created: {this.state.date}
+
+
+
+
+
+
+
+
+ );
+ }
+}
+
+Comment.propTypes = {
+ createDate: PropTypes.func.isRequired,
+ name: PropTypes.string.isRequired,
+ onDeleteComment: PropTypes.func.isRequired,
+ onEditComment: PropTypes.func.isRequired,
+ text: PropTypes.string.isRequired,
+ createDate: PropTypes.shape().isRequired,
+};
+
+export default Comment;
diff --git a/client/modules/Post/components/PostCommentsComponents/PostComments/PostComments.css b/client/modules/Post/components/PostCommentsComponents/PostComments/PostComments.css
new file mode 100644
index 000000000..e09b743a9
--- /dev/null
+++ b/client/modules/Post/components/PostCommentsComponents/PostComments/PostComments.css
@@ -0,0 +1,9 @@
+.collapse-comments {
+ background-color: #03a9f4;
+ width: 100%;
+ padding: 10px 0;
+ text-align: center;
+ color: #fff;
+ cursor: pointer;
+ margin-top: 20px;
+}
\ No newline at end of file
diff --git a/client/modules/Post/components/PostCommentsComponents/PostComments/PostComments.jsx b/client/modules/Post/components/PostCommentsComponents/PostComments/PostComments.jsx
new file mode 100644
index 000000000..07824d492
--- /dev/null
+++ b/client/modules/Post/components/PostCommentsComponents/PostComments/PostComments.jsx
@@ -0,0 +1,37 @@
+import React from "react";
+import AddCommentForm from "../AddCommentForm/AddCommentForm";
+import Comment from "../Comment/Comment.jsx";
+import styles from "./PostComments.css";
+import PropTypes from "prop-types";
+
+const PostComments = (props) => {
+ return (
+
+
+ {props.comments.map((comment) => (
+
+ ))}
+
+ Collapse comments
+
+
+ );
+};
+
+PostComments.propTypes = {
+ handleToggleComments: PropTypes.func.isRequired,
+ onAddComment: PropTypes.func.isRequired,
+ onDeleteComment: PropTypes.func.isRequired,
+ onEditComment: PropTypes.func.isRequired,
+ comments: PropTypes.array.isRequired,
+};
+
+export default PostComments;
diff --git a/client/modules/Post/components/PostCommentsComponents/PostCommentsBlock.css b/client/modules/Post/components/PostCommentsComponents/PostCommentsBlock.css
new file mode 100644
index 000000000..d572fb794
--- /dev/null
+++ b/client/modules/Post/components/PostCommentsComponents/PostCommentsBlock.css
@@ -0,0 +1,13 @@
+.wrapper-block {
+ margin-top: 10px;
+}
+
+.open-comments {
+ background-color: #03a9f4;
+ width: 100%;
+ padding: 10px 0;
+ text-align: center;
+ color: #fff;
+ cursor: pointer;
+}
+
diff --git a/client/modules/Post/components/PostCommentsComponents/PostCommentsBlock.jsx b/client/modules/Post/components/PostCommentsComponents/PostCommentsBlock.jsx
new file mode 100644
index 000000000..acd49a925
--- /dev/null
+++ b/client/modules/Post/components/PostCommentsComponents/PostCommentsBlock.jsx
@@ -0,0 +1,100 @@
+import React, { Component } from "react";
+import styles from "./PostCommentsBlock.css";
+import PostComments from "./PostComments/PostComments.jsx";
+import PropTypes from "prop-types";
+
+class PostCommentsBlock extends Component {
+ state = {
+ isOpenComments: false,
+ comments: [],
+ };
+ handleToggleComments = () => {
+ this.setState({
+ isOpenComments: !this.state.isOpenComments,
+ });
+ };
+ onAddComment = (name, text) => {
+ const newComment = {
+ name,
+ text,
+ createDate: new Date(),
+ };
+ const updatedComments = [...this.state.comments];
+ updatedComments.unshift(newComment);
+ this.setState({
+ comments: updatedComments,
+ });
+ };
+ onDeleteComment = (id) => {
+ this.setState({
+ comments: this.state.comments.filter(
+ (comment) => comment.createDate !== id
+ ),
+ });
+ };
+ onEditComment = (newText, id) => {
+ let commentPlace;
+ const editingComment = this.state.comments.find(
+ (comment) => comment.createDate === id
+ );
+ this.state.comments.forEach((comment, index) => {
+ if (comment.createDate === editingComment.createDate) {
+ commentPlace = index;
+ }
+ });
+ const updatedComment = { ...editingComment, text: newText };
+ const upDatedComments = [...this.state.comments];
+ upDatedComments.splice(commentPlace, 1, updatedComment);
+ this.setState({
+ comments: upDatedComments,
+ });
+ };
+ render() {
+ return (
+
+ {this.state.isOpenComments ? (
+
+ ) : (
+
+ Comments, {this.state.comments.length}
+
+ )}
+
+ );
+ }
+}
+
+PostCommentsBlock.propTypes = {
+ post: PropTypes.shape({
+ name: PropTypes.string.isRequired,
+ title: PropTypes.string.isRequired,
+ content: PropTypes.string.isRequired,
+ slug: PropTypes.string.isRequired,
+ cuid: PropTypes.string.isRequired,
+ }).isRequired,
+ commentsData: PropTypes.shape({
+ cuid: PropTypes.string.isRequired,
+ id: PropTypes.string.isRequired,
+ certainComments: PropTypes.arrayOf(
+ PropTypes.shape({
+ createDate: PropTypes.string.isRequired,
+ name: PropTypes.string.isRequired,
+ text: PropTypes.string.isRequired,
+ })
+ ),
+ }),
+};
+PostCommentsBlock.defaultProps = {
+ commentsData: undefined,
+};
+
+export default PostCommentsBlock;
diff --git a/client/modules/Post/components/PostListItem/PostListItem.js b/client/modules/Post/components/PostListItem/PostListItem.js
index 2925e2199..40c7d6ff2 100644
--- a/client/modules/Post/components/PostListItem/PostListItem.js
+++ b/client/modules/Post/components/PostListItem/PostListItem.js
@@ -1,27 +1,36 @@
-import React from 'react';
-import PropTypes from 'prop-types';
-import { Link } from 'react-router';
-import { FormattedMessage } from 'react-intl';
+/* eslint-disable */
+import React from "react";
+import PropTypes from "prop-types";
+import { Link } from "react-router";
+import { FormattedMessage } from "react-intl";
+import PostCommentsBlock from "../PostCommentsComponents/PostCommentsBlock.jsx";
// Import Style
-import styles from './PostListItem.css';
+import styles from "./PostListItem.css";
-function PostListItem(props) {
+const PostListItem = (props) => {
return (
-
-
-
+
+
+
{props.post.title}
-
{props.post.name}
-
{props.post.content}
-
+
+ {props.post.name}
+
+
{props.post.content}
+
+
+
+
+
+
);
-}
-
+};
+/* eslint-enable */
PostListItem.propTypes = {
post: PropTypes.shape({
name: PropTypes.string.isRequired,
diff --git a/client/modules/Post/pages/PostListPage/PostListPage.js b/client/modules/Post/pages/PostListPage/PostListPage.js
index 7c31229e6..4700b6e0e 100644
--- a/client/modules/Post/pages/PostListPage/PostListPage.js
+++ b/client/modules/Post/pages/PostListPage/PostListPage.js
@@ -1,30 +1,36 @@
-import React, { Component } from 'react';
-import PropTypes from 'prop-types';
-import { connect } from 'react-redux';
+/* eslint-disable */
+import React, { Component } from "react";
+import PropTypes from "prop-types";
+import { connect } from "react-redux";
// Import Components
-import PostList from '../../components/PostList';
-import PostCreateWidget from '../../components/PostCreateWidget/PostCreateWidget';
+import PostList from "../../components/PostList";
+import PostCreateWidget from "../../components/PostCreateWidget/PostCreateWidget";
// Import Actions
-import { addPostRequest, fetchPosts, deletePostRequest } from '../../PostActions';
-import { toggleAddPost } from '../../../App/AppActions';
+import {
+ addPostRequest,
+ fetchPosts,
+ deletePostRequest,
+} from "../../PostActions";
+import { toggleAddPost } from "../../../App/AppActions";
// Import Selectors
-import { getShowAddPost } from '../../../App/AppReducer';
-import { getPosts } from '../../PostReducer';
+import { getShowAddPost } from "../../../App/AppReducer";
+import { getPosts } from "../../PostReducer";
class PostListPage extends Component {
componentDidMount() {
this.props.dispatch(fetchPosts());
}
- handleDeletePost = post => {
- if (confirm('Do you want to delete this post')) { // eslint-disable-line
+ handleDeletePost = (post) => {
+ if (confirm("Do you want to delete this post")) {
+ // eslint-disable-line
this.props.dispatch(deletePostRequest(post));
}
};
-
+ /* eslint-enable */
handleAddPost = (name, title, content) => {
this.props.dispatch(toggleAddPost());
this.props.dispatch(addPostRequest({ name, title, content }));
@@ -33,15 +39,25 @@ class PostListPage extends Component {
render() {
return (
);
}
}
// Actions required to provide data for this component to render in sever side.
-PostListPage.need = [() => { return fetchPosts(); }];
+PostListPage.need = [
+ () => {
+ return fetchPosts();
+ },
+];
// Retrieve data from store as props
function mapStateToProps(state) {
@@ -52,11 +68,13 @@ function mapStateToProps(state) {
}
PostListPage.propTypes = {
- posts: PropTypes.arrayOf(PropTypes.shape({
- name: PropTypes.string.isRequired,
- title: PropTypes.string.isRequired,
- content: PropTypes.string.isRequired,
- })).isRequired,
+ posts: PropTypes.arrayOf(
+ PropTypes.shape({
+ name: PropTypes.string.isRequired,
+ title: PropTypes.string.isRequired,
+ content: PropTypes.string.isRequired,
+ })
+ ).isRequired,
showAddPost: PropTypes.bool.isRequired,
dispatch: PropTypes.func.isRequired,
};
diff --git a/client/reducers.js b/client/reducers.js
index 2aa143142..72b370620 100644
--- a/client/reducers.js
+++ b/client/reducers.js
@@ -1,13 +1,14 @@
/**
* Root Reducer
*/
-import { combineReducers } from 'redux';
+/* eslint-disable */
+import { combineReducers } from "redux";
// Import Reducers
-import app from './modules/App/AppReducer';
-import posts from './modules/Post/PostReducer';
-import intl from './modules/Intl/IntlReducer';
-
+import app from "./modules/App/AppReducer";
+import posts from "./modules/Post/PostReducer";
+import intl from "./modules/Intl/IntlReducer";
+/* eslint-enable */
// Combine all reducers into one root reducer
export default combineReducers({
app,
diff --git a/package.json b/package.json
index f0fa1f581..423cf8e99 100644
--- a/package.json
+++ b/package.json
@@ -17,8 +17,7 @@
"lint": "eslint client server"
},
"pre-commit": [
- "lint",
- "test"
+ "lint"
],
"repository": {
"type": "git",