2018-08-02 15:48:02 +00:00
|
|
|
import React, { Component } from 'react';
|
2018-08-03 13:01:15 +00:00
|
|
|
import PropTypes from 'prop-types';
|
2018-08-02 15:48:02 +00:00
|
|
|
import { withRouter } from 'react-router-dom';
|
|
|
|
import { Image } from 'react-bootstrap';
|
|
|
|
import Helmet from 'react-helmet';
|
|
|
|
|
|
|
|
import { getFeaturedList } from '../../utils/ajax';
|
|
|
|
import { Loader, Spacer } from '../../../common/app/helperComponents';
|
|
|
|
import BannerWide from '../../components/BannerWide';
|
2018-08-03 13:01:15 +00:00
|
|
|
import ArticleMeta from '../../components/ArticleMeta';
|
2018-08-01 11:40:44 +00:00
|
|
|
|
2018-08-03 13:01:15 +00:00
|
|
|
const propTypes = {
|
|
|
|
history: PropTypes.shape({
|
|
|
|
push: PropTypes.func.isRequired
|
|
|
|
})
|
|
|
|
};
|
2018-08-01 11:40:44 +00:00
|
|
|
|
2018-08-02 15:48:02 +00:00
|
|
|
const styles = `
|
|
|
|
.featured-list {
|
|
|
|
list-style: none;
|
|
|
|
padding-left: 0;
|
2018-08-03 13:01:15 +00:00
|
|
|
margin-top: 40px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.featured-list-item {
|
|
|
|
padding-bottom: 20px;
|
2018-08-02 15:48:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
.featured-list-item .title {
|
|
|
|
color: #333;
|
2018-08-03 13:01:15 +00:00
|
|
|
padding-bottom: 20px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.featured-list-item a {
|
|
|
|
padding-top: 5px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.featured-list-image {
|
|
|
|
margin: 0 auto;
|
2018-08-02 15:48:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
.featured-list-item a:hover,
|
|
|
|
.featured-list-item a:focus {
|
|
|
|
text-decoration: none;
|
|
|
|
text-decoration-line: none;
|
|
|
|
text-decoration-color: transparaent;
|
|
|
|
}
|
|
|
|
.featured-list-item a:hover > .meta-wrapper,
|
|
|
|
.featured-list-item a:focus > .meta-wrapper {
|
|
|
|
color: #006400;
|
|
|
|
}
|
|
|
|
`;
|
|
|
|
|
|
|
|
class Featured extends Component {
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
|
|
|
|
this.state = {
|
|
|
|
fetchState: {
|
|
|
|
pending: false,
|
|
|
|
complete: false,
|
|
|
|
errored: false,
|
|
|
|
error: null
|
|
|
|
},
|
|
|
|
featuredList: []
|
|
|
|
};
|
|
|
|
|
|
|
|
this.fetchFeaturedList = this.fetchFeaturedList.bind(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
componentDidMount() {
|
|
|
|
return this.fetchFeaturedList();
|
|
|
|
}
|
|
|
|
|
|
|
|
fetchFeaturedList() {
|
|
|
|
return this.setState(
|
|
|
|
{
|
|
|
|
fetchState: { pending: true, complete: false, errored: false }
|
|
|
|
},
|
|
|
|
() =>
|
|
|
|
getFeaturedList().then(({ data }) =>
|
|
|
|
this.setState({
|
|
|
|
featuredList: data,
|
|
|
|
fetchState: {
|
|
|
|
pending: false,
|
|
|
|
complete: true,
|
|
|
|
errored: false,
|
|
|
|
error: null
|
|
|
|
}
|
|
|
|
})
|
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
createHandleArticleClick(slug, article) {
|
|
|
|
const { history } = this.props;
|
|
|
|
return e => {
|
|
|
|
e.preventDefault();
|
|
|
|
return history.push({ pathname: slug, state: { article } });
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
renderFeatured(articles) {
|
|
|
|
return articles.map(article => {
|
|
|
|
const slug = `/${article.author.username}/`.concat(
|
|
|
|
article.slugPart,
|
|
|
|
'--',
|
|
|
|
article.shortId
|
|
|
|
);
|
2018-08-03 13:01:15 +00:00
|
|
|
const { featureImage, shortId, title } = article;
|
2018-08-02 15:48:02 +00:00
|
|
|
return (
|
|
|
|
<li className='featured-list-item' key={shortId}>
|
2018-08-03 13:01:15 +00:00
|
|
|
<a
|
|
|
|
href={'/news' + slug}
|
|
|
|
onClick={this.createHandleArticleClick(slug, article)}
|
|
|
|
>
|
2018-08-02 15:48:02 +00:00
|
|
|
<h3 className='title'>{title}</h3>
|
2018-08-03 13:01:15 +00:00
|
|
|
{featureImage && featureImage.src ? (
|
|
|
|
<Image
|
|
|
|
className='featured-list-image'
|
|
|
|
responsive={true}
|
|
|
|
src={featureImage.src}
|
|
|
|
/>
|
|
|
|
) : (
|
|
|
|
<BannerWide />
|
|
|
|
)}
|
|
|
|
<ArticleMeta article={article} />
|
2018-08-02 15:48:02 +00:00
|
|
|
</a>
|
|
|
|
<Spacer />
|
|
|
|
</li>
|
|
|
|
);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
|
|
|
const {
|
|
|
|
fetchState: { pending, complete, errored },
|
|
|
|
featuredList
|
|
|
|
} = this.state;
|
|
|
|
if (pending || !complete) {
|
2018-08-03 13:42:50 +00:00
|
|
|
return (
|
|
|
|
<div className='full-size' style={{ position: 'fixed', left: 0 }}>
|
|
|
|
<Loader />
|
|
|
|
</div>
|
|
|
|
);
|
2018-08-02 15:48:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (complete && errored) {
|
|
|
|
return <h2>Oh noes!! Something went wrong!</h2>;
|
|
|
|
}
|
|
|
|
return (
|
|
|
|
<div>
|
|
|
|
<Helmet>
|
|
|
|
<style>{styles}</style>
|
2018-08-24 05:15:33 +00:00
|
|
|
<title>Featured | freeCodeCamp News</title>
|
2018-08-02 15:48:02 +00:00
|
|
|
</Helmet>
|
2018-08-03 13:01:15 +00:00
|
|
|
<ul className='featured-list'>{this.renderFeatured(featuredList)}</ul>
|
2018-08-02 15:48:02 +00:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
2018-08-01 11:40:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Featured.displayName = 'Featured';
|
|
|
|
Featured.propTypes = propTypes;
|
|
|
|
|
2018-08-02 15:48:02 +00:00
|
|
|
export default withRouter(Featured);
|