Compare commits

..

22 Commits

Author SHA1 Message Date
Douglas Hall
ab61fd35eb Merge pull request #34 from edx/douglashall/reduce_bundle_size
fix: remove paragon from bundle
2019-05-23 14:34:38 -04:00
Douglas Hall
4d739f2962 fix: remove paragon from bundle
BREAKING CHANGE: Now requires containing app to provide `@edx/paragon`.
2019-05-23 14:28:28 -04:00
albemarle
28a6c85bc0 Merge pull request #30 from edx/aehsan/prod-277/update_the_edx_icp_license
Updated ICP license in footer
2019-05-22 14:01:36 -04:00
adeelehsan
6125988bbd Updated ICP license in footer 2019-05-22 00:33:19 +05:00
edX Transifex Bot
9eeccc63cb fix(i18n): update translations 2019-05-19 17:33:41 -04:00
Robert Raposa
2f33c6718b Merge pull request #31 from edx/robrap/ARCH-748-fix-i18n-jobs
fix(i18n): fix i18n make targets
2019-05-16 13:20:46 -04:00
Adam Stankiewicz
89397fcfdb Merge pull request #32 from edx/astankiewicz/downgrade-query-string
fix(query-string): downgrade query-string to version 5 for es5
2019-05-16 12:57:21 -04:00
Adam Stankiewicz
278b4b1473 fix(query-string): downgrade query-string to version 5 for es5 2019-05-16 09:44:44 -07:00
Robert Raposa
7ff9039bb7 fix(i18n): fix i18n make targets
ARCH-748
2019-05-16 12:27:27 -04:00
Chris Pappas
0cf3164901 Merge pull request #28 from edx/cpappas/ENT-1888
fix: updating enterprise marketing link logic
2019-05-10 16:55:50 -04:00
Christopher Pappas
bf8020dfac fix: updating business marketing footer
fix: adding https:// to business marketing link

fix: fixing marketing link for business

fix: fixing marketing link for business
2019-05-10 15:49:40 -04:00
Adam Butterworth
f2a13b8c8e fix: move dependencies out of footer 2019-05-10 08:27:18 -06:00
Adam Butterworth
3dd9b25d11 fix: move peerDependencies to dependencies 2019-05-10 10:24:23 -04:00
Adam Butterworth
21d7fe04e3 fix: move dependencies out of footer 2019-05-10 10:14:37 -04:00
AlasdairSwan
46d464d515 Merge pull request #27 from edx/alasdair/add-language-selector
Alasdair/add language selector
2019-05-08 13:42:52 -04:00
AlasdairSwan
85ed8fbff4 feat(langselect): add optional language selector 2019-05-08 13:38:01 -04:00
AlasdairSwan
d6adfec189 Merge pull request #25 from edx/alasdair/update-social-media-link-approach
fix(sociallinks): update link props
2019-05-07 12:53:21 -04:00
AlasdairSwan
8b1943356e fix(sociallinks): update link props
BREAKING CHANGE will not render social links unless array is passed in
2019-05-07 12:17:42 -04:00
AlasdairSwan
5aae6e8336 Merge pull request #26 from edx/alasdair/version-bump
fix(version): trivial update to minor version bump
2019-05-07 12:12:33 -04:00
AlasdairSwan
ae18ad45b9 fix(version): trivial update to minor version bump 2019-05-07 11:56:32 -04:00
AlasdairSwan
0e15bb7e55 Merge pull request #24 from edx/alasdair/revert-social-media-links
Revert social media links PR
2019-05-07 11:30:02 -04:00
AlasdairSwan
ff664b9d3b Revert social media links PR 2019-05-07 11:24:04 -04:00
16 changed files with 7790 additions and 5548 deletions

2
.gitignore vendored
View File

@@ -4,3 +4,5 @@ node_modules
temp
.idea/
src/i18n/transifex_input.json

View File

@@ -1,8 +1,5 @@
extract_translations: ## no prerequisites so we can control order of operations
echo "We have to define this target due to tooling assumptions"
echo "Also we have to npm install using this hook b/c there's no other place for it in the current setup"
requirements:
npm install
npm run-script i18n_extract
i18n.extract:
# Pulling display strings from .jsx files into .json files...
@@ -12,6 +9,12 @@ i18n.concat:
# Gathering JSON messages into one file...
./src/i18n/i18n-concat.js ./temp/src ./src/i18n/transifex_input.json
# The following make targets are required by our tooling scripts found in:
# - https://github.com/edx/ecommerce-scripts/tree/master/transifex
extract_translations: | requirements i18n.extract i18n.concat
detect_changed_source_translations:
git diff --exit-code ./src/i18n/transifex_input.json
@@ -19,7 +22,9 @@ tx_url1 = https://www.transifex.com/api/2/project/edx-platform/resource/frontend
tx_url2 = https://www.transifex.com/api/2/project/edx-platform/resource/frontend-component-footer/source/
# push translations to Transifex, doing magic so we can include the translator comments
push_translations: | i18n.extract
# Note: extract_translations is a prereq that our translation script calls separately.
push_translations:
tx push -s
# Adding translator comments...
# Fetching strings from Transifex...
./node_modules/reactifex/bash_scripts/get_hashed_strings.sh $(tx_url1)

View File

@@ -1,9 +1,9 @@
// This is the dev Webpack config. All settings here should prefer a fast build
// time at the expense of creating larger, unoptimized bundles.
const Merge = require('webpack-merge');
const Merge = require('webpack-merge'); // eslint-disable-line import/no-extraneous-dependencies
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin'); // eslint-disable-line import/no-extraneous-dependencies
const webpack = require('webpack'); // eslint-disable-line import/no-extraneous-dependencies
const commonConfig = require('./webpack.common.config.js');

View File

