Skip to content

Commit

Permalink
Merge pull request #29 from andela/ft-articles-pagination-165305229
Browse files Browse the repository at this point in the history
#165305229 Implement pagination support for articles
  • Loading branch information
AnguleMathias committed Jun 18, 2019
2 parents 1e75c09 + 2a384e9 commit 57a5396
Show file tree
Hide file tree
Showing 9 changed files with 199 additions and 41 deletions.
29 changes: 22 additions & 7 deletions src/assets/styles/articles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
height: 400px;
border: 1px solid $bordergray;
margin-bottom: 20px;
margin: 10px;
}

.flip-box-inner {
Expand All @@ -83,18 +84,18 @@
backface-visibility: hidden;
}

.flip-box-front {
background-color: $cardgray;
color: $black;
}

.flip-box-back {
overflow: hidden !important;
transform: rotateY(180deg);
}

.home-card {
height: 100% !important;
-ms-flex-direction: column;
flex-direction: column;
margin-right: 0px !important;
margin-bottom: 0 !important;
margin-left: 0px !important;
}

.homepage-card-image {
Expand All @@ -113,11 +114,12 @@
font-weight: 900;
}

.socialShare{
.socialShare {
margin-top: 1%;
text-align: right;

&-twitter, &-facebook {
&-twitter,
&-facebook {
height: 5%;
width: 5%;
margin-right: 1%;
Expand All @@ -127,3 +129,16 @@
width: 4.7%;
}
}
.pagination {
display: flex;
justify-content: center;
}

.page-link {
cursor: pointer;
}

.active-page {
color: white !important;
background-color: blue !important;
}
55 changes: 55 additions & 0 deletions src/components/articles/Pagination.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import React, { Component } from 'react';

class Pagination extends Component {
render() {
const {
handleLink, handleClick, pageNumbers, next, previous, currentPage,
} = this.props;
return (
<div className="pagination">
<nav aria-label="Page navigation">
<ul className="pagination">
{previous ? (
<li className="page-item">
<span
className="page-link"
id={previous}
onClick={handleLink}
aria-label="Previous"
>
<span aria-hidden="true">&laquo;</span>
<span className="sr-only">Previous</span>
</span>
</li>
) : null}

{pageNumbers.map((num, index) => (
<li key={index} className="page-item">
{currentPage === num ? (
<span id={num} className="page-link active-page" onClick={handleClick}>
{num}
</span>
) : (
<span id={num} className="page-link" onClick={handleClick}>
{num}
</span>
)}
</li>
))}

{next ? (
<li className="page-item">
<span className="page-link" id={next} onClick={handleLink} aria-label="Next">
<span aria-hidden="true">&raquo;</span>
<span className="sr-only">Next</span>
</span>
</li>
) : null}
</ul>
</nav>
</div>
);
}
}

export default Pagination;
8 changes: 4 additions & 4 deletions src/components/articles/TagsSearch.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import PropTypes from 'prop-types';
import '../../assets/styles/searchComponent.scss';

/*
* Tags search Component
* Display tags that contain keyword searched
*@return {jsx}
*/
* Tags search Component
* Display tags that contain keyword searched
*@return {jsx}
*/
class TagsSearch extends Component {
render() {
const { tag } = this.props;
Expand Down
1 change: 0 additions & 1 deletion src/components/comments/Comments.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ class Comments extends Component {
const { slug } = this.props;
const { isLoading, data } = this.props.myState;
const comments = data.Comments;
console.log(comments);

return (
<div>
Expand Down
8 changes: 3 additions & 5 deletions src/redux/actions/FetchArticlesActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import axios from 'axios';
import { FETCH_ARTICLES, DELETE_ARTICLE, BASE_URL } from '../constants';
import { successToast } from '../../helpers';


/*
*Defines the action types for successful all articles fetch
*/
Expand Down Expand Up @@ -64,16 +63,15 @@ export const deleteArticleFailure = error => ({
error,
});


/*
*Defines the fetchArticles actions and dispatches the right
*action for either success
*failure
*/
export const fetchArticles = () => dispatch => {
export const fetchArticles = url => dispatch => {
dispatch({ type: FETCH_ARTICLES });
return axios
.get(`${BASE_URL}/articles/`)
.get(url)
.then(response => {
dispatch(fetchSuccess(response));
})
Expand Down Expand Up @@ -105,7 +103,7 @@ export const fetchOneArticle = (slug, history) => dispatch => {
*action for either success
*failure
*/
export const fetchByAuthor = (author) => dispatch => {
export const fetchByAuthor = author => dispatch => {
dispatch({ type: FETCH_ARTICLES });
return axios
.get(`${BASE_URL}/article/search/?author=${author}`)
Expand Down
1 change: 1 addition & 0 deletions src/redux/constants/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ export const DELETE_ARTICLE = 'DELETE_ARTICLE';
export const CREATE_ARTICLE = 'CREATE_ARTICLE';
export const UPDATE_ARTICLE = 'UPDATE_ARTICLE';
export const GET_ONE_ARTICLE = 'GET_ONE_ARTICLE';
export const ARTICLES_URL = `${BASE_URL}/articles/`;
83 changes: 64 additions & 19 deletions src/views/AllArticles.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,44 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import moment from 'moment';
import { CardColumns } from 'react-bootstrap';
import { CardColumns, CardDeck } from 'react-bootstrap';
import { connect } from 'react-redux';
import parse from 'html-react-parser';
import { fetchArticles } from '../redux/actions/FetchArticlesActions';
import Article from '../components/articles/Article';
import { Loader } from '../components/layout/Loader';
import { ARTICLES_URL } from '../redux/constants';
import Pagination from '../components/articles/Pagination';

class AllArticles extends Component {
state = {
ArticlesPerPage: 9,
currentPage: '',
};

componentWillMount() {
const { fetchArticles: fetchAllArticles } = this.props;
fetchAllArticles();
this.setState({ currentPage: 1 });
fetchAllArticles(ARTICLES_URL);
}

handleClick = e => {
const { fetchArticles: fetchAllArticles } = this.props;
const id = Number(e.target.id);
fetchAllArticles(`${ARTICLES_URL}?page=${id}`);
this.setState({
currentPage: id,
});
};

handleLink = e => {
const { fetchArticles: fetchAllArticles } = this.props;
const url = e.target.id;
const id = url.substring(url.lastIndexOf('=') + 1);
this.setState({ currentPage: Number(id) });
fetchAllArticles(url);
};

render() {
const {
articles: { isLoading },
Expand All @@ -26,27 +51,47 @@ class AllArticles extends Component {
},
} = this.props;

const { results } = { ...data };
const {
results, previous, next, count,
} = { ...data };

const { ArticlesPerPage, currentPage } = this.state;

// Logic for displaying page numbers
const pageNumbers = [];
for (let i = 1; i <= Math.ceil(count / ArticlesPerPage); i++) {
pageNumbers.push(i);
}
return (
<div className="container">
<h1>Latest Articles</h1>
<CardColumns className="all-articles">
{results && results.map((values) => (
<Article
title={values.title}
key={values.id}
description={values.description}
readtime={values.readtime}
created_at={moment(values.created_at).format('MMMM Do YYYY')}
author={values.author.username}
image={values.image}
slug={values.slug}
read_count={values.read_count}
body={parse(values.body)}
/>
))}
</CardColumns>
<CardDeck>
{results
&& results.map(values => (
<Article
title={values.title}
key={values.id}
description={values.description}
readtime={values.readtime}
created_at={moment(values.created_at).format('MMMM Do YYYY')}
author={values.author.username}
image={values.image}
slug={values.slug}
read_count={values.read_count}
body={parse(values.body)}
/>
))}
</CardDeck>

<Pagination
handleLink={this.handleLink}
handleClick={this.handleClick}
pageNumbers={pageNumbers}
next={next}
previous={previous}
currentPage={currentPage}
/>

<hr />
</div>
);
Expand Down
10 changes: 5 additions & 5 deletions tests/FetchDeleteArticlesActions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
fetchByAuthor,
deleteArticle,
} from '../src/redux/actions/FetchArticlesActions';
import { FETCH_ARTICLES, DELETE_ARTICLE } from '../src/redux/constants';
import { FETCH_ARTICLES, DELETE_ARTICLE, ARTICLES_URL } from '../src/redux/constants';

/*
* Defines tests for search action:
Expand Down Expand Up @@ -49,6 +49,8 @@ const middlewares = [thunk];

const mockStore = configureMockStore(middlewares);

const url = ARTICLES_URL;

describe('test get all articles actions', () => {
beforeEach(() => {
moxios.install();
Expand Down Expand Up @@ -76,7 +78,7 @@ describe('test get all articles actions', () => {
const store = mockStore({});

return store
.dispatch(fetchArticles())
.dispatch(fetchArticles(url))
.then(() => {
expect(store.getActions()[1].type).toEqual(expectedActions[1].type);
})
Expand All @@ -102,12 +104,11 @@ describe('test get all articles actions', () => {

const store = mockStore({});

return store.dispatch(fetchArticles()).catch(() => {
return store.dispatch(fetchArticles(url)).catch(() => {
expect(error.response.data).toEqual(expectedActions.type);
});
});


it('tests for successful get one action', () => {
const { response } = mockData;
moxios.wait(() => {
Expand Down Expand Up @@ -158,7 +159,6 @@ describe('test get all articles actions', () => {
});
});


it('tests for successful get author articles', () => {
const { response } = mockData;
moxios.wait(() => {
Expand Down
45 changes: 45 additions & 0 deletions tests/Pagination.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from 'react';
import { shallow, mount } from 'enzyme';
import { BrowserRouter } from 'react-router-dom';
import { Provider } from 'react-redux';
import store from '../src/redux/store';
import Pagination from '../src/components/articles/Pagination';

describe('should mount Pagination component when it is called', () => {
it('tests for successful mount of pagination', () => {
const props = {
handleLink: jest.fn(),
handleClick: jest.fn(),
pageNumbers: [],
next: '',
previous: '',
currentPage: 1,
};
const wrapper = mount(
<BrowserRouter>
<Provider store={store}>
<Pagination {...props} />
</Provider>
</BrowserRouter>,
);
});

it('renders Pagination component', () => {
const props = {
handleLink: jest.fn(),
handleClick: jest.fn(),
pageNumbers: [],
next: '',
previous: 'a',
currentPage: 1,
};
const event = {
preventDefault() {},
target: { value: 'the-value' },
};
const wrapper = shallow(<Pagination {...props} />);

wrapper.find('.page-link').simulate('click', event);
expect(props.handleLink).toHaveBeenCalled();
});
});

0 comments on commit 57a5396

Please sign in to comment.