Files
frontend-app-account/src/components/App.jsx

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);