@@ -1,9 +1,9 @@
// This is the prod Webpack config. All settings here should prefer smaller,
// optimized bundles at the expense of a longer build time.
const Merge = require('webpack-merge');
const Merge = require('webpack-merge'); // eslint-disable-line import/no-extraneous-dependencies
const commonConfig = require('./webpack.common.config.js');
const path = require('path');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin'); // eslint-disable-line import/no-extraneous-dependencies
module.exports = Merge.smart(commonConfig, {
mode: 'production',
@@ -35,6 +35,18 @@ module.exports = Merge.smart(commonConfig, {
amd: 'ReactDOM',
root: 'ReactDOM',
},
'react-intl': {
commonjs: 'react-intl',
commonjs2: 'react-intl',
amd: 'ReactIntl',
root: 'ReactIntl',
},
'@edx/paragon': {
commonjs: '@edx/paragon',
commonjs2: '@edx/paragon',
amd: 'Paragon',
root: 'Paragon',
},
},
plugins: [
// Cleans the dist directory before each build

10999
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -9,6 +9,7 @@
},
"scripts": {
"build": "NODE_ENV=production BABEL_ENV=production webpack --config=config/webpack.prod.config.js",
"build:stats": "NODE_ENV=production BABEL_ENV=production webpack --config=config/webpack.prod.config.js --profile --progress --json > stats.json",
"gc": "commit",
"commitmsg": "commitlint -e $GIT_PARAMS",
"coveralls": "cat ./coverage/lcov.info | coveralls",
@@ -38,7 +39,12 @@
"@commitlint/config-angular": "^6.0.2",
"@commitlint/prompt": "^6.0.2",
"@commitlint/prompt-cli": "^6.0.2",
"@edx/paragon": "^3.8.0",
"@edx/paragon": "^4.2.4",
"@fortawesome/fontawesome-svg-core": "^1.2.17",
"@fortawesome/free-brands-svg-icons": "^5.8.1",
"@fortawesome/free-regular-svg-icons": "^5.8.1",
"@fortawesome/free-solid-svg-icons": "^5.8.1",
"@fortawesome/react-fontawesome": "^0.1.4",
"babel-cli": "^6.26.0",
"babel-core": "^6.26.3",
"babel-loader": "^7.1.5",
@@ -66,7 +72,7 @@
"react": "^16.4.2",
"react-dev-utils": "^5.0.0",
"react-dom": "^16.2.0",
"react-intl": "^2.8.0",
"react-intl": "2.x",
"react-test-renderer": "^16.6.0",
"reactifex": "^1.1.1",
"sass-loader": "^6.0.6",
@@ -80,16 +86,15 @@
"webpack-dev-server": "^3.1.9",
"webpack-merge": "^4.2.1"
},
"dependencies": {
"query-string": "^5.1.1"
},
"peerDependencies": {
"@edx/paragon": "^3.8.0",
"clean-webpack-plugin": "^0.1.19",
"html-webpack-plugin": "^3.2.0",
"@edx/paragon": "^4.2.4",
"prop-types": "^15.5.10",
"react": "^16.4.2",
"react-dom": "^16.2.0",
"react-intl": "2.x",
"webpack": "^4.19.1",
"webpack-merge": "^4.2.1"
"react-intl": "2.x"
},
"jest": {
"setupFiles": [
@@ -106,12 +111,5 @@
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
"\\.(css|scss)$": "identity-obj-proxy"
}
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "^1.2.17",
"@fortawesome/free-brands-svg-icons": "^5.8.1",
"@fortawesome/free-regular-svg-icons": "^5.8.1",
"@fortawesome/free-solid-svg-icons": "^5.8.1",
"@fortawesome/react-fontawesome": "^0.1.4"
}
}

View File

@@ -1,6 +1,6 @@
{
"footer.site-footer.link.about": "About",
"footer.site-footer.link.business": "{siteName} for Business",
"footer.site-footer.link.about": "About",
"footer.site-footer.link.affiliates": "Affiliates",
"footer.site-footer.link.open-source": "Open {siteName}",
"footer.site-footer.link.careers": "Careers",

View File

@@ -1,6 +1,6 @@
{
"footer.site-footer.link.about": "About",
"footer.site-footer.link.business": "{siteName} for Business",
"footer.site-footer.link.about": "About",
"footer.site-footer.link.affiliates": "Affiliates",
"footer.site-footer.link.open-source": "Open {siteName}",
"footer.site-footer.link.careers": "Careers",

View File

@@ -1,6 +1,6 @@
{
"footer.site-footer.link.about": "About",
"footer.site-footer.link.business": "{siteName} for Business",
"footer.site-footer.link.about": "About",
"footer.site-footer.link.affiliates": "Affiliates",
"footer.site-footer.link.open-source": "Open {siteName}",
"footer.site-footer.link.careers": "Careers",

View File

@@ -1,39 +1,39 @@
{
"footer.site-footer.link.about": "About",
"footer.site-footer.link.business": "{siteName} for Business",
"footer.site-footer.link.affiliates": "Affiliates",
"footer.site-footer.link.open-source": "Open {siteName}",
"footer.site-footer.link.careers": "Careers",
"footer.site-footer.link.news": "News",
"footer.site-footer.link.header.legal": "Legal",
"footer.site-footer.link.terms-of-service": "Terms of Service & Honor Code",
"footer.site-footer.link.privacy": "Privacy Policy",
"footer.site-footer.link.accessibility": "Accessibility Policy",
"footer.site-footer.link.trademark": "Trademark Policy",
"footer.site-footer.link.sitemap": "Sitemap",
"footer.site-footer.link.header.connect": "Connect",
"footer.site-footer.link.blog": "Blog",
"footer.site-footer.link.contact-us": "Contact Us",
"footer.site-footer.link.help-center": "Help Center",
"footer.site-footer.link.media-kit": "Media Kit",
"footer.site-footer.link.donate": "Donate",
"footer.site-footer.link.business": "商用{siteName} ",
"footer.site-footer.link.about": "关于",
"footer.site-footer.link.affiliates": "附属机构",
"footer.site-footer.link.open-source": "打开{siteName}",
"footer.site-footer.link.careers": "招才纳贤",
"footer.site-footer.link.news": "新闻",
"footer.site-footer.link.header.legal": "法律条款",
"footer.site-footer.link.terms-of-service": "服务条款 & 荣誉准则",
"footer.site-footer.link.privacy": "隐私政策",
"footer.site-footer.link.accessibility": "可访问策略",
"footer.site-footer.link.trademark": "商标政策",
"footer.site-footer.link.sitemap": "网站导航",
"footer.site-footer.link.header.connect": "连接",
"footer.site-footer.link.blog": "博客",
"footer.site-footer.link.contact-us": "联系我们",
"footer.site-footer.link.help-center": "帮助中心",
"footer.site-footer.link.media-kit": "多媒体工具箱",
"footer.site-footer.link.donate": "捐献",
"footer.site-footer.copyright-text": "{copyrightSymbol} {startDate}{endDate} {siteName} Inc.",
"footer.site-footer.trademark-text": "EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | {icpLicense}",
"footer.site-footer.site-logo.alt-text": "{siteName} logo",
"footer.site-footer.site-logo.aria-label": "{siteName} Home",
"footer.site-footer.facebook.title": "Facebook",
"footer.site-footer.facebook.screen-reader-text": "Like {siteName} on Facebook",
"footer.site-footer.twitter.title": "Twitter",
"footer.site-footer.twitter.screen-reader-text": "Follow {siteName} on Twitter",
"footer.site-footer.site-logo.aria-label": "{siteName} 主页",
"footer.site-footer.facebook.title": "脸书",
"footer.site-footer.facebook.screen-reader-text": "在Facebook上为 {siteName}点赞",
"footer.site-footer.twitter.title": "推特",
"footer.site-footer.twitter.screen-reader-text": "在Twitter上关注 {siteName}",
"footer.site-footer.youtube.title": "Youtube",
"footer.site-footer.youtube.screen-reader-text": "Subscribe to the {siteName} YouTube channel",
"footer.site-footer.youtube.screen-reader-text": "订阅{siteName} YouTube频道",
"footer.site-footer.linkedin.title": "LinkedIn",
"footer.site-footer.linkedin.screen-reader-text": "Follow {siteName} on LinkedIn",
"footer.site-footer.linkedin.screen-reader-text": "在LinkedIn上关注{siteName}",
"footer.site-footer.google-plus.title": "Google+",
"footer.site-footer.google-plus.screen-reader-text": "Follow {siteName} on Google+",
"footer.site-footer.google-plus.screen-reader-text": "在Google+上关注{siteName} ",
"footer.site-footer.reddit.title": "Reddit",
"footer.site-footer.reddit.screen-reader-text": "Subscribe to the {siteName} subreddit",
"footer.site-footer.apple-app-store.alt-text": "Download the {siteName} mobile app from the Apple App Store",
"footer.site-footer.google-play.alt-text": "Download the {siteName} mobile app from Google Play",
"footer.site-footer.footer.aria-label": "Page Footer"
"footer.site-footer.reddit.screen-reader-text": "订阅{siteName} subreddit",
"footer.site-footer.apple-app-store.alt-text": "从Apple App Store下载 {siteName} 的移动客户端",
"footer.site-footer.google-play.alt-text": "从Google Play下载 {siteName} 的移动客户端",
"footer.site-footer.footer.aria-label": "页脚"
}

View File

@@ -1,39 +0,0 @@
{
"footer.site-footer.link.about": "About",
"footer.site-footer.link.business": "{siteName} for Business",
"footer.site-footer.link.affiliates": "Affiliates",
"footer.site-footer.link.open-source": "Open {siteName}",
"footer.site-footer.link.careers": "Careers",
"footer.site-footer.link.news": "News",
"footer.site-footer.link.header.legal": "Legal",
"footer.site-footer.link.terms-of-service": "Terms of Service & Honor Code",
"footer.site-footer.link.privacy": "Privacy Policy",
"footer.site-footer.link.accessibility": "Accessibility Policy",
"footer.site-footer.link.trademark": "Trademark Policy",
"footer.site-footer.link.sitemap": "Sitemap",
"footer.site-footer.link.header.connect": "Connect",
"footer.site-footer.link.blog": "Blog",
"footer.site-footer.link.contact-us": "Contact Us",
"footer.site-footer.link.help-center": "Help Center",
"footer.site-footer.link.media-kit": "Media Kit",
"footer.site-footer.link.donate": "Donate",
"footer.site-footer.copyright-text": "{copyrightSymbol} {startDate}{endDate} {siteName} Inc.",
"footer.site-footer.trademark-text": "EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | {icpLicense}",
"footer.site-footer.site-logo.alt-text": "{siteName} logo",
"footer.site-footer.site-logo.aria-label": "{siteName} Home",
"footer.site-footer.facebook.title": "Facebook",
"footer.site-footer.facebook.screen-reader-text": "Like {siteName} on Facebook",
"footer.site-footer.twitter.title": "Twitter",
"footer.site-footer.twitter.screen-reader-text": "Follow {siteName} on Twitter",
"footer.site-footer.youtube.title": "Youtube",
"footer.site-footer.youtube.screen-reader-text": "Subscribe to the {siteName} YouTube channel",
"footer.site-footer.linkedin.title": "LinkedIn",
"footer.site-footer.linkedin.screen-reader-text": "Follow {siteName} on LinkedIn",
"footer.site-footer.google-plus.title": "Google+",
"footer.site-footer.google-plus.screen-reader-text": "Follow {siteName} on Google+",
"footer.site-footer.reddit.title": "Reddit",
"footer.site-footer.reddit.screen-reader-text": "Subscribe to the {siteName} subreddit",
"footer.site-footer.apple-app-store.alt-text": "Download the {siteName} mobile app from the Apple App Store",
"footer.site-footer.google-play.alt-text": "Download the {siteName} mobile app from Google Play",
"footer.site-footer.footer.aria-label": "Page Footer"
}

View File

@@ -2,6 +2,7 @@ import React from 'react';
import { render } from 'react-dom';
import { IntlProvider } from 'react-intl';
/* eslint-disable import/no-extraneous-dependencies */
import {
faFacebookSquare,
faTwitterSquare,
@@ -10,7 +11,9 @@ import {
faGooglePlusSquare,
faRedditSquare,
} from '@fortawesome/free-brands-svg-icons';
import { faLanguage } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
/* eslint-enable import/no-extraneous-dependencies */
import SiteFooter from './lib';
import './index.scss';
@@ -56,12 +59,17 @@ const socialLinks = [
},
];
const App = () => (
<IntlProvider locale="en">
<SiteFooter
siteName="edX"
siteLogo={FooterLogo}
marketingSiteBaseUrl="https://www.example.com"
enterpriseMarketingLink={{
url: 'https://business.edx.org',
queryParams: { utm_test: 'utm_test_value' },
}}
supportUrl="https://www.example.com/support"
contactUrl="https://www.example.com/contact"
openSourceUrl="https://www.example.com/open"
@@ -71,6 +79,22 @@ const App = () => (
googlePlayUrl="https://play.google.com"
handleAllTrackEvents={() => {}}
socialLinks={socialLinks}
supportedLanguages={[
{
label: 'English',
value: 'en',
}, {
label: 'español',
value: 'es-419',
},
]}
languageForm={{
activeLanguage: 'en',
screenReaderLabel: 'Choose Language',
submitLabel: 'Apply',
icon: <FontAwesomeIcon icon={faLanguage} size="2x" className="text-primary" />,
onLanguageSelected: () => {},
}}
/>
</IntlProvider>
);

View File

@@ -11,6 +11,7 @@ import {
faGooglePlusSquare,
faRedditSquare,
} from '@fortawesome/free-brands-svg-icons';
import { faLanguage } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import FooterLogo from '../../../edx-footer.png';
@@ -56,6 +57,24 @@ const socialLinks = [
},
];
const supportedLanguages = [
{
label: 'English',
value: 'en',
}, {
label: 'español',
value: 'es-419',
},
];
const languageForm = {
activeLanguage: 'en',
screenReaderLabel: 'Choose Language',
submitLabel: 'Apply',
icon: <FontAwesomeIcon icon={faLanguage} size="2x" className="text-primary" />,
onLanguageSelected: () => {},
};
const completeSiteFooterComponent = mockHandleAllTrackEvents =>
(
<IntlProvider locale="en">
@@ -72,6 +91,12 @@ const completeSiteFooterComponent = mockHandleAllTrackEvents =>
appleAppStoreUrl="https://store.apple.com"
googlePlayUrl="https://play.google.com"
handleAllTrackEvents={mockHandleAllTrackEvents}
supportedLanguages={supportedLanguages}
languageForm={languageForm}
enterpriseMarketingLink={{
url: 'https://business.edx.org',
queryParams: { utm_test: 'utm_test_value' },
}}
/>
</IntlProvider>
);
@@ -101,7 +126,13 @@ describe('<SiteFooter />', () => {
privacyPolicyUrl="https://www.example.com/privacy-policy"
appleAppStoreUrl="https://store.apple.com"
googlePlayUrl="https://play.google.com"
supportedLanguages={supportedLanguages}
languageForm={languageForm}
handleAllTrackEvents={jest.fn()}
enterpriseMarketingLink={{
url: 'https://business.edx.org',
queryParams: { utm_test: 'utm_test_value' },
}}
/>
</IntlProvider>
)).toJSON();
@@ -124,6 +155,8 @@ describe('<SiteFooter />', () => {
socialLinks={socialLinks}
appleAppStoreUrl="https://store.apple.com"
googlePlayUrl="https://play.google.com"
supportedLanguages={supportedLanguages}
languageForm={languageForm}
handleAllTrackEvents={jest.fn()}
showMobileLinks={false}
/>
@@ -131,6 +164,50 @@ describe('<SiteFooter />', () => {
)).toJSON();
expect(tree).toMatchSnapshot();
});
it('does not render language selector', () => {
const tree = renderer
.create((
<IntlProvider locale="en">
<SiteFooter
siteName="example"
siteLogo={FooterLogo}
marketingSiteBaseUrl="https://www.example.com"
supportUrl="https://www.example.com/support"
contactUrl="https://www.example.com/contact"
openSourceUrl="https://www.example.com/open"
termsOfServiceUrl="https://www.example.com/terms-of-service"
privacyPolicyUrl="https://www.example.com/privacy-policy"
appleAppStoreUrl="https://store.apple.com"
googlePlayUrl="https://play.google.com"
handleAllTrackEvents={jest.fn()}
/>
</IntlProvider>
)).toJSON();
expect(tree).toMatchSnapshot();
});
it('does not render business links', () => {
const tree = renderer
.create((
<IntlProvider locale="en">
<SiteFooter
siteName="example"
siteLogo={FooterLogo}
marketingSiteBaseUrl="https://www.example.com"
supportUrl="https://www.example.com/support"
contactUrl="https://www.example.com/contact"
openSourceUrl="https://www.example.com/open"
termsOfServiceUrl="https://www.example.com/terms-of-service"
privacyPolicyUrl="https://www.example.com/privacy-policy"
appleAppStoreUrl="https://store.apple.com"
googlePlayUrl="https://play.google.com"
handleAllTrackEvents={jest.fn()}
/>
</IntlProvider>
)).toJSON();
expect(tree).toMatchSnapshot();
});
});
describe('handles analytics', () => {

View File

@@ -1,6 +1,6 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<SiteFooter /> renders correctly does not render mobile links 1`] = `
exports[`<SiteFooter /> renders correctly does not render business links 1`] = `
<footer
aria-label="Page Footer"
className="footer d-flex justify-content-center border-top py-3 px-4"
@@ -44,10 +44,559 @@ exports[`<SiteFooter /> renders correctly does not render mobile links 1`] = `
</li>
<li>
<a
href="https://www.example.com/enterprise"
href="https://www.example.com/affiliate-program"
>
<span>
example for Business
Affiliates
</span>
</a>
</li>
<li>
<a
href="https://www.example.com/open"
>
<span>
Open example
</span>
</a>
</li>
<li>
<a
href="https://www.example.com/careers"
>
<span>
Careers
</span>
</a>
</li>
<li>
<a
href="https://www.example.com/news-announcements"
>
<span>
News
</span>
</a>
</li>
</ul>
</div>
<div
className="area-3"
>
<h2>
<span>
Legal
</span>
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/terms-of-service"
>
<span>
Terms of Service & Honor Code
</span>
</a>
</li>
<li>
<a
href="https://www.example.com/privacy-policy"
>
<span>
Privacy Policy
</span>
</a>
</li>
<li>
<a
href="https://www.example.com/accessibility"
>
<span>
Accessibility Policy
</span>
</a>
</li>
<li>
<a
href="https://www.example.com/trademarks"
>
<span>
Trademark Policy
</span>
</a>
</li>
<li>
<a
href="https://www.example.com/sitemap"
>
<span>
Sitemap
</span>
</a>
</li>
</ul>
</div>
<div
className="area-4"
>
<h2>
<span>
Connect
</span>
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/blog"
>
<span>
Blog
</span>
</a>
</li>
<li>
<a
href="https://www.example.com/contact"
>
<span>
Contact Us
</span>
</a>
</li>
<li>
<a
href="https://www.example.com/support"
>
<span>
Help Center
</span>
</a>
</li>
<li>
<a
href="https://www.example.com/media-kit"
>
<span>
Media Kit
</span>
</a>
</li>
<li>
<a
href="https://www.example.com/donate"
>
<span>
Donate
</span>
</a>
</li>
</ul>
</div>
<div
className="area-5"
>
<ul
className="d-flex flex-row justify-content-between list-unstyled max-width-264 p-0 mb-5"
>
<li>
<a
href="https://store.apple.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
>
<img
alt="Download the example mobile app from the Apple App Store"
className="max-height-39"
src="https://prod-edxapp.edx-cdn.org/static/images/app/app_store_badge_135x40.d0558d910630.svg"
/>
</a>
</li>
<li>
<a
href="https://play.google.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
>
<img
alt="Download the example mobile app from Google Play"
className="max-height-39"
src="https://prod-edxapp.edx-cdn.org/static/images/app/google_play_badge_45.6ea466e328da.png"
/>
</a>
</li>
</ul>
<p>
<span>
© 20122019 example Inc.
</span>
<br />
<span>
EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 深圳市恒宇博科技有限公司
<a
href="http://www.beian.miit.gov.cn"
>
粤ICP备17044299号-2
</a>
</span>
</p>
</div>
</div>
</footer>
`;
exports[`<SiteFooter /> renders correctly does not render language selector 1`] = `
<footer
aria-label="Page Footer"
className="footer d-flex justify-content-center border-top py-3 px-4"
role="contentinfo"
>
<div
className="max-width-1180 d-grid"
>
<div
className="area-1"
>
<a
aria-label="example Home"
href="https://www.example.com/"
onClick={[Function]}
target="_self"
>
<img
alt="example logo"
src="test-file-stub"
/>
</a>
</div>
<div
className="area-2"
>
<h2>
example
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/about-us"
>
<span>
About
</span>
</a>
</li>
<li>
<a
href="https://www.example.com/affiliate-program"
>
<span>
Affiliates
</span>
</a>
</li>
<li>
<a
href="https://www.example.com/open"
>
<span>
Open example
</span>
</a>
</li>
<li>
<a
href="https://www.example.com/careers"
>
<span>
Careers
</span>
</a>
</li>
<li>
<a
href="https://www.example.com/news-announcements"
>
<span>
News
</span>
</a>
</li>
</ul>
</div>
<div
className="area-3"
>
<h2>
<span>
Legal
</span>
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/terms-of-service"
>
<span>
Terms of Service & Honor Code
</span>
</a>
</li>
<li>
<a
href="https://www.example.com/privacy-policy"
>
<span>
Privacy Policy
</span>
</a>
</li>
<li>
<a
href="https://www.example.com/accessibility"
>
<span>
Accessibility Policy
</span>
</a>
</li>
<li>
<a
href="https://www.example.com/trademarks"
>
<span>
Trademark Policy
</span>
</a>
</li>
<li>
<a
href="https://www.example.com/sitemap"
>
<span>
Sitemap
</span>
</a>
</li>
</ul>
</div>
<div
className="area-4"
>
<h2>
<span>
Connect
</span>
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/blog"
>
<span>
Blog
</span>
</a>
</li>
<li>
<a
href="https://www.example.com/contact"
>
<span>
Contact Us
</span>
</a>
</li>
<li>
<a
href="https://www.example.com/support"
>
<span>
Help Center
</span>
</a>
</li>
<li>
<a
href="https://www.example.com/media-kit"
>
<span>
Media Kit
</span>
</a>
</li>
<li>
<a
href="https://www.example.com/donate"
>
<span>
Donate
</span>
</a>
</li>
</ul>
</div>
<div
className="area-5"
>
<ul
className="d-flex flex-row justify-content-between list-unstyled max-width-264 p-0 mb-5"
>
<li>
<a
href="https://store.apple.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
>
<img
alt="Download the example mobile app from the Apple App Store"
className="max-height-39"
src="https://prod-edxapp.edx-cdn.org/static/images/app/app_store_badge_135x40.d0558d910630.svg"
/>
</a>
</li>
<li>
<a
href="https://play.google.com"
onClick={[Function]}
rel="noopener noreferrer"
target="_blank"
>
<img
alt="Download the example mobile app from Google Play"
className="max-height-39"
src="https://prod-edxapp.edx-cdn.org/static/images/app/google_play_badge_45.6ea466e328da.png"
/>
</a>
</li>
</ul>
<p>
<span>
© 20122019 example Inc.
</span>
<br />
<span>
EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 深圳市恒宇博科技有限公司
<a
href="http://www.beian.miit.gov.cn"
>
粤ICP备17044299号-2
</a>
</span>
</p>
</div>
</div>
</footer>
`;
exports[`<SiteFooter /> renders correctly does not render mobile links 1`] = `
<footer
aria-label="Page Footer"
className="footer d-flex justify-content-center border-top py-3 px-4"
role="contentinfo"
>
<div
className="max-width-1180 d-grid"
>
<div
className="area-1"
>
<a
aria-label="example Home"
href="https://www.example.com/"
onClick={[Function]}
target="_self"
>
<img
alt="example logo"
src="test-file-stub"
/>
</a>
<div
className="i18n d-flex mt-2"
>
<form
className="d-flex align-items-start"
onSubmit={[Function]}
>
<label
htmlFor="site-footer-language-select"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-language fa-w-20 fa-2x text-primary"
data-icon="language"
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 640 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M152.1 236.2c-3.5-12.1-7.8-33.2-7.8-33.2h-.5s-4.3 21.1-7.8 33.2l-11.1 37.5H163zM616 96H336v320h280c13.3 0 24-10.7 24-24V120c0-13.3-10.7-24-24-24zm-24 120c0 6.6-5.4 12-12 12h-11.4c-6.9 23.6-21.7 47.4-42.7 69.9 8.4 6.4 17.1 12.5 26.1 18 5.5 3.4 7.3 10.5 4.1 16.2l-7.9 13.9c-3.4 5.9-10.9 7.8-16.7 4.3-12.6-7.8-24.5-16.1-35.4-24.9-10.9 8.7-22.7 17.1-35.4 24.9-5.8 3.5-13.3 1.6-16.7-4.3l-7.9-13.9c-3.2-5.6-1.4-12.8 4.2-16.2 9.3-5.7 18-11.7 26.1-18-7.9-8.4-14.9-17-21-25.7-4-5.7-2.2-13.6 3.7-17.1l6.5-3.9 7.3-4.3c5.4-3.2 12.4-1.7 16 3.4 5 7 10.8 14 17.4 20.9 13.5-14.2 23.8-28.9 30-43.2H412c-6.6 0-12-5.4-12-12v-16c0-6.6 5.4-12 12-12h64v-16c0-6.6 5.4-12 12-12h16c6.6 0 12 5.4 12 12v16h64c6.6 0 12 5.4 12 12zM0 120v272c0 13.3 10.7 24 24 24h280V96H24c-13.3 0-24 10.7-24 24zm58.9 216.1L116.4 167c1.7-4.9 6.2-8.1 11.4-8.1h32.5c5.1 0 9.7 3.3 11.4 8.1l57.5 169.1c2.6 7.8-3.1 15.9-11.4 15.9h-22.9a12 12 0 0 1-11.5-8.6l-9.4-31.9h-60.2l-9.1 31.8c-1.5 5.1-6.2 8.7-11.5 8.7H70.3c-8.2 0-14-8.1-11.4-15.9z"
fill="currentColor"
style={Object {}}
/>
</svg>
<div
className="sr-only"
>
Choose Language
</div>
</label>
<select
className="mx-2 mt-1"
defaultValue="en"
id="site-footer-language-select"
name="site-footer-language-select"
>
<option
value="en"
>
English
</option>
<option
value="es-419"
>
español
</option>
</select>
<button
className="mt-1"
type="submit"
>
Apply
</button>
</form>
</div>
</div>
<div
className="area-2"
>
<h2>
example
</h2>
<ul
className="list-unstyled p-0 m-0"
>
<li>
<a
href="https://www.example.com/about-us"
>
<span>
About
</span>
</a>
</li>
@@ -410,7 +959,12 @@ exports[`<SiteFooter /> renders correctly does not render mobile links 1`] = `
</span>
<br />
<span>
EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 粤ICP备17044299号-2
EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 深圳市恒宇博科技有限公司
<a
href="http://www.beian.miit.gov.cn"
>
粤ICP备17044299号-2
</a>
</span>
</p>
</div>
@@ -441,6 +995,64 @@ exports[`<SiteFooter /> renders correctly does not render social links 1`] = `
src="test-file-stub"
/>
</a>
<div
className="i18n d-flex mt-2"
>
<form
className="d-flex align-items-start"
onSubmit={[Function]}
>
<label
htmlFor="site-footer-language-select"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-language fa-w-20 fa-2x text-primary"
data-icon="language"
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 640 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M152.1 236.2c-3.5-12.1-7.8-33.2-7.8-33.2h-.5s-4.3 21.1-7.8 33.2l-11.1 37.5H163zM616 96H336v320h280c13.3 0 24-10.7 24-24V120c0-13.3-10.7-24-24-24zm-24 120c0 6.6-5.4 12-12 12h-11.4c-6.9 23.6-21.7 47.4-42.7 69.9 8.4 6.4 17.1 12.5 26.1 18 5.5 3.4 7.3 10.5 4.1 16.2l-7.9 13.9c-3.4 5.9-10.9 7.8-16.7 4.3-12.6-7.8-24.5-16.1-35.4-24.9-10.9 8.7-22.7 17.1-35.4 24.9-5.8 3.5-13.3 1.6-16.7-4.3l-7.9-13.9c-3.2-5.6-1.4-12.8 4.2-16.2 9.3-5.7 18-11.7 26.1-18-7.9-8.4-14.9-17-21-25.7-4-5.7-2.2-13.6 3.7-17.1l6.5-3.9 7.3-4.3c5.4-3.2 12.4-1.7 16 3.4 5 7 10.8 14 17.4 20.9 13.5-14.2 23.8-28.9 30-43.2H412c-6.6 0-12-5.4-12-12v-16c0-6.6 5.4-12 12-12h64v-16c0-6.6 5.4-12 12-12h16c6.6 0 12 5.4 12 12v16h64c6.6 0 12 5.4 12 12zM0 120v272c0 13.3 10.7 24 24 24h280V96H24c-13.3 0-24 10.7-24 24zm58.9 216.1L116.4 167c1.7-4.9 6.2-8.1 11.4-8.1h32.5c5.1 0 9.7 3.3 11.4 8.1l57.5 169.1c2.6 7.8-3.1 15.9-11.4 15.9h-22.9a12 12 0 0 1-11.5-8.6l-9.4-31.9h-60.2l-9.1 31.8c-1.5 5.1-6.2 8.7-11.5 8.7H70.3c-8.2 0-14-8.1-11.4-15.9z"
fill="currentColor"
style={Object {}}
/>
</svg>
<div
className="sr-only"
>
Choose Language
</div>
</label>
<select
className="mx-2 mt-1"
defaultValue="en"
id="site-footer-language-select"
name="site-footer-language-select"
>
<option
value="en"
>
English
</option>
<option
value="es-419"
>
español
</option>
</select>
<button
className="mt-1"
type="submit"
>
Apply
</button>
</form>
</div>
</div>
<div
className="area-2"
@@ -462,7 +1074,7 @@ exports[`<SiteFooter /> renders correctly does not render social links 1`] = `
</li>
<li>
<a
href="https://www.example.com/enterprise"
href="https://business.edx.org/?utm_test=utm_test_value"
>
<span>
example for Business
@@ -664,7 +1276,12 @@ exports[`<SiteFooter /> renders correctly does not render social links 1`] = `
</span>
<br />
<span>
EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 粤ICP备17044299号-2
EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 深圳市恒宇博科技有限公司
<a
href="http://www.beian.miit.gov.cn"
>
粤ICP备17044299号-2
</a>
</span>
</p>
</div>
@@ -695,6 +1312,64 @@ exports[`<SiteFooter /> renders correctly renders with social and mobile links 1
src="test-file-stub"
/>
</a>
<div
className="i18n d-flex mt-2"
>
<form
className="d-flex align-items-start"
onSubmit={[Function]}
>
<label
htmlFor="site-footer-language-select"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-language fa-w-20 fa-2x text-primary"
data-icon="language"
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 640 512"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M152.1 236.2c-3.5-12.1-7.8-33.2-7.8-33.2h-.5s-4.3 21.1-7.8 33.2l-11.1 37.5H163zM616 96H336v320h280c13.3 0 24-10.7 24-24V120c0-13.3-10.7-24-24-24zm-24 120c0 6.6-5.4 12-12 12h-11.4c-6.9 23.6-21.7 47.4-42.7 69.9 8.4 6.4 17.1 12.5 26.1 18 5.5 3.4 7.3 10.5 4.1 16.2l-7.9 13.9c-3.4 5.9-10.9 7.8-16.7 4.3-12.6-7.8-24.5-16.1-35.4-24.9-10.9 8.7-22.7 17.1-35.4 24.9-5.8 3.5-13.3 1.6-16.7-4.3l-7.9-13.9c-3.2-5.6-1.4-12.8 4.2-16.2 9.3-5.7 18-11.7 26.1-18-7.9-8.4-14.9-17-21-25.7-4-5.7-2.2-13.6 3.7-17.1l6.5-3.9 7.3-4.3c5.4-3.2 12.4-1.7 16 3.4 5 7 10.8 14 17.4 20.9 13.5-14.2 23.8-28.9 30-43.2H412c-6.6 0-12-5.4-12-12v-16c0-6.6 5.4-12 12-12h64v-16c0-6.6 5.4-12 12-12h16c6.6 0 12 5.4 12 12v16h64c6.6 0 12 5.4 12 12zM0 120v272c0 13.3 10.7 24 24 24h280V96H24c-13.3 0-24 10.7-24 24zm58.9 216.1L116.4 167c1.7-4.9 6.2-8.1 11.4-8.1h32.5c5.1 0 9.7 3.3 11.4 8.1l57.5 169.1c2.6 7.8-3.1 15.9-11.4 15.9h-22.9a12 12 0 0 1-11.5-8.6l-9.4-31.9h-60.2l-9.1 31.8c-1.5 5.1-6.2 8.7-11.5 8.7H70.3c-8.2 0-14-8.1-11.4-15.9z"
fill="currentColor"
style={Object {}}
/>
</svg>
<div
className="sr-only"
>
Choose Language
</div>
</label>
<select
className="mx-2 mt-1"
defaultValue="en"
id="site-footer-language-select"
name="site-footer-language-select"
>
<option
value="en"
>
English
</option>
<option
value="es-419"
>
español
</option>
</select>
<button
className="mt-1"
type="submit"
>
Apply
</button>
</form>
</div>
</div>
<div
className="area-2"
@@ -716,7 +1391,7 @@ exports[`<SiteFooter /> renders correctly renders with social and mobile links 1
</li>
<li>
<a
href="https://www.example.com/enterprise"
href="https://business.edx.org/?utm_test=utm_test_value"
>
<span>
example for Business
@@ -1114,7 +1789,12 @@ exports[`<SiteFooter /> renders correctly renders with social and mobile links 1
</span>
<br />
<span>
EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 粤ICP备17044299号-2
EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 深圳市恒宇博科技有限公司
<a
href="http://www.beian.miit.gov.cn"
>
粤ICP备17044299号-2
</a>
</span>
</p>
</div>

View File

@@ -2,16 +2,27 @@ import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage, injectIntl, intlShape } from 'react-intl';
import { Hyperlink } from '@edx/paragon';
import qs from 'query-string';
import messages from './SiteFooter.messages';
const EVENT_NAMES = {
FOOTER_LINK: 'edx.bi.footer.link',
};
class SiteFooter extends React.Component {
constructor(props) {
super(props);
this.externalLinkClickHandler = this.externalLinkClickHandler.bind(this);
this.applyLanguageSelection = this.applyLanguageSelection.bind(this);
}
applyLanguageSelection(event) {
event.preventDefault();
const languageCode = event.target.elements['site-footer-language-select'].value;
const { languageForm: { onLanguageSelected } } = this.props;
onLanguageSelected(languageCode);
}
externalLinkClickHandler(event) {
@@ -40,6 +51,14 @@ class SiteFooter extends React.Component {
return `${this.props.marketingSiteBaseUrl}${path}`;
}
renderEnterpriseMarketingSiteUrl(enterpriseLinkData) {
const {
queryParams,
url,
} = enterpriseLinkData;
return queryParams ? `${url}/?${qs.stringify(queryParams)}` : url;
}
renderMobileLinks() {
const {
intl,
@@ -82,6 +101,22 @@ class SiteFooter extends React.Component {
return mobileLinks;
}
renderBusinessMarketingListItem() {
const { siteName, enterpriseMarketingLink } = this.props;
return enterpriseMarketingLink && (
<li>
<a href={this.renderEnterpriseMarketingSiteUrl(enterpriseMarketingLink)}>
<FormattedMessage
id="footer.site-footer.link.business"
defaultMessage="{siteName} for Business"
description="A link that points to a business marketing page for a specified website"
values={{ siteName }}
/>
</a>
</li>
);
}
render() {
const {
intl,
@@ -92,7 +127,11 @@ class SiteFooter extends React.Component {
contactUrl,
supportUrl,
socialLinks,
supportedLanguages,
languageForm,
} = this.props;
const showLanguageSelector = supportedLanguages.length > 0 &&
languageForm;
return (
<footer
role="contentinfo"
@@ -109,6 +148,30 @@ class SiteFooter extends React.Component {
{ siteName },
)}
/>
{showLanguageSelector &&
<div className="i18n d-flex mt-2">
<form
className="d-flex align-items-start"
onSubmit={this.applyLanguageSelection}
>
{/* eslint-disable-next-line jsx-a11y/label-has-for */}
<label htmlFor="site-footer-language-select">
{languageForm.icon}
<div className="sr-only">{languageForm.screenReaderLabel}</div>
</label>
<select
id="site-footer-language-select"
className="mx-2 mt-1"
name="site-footer-language-select"
defaultValue={languageForm.activeLanguage}
>
{supportedLanguages.map(({ value, label }) =>
<option key={value} value={value}>{label}</option>)}
</select>
<button className="mt-1" type="submit">{languageForm.submitLabel}</button>
</form>
</div>
}
</div>
<div className="area-2">
<h2>{siteName}</h2>
@@ -121,15 +184,7 @@ class SiteFooter extends React.Component {
/>
</a>
</li>
<li>
<a href={this.renderMarketingSiteUrl('/enterprise')}>
<FormattedMessage
id="footer.site-footer.link.business"
defaultMessage="{siteName} for Business"
values={{ siteName }}
/>
</a>
</li>
{this.renderBusinessMarketingListItem()}
<li>
<a href={this.renderMarketingSiteUrl('/affiliate-program')}>
<FormattedMessage
@@ -303,8 +358,8 @@ class SiteFooter extends React.Component {
<br />
<FormattedMessage
id="footer.site-footer.trademark-text"
defaultMessage="EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | {icpLicense}"
values={{ icpLicense: '粤ICP备17044299号-2' }}
defaultMessage="EdX, Open edX, and MicroMasters are registered trademarks of edX Inc. | 深圳市恒宇博科技有限公司 {icpLicense}"
values={{ icpLicense: <a href="http://www.beian.miit.gov.cn">粤ICP备17044299号-2</a> }}
description="Footer trademark text"
/>
</p>
@@ -319,6 +374,10 @@ SiteFooter.propTypes = {
siteName: PropTypes.string,
siteLogo: PropTypes.node,
marketingSiteBaseUrl: PropTypes.string,
enterpriseMarketingLink: PropTypes.shape({
url: PropTypes.string,
queryParams: PropTypes.shape({}),
}),
supportUrl: PropTypes.string,
contactUrl: PropTypes.string,
openSourceUrl: PropTypes.string,
@@ -333,6 +392,17 @@ SiteFooter.propTypes = {
showMobileLinks: PropTypes.bool,
appleAppStoreUrl: PropTypes.string,
googlePlayUrl: PropTypes.string,
supportedLanguages: PropTypes.arrayOf(PropTypes.shape({
label: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
})),
languageForm: PropTypes.shape({
screenReaderLabel: PropTypes.string.isRequired,
submitLabel: PropTypes.string.isRequired,
onLanguageSelected: PropTypes.func.isRequired,
icon: PropTypes.node.isRequired,
activeLanguage: PropTypes.string,
}),
handleAllTrackEvents: PropTypes.func.isRequired,
intl: intlShape.isRequired,
};
@@ -341,6 +411,7 @@ SiteFooter.defaultProps = {
siteName: null,
siteLogo: null,
marketingSiteBaseUrl: null,
enterpriseMarketingLink: null,
supportUrl: null,
contactUrl: null,
openSourceUrl: null,
@@ -350,6 +421,8 @@ SiteFooter.defaultProps = {
showMobileLinks: true,
appleAppStoreUrl: null,
googlePlayUrl: null,
supportedLanguages: [],
languageForm: null,
};
export default injectIntl(SiteFooter);

1275
stats.json Normal file

File diff suppressed because one or more lines are too long