Skip to content

Commit

Permalink
Merge afd0a39 into c03e59b
Browse files Browse the repository at this point in the history
  • Loading branch information
Gilles Kagarama committed Jul 29, 2019
2 parents c03e59b + afd0a39 commit c60f4fa
Show file tree
Hide file tree
Showing 12 changed files with 211 additions and 52 deletions.
34 changes: 34 additions & 0 deletions src/__tests__/components/Articles/Pagination.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import React from 'react';
import { Provider } from 'react-redux';
import { MemoryRouter } from 'react-router-dom';
import { mockStore, initialState } from '../../../__mocks__/store';
import {
Pagination as PaginationComponent,
mapStateToProps
} from '../../../components/Articles/Pagination/Pagination';
import { shallow, mount } from '../../../../config/enzymeConfig';

describe('<Pagination />', () => {
const state = {
buttons: ['button'],
pageNumber: 1,
getAllArticles: jest.fn(),
displayButtons: jest.fn(),
paginateArticles: jest.fn()
};
const component = shallow(<PaginationComponent {...state} />);
it('should create <PaginationComponent /> snapshot ', () => {
expect(component).toMatchSnapshot();
});
it('should trigger submit button ', () => {
component.instance().displayButtons(40);
});
it('should trigger close message ', () => {
component.setProps({ limit: 1, offset: 10, label: 1 });
component
.find('.pagination button')
.at(0)
.simulate('click');
component.instance().paginateArticles({ limit: 1, offset: 10, label: 1 });
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<Pagination /> should create <PaginationComponent /> snapshot 1`] = `ShallowWrapper {}`;
4 changes: 2 additions & 2 deletions src/actions/articles/getAllArticles.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { articlesType } from '../../actions-types';
import { apiAction } from '../../helpers';

export const getAllArticles = () => dispatch => dispatch(apiAction({
export const getAllArticles = (offset, limit) => dispatch => dispatch(apiAction({
method: 'get',
url: '/articles',
url: `/articles?offset=${offset || 0}&limit=${limit || 10}`,
onStart: articlesType.FETCH_ARTICLES_START,
onEnd: articlesType.FETCH_ARTICLES_END,
onSuccess: articlesType.FETCH_ARTICLES_SUCCESS,
Expand Down
Binary file added src/assets/images/ARTICLE_PLACEHOLER.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified src/assets/images/logo_ah_small.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/welcome_cover.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
29 changes: 26 additions & 3 deletions src/components/Articles/ListOfArticles/ListOfArticles.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@ import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import 'dotenv/config';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faClock } from '@fortawesome/free-solid-svg-icons';
import PropTypes from 'prop-types';
import { getAllArticles } from '../../../actions';
import placeholder from '../../../assets/images/placeholder.png';
import timeStamp from '../../../helpers/timeStamp';
import imagePlaceholder from '../../../assets/images/ARTICLE_PLACEHOLER.png';
import { Img } from '../../common';
import './listOfArticles.scss';
import Pagination from '../Pagination';

const { REACT_APP_IMAGE_BASE_URL } = process.env;
export class ListsOfArticles extends Component {
Expand All @@ -22,7 +26,7 @@ export class ListsOfArticles extends Component {
}

render() {
const { articles } = this.props;
const { articles, loading } = this.props;
const { imageRectangle } = this.state;
return (
<div className="row" id="articleCard">
Expand Down Expand Up @@ -60,16 +64,35 @@ export class ListsOfArticles extends Component {
</div>
))}
<div className="clear" />
{loading ? (
<Img
imgSrc={imagePlaceholder}
imgClass="center radius-1 loading-article"
alt="Loading article"
/>
) : ''}
<div className="clear" />

<div className="row pagination center-align">
<Pagination />
</div>
<div className="clear" />
</div>
);
}
}

ListsOfArticles.propTypes = {
articles: PropTypes.array,
getAllArticles: PropTypes.func.isRequired
getAllArticles: PropTypes.func.isRequired,
loading: PropTypes.bool,
errors: PropTypes.object
};
const mapStateToProps = ({ articles: { articles } }) => ({ articles });
const mapStateToProps = ({ articles: { articles, loading, errors } }) => ({
articles,
loading,
errors
});

export default connect(
mapStateToProps,
Expand Down
77 changes: 77 additions & 0 deletions src/components/Articles/Pagination/Pagination.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { getAllArticles } from '../../../actions';
import './Pagination.scss';

export class Pagination extends Component {
state = { buttons: [], pageNumber: 1, articlesCount: 0 };

displayButtons = (articlesCount) => {
const maxPerPage = 10;
const numberOfButtons = (articlesCount % maxPerPage) + articlesCount / maxPerPage;
let buttons = [];
for (let i = 1; i <= numberOfButtons; i += 1) {
buttons = [
...buttons,
{
offset: i === 1 ? 0 : i * 10 - 10,
limit: 10,
label: i
}
];
}
this.setState(prevState => ({ ...prevState, buttons }));
return buttons;
};

componentWillReceiveProps = (nextProps) => {
const { articlesCount } = nextProps;
return articlesCount && this.displayButtons(articlesCount);
};

componentDidMount = () => {
const { articlesCount } = this.props;
return articlesCount && this.displayButtons(articlesCount);
};

paginateArticles = ({ offset, limit, label }) => {
const { getAllArticles } = this.props;
this.setState(prevState => ({
...prevState,
pageNumber: label
}));
return getAllArticles(offset, limit);
};

render() {
const { buttons, pageNumber } = this.state;
return (
<div className="row">
<ul className="list-inline pagination">
{buttons.map((button, key) => (
<li key={key}>
<button
className={`${pageNumber === button.label ? 'yellow' : 'light bold'}`}
onClick={() => this.paginateArticles(button)}
>
{button.label}
</button>
</li>
))}
</ul>
</div>
);
}
}

Pagination.propTypes = {
articlesCount: PropTypes.any,
getAllArticles: PropTypes.func
};
export const mapStateToProps = ({ articles: { articlesCount } }) => ({ articlesCount });

export default connect(
mapStateToProps,
{ getAllArticles }
)(Pagination);
16 changes: 16 additions & 0 deletions src/components/Articles/Pagination/Pagination.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
@import '../../../assets/css/_colors';
@import '../../../assets/css/_radius';

.pagination {
margin: 10px 0;
ul li {
background: none !important;
button {
padding: 8px 20px;
border: none;
margin-right: 5px;
cursor: pointer;
@extend .radius-4;
}
}
}
3 changes: 3 additions & 0 deletions src/components/Articles/Pagination/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Pagination from './Pagination';

export default Pagination;
88 changes: 44 additions & 44 deletions src/components/Bookmarks/Bookmarks.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,52 +46,52 @@ class Bookmarks extends Component {
<div className="large-margin">No bookmarks</div>
</div>
) : (
bookmarks.map((element, key) => (
<div key={key} className="row">
<Link to={`/articles/${element.articleSlug}`}>
<div className="small-screen-4 medium-screen-1 large-screen-1 ">
<div className="image">
<Img
imgSrc={`${REACT_APP_IMAGE_BASE_URL}/${imageRectangle}/${
element.article.coverUrl
}`}
imgClass="center radius-1"
/>
<br />
bookmarks.map((element, key) => (
<div key={key} className="row">
<Link to={`/articles/${element.articleSlug}`}>
<div className="small-screen-4 medium-screen-1 large-screen-1 ">
<div className="image">
<Img
imgSrc={`${REACT_APP_IMAGE_BASE_URL}/${imageRectangle}/${
element.article.coverUrl
}`}
imgClass="center radius-1"
/>
<br />
</div>
</div>
</div>
<div className="large-margin">
<div className="large-margin">
<h3>{element.article.title}</h3>
</div>
<div className="xxlarge-h-margin">
<p>{element.article.description}</p>
<div className="large-margin">
<h3>{element.article.title}</h3>
</div>
<div className="xxlarge-h-margin">
<p>{element.article.description}</p>
</div>
<div className="xxlarge-h-margin text-grey small-text">
<span>{element.article.readTime} min</span>
<span className="xlarge-margin">
{new Date(element.createdAt).toDateString()}
</span>
</div>
</div>
<div className="xxlarge-h-margin text-grey small-text">
<span>{element.article.readTime} min</span>
<span className="xlarge-margin">
{new Date(element.createdAt).toDateString()}
</span>
</div>
</div>
</Link>
<button
className="danger text-white "
onClick={() => this.deleteBookmark(element)}
>
<span>
<FontAwesomeIcon
icon={faTrash}
size="1x"
className="left text-white small-h-padding"
/>
</span>
<span className="small-h-padding">Remove</span>
</button>
<div className="divider light-grey" />
</div>
))
)}
</Link>
<button
className="danger text-white "
onClick={() => this.deleteBookmark(element)}
>
<span>
<FontAwesomeIcon
icon={faTrash}
size="1x"
className="left text-white small-h-padding"
/>
</span>
<span className="small-h-padding">Remove</span>
</button>
<div className="divider light-grey" />
</div>
))
)}
</div>
</div>
</Layout>
Expand All @@ -103,7 +103,7 @@ Bookmarks.propTypes = {
loading: PropTypes.bool,
errors: PropTypes.object,
message: PropTypes.string,
bookmarks: PropTypes.array,
bookmarks: PropTypes.any,
getAllBookmarks: PropTypes.func.isRequired,
deleteOneBookmark: PropTypes.func.isRequired
};
Expand Down
9 changes: 6 additions & 3 deletions src/reducers/articlesReducer.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,20 @@ export default (state = initialState, { type, payload }) => {
case articlesType.FETCH_ARTICLES_START:
return {
...state,
articles: []
articles: [],
loading: true
};
case articlesType.FETCH_ARTICLES_SUCCESS:
return {
...state,
articles: [...state.articles, ...payload.articles]
articles: [...state.articles, ...payload.articles],
articlesCount: payload.articlesCount,
loading: false
};
case articlesType.FETCH_ARTICLE_START:
return {
...state,
article: { ...state.article }
article: { ...state.article },
};
case articlesType.FETCH_ARTICLE_SUCCESS:
return {
Expand Down

0 comments on commit c60f4fa

Please sign in to comment.