diff --git a/src/AC/index.js b/src/AC/index.js
index d3d7bdb..50f910b 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,
- LOAD_ARTICLE_COMMENTS, START, SUCCESS, FAIL
+ LOAD_ARTICLE_COMMENTS, START, SUCCESS, FAIL, LOAD_ALL_COMMENTS
} from '../constants'
export function increment() {
@@ -82,4 +82,29 @@ export function loadArticleComments(articleId) {
payload: { articleId },
callAPI: `/api/comment?article=${articleId}`
}
-}
\ No newline at end of file
+}
+
+export function loadAllcomments(offset, page) {
+ return (dispatch, getState) => {
+ const pageLoaded = getState().comments.loadedPages.has(page)
+ if (!pageLoaded) {
+ dispatch({
+ type: LOAD_ALL_COMMENTS + START,
+ })
+
+ setTimeout(() => {
+ fetch(`/api/comment?limit=5&offset=${offset}`)
+ .then(res => res.json())
+ .then(response => dispatch({
+ type: LOAD_ALL_COMMENTS + SUCCESS,
+ payload: { page },
+ response
+ }))
+ .catch(error => dispatch({
+ type: LOAD_ALL_COMMENTS + FAIL,
+ payload: { page, error }
+ }))
+ }, 1000)
+ }
+ }
+}
diff --git a/src/App.js b/src/App.js
index e7c257c..e86b2c7 100644
--- a/src/App.js
+++ b/src/App.js
@@ -5,6 +5,7 @@ import ArticlesPage from './components/routes/articles'
import UserForm from './components/user-form'
import Filters from './components/filters'
import Counter from './components/counter'
+import AllComments from './components/AllComments'
import 'react-select/dist/react-select.css'
class App extends Component {
@@ -19,8 +20,10 @@ class App extends Component {
counter
filters
articles
+ comments
+
New Article Form
} />
@@ -32,4 +35,4 @@ class App extends Component {
}
}
-export default App
\ No newline at end of file
+export default App
diff --git a/src/components/AllComments/CommentsPage.js b/src/components/AllComments/CommentsPage.js
new file mode 100644
index 0000000..93e1f45
--- /dev/null
+++ b/src/components/AllComments/CommentsPage.js
@@ -0,0 +1,58 @@
+import React from 'react'
+import PropTypes from 'prop-types'
+import { connect } from 'react-redux'
+import Comment from '../comment'
+import { commentsByPage, commentsLoading } from '../../selectors'
+import { loadAllcomments } from '../../AC'
+import Loader from '../loader'
+
+class CommentsPage extends React.Component {
+
+ componentWillReceiveProps(nextProps) {
+ if (nextProps.page !== this.props.page) {
+ const { comments } = this.props
+ this.props.loadAllcomments((nextProps.page - 1)*5, nextProps.page)
+ }
+ }
+
+ render() {
+ const { comments, loading } = this.props
+ return(
+
+ {loading ?
:
+
+ {
+ comments.map(id =>
+ -
+
+
)
+ }
+
+ }
+
+ )
+ }
+}
+
+CommentsPage.propTypes = {
+ comments: PropTypes.array,
+ loading: PropTypes.bool,
+ loadAllcomments: PropTypes.fun
+}
+
+CommentsPage.defaultProps = {
+ comments: [],
+}
+
+const mapStateToProps = (state, ownProps) => {
+ return {
+ comments: commentsByPage(state, ownProps),
+ loading: commentsLoading(state)
+ }
+}
+
+const mapDispatchToProps = {
+ loadAllcomments
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(CommentsPage)
diff --git a/src/components/AllComments/index.js b/src/components/AllComments/index.js
new file mode 100644
index 0000000..2d50da0
--- /dev/null
+++ b/src/components/AllComments/index.js
@@ -0,0 +1,58 @@
+import React from 'react'
+import { NavLink, Route } from 'react-router-dom'
+import PropTypes from 'prop-types'
+import { connect } from 'react-redux'
+import Comment from '../comment'
+import CommentsPage from './CommentsPage'
+import { loadAllcomments } from '../../AC'
+import { allCommentsSelector, totalComments } from '../../selectors'
+
+class AllComments extends React.Component {
+
+ componentDidMount() {
+ this.props.loadAllcomments(0, "1")
+ }
+
+ renderButtons = total => {
+ const count = new Array(Math.ceil(total / 5)).fill(null)
+ return count.map((_, index) => (
+
+
+
+ ))
+ }
+
+ render() {
+ const { total, match } = this.props
+ return(
+
+
+ {this.renderButtons(total)}
+
+ )
+ }
+
+ getCommentsPage = ({ match }) => {
+ if (!match) {
+ return
+ }
+ return
+ }
+}
+
+AllComments.propTypes = {
+ match: PropTypes.object,
+ total: PropTypes.number
+}
+
+const mapStateToProps = (state, ownProps) => {
+ return {
+ total: totalComments(state),
+ }
+}
+
+const mapDispatchToProps = {
+ loadAllcomments
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(AllComments)
diff --git a/src/constants/index.js b/src/constants/index.js
index c71387f..64d40c2 100644
--- a/src/constants/index.js
+++ b/src/constants/index.js
@@ -9,7 +9,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/middlewares/api.js b/src/middlewares/api.js
index 2386a76..0581553 100644
--- a/src/middlewares/api.js
+++ b/src/middlewares/api.js
@@ -8,7 +8,7 @@ export default store => next => action => {
type: type + START,
...rest
})
-
+
//REMOVE THIS!
setTimeout(() => {
fetch(callAPI)
@@ -16,4 +16,4 @@ export default store => next => action => {
.then(response => next({ ...rest, type: type + SUCCESS, response }))
.catch(error => next({ ...rest, type: type + FAIL, error }))
}, 1000)
-}
\ No newline at end of file
+}
diff --git a/src/reducer/comments.js b/src/reducer/comments.js
index 6586253..8a32b6e 100644
--- a/src/reducer/comments.js
+++ b/src/reducer/comments.js
@@ -1,4 +1,4 @@
-import { ADD_COMMENT, LOAD_ARTICLE_COMMENTS, SUCCESS } from '../constants'
+import { ADD_COMMENT, LOAD_ARTICLE_COMMENTS, SUCCESS, LOAD_ALL_COMMENTS, START } from '../constants'
import {Record, OrderedMap} from 'immutable'
import {arrToMap} from './utils'
@@ -9,7 +9,10 @@ const CommentRecord = Record({
})
const ReducerState = Record({
- entities: new OrderedMap({})
+ entities: new OrderedMap({}),
+ loadedPages: new OrderedMap({}),
+ total: null,
+ loading: false,
})
export default (state = new ReducerState(), action) => {
@@ -25,7 +28,17 @@ export default (state = new ReducerState(), action) => {
case LOAD_ARTICLE_COMMENTS + SUCCESS:
return state.mergeIn(['entities'], arrToMap(response, CommentRecord))
+ case LOAD_ALL_COMMENTS + START:
+ return state.updateIn(['loading'], value => true)
+
+ case LOAD_ALL_COMMENTS + SUCCESS:
+ const ids = response.records.map(comment => comment.id)
+ return state.mergeIn(['entities'], arrToMap(response.records, CommentRecord))
+ .mergeIn(['loadedPages'], new OrderedMap({[payload.page]: ids}))
+ .updateIn(['total'], value => response.total === value ? value : response.total )
+ .updateIn(['loading'], value => false)
+
default:
return state
}
-}
\ No newline at end of file
+}
diff --git a/src/reducer/utils.js b/src/reducer/utils.js
index e8c7c63..042c8ba 100644
--- a/src/reducer/utils.js
+++ b/src/reducer/utils.js
@@ -5,4 +5,4 @@ export function arrToMap(arr, DataRecord) {
acc.set(item.id, DataRecord ? new DataRecord(item) : item)
, new OrderedMap({})
)
-}
\ No newline at end of file
+}
diff --git a/src/selectors/index.js b/src/selectors/index.js
index 421e61a..58b7659 100644
--- a/src/selectors/index.js
+++ b/src/selectors/index.js
@@ -22,4 +22,13 @@ export const filtratedArticles = createSelector(articleListSelector, filtersSele
export const articleSelector = createSelector(articlesMapSelector, idSelector, (articles, id) => articles.get(id))
-export const createCommentSelector = () => createSelector(commentsSelector, idSelector, (comments, id) => comments.get(id))
\ No newline at end of file
+export const createCommentSelector = () => createSelector(commentsSelector, idSelector, (comments, id) => comments.get(id))
+
+const allCommentsSelector = state => state.comments.loadedPages.toJS()
+const getPage = (_, props) => props.page
+export const commentsByPage = createSelector(allCommentsSelector, getPage, (comments, page) => comments[page])
+
+const totalCommentsSelector = state => state.comments.total
+export const totalComments = createSelector(totalCommentsSelector, total => total)
+
+export const commentsLoading = state => state.comments.loading