235 lines
7.5 KiB
JavaScript
235 lines
7.5 KiB
JavaScript
import React, { Component } from 'react';
|
|
import { connect, Provider } from 'react-redux';
|
|
import PropTypes from 'prop-types';
|
|
import { IntlProvider, injectIntl, intlShape } from 'react-intl';
|
|
import { Route, Switch } from 'react-router-dom';
|
|
import { ConnectedRouter } from 'connected-react-router';
|
|
import { sendTrackEvent } from '@edx/frontend-analytics';
|
|
import SiteHeader from '@edx/frontend-component-site-header';
|
|
import SiteFooter from '@edx/frontend-component-footer';
|
|
import { getLocale, getMessages } from '@edx/frontend-i18n'; // eslint-disable-line
|
|
|
|
import { PageLoading, fetchUserAccount } from '../common';
|
|
import { ConnectedFeaturePage } from '../feature';
|
|
|
|
import FooterLogo from '../assets/edx-footer.png';
|
|
import HeaderLogo from '../assets/logo.svg';
|
|
import ErrorPage from './ErrorPage';
|
|
import NotFoundPage from './NotFoundPage';
|
|
|
|
import messages from './App.messages';
|
|
import WelcomePage from './WelcomePage';
|
|
|
|
|
|
function PageContent({
|
|
ready,
|
|
configuration,
|
|
username,
|
|
avatar,
|
|
intl,
|
|
}) {
|
|
if (!ready) {
|
|
return <PageLoading srMessage={intl.formatMessage(messages['app.loading.message'])} />;
|
|
}
|
|
|
|
const mainMenu = [
|
|
{
|
|
type: 'item',
|
|
href: `${process.env.MARKETING_SITE_BASE_URL}/course`,
|
|
content: intl.formatMessage(messages['siteheader.links.courses']),
|
|
},
|
|
{
|
|
type: 'item',
|
|
href: `${process.env.MARKETING_SITE_BASE_URL}/course?program=all`,
|
|
content: intl.formatMessage(messages['siteheader.links.programs']),
|
|
},
|
|
{
|
|
type: 'item',
|
|
href: `${process.env.MARKETING_SITE_BASE_URL}/schools-partners`,
|
|
content: intl.formatMessage(messages['siteheader.links.schools']),
|
|
},
|
|
];
|
|
const userMenu = [
|
|
{
|
|
type: 'item',
|
|
href: `${process.env.LMS_BASE_URL}`,
|
|
content: intl.formatMessage(messages['siteheader.user.menu.dashboard']),
|
|
},
|
|
{
|
|
type: 'item',
|
|
href: `${process.env.LMS_BASE_URL}/u/${username}`,
|
|
content: intl.formatMessage(messages['siteheader.user.menu.profile']),
|
|
},
|
|
{
|
|
type: 'item',
|
|
href: `${process.env.LMS_BASE_URL}/account/settings`,
|
|
content: intl.formatMessage(messages['siteheader.user.menu.account.settings']),
|
|
},
|
|
{
|
|
type: 'item',
|
|
href: process.env.LOGOUT_URL,
|
|
content: intl.formatMessage(messages['siteheader.user.menu.logout']),
|
|
},
|
|
];
|
|
const loggedOutItems = [
|
|
{
|
|
type: 'item',
|
|
href: `${process.env.LMS_BASE_URL}/login`,
|
|
content: intl.formatMessage(messages['siteheader.user.menu.login']),
|
|
},
|
|
{
|
|
type: 'item',
|
|
href: `${process.env.LMS_BASE_URL}/register`,
|
|
content: intl.formatMessage(messages['siteheader.user.menu.register']),
|
|
},
|
|
];
|
|
|
|
return (
|
|
<div id="app">
|
|
<SiteHeader
|
|
logo={HeaderLogo}
|
|
loggedIn
|
|
username={username}
|
|
avatar={avatar}
|
|
logoAltText={configuration.SITE_NAME}
|
|
logoDestination={configuration.MARKETING_SITE_BASE_URL}
|
|
mainMenu={mainMenu}
|
|
userMenu={userMenu}
|
|
loggedOutItems={loggedOutItems}
|
|
/>
|
|
<main>
|
|
<Switch>
|
|
<Route path="/feature" component={ConnectedFeaturePage} />
|
|
<Route path="/error" component={ErrorPage} />
|
|
<Route path="/notfound" component={NotFoundPage} />
|
|
<Route path="/" component={WelcomePage} />
|
|
<Route path="*" component={NotFoundPage} />
|
|
</Switch>
|
|
</main>
|
|
<SiteFooter
|
|
siteName={configuration.SITE_NAME}
|
|
siteLogo={FooterLogo}
|
|
marketingSiteBaseUrl={configuration.MARKETING_SITE_BASE_URL}
|
|
supportUrl={configuration.SUPPORT_URL}
|
|
contactUrl={configuration.CONTACT_URL}
|
|
openSourceUrl={configuration.OPEN_SOURCE_URL}
|
|
termsOfServiceUrl={configuration.TERMS_OF_SERVICE_URL}
|
|
privacyPolicyUrl={configuration.PRIVACY_POLICY_URL}
|
|
facebookUrl={configuration.FACEBOOK_URL}
|
|
twitterUrl={configuration.TWITTER_URL}
|
|
youTubeUrl={configuration.YOU_TUBE_URL}
|
|
linkedInUrl={configuration.LINKED_IN_URL}
|
|
googlePlusUrl={configuration.GOOGLE_PLUS_URL}
|
|
redditUrl={configuration.REDDIT_URL}
|
|
appleAppStoreUrl={configuration.APPLE_APP_STORE_URL}
|
|
googlePlayUrl={configuration.GOOGLE_PLAY_URL}
|
|
handleAllTrackEvents={sendTrackEvent}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
PageContent.propTypes = {
|
|
username: PropTypes.string.isRequired,
|
|
avatar: PropTypes.string,
|
|
ready: PropTypes.bool,
|
|
configuration: PropTypes.shape({
|
|
SITE_NAME: PropTypes.string.isRequired,
|
|
MARKETING_SITE_BASE_URL: PropTypes.string.isRequired,
|
|
SUPPORT_URL: PropTypes.string.isRequired,
|
|
CONTACT_URL: PropTypes.string.isRequired,
|
|
OPEN_SOURCE_URL: PropTypes.string.isRequired,
|
|
TERMS_OF_SERVICE_URL: PropTypes.string.isRequired,
|
|
PRIVACY_POLICY_URL: PropTypes.string.isRequired,
|
|
FACEBOOK_URL: PropTypes.string.isRequired,
|
|
TWITTER_URL: PropTypes.string.isRequired,
|
|
YOU_TUBE_URL: PropTypes.string.isRequired,
|
|
LINKED_IN_URL: PropTypes.string.isRequired,
|
|
GOOGLE_PLUS_URL: PropTypes.string.isRequired,
|
|
REDDIT_URL: PropTypes.string.isRequired,
|
|
APPLE_APP_STORE_URL: PropTypes.string.isRequired,
|
|
GOOGLE_PLAY_URL: PropTypes.string.isRequired,
|
|
}).isRequired,
|
|
intl: intlShape.isRequired,
|
|
};
|
|
|
|
PageContent.defaultProps = {
|
|
ready: false,
|
|
avatar: null,
|
|
};
|
|
|
|
const IntlPageContent = injectIntl(PageContent);
|
|
|
|
class App extends Component {
|
|
componentDidMount() {
|
|
const { username } = this.props;
|
|
this.props.fetchUserAccount(username);
|
|
}
|
|
|
|
render() {
|
|
return (
|
|
<IntlProvider locale={getLocale()} messages={getMessages()}>
|
|
<Provider store={this.props.store}>
|
|
<ConnectedRouter history={this.props.history}>
|
|
<IntlPageContent
|
|
ready={this.props.ready}
|
|
configuration={this.props.configuration}
|
|
username={this.props.username}
|
|
avatar={this.props.avatar}
|
|
/>
|
|
</ConnectedRouter>
|
|
</Provider>
|
|
</IntlProvider>
|
|
);
|
|
}
|
|
}
|
|
|
|
App.propTypes = {
|
|
fetchUserAccount: PropTypes.func.isRequired,
|
|
username: PropTypes.string.isRequired,
|
|
avatar: PropTypes.string,
|
|
store: PropTypes.object.isRequired, // eslint-disable-line
|
|
history: PropTypes.object.isRequired, // eslint-disable-line
|
|
ready: PropTypes.bool,
|
|
configuration: PropTypes.shape({
|
|
SITE_NAME: PropTypes.string.isRequired,
|
|
MARKETING_SITE_BASE_URL: PropTypes.string.isRequired,
|
|
SUPPORT_URL: PropTypes.string.isRequired,
|
|
CONTACT_URL: PropTypes.string.isRequired,
|
|
OPEN_SOURCE_URL: PropTypes.string.isRequired,
|
|
TERMS_OF_SERVICE_URL: PropTypes.string.isRequired,
|
|
PRIVACY_POLICY_URL: PropTypes.string.isRequired,
|
|
FACEBOOK_URL: PropTypes.string.isRequired,
|
|
TWITTER_URL: PropTypes.string.isRequired,
|
|
YOU_TUBE_URL: PropTypes.string.isRequired,
|
|
LINKED_IN_URL: PropTypes.string.isRequired,
|
|
GOOGLE_PLUS_URL: PropTypes.string.isRequired,
|
|
REDDIT_URL: PropTypes.string.isRequired,
|
|
APPLE_APP_STORE_URL: PropTypes.string.isRequired,
|
|
GOOGLE_PLAY_URL: PropTypes.string.isRequired,
|
|
}).isRequired,
|
|
};
|
|
|
|
App.defaultProps = {
|
|
ready: false,
|
|
avatar: null,
|
|
};
|
|
|
|
const mapStateToProps = state => ({
|
|
username: state.authentication.username,
|
|
// An error means that we tried to load the user account and failed,
|
|
// which also means we're ready to display something.
|
|
ready: state.userAccount.loaded || state.userAccount.error != null,
|
|
configuration: state.configuration,
|
|
avatar: state.userAccount.profileImage.hasImage
|
|
? state.userAccount.profileImage.imageUrlMedium
|
|
: null,
|
|
});
|
|
|
|
export default connect(
|
|
mapStateToProps,
|
|
{
|
|
fetchUserAccount,
|
|
},
|
|
)(App);
|