diff --git a/src/AC/index.js b/src/AC/index.js
index 401b5b1..944d2c4 100644
--- a/src/AC/index.js
+++ b/src/AC/index.js
@@ -1,6 +1,6 @@
import {
INCREMENT, DELETE_ARTICLE, CHANGE_DATE_RANGE, CHANGE_SELECTION, ADD_COMMENT, LOAD_ALL_ARTICLES, LOAD_ARTICLE,
- START, SUCCESS, FAIL
+ START, SUCCESS, FAIL, LOAD_ALL_COMMENTS
} from '../constants'
export function increment() {
@@ -74,4 +74,11 @@ export function loadArticleById(id) {
}))
}, 1000)
}
-}
\ No newline at end of file
+}
+
+export function loadCommentsByArticle(article) {
+ return {
+ type: LOAD_ALL_COMMENTS,
+ callAPI: `/api/comment?article=${article}`
+ }
+}
diff --git a/src/components/comment-form/index.js b/src/components/comment-form/index.js
index e5a795b..672881b 100644
--- a/src/components/comment-form/index.js
+++ b/src/components/comment-form/index.js
@@ -63,4 +63,4 @@ const limits = {
export default connect(null, (dispatch, ownProps) => ({
addComment: (comment) => dispatch(addComment(comment, ownProps.articleId))
-}))(CommentForm)
\ No newline at end of file
+}))(CommentForm)
diff --git a/src/components/comment-list/index.js b/src/components/comment-list/index.js
index 173cb68..3721820 100644
--- a/src/components/comment-list/index.js
+++ b/src/components/comment-list/index.js
@@ -1,9 +1,13 @@
import React, {Component} from 'react'
import PropTypes from 'prop-types'
+import { connect } from 'react-redux'
import CSSTransition from 'react-addons-css-transition-group'
import Comment from '../comment'
import CommentForm from '../comment-form'
import toggleOpen from '../../decorators/toggleOpen'
+import { loadCommentsByArticle } from '../../AC'
+import { createCommentSelector, loadingCommentsSelector, loadedCommentsSelector } from '../../selectors'
+import Loader from '../loader'
import './style.css'
class CommentList extends Component {
@@ -18,6 +22,10 @@ class CommentList extends Component {
toggleOpen: PropTypes.func
}
+ componentWillReceiveProps({ isOpen }) {
+ if (!this.props.isOpen && isOpen) this.props.loadCommentsByArticle(this.props.article.id)
+ }
+
render() {
const {isOpen, toggleOpen} = this.props
const text = isOpen ? 'hide comments' : 'show comments'
@@ -36,19 +44,25 @@ class CommentList extends Component {
}
getBody() {
- const {article: { comments, id }, isOpen} = this.props
+ const {article: { comments, id }, isOpen, loading, loaded} = this.props
if (!isOpen) return null
+ if (loading){
+ return
+ }
+ if (loaded) {
+ return (
+
+ {
+ comments.length
+ ? this.getComments()
+ :
No comments yet
+ }
+
+
+ )
+ }
- return (
-
- {
- comments.length
- ? this.getComments()
- :
No comments yet
- }
-
-
- )
+ return error
}
getComments() {
@@ -65,5 +79,15 @@ class CommentList extends Component {
}
}
+const mapStateToProps = state => {
+ return {
+ loading: loadingCommentsSelector(state),
+ loaded: loadedCommentsSelector(state)
+ }
+}
+
+const mapDispatchToProps = {
+ loadCommentsByArticle
+}
-export default toggleOpen(CommentList)
\ No newline at end of file
+export default connect(mapStateToProps, mapDispatchToProps)(toggleOpen(CommentList))
diff --git a/src/components/comment.js b/src/components/comment.js
index dba04b4..04730b6 100644
--- a/src/components/comment.js
+++ b/src/components/comment.js
@@ -3,7 +3,8 @@ import PropTypes from 'prop-types'
import { connect } from 'react-redux'
import { createCommentSelector } from '../selectors'
-function Comment({comment}) {
+function Comment(props) {
+ const { comment } = props;
return (
{comment.text} by {comment.user}
@@ -18,6 +19,10 @@ Comment.propTypes = {
}).isRequired
}
+Comment.defaultProps = {
+ comment: {},
+}
+
const createMapStateToProps = () => {
const commentSelector = createCommentSelector()
@@ -26,4 +31,4 @@ const createMapStateToProps = () => {
})
}
-export default connect(createMapStateToProps)(Comment)
\ No newline at end of file
+export default connect(createMapStateToProps)(Comment)
diff --git a/src/constants/index.js b/src/constants/index.js
index f34f842..c1e13ce 100644
--- a/src/constants/index.js
+++ b/src/constants/index.js
@@ -8,7 +8,8 @@ export const CHANGE_SELECTION = 'CHANGE_SELECTION'
export const CHANGE_DATE_RANGE = 'CHANGE_DATE_RANGE'
export const ADD_COMMENT = 'ADD_COMMENT'
+export const LOAD_ALL_COMMENTS = 'LOAD_ALL_COMMENTS'
export const START = '_START'
export const SUCCESS = '_SUCCESS'
-export const FAIL = '_FAIL'
\ No newline at end of file
+export const FAIL = '_FAIL'
diff --git a/src/fixtures.js b/src/fixtures.js
index 97eed41..0cc8aa1 100644
--- a/src/fixtures.js
+++ b/src/fixtures.js
@@ -269,4 +269,4 @@ export default [
"text": "Commodo laborum sit nostrud reprehenderit cupidatat officia laboris. Ipsum minim culpa in enim. Voluptate dolor ea irure nisi incididunt enim magna.\n\nCupidatat quis cillum velit culpa tempor esse irure nostrud ea consectetur officia fugiat irure qui. Enim quis officia do in. Velit veniam ipsum consequat aliqua duis voluptate. Minim nisi ex aute ad.\n\nNisi Lorem ex tempor adipisicing labore. Quis occaecat fugiat pariatur labore culpa cillum laboris. Labore occaecat ut laborum sit ex do sit. Deserunt consectetur elit aute laboris est deserunt officia ullamco sit laboris officia aliquip. Aliqua ut sunt nostrud voluptate excepteur quis incididunt Lorem ut."
}
-]
\ No newline at end of file
+]
diff --git a/src/reducer/articles.js b/src/reducer/articles.js
index 26166cc..b4e900e 100644
--- a/src/reducer/articles.js
+++ b/src/reducer/articles.js
@@ -50,4 +50,4 @@ export default (articles = new ReducerState(), action) => {
default:
return articles
}
-}
\ No newline at end of file
+}
diff --git a/src/reducer/comments.js b/src/reducer/comments.js
index 9f32503..4e1d1ba 100644
--- a/src/reducer/comments.js
+++ b/src/reducer/comments.js
@@ -1,18 +1,42 @@
-import { ADD_COMMENT } from '../constants'
+import { ADD_COMMENT, START, SUCCESS, FAIL, LOAD_ALL_COMMENTS } from '../constants'
import {normalizedComments} from '../fixtures'
import {arrToMap} from './utils'
+import { Record } from 'immutable'
-export default (state = arrToMap(normalizedComments), action) => {
- const { type, payload, randomId } = action
+const CommentRecord = Record({
+ id: null,
+ user: null,
+ text: null,
+})
+
+const ReducerState = Record({
+ entities: arrToMap([], CommentRecord),
+ loading: false,
+ loaded: false,
+ error: null
+})
+
+export default (comments = new ReducerState(), action) => {
+ const { type, payload, randomId, response } = action
switch (type) {
case ADD_COMMENT:
- return state.set(randomId, {
+ return comments.set(randomId, {
...payload.comment,
id: randomId
})
+ case LOAD_ALL_COMMENTS + START:
+ if (comments.loaded) return comments
+ return comments.set('loading', true)
+
+ case LOAD_ALL_COMMENTS + SUCCESS:
+ return comments
+ .set('entities', arrToMap(response, CommentRecord))
+ .set('loading', false)
+ .set('loaded', true)
+
default:
- return state
+ return comments
}
-}
\ No newline at end of file
+}
diff --git a/src/selectors/index.js b/src/selectors/index.js
index 0f58db6..e61da89 100644
--- a/src/selectors/index.js
+++ b/src/selectors/index.js
@@ -4,7 +4,11 @@ export const articlesMapSelector = state => state.articles.entities
export const articleListSelector = createSelector(articlesMapSelector, articlesMap => articlesMap.valueSeq().toArray())
export const loadingArticlesSelector = state => state.articles.loading
-const commentsSelector = state => state.comments
+const commentsMapSelector = state => state.comments.entities
+export const loadingCommentsSelector = state => state.comments.loading
+export const loadedCommentsSelector = state => state.comments.loaded
+
+
const filtersSelector = state => state.filters
const idSelector = (_, props) => props.id
@@ -19,4 +23,4 @@ export const filtratedArticles = createSelector(articleListSelector, filtersSele
})
})
-export const createCommentSelector = () => createSelector(commentsSelector, idSelector, (comments, id) => comments.get(id))
\ No newline at end of file
+export const createCommentSelector = () => createSelector(commentsMapSelector, idSelector, (comments, id) => comments.get(id))