Skip to content

Commit

Permalink
feature(article list):user can see list of articles
Browse files Browse the repository at this point in the history
 - add list article components, container, actions and actiontypes
 - add utils to get image from body and format db DateTime field
 - style homepage
 - add utils tests

[Finishes #164046214]
  • Loading branch information
RachelleMaina committed Apr 12, 2019
1 parent 6e60bb7 commit 4cc0734
Show file tree
Hide file tree
Showing 19 changed files with 480 additions and 14 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
"env": {
"browser": true,
"es6": true,
"node": true
"node": true,
"jest":true
},
"extends": "airbnb",
"globals": {
Expand Down
38 changes: 38 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"axios": "^0.18.0",
"bootstrap": "^4.3.1",
"i": "^0.3.6",
"node-sass": "^4.11.0",
Expand All @@ -13,8 +14,10 @@
"react-redux": "^6.0.1",
"react-router-dom": "^5.0.0",
"react-scripts": "2.1.8",
"react-toastify": "^5.0.1",
"redux": "^4.0.1",
"redux-thunk": "^2.3.0"
"redux-thunk": "^2.3.0",
"validator": "^10.11.0"
},
"scripts": {
"start": "react-scripts start",
Expand Down Expand Up @@ -42,7 +45,8 @@
"eslint-config-airbnb": "^17.1.0",
"eslint-plugin-import": "^2.16.0",
"eslint-plugin-jsx-a11y": "^6.2.1",
"eslint-plugin-react": "^7.12.4"
"eslint-plugin-react": "^7.12.4",
"moxios": "^0.4.0"
},
"jest": {
"snapshotSerializers": [
Expand Down
11 changes: 11 additions & 0 deletions src/axiosConfig.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import axios from 'axios';

const BASE_URL = 'https://ah-legion-staging.herokuapp.com/api/';

const axiosConfig = axios.create({
baseURL: BASE_URL,
headers: {
'Content-Type': 'application/json',
},
});
export default axiosConfig;
45 changes: 45 additions & 0 deletions src/components/AllArticles.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import unixTimeToDate from '../utils/dateFormatter';
import extractImageFromBody from '../utils/imageExtractor';

const AllArticles = ({ articles }) => (articles ? (
articles.map(article => (
<div key={article.id}>

<div className="home-view-last">
<img
src={extractImageFromBody(article.body)}
alt=""
/>

{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
<h3><Link a href="#" className="title-link">{article.title}</Link></h3>

<span className="description">{article.description}</span>
<br />
<span className="author">{article.author.username}</span>
<br />
<span className="meta">
{unixTimeToDate(article.created_at)}
&nbsp;.&nbsp;
{article.reading_time}
&nbsp;read
</span>
</div>
</div>
))
) : (
<div>Loading...</div>
));

AllArticles.propTypes = {
articles: PropTypes.arrayOf(PropTypes.oneOfType[(PropTypes.object,
PropTypes.string, PropTypes.number)]),
};

AllArticles.defaultProps = {
articles: [],
};
export default AllArticles;
42 changes: 42 additions & 0 deletions src/components/ArticlesByCriteria.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import unixTimeToDate from '../utils/dateFormatter';
import extractImageFromBody from '../utils/imageExtractor';

const ArticlesByCriteria = ({ articles, start, end }) => (articles ? (
articles.slice(start, end).map(article => (
<div key={article.id}>
<img
src={extractImageFromBody(article.body)}
alt=""
/>
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
<h3><Link a href="#" className="title-link">{article.title}</Link></h3>
<span className="author">{article.author.username}</span>
<br />
<span className="meta">
{unixTimeToDate(article.created_at)}
&nbsp;.&nbsp;
{article.reading_time}
&nbsp;read
</span>
</div>
))
) : (
<div>Loading...</div>
));

ArticlesByCriteria.propTypes = {
articles: PropTypes.arrayOf(PropTypes.oneOfType[(PropTypes.object,
PropTypes.string, PropTypes.number)]),
start: PropTypes.number,
end: PropTypes.number,
};

ArticlesByCriteria.defaultProps = {
articles: [],
start: 0,
end: 0,
};
export default ArticlesByCriteria;
102 changes: 97 additions & 5 deletions src/components/Home.jsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,100 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Container, Row, Col, Card } from 'react-bootstrap';
import AllArticles from './AllArticles';
import ArticlesByCriteria from './ArticlesByCriteria';

const Home = () => (
<div className="main-container">
<h3>Home</h3>
</div>
);
const Home = ({ articles }) => {
return (
<Container>
<Row>
<Col xs={3}>
<ArticlesByCriteria articles={articles} start={0} end={1} />
</Col>

<Col xs={{ offset: 1 }}>
<Row>
<Col>
<div className="home-view">
<ArticlesByCriteria articles={articles} start={2} end={3} />
</div>
</Col>
</Row>

<Row>
<Col>
<div className="home-view">
<ArticlesByCriteria articles={articles} start={1} end={2} />
</div>
</Col>
</Row>

<Row>
<Col>
<div className="home-view">
<ArticlesByCriteria articles={articles} start={2} end={3} />
</div>
</Col>
</Row>
</Col>

<Col xs={3}>
<ArticlesByCriteria articles={articles} start={0} end={1} />
</Col>
</Row>

{/* Start Second Section */}
<Row>
<Col>
<Card className="welcome-card">
<Card.Body>
<Row>
<Col>
<h2>Welcome to Author&apos;s Haven</h2>
<br />
<span className="author">
We are community of like minded authors to foster
inspiration and innovation by leveraging the modern web.
Whatever your interest, you can always find fresh thinking
and unique perspectives.
</span>
<br />
</Col>
<Col xs={3}>
<img
src="https://images.unsplash.com/photo-1501504905252-473c47e087f8?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1867&q=80"
alt=""
/>
</Col>
</Row>
</Card.Body>
</Card>
</Col>
</Row>
{/* End Second Section */}

<Row>
<Col>
<AllArticles articles={articles} />
</Col>
<Col xs={{ span: 3, offset: 1 }}>
<Row>
<Col>
<h3>Popular on Author&apos;s Haven</h3>
<hr />
</Col>
</Row>
</Col>
</Row>
</Container>
);
};
Home.propTypes = {
articles: PropTypes.arrayOf(PropTypes.oneOfType[(PropTypes.object,
PropTypes.string, PropTypes.number)]),
};

Home.defaultProps = {
articles: [],
};
export default Home;
40 changes: 40 additions & 0 deletions src/containers/HomeView.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import Home from '../components/Home';
import { fetchAllArticles } from '../store/actions/articles';

class HomeView extends Component {
componentDidMount() {
const { fetchAllArticles } = this.props;
fetchAllArticles()

}

render() {
const { articles } = this.props;
const items = articles.articles.results;

return <Home articles={items} />;
}
}

HomeView.propTypes = {
fetchAllArticles: PropTypes.func,
articles: PropTypes.arrayOf(PropTypes.oneOfType[(PropTypes.object,
PropTypes.string, PropTypes.number)]),
};

HomeView.defaultProps = {
articles: [],
fetchAllArticles: () => {},

};
const mapStateToProps = state => ({ articles: state.articles });
const mapDispatchToProps = dispatch => ({
fetchAllArticles: articles => dispatch(fetchAllArticles())
});
export default connect(
mapStateToProps,
mapDispatchToProps,
)(HomeView);
Loading

0 comments on commit 4cc0734

Please sign in to comment.