2016-08-18 11:41:13 +02:00
|
|
|
/*
|
|
|
|
*
|
2017-08-21 15:12:53 +02:00
|
|
|
* HomePage
|
2016-08-18 11:47:26 +02:00
|
|
|
*
|
2016-08-18 11:41:13 +02:00
|
|
|
*/
|
|
|
|
|
2017-09-26 16:36:28 +02:00
|
|
|
import React from 'react';
|
2016-08-19 13:57:50 +02:00
|
|
|
import { connect } from 'react-redux';
|
2017-08-21 15:12:53 +02:00
|
|
|
import Helmet from 'react-helmet';
|
2018-04-04 12:36:02 +02:00
|
|
|
import { FormattedMessage } from 'react-intl';
|
2018-04-04 17:14:08 +02:00
|
|
|
import { bindActionCreators, compose } from 'redux';
|
|
|
|
import { createStructuredSelector } from 'reselect';
|
|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import { get, isEmpty } from 'lodash';
|
2018-04-03 17:56:19 +02:00
|
|
|
import cn from 'classnames';
|
2017-10-18 16:51:50 +02:00
|
|
|
|
2018-04-03 17:56:19 +02:00
|
|
|
import Block from 'components/HomePageBlock/Loadable';
|
2018-04-04 10:21:06 +02:00
|
|
|
import Button from 'components/Button';
|
2018-04-04 08:54:15 +02:00
|
|
|
import Sub from 'components/Sub/Loadable';
|
2018-04-04 16:18:12 +02:00
|
|
|
import Input from 'components/InputText';
|
|
|
|
|
2018-04-04 17:14:08 +02:00
|
|
|
import { selectPlugins } from 'containers/App/selectors';
|
|
|
|
|
|
|
|
import injectReducer from 'utils/injectReducer';
|
|
|
|
import injectSaga from 'utils/injectSaga';
|
2018-04-04 16:18:12 +02:00
|
|
|
import validateInput from 'utils/inputsValidations';
|
2017-10-18 16:51:50 +02:00
|
|
|
|
2018-04-04 12:36:02 +02:00
|
|
|
import BlockLink from './BlockLink';
|
2018-04-04 15:24:09 +02:00
|
|
|
import CommunityContent from './CommunityContent';
|
2018-04-04 10:21:06 +02:00
|
|
|
import CreateContent from './CreateContent';
|
2018-04-04 15:24:09 +02:00
|
|
|
import SocialLink from './SocialLink';
|
2018-04-04 12:36:02 +02:00
|
|
|
import WelcomeContent from './WelcomeContent';
|
2018-04-04 10:21:06 +02:00
|
|
|
|
2018-04-04 17:14:08 +02:00
|
|
|
import { onChange, submit } from './actions';
|
|
|
|
import makeSelectHomePage from './selectors';
|
|
|
|
import reducer from './reducer';
|
|
|
|
import saga from './saga';
|
2017-08-21 15:12:53 +02:00
|
|
|
import styles from './styles.scss';
|
2016-08-18 11:41:13 +02:00
|
|
|
|
2018-04-04 10:21:06 +02:00
|
|
|
const FIRST_BLOCK = [
|
|
|
|
{
|
|
|
|
title: {
|
|
|
|
id: 'app.components.HomePage.welcome',
|
|
|
|
},
|
|
|
|
content: () => <WelcomeContent />,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
title: {
|
|
|
|
id: 'app.components.HomePage.create',
|
|
|
|
},
|
|
|
|
content: () => <CreateContent />,
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
2018-04-04 12:36:02 +02:00
|
|
|
const FIRST_BLOCK_LINKS = [
|
|
|
|
{
|
|
|
|
link: 'https://strapi.io/documentation/',
|
|
|
|
content: {
|
|
|
|
id: 'app.components.BlockLink.documentation.content',
|
|
|
|
},
|
|
|
|
isDocumentation: true,
|
|
|
|
title: {
|
|
|
|
id: 'app.components.BlockLink.documentation',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
link: 'https://github.com/strapi/strapi-examples',
|
|
|
|
content: {
|
|
|
|
id: 'app.components.BlockLink.code.content',
|
|
|
|
},
|
|
|
|
isDocumentation: false,
|
|
|
|
title: {
|
|
|
|
id: 'app.components.BlockLink.code',
|
|
|
|
},
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
2018-04-04 15:24:09 +02:00
|
|
|
const SECOND_BLOCK = {
|
|
|
|
title: {
|
|
|
|
id: 'app.components.HomePage.community',
|
|
|
|
},
|
|
|
|
content: () => <CommunityContent />,
|
|
|
|
};
|
|
|
|
|
|
|
|
const SOCIAL_LINKS = [
|
|
|
|
{
|
|
|
|
name: 'Github',
|
|
|
|
link: 'https://github.com/strapi/strapi/',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: 'Slack',
|
|
|
|
link: 'https://slack.strapi.io/',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: 'Medium',
|
|
|
|
link: 'https://medium.com/@strapi',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: 'Twitter',
|
|
|
|
link: 'https://twitter.com/strapijs',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: 'Reddit',
|
|
|
|
link: 'https://www.reddit.com/r/node/search?q=strapi',
|
|
|
|
},
|
|
|
|
{
|
|
|
|
name: 'Stack Overflow',
|
|
|
|
link: 'https://stackoverflow.com/questions/tagged/strapi',
|
|
|
|
},
|
|
|
|
];
|
|
|
|
|
2018-04-04 17:14:08 +02:00
|
|
|
export class HomePage extends React.PureComponent {
|
2018-04-04 12:36:02 +02:00
|
|
|
// eslint-disable-line react/prefer-stateless-function
|
2018-04-04 17:14:08 +02:00
|
|
|
state = { errors: [] };
|
2018-04-04 16:18:12 +02:00
|
|
|
|
|
|
|
handleSubmit = e => {
|
|
|
|
e.preventDefault();
|
2018-04-04 17:14:08 +02:00
|
|
|
const errors = validateInput(this.props.homePage.body.email, { required: true }, 'email');
|
2018-04-04 16:18:12 +02:00
|
|
|
this.setState({ errors });
|
2018-04-04 17:14:08 +02:00
|
|
|
|
|
|
|
if (isEmpty(errors)) {
|
|
|
|
return this.props.submit();
|
|
|
|
}
|
2018-04-04 16:18:12 +02:00
|
|
|
};
|
|
|
|
|
2018-04-04 17:14:08 +02:00
|
|
|
showFirstBlock = () =>
|
|
|
|
get(this.props.plugins.toJS(), 'content-manager.leftMenuSections.0.links', []).length === 0;
|
|
|
|
|
2016-08-18 11:41:13 +02:00
|
|
|
render() {
|
2018-04-04 17:14:08 +02:00
|
|
|
const { homePage: { body } } = this.props;
|
|
|
|
|
2016-08-18 11:41:13 +02:00
|
|
|
return (
|
2018-04-03 17:56:19 +02:00
|
|
|
<div className={cn('container-fluid', styles.containerFluid)}>
|
|
|
|
<Helmet title="Home Page" />
|
|
|
|
<div className="row">
|
2018-04-04 12:36:02 +02:00
|
|
|
<div className="col-md-8 col-lg-8">
|
2018-04-04 17:14:08 +02:00
|
|
|
{this.showFirstBlock() && (
|
|
|
|
<Block>
|
|
|
|
{FIRST_BLOCK.map((value, key) => (
|
|
|
|
<Sub key={key} {...value} underline={key === 0} bordered={key === 0} />
|
|
|
|
))}
|
|
|
|
<a href="https://strapi.io/getting-started" target="_blank">
|
|
|
|
<Button className={styles.homePageTutorialButton} primary>
|
|
|
|
<FormattedMessage id="app.components.HomePage.button.quickStart" />
|
|
|
|
</Button>
|
|
|
|
</a>
|
|
|
|
<div className={styles.homePageFlex}>
|
|
|
|
{FIRST_BLOCK_LINKS.map((value, key) => <BlockLink {...value} key={key} />)}
|
|
|
|
</div>
|
|
|
|
</Block>
|
|
|
|
)}
|
2018-04-04 15:24:09 +02:00
|
|
|
<Block>
|
|
|
|
<Sub {...SECOND_BLOCK} />
|
|
|
|
<div className={styles.homePageFlex}>
|
|
|
|
<div className="row" style={{ width: '100%', marginRight: '0' }}>
|
|
|
|
{SOCIAL_LINKS.map((value, key) => <SocialLink key={key} {...value} />)}
|
|
|
|
</div>
|
2018-04-04 16:18:12 +02:00
|
|
|
<div className={styles.newsLetterWrapper}>
|
|
|
|
<div>
|
|
|
|
<FormattedMessage id="app.components.HomePage.newsLetter" />
|
|
|
|
</div>
|
|
|
|
<form onSubmit={this.handleSubmit}>
|
|
|
|
<div className={cn(styles.homePageForm, 'row')}>
|
|
|
|
<div className="col-md-6">
|
|
|
|
<Input
|
2018-04-04 17:14:08 +02:00
|
|
|
value={body.email}
|
|
|
|
onChange={this.props.onChange}
|
2018-04-04 16:18:12 +02:00
|
|
|
name=""
|
|
|
|
placeholder="johndoe@gmail.com"
|
|
|
|
error={!isEmpty(this.state.errors)}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
<div className="col-md-6">
|
|
|
|
<FormattedMessage id="app.components.HomePage.cta">
|
|
|
|
{message => <button type="submit">{message}</button>}
|
|
|
|
</FormattedMessage>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</form>
|
|
|
|
</div>
|
2018-04-04 15:24:09 +02:00
|
|
|
</div>
|
|
|
|
</Block>
|
2018-04-03 17:56:19 +02:00
|
|
|
</div>
|
2018-04-04 12:36:02 +02:00
|
|
|
<div className="col-lg-4 col-md-4">
|
2018-04-04 13:55:27 +02:00
|
|
|
<Block className={styles.blockShirt}>
|
|
|
|
<div>
|
|
|
|
<FormattedMessage id="app.components.HomePage.support" />
|
|
|
|
<FormattedMessage id="app.components.HomePage.support.content">
|
|
|
|
{message => <p>{message}</p>}
|
|
|
|
</FormattedMessage>
|
|
|
|
<FormattedMessage id="app.components.HomePage.support.link">
|
|
|
|
{message => (
|
|
|
|
<a href="https://strapi.io/shop" target="_blank">
|
|
|
|
{message}
|
|
|
|
</a>
|
|
|
|
)}
|
|
|
|
</FormattedMessage>
|
|
|
|
</div>
|
|
|
|
</Block>
|
2018-04-03 17:56:19 +02:00
|
|
|
</div>
|
2017-10-18 16:51:50 +02:00
|
|
|
</div>
|
2016-08-19 13:57:50 +02:00
|
|
|
</div>
|
2016-08-18 11:41:13 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
2016-08-19 13:57:50 +02:00
|
|
|
|
2017-10-18 16:51:50 +02:00
|
|
|
HomePage.propTypes = {
|
2018-04-04 17:14:08 +02:00
|
|
|
homePage: PropTypes.object.isRequired,
|
|
|
|
onChange: PropTypes.func.isRequired,
|
|
|
|
plugins: PropTypes.object.isRequired,
|
|
|
|
submit: PropTypes.func.isRequired,
|
2017-10-18 16:51:50 +02:00
|
|
|
};
|
2016-08-19 13:57:50 +02:00
|
|
|
|
2018-04-04 17:14:08 +02:00
|
|
|
const mapStateToProps = createStructuredSelector({
|
|
|
|
homePage: makeSelectHomePage(),
|
|
|
|
plugins: selectPlugins(),
|
|
|
|
});
|
|
|
|
|
2016-08-19 13:57:50 +02:00
|
|
|
function mapDispatchToProps(dispatch) {
|
2018-04-04 17:14:08 +02:00
|
|
|
return bindActionCreators(
|
|
|
|
{
|
|
|
|
onChange,
|
|
|
|
submit,
|
|
|
|
},
|
2016-08-19 13:57:50 +02:00
|
|
|
dispatch,
|
2018-04-04 17:14:08 +02:00
|
|
|
);
|
2016-08-19 13:57:50 +02:00
|
|
|
}
|
|
|
|
|
2018-04-04 17:14:08 +02:00
|
|
|
const withConnect = connect(mapStateToProps, mapDispatchToProps);
|
|
|
|
|
|
|
|
const withReducer = injectReducer({ key: 'homePage', reducer });
|
|
|
|
const withSaga = injectSaga({ key: 'homePage', saga });
|
|
|
|
|
|
|
|
// export default connect(mapDispatchToProps)(HomePage);
|
|
|
|
export default compose(withReducer, withSaga, withConnect)(HomePage);
|