261 lines
8.2 KiB
JavaScript
261 lines
8.2 KiB
JavaScript
import React, { Component } from 'react';
|
|
import { connect, Provider } from 'react-redux';
|
|
import PropTypes from 'prop-types';
|
|
import { Route, Switch } from 'react-router-dom';
|
|
import { ConnectedRouter } from 'connected-react-router';
|
|
import { sendTrackEvent } from '@edx/frontend-analytics';
|
|
import { IntlProvider, injectIntl, intlShape, getMessages } from '@edx/frontend-i18n';
|
|
import SiteHeader from '@edx/frontend-component-site-header';
|
|
import SiteFooter from '@edx/frontend-component-footer';
|
|
|
|
import {
|
|
faFacebookSquare,
|
|
faTwitterSquare,
|
|
faYoutubeSquare,
|
|
faLinkedin,
|
|
faRedditSquare,
|
|
} from '@fortawesome/free-brands-svg-icons';
|
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
|
|
import { ErrorBoundary, fetchUserAccount } from '../common';
|
|
import { ConnectedAccountSettingsPage } from '../account-settings';
|
|
|
|
import FooterLogo from '../assets/edx-footer.png';
|
|
import HeaderLogo from '../assets/logo.svg';
|
|
import NotFoundPage from './NotFoundPage';
|
|
|
|
import messages from './App.messages';
|
|
|
|
function PageContent({
|
|
configuration,
|
|
username,
|
|
avatar,
|
|
intl,
|
|
}) {
|
|
const mainMenu = [
|
|
{
|
|
type: 'item',
|
|
href: `${configuration.MARKETING_SITE_BASE_URL}/course`,
|
|
content: intl.formatMessage(messages['siteheader.links.courses']),
|
|
},
|
|
{
|
|
type: 'item',
|
|
href: `${configuration.MARKETING_SITE_BASE_URL}/course?program=all`,
|
|
content: intl.formatMessage(messages['siteheader.links.programs']),
|
|
},
|
|
{
|
|
type: 'item',
|
|
href: `${configuration.MARKETING_SITE_BASE_URL}/schools-partners`,
|
|
content: intl.formatMessage(messages['siteheader.links.schools']),
|
|
},
|
|
];
|
|
const userMenu = [
|
|
{
|
|
type: 'item',
|
|
href: `${configuration.LMS_BASE_URL}`,
|
|
content: intl.formatMessage(messages['siteheader.user.menu.dashboard']),
|
|
},
|
|
{
|
|
type: 'item',
|
|
href: `${configuration.LMS_BASE_URL}/u/${username}`,
|
|
content: intl.formatMessage(messages['siteheader.user.menu.profile']),
|
|
},
|
|
{
|
|
type: 'item',
|
|
href: `${configuration.LMS_BASE_URL}/account/settings`,
|
|
content: intl.formatMessage(messages['siteheader.user.menu.account.settings']),
|
|
},
|
|
{
|
|
type: 'item',
|
|
href: configuration.ORDER_HISTORY_URL,
|
|
content: intl.formatMessage(messages['siteheader.user.menu.order.history']),
|
|
},
|
|
{
|
|
type: 'item',
|
|
href: configuration.LOGOUT_URL,
|
|
content: intl.formatMessage(messages['siteheader.user.menu.logout']),
|
|
},
|
|
];
|
|
const loggedOutItems = [
|
|
{
|
|
type: 'item',
|
|
href: `${configuration.LMS_BASE_URL}/login`,
|
|
content: intl.formatMessage(messages['siteheader.user.menu.login']),
|
|
},
|
|
{
|
|
type: 'item',
|
|
href: `${configuration.LMS_BASE_URL}/register`,
|
|
content: intl.formatMessage(messages['siteheader.user.menu.register']),
|
|
},
|
|
];
|
|
const socialLinks = [
|
|
{
|
|
title: 'Facebook',
|
|
url: configuration.FACEBOOK_URL,
|
|
icon: <FontAwesomeIcon icon={faFacebookSquare} className="social-icon" size="2x" />,
|
|
screenReaderText: 'Like edX on Facebook',
|
|
},
|
|
{
|
|
title: 'Twitter',
|
|
url: configuration.TWITTER_URL,
|
|
icon: <FontAwesomeIcon icon={faTwitterSquare} className="social-icon" size="2x" />,
|
|
screenReaderText: 'Follow edX on Twitter',
|
|
},
|
|
{
|
|
title: 'Youtube',
|
|
url: configuration.YOU_TUBE_URL,
|
|
icon: <FontAwesomeIcon icon={faYoutubeSquare} className="social-icon" size="2x" />,
|
|
screenReaderText: 'Subscribe to the edX YouTube channel',
|
|
},
|
|
{
|
|
title: 'LinkedIn',
|
|
url: configuration.LINKED_IN_URL,
|
|
icon: <FontAwesomeIcon icon={faLinkedin} className="social-icon" size="2x" />,
|
|
screenReaderText: 'Follow edX on LinkedIn',
|
|
},
|
|
{
|
|
title: 'Reddit',
|
|
url: configuration.REDDIT_URL,
|
|
icon: <FontAwesomeIcon icon={faRedditSquare} className="social-icon" size="2x" />,
|
|
screenReaderText: 'Subscribe to the edX subreddit',
|
|
},
|
|
];
|
|
|
|
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 exact path="/" component={ConnectedAccountSettingsPage} />
|
|
<Route path="/notfound" component={NotFoundPage} />
|
|
<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}
|
|
appleAppStoreUrl={configuration.APPLE_APP_STORE_URL}
|
|
googlePlayUrl={configuration.GOOGLE_PLAY_URL}
|
|
socialLinks={socialLinks}
|
|
enterpriseMarketingLink={{
|
|
url: configuration.ENTERPRISE_MARKETING_URL,
|
|
queryParams: {
|
|
utm_source: configuration.ENTERPRISE_MARKETING_UTM_SOURCE,
|
|
utm_campaign: configuration.ENTERPRISE_MARKETING_UTM_CAMPAIGN,
|
|
utm_medium: configuration.ENTERPRISE_MARKETING_FOOTER_UTM_MEDIUM,
|
|
},
|
|
}}
|
|
handleAllTrackEvents={sendTrackEvent}
|
|
/>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const IntlPageContent = injectIntl(PageContent);
|
|
|
|
class App extends Component {
|
|
componentDidMount() {
|
|
const { username } = this.props;
|
|
this.props.fetchUserAccount(username);
|
|
}
|
|
|
|
render() {
|
|
return (
|
|
<ErrorBoundary>
|
|
<IntlProvider locale={this.props.locale} messages={getMessages()}>
|
|
<Provider store={this.props.store}>
|
|
<ConnectedRouter history={this.props.history}>
|
|
<IntlPageContent
|
|
configuration={this.props.configuration}
|
|
username={this.props.username}
|
|
avatar={this.props.avatar}
|
|
/>
|
|
</ConnectedRouter>
|
|
</Provider>
|
|
</IntlProvider>
|
|
</ErrorBoundary>
|
|
);
|
|
}
|
|
}
|
|
|
|
const configurationPropTypes = {
|
|
SITE_NAME: PropTypes.string.isRequired,
|
|
LMS_BASE_URL: PropTypes.string.isRequired,
|
|
LOGOUT_URL: 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,
|
|
REDDIT_URL: PropTypes.string.isRequired,
|
|
APPLE_APP_STORE_URL: PropTypes.string.isRequired,
|
|
GOOGLE_PLAY_URL: PropTypes.string.isRequired,
|
|
ORDER_HISTORY_URL: PropTypes.string.isRequired,
|
|
ENTERPRISE_MARKETING_URL: PropTypes.string.isRequired,
|
|
ENTERPRISE_MARKETING_UTM_SOURCE: PropTypes.string.isRequired,
|
|
ENTERPRISE_MARKETING_UTM_CAMPAIGN: PropTypes.string.isRequired,
|
|
ENTERPRISE_MARKETING_FOOTER_UTM_MEDIUM: PropTypes.string.isRequired,
|
|
};
|
|
|
|
PageContent.propTypes = {
|
|
username: PropTypes.string.isRequired,
|
|
avatar: PropTypes.string,
|
|
configuration: PropTypes.shape(configurationPropTypes).isRequired,
|
|
intl: intlShape.isRequired,
|
|
};
|
|
|
|
PageContent.defaultProps = {
|
|
avatar: null,
|
|
};
|
|
|
|
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
|
|
locale: PropTypes.string.isRequired,
|
|
configuration: PropTypes.shape(configurationPropTypes).isRequired,
|
|
};
|
|
|
|
App.defaultProps = {
|
|
avatar: null,
|
|
};
|
|
|
|
const mapStateToProps = state => ({
|
|
username: state.authentication.username,
|
|
configuration: state.configuration,
|
|
locale: state.i18n.locale,
|
|
avatar: state.userAccount.profileImage.hasImage
|
|
? state.userAccount.profileImage.imageUrlMedium
|
|
: null,
|
|
});
|
|
|
|
export default connect(
|
|
mapStateToProps,
|
|
{
|
|
fetchUserAccount,
|
|
},
|
|
)(App);
|