Compare commits
2 Commits
v12.3.0
...
djoy/moder
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9667a5cee4 | ||
|
|
9df6e12174 |
31
.babelrc
31
.babelrc
@@ -1,28 +1,23 @@
|
||||
{
|
||||
"presets": [
|
||||
["env", {
|
||||
"targets": {
|
||||
"browsers": ["last 2 versions", "ie 11"]
|
||||
}
|
||||
}],
|
||||
"babel-preset-react"
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"modules": false
|
||||
},
|
||||
],
|
||||
"@babel/preset-react"
|
||||
],
|
||||
"plugins": [
|
||||
"transform-object-rest-spread"
|
||||
["@babel/plugin-proposal-object-rest-spread", {}, "object-rest-spread"],
|
||||
["@babel/plugin-proposal-class-properties", {}, "class-properties"]
|
||||
],
|
||||
"env": {
|
||||
"test": {
|
||||
"plugins": [
|
||||
"rewire"
|
||||
]
|
||||
},
|
||||
"i18n": {
|
||||
"plugins": [
|
||||
["react-intl", {
|
||||
"messagesDir": "./temp/babel-plugin-react-intl",
|
||||
"moduleSourceName": "@edx/frontend-i18n"
|
||||
}]
|
||||
]
|
||||
"presets": [
|
||||
"@babel/preset-env",
|
||||
"@babel/preset-react"
|
||||
],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,7 @@
|
||||
"error",
|
||||
{
|
||||
"devDependencies": [
|
||||
"webpack.config.js",
|
||||
"src/tests/setupTest.js",
|
||||
"src/lib/setupTest.js",
|
||||
"**/*.test.jsx",
|
||||
"**/*.test.js"
|
||||
]
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -1,9 +1,6 @@
|
||||
coverage
|
||||
dist
|
||||
node_modules
|
||||
temp
|
||||
|
||||
.idea/
|
||||
|
||||
src/i18n/transifex_input.json
|
||||
temp/babel-plugin-react-intl
|
||||
/.cache
|
||||
|
||||
@@ -8,10 +8,8 @@ install:
|
||||
- npm install
|
||||
script:
|
||||
- npm run lint
|
||||
- npm run i18n_extract
|
||||
- npm run test
|
||||
- npm run build
|
||||
- npm run is-es5
|
||||
after_success:
|
||||
- npm run travis-deploy-once "npm run semantic-release"
|
||||
- npm run coveralls
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
[main]
|
||||
host = https://www.transifex.com
|
||||
|
||||
[edx-platform.frontend-component-footer]
|
||||
file_filter = src/i18n/messages/<lang>.json
|
||||
source_file = src/i18n/transifex_input.json
|
||||
source_lang = en
|
||||
type = KEYVALUEJSON
|
||||
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"restructuredtext.confPath": ""
|
||||
}
|
||||
52
Makefile
52
Makefile
@@ -1,50 +1,16 @@
|
||||
transifex_resource = frontend-component-footer
|
||||
transifex_langs = "ar,fr,es_419,zh_CN"
|
||||
|
||||
transifex_utils = ./node_modules/.bin/transifex-utils.js
|
||||
i18n = ./src/i18n
|
||||
transifex_input = $(i18n)/transifex_input.json
|
||||
tx_url1 = https://www.transifex.com/api/2/project/edx-platform/resource/$(transifex_resource)/translation/en/strings/
|
||||
tx_url2 = https://www.transifex.com/api/2/project/edx-platform/resource/$(transifex_resource)/source/
|
||||
|
||||
# This directory must match .babelrc .
|
||||
transifex_temp = ./temp/babel-plugin-react-intl
|
||||
|
||||
requirements:
|
||||
npm install
|
||||
|
||||
i18n.extract:
|
||||
# Pulling display strings from .jsx files into .json files...
|
||||
rm -rf $(transifex_temp)
|
||||
npm run-script i18n_extract
|
||||
|
||||
i18n.concat:
|
||||
# Gathering JSON messages into one file...
|
||||
$(transifex_utils) $(transifex_temp) $(transifex_input)
|
||||
|
||||
extract_translations: | requirements i18n.extract i18n.concat
|
||||
|
||||
# Despite the name, we actually need this target to detect changes in the incoming translated message files as well.
|
||||
detect_changed_source_translations:
|
||||
# Checking for changed translations...
|
||||
git diff --exit-code $(i18n)
|
||||
|
||||
# Pushes translations to Transifex. You must run make extract_translations first.
|
||||
push_translations:
|
||||
# Pushing strings to Transifex...
|
||||
tx push -s
|
||||
# Fetching hashes from Transifex...
|
||||
./node_modules/reactifex/bash_scripts/get_hashed_strings.sh $(tx_url1)
|
||||
# Writing out comments to file...
|
||||
$(transifex_utils) $(transifex_temp) --comments
|
||||
# Pushing comments to Transifex...
|
||||
./node_modules/reactifex/bash_scripts/put_comments.sh $(tx_url2)
|
||||
|
||||
# Pulls translations from Transifex.
|
||||
pull_translations:
|
||||
tx pull -f --mode reviewed --language=$(transifex_langs)
|
||||
|
||||
# This target is used by Travis.
|
||||
validate-no-uncommitted-package-lock-changes:
|
||||
# Checking for package-lock.json changes...
|
||||
git diff --exit-code package-lock.json
|
||||
|
||||
build:
|
||||
rm -rf ./dist
|
||||
./node_modules/.bin/babel src --out-dir dist --source-maps --ignore **/*.test.jsx,**/*.stories.jsx,**/__mocks__,**/__snapshots__,**/setupTest.js --copy-files
|
||||
rm -rf ./dist/example
|
||||
rm -rf dist/**/*.test.jsx
|
||||
rm -rf dist/**/__snapshots__
|
||||
rm -rf dist/**/__mocks__
|
||||
rm -rf dist/lib/setupTest.js
|
||||
|
||||
12
README.rst
12
README.rst
@@ -4,10 +4,7 @@ frontend-component-footer
|
||||
|Build Status| |Coveralls| |npm_version| |npm_downloads| |license|
|
||||
|semantic-release|
|
||||
|
||||
frontend-component-footer is a library containing a site footer
|
||||
component for use when building edX frontend applications.
|
||||
|
||||
At this time, this component is hard-coded to match the legacy LMS site footer, including all of its links. As implemented, this component should probably be called the ``frontend-component-lms-footer``.
|
||||
frontend-component-footer is a library containing a site footer component for use when building edX frontend applications.
|
||||
|
||||
Usage
|
||||
-----
|
||||
@@ -17,13 +14,10 @@ To install frontend-component-footer into your project::
|
||||
npm i --save @edx/frontend-component-footer
|
||||
|
||||
The component expects properties specifying the various URLs that are
|
||||
linked in the footer. See the sample app in `src/index.jsx <src/index.jsx>`__ for an example
|
||||
linked in the footer. See the sample app in `src/example/index.jsx <src/example/index.jsx>`__ for an example
|
||||
of how the SiteFooter component can be specified.
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
This component uses ``@edx/frontend-i18n``. Any containing app must provide ``@edx/frontend-i18n`` as a peer dependency, and be wrapped inside an ``IntlProvider`` element, whether or not your consuming application is actually localized. For a basic default locale (English) version, follow the ``IntlProvider`` example in the sample application in `src/index.jsx <src/index.jsx>`__.
|
||||
The distribution
|
||||
|
||||
Development
|
||||
-----------
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
// This is the common Webpack config. The dev and prod Webpack configs both
|
||||
// inherit config defined here.
|
||||
const path = require('path');
|
||||
|
||||
module.exports = {
|
||||
entry: {
|
||||
app: path.resolve(__dirname, '../src/index.jsx'),
|
||||
},
|
||||
output: {
|
||||
path: path.resolve(__dirname, '../dist'),
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js', '.jsx'],
|
||||
},
|
||||
};
|
||||
@@ -1,115 +0,0 @@
|
||||
// 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'); // eslint-disable-line import/no-extraneous-dependencies
|
||||
const path = require('path');
|
||||
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');
|
||||
|
||||
module.exports = Merge.smart(commonConfig, {
|
||||
mode: 'development',
|
||||
entry: [
|
||||
// enable react's custom hot dev client so we get errors reported in the browser
|
||||
require.resolve('react-dev-utils/webpackHotDevClient'),
|
||||
path.resolve(__dirname, '../src/index.jsx'),
|
||||
],
|
||||
module: {
|
||||
// Specify file-by-file rules to Webpack. Some file-types need a particular kind of loader.
|
||||
rules: [
|
||||
// The babel-loader transforms newer ES2015+ syntax to older ES5 for older browsers.
|
||||
// Babel is configured with the .babelrc file at the root of the project.
|
||||
{
|
||||
test: /\.(js|jsx)$/,
|
||||
include: [
|
||||
path.resolve(__dirname, '../src'),
|
||||
],
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
// Caches result of loader to the filesystem. Future builds will attempt to read from the
|
||||
// cache to avoid needing to run the expensive recompilation process on each run.
|
||||
cacheDirectory: true,
|
||||
},
|
||||
},
|
||||
// We are not extracting CSS from the javascript bundles in development because extracting
|
||||
// prevents hot-reloading from working, it increases build time, and we don't care about
|
||||
// flash-of-unstyled-content issues in development.
|
||||
{
|
||||
test: /(.scss|.css)$/,
|
||||
use: [
|
||||
'style-loader', // creates style nodes from JS strings
|
||||
{
|
||||
loader: 'css-loader', // translates CSS into CommonJS
|
||||
options: {
|
||||
sourceMap: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
loader: 'sass-loader', // compiles Sass to CSS
|
||||
options: {
|
||||
sourceMap: true,
|
||||
includePaths: [
|
||||
path.join(__dirname, '../node_modules'),
|
||||
path.join(__dirname, '../src'),
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
// Webpack, by default, uses the url-loader for images and fonts that are required/included by
|
||||
// files it processes, which just base64 encodes them and inlines them in the javascript
|
||||
// bundles. This makes the javascript bundles ginormous and defeats caching so we will use the
|
||||
// file-loader instead to copy the files directly to the output directory.
|
||||
{
|
||||
test: /\.(woff2?|ttf|svg|eot)(\?v=\d+\.\d+\.\d+)?$/,
|
||||
loader: 'file-loader',
|
||||
},
|
||||
{
|
||||
test: /\.(jpe?g|png|gif|ico)(\?v=\d+\.\d+\.\d+)?$/,
|
||||
use: [
|
||||
'file-loader',
|
||||
{
|
||||
loader: 'image-webpack-loader',
|
||||
options: {
|
||||
optimizationlevel: 7,
|
||||
mozjpeg: {
|
||||
progressive: true,
|
||||
},
|
||||
gifsicle: {
|
||||
interlaced: false,
|
||||
},
|
||||
pngquant: {
|
||||
quality: '65-90',
|
||||
speed: 4,
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
// Specify additional processing or side-effects done on the Webpack output bundles as a whole.
|
||||
plugins: [
|
||||
// Generates an HTML file in the output directory.
|
||||
new HtmlWebpackPlugin({
|
||||
inject: true, // Appends script tags linking to the webpack bundles at the end of the body
|
||||
template: path.resolve(__dirname, '../public/index.html'),
|
||||
}),
|
||||
new webpack.EnvironmentPlugin({
|
||||
NODE_ENV: 'development',
|
||||
}),
|
||||
// when the --hot option is not passed in as part of the command
|
||||
// the HotModuleReplacementPlugin has to be specified in the Webpack configuration
|
||||
// https://webpack.js.org/configuration/dev-server/#devserver-hot
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
],
|
||||
// This configures webpack-dev-server which serves bundles from memory and provides live
|
||||
// reloading.
|
||||
devServer: {
|
||||
host: '0.0.0.0',
|
||||
port: 3000,
|
||||
historyApiFallback: true,
|
||||
hot: true,
|
||||
inline: true,
|
||||
},
|
||||
});
|
||||
@@ -1,71 +0,0 @@
|
||||
// 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'); // eslint-disable-line import/no-extraneous-dependencies
|
||||
const commonConfig = require('./webpack.common.config.js');
|
||||
const path = require('path');
|
||||
const CleanWebpackPlugin = require('clean-webpack-plugin'); // eslint-disable-line import/no-extraneous-dependencies
|
||||
|
||||
module.exports = Merge.smart(commonConfig, {
|
||||
mode: 'production',
|
||||
devtool: 'source-map',
|
||||
entry: './src/lib/index.js',
|
||||
output: {
|
||||
path: path.resolve(__dirname, '../dist'),
|
||||
library: 'frontend-component-footer',
|
||||
libraryTarget: 'umd',
|
||||
globalObject: 'typeof self !== \'undefined\' ? self : this',
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js', '.jsx'],
|
||||
alias: {
|
||||
react: path.resolve(__dirname, './node_modules/react'),
|
||||
'react-dom': path.resolve(__dirname, './node_modules/react-dom'),
|
||||
},
|
||||
},
|
||||
externals: {
|
||||
react: {
|
||||
commonjs: 'react',
|
||||
commonjs2: 'react',
|
||||
amd: 'React',
|
||||
root: 'React',
|
||||
},
|
||||
'react-dom': {
|
||||
commonjs: 'react-dom',
|
||||
commonjs2: 'react-dom',
|
||||
amd: 'ReactDOM',
|
||||
root: 'ReactDOM',
|
||||
},
|
||||
'@edx/frontend-i18n': {
|
||||
commonjs: '@edx/frontend-i18n',
|
||||
commonjs2: '@edx/frontend-i18n',
|
||||
amd: '@edx/frontend-i18n',
|
||||
root: '@edx/frontend-i18n',
|
||||
},
|
||||
'@edx/frontend-logging': {
|
||||
commonjs: '@edx/frontend-logging',
|
||||
commonjs2: '@edx/frontend-logging',
|
||||
amd: '@edx/frontend-logging',
|
||||
root: '@edx/frontend-logging',
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
// Cleans the dist directory before each build
|
||||
new CleanWebpackPlugin(['dist'], {
|
||||
root: path.join(__dirname, '../'),
|
||||
}),
|
||||
],
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(js|jsx)$/,
|
||||
include: [
|
||||
path.resolve(__dirname, '../src/lib'),
|
||||
],
|
||||
exclude: /(node_modules)/,
|
||||
use: [
|
||||
{ loader: 'babel-loader' },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
24218
package-lock.json
generated
24218
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
88
package.json
88
package.json
@@ -2,28 +2,24 @@
|
||||
"name": "@edx/frontend-component-footer",
|
||||
"version": "1.0.0-semantically-released",
|
||||
"description": "Site footer component for use when building edX frontend applications",
|
||||
"main": "dist/main.js",
|
||||
"module": "dist/main.js",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.js",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"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",
|
||||
"build": "make build",
|
||||
"gc": "commit",
|
||||
"commitmsg": "commitlint -e $GIT_PARAMS",
|
||||
"coveralls": "cat ./coverage/lcov.info | coveralls",
|
||||
"is-es5": "es-check es5 ./dist/*.js",
|
||||
"i18n_extract": "BABEL_ENV=i18n babel src --quiet > /dev/null",
|
||||
"lint": "eslint --ext .js --ext .jsx .",
|
||||
"precommit": "npm run lint",
|
||||
"prepublishOnly": "npm run build",
|
||||
"semantic-release": "semantic-release",
|
||||
"start": "NODE_ENV=development BABEL_ENV=development node_modules/.bin/webpack-dev-server --config=config/webpack.dev.config.js --progress",
|
||||
"start": "./node_modules/.bin/parcel src/example/index.html",
|
||||
"test": "jest --coverage",
|
||||
"snapshot": "jest --updateSnapshot",
|
||||
"travis-deploy-once": "travis-deploy-once",
|
||||
"watch": "watch 'npm run build' ./src"
|
||||
"travis-deploy-once": "travis-deploy-once"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -36,83 +32,65 @@
|
||||
},
|
||||
"homepage": "https://github.com/edx/frontend-component-footer#readme",
|
||||
"devDependencies": {
|
||||
"@babel/cli": "^7.4.4",
|
||||
"@babel/core": "^7.4.5",
|
||||
"@babel/plugin-proposal-class-properties": "^7.4.4",
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.4.4",
|
||||
"@babel/preset-env": "^7.4.5",
|
||||
"@babel/preset-react": "^7.0.0",
|
||||
"@commitlint/cli": "^7.1.2",
|
||||
"@commitlint/config-angular": "^6.0.2",
|
||||
"@commitlint/prompt": "^6.0.2",
|
||||
"@commitlint/prompt-cli": "^6.0.2",
|
||||
"@edx/edx-bootstrap": "^2.2.1",
|
||||
"@edx/frontend-i18n": "^2.1.0",
|
||||
"@edx/frontend-logging": "^2.0.2",
|
||||
"@edx/frontend-i18n": "^3.0.0",
|
||||
"@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",
|
||||
"babel-plugin-react-intl": "^3.0.1",
|
||||
"babel-plugin-rewire": "^1.2.0",
|
||||
"babel-plugin-transform-object-rest-spread": "^6.26.0",
|
||||
"babel-preset-env": "^1.7.0",
|
||||
"babel-preset-react": "^6.24.1",
|
||||
"clean-webpack-plugin": "^0.1.19",
|
||||
"babel-jest": "^24.8.0",
|
||||
"coveralls": "^3.0.0",
|
||||
"css-loader": "^0.28.9",
|
||||
"enzyme": "^3.3.0",
|
||||
"enzyme-adapter-react-16": "^1.1.1",
|
||||
"es-check": "^5.0.0",
|
||||
"eslint": "^5.2.0",
|
||||
"eslint": "^6.0.1",
|
||||
"eslint-config-edx": "^4.0.4",
|
||||
"eslint-plugin-jsx-a11y": "^6.1.2",
|
||||
"file-loader": "^1.1.9",
|
||||
"glob": "^7.1.3",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"husky": "^0.14.3",
|
||||
"image-webpack-loader": "^4.2.0",
|
||||
"jest": "23.6.0",
|
||||
"node-sass": "^4.7.2",
|
||||
"prop-types": "^15.5.10",
|
||||
"react": "^16.4.2",
|
||||
"jest": "^24.8.0",
|
||||
"parcel-bundler": "^1.12.3",
|
||||
"prop-types": "^15.7.2",
|
||||
"react": "^16.8.6",
|
||||
"react-dev-utils": "^5.0.0",
|
||||
"react-dom": "^16.2.0",
|
||||
"react-dom": "^16.8.6",
|
||||
"react-test-renderer": "^16.6.0",
|
||||
"reactifex": "^1.1.1",
|
||||
"sass-loader": "^6.0.6",
|
||||
"sass": "^1.22.1",
|
||||
"semantic-release": "^15.1.7",
|
||||
"source-map-loader": "^0.2.1",
|
||||
"style-loader": "^0.20.2",
|
||||
"travis-deploy-once": "^5.0.0",
|
||||
"watch": "^1.0.2",
|
||||
"webpack": "^4.19.1",
|
||||
"webpack-cli": "^3.1.0",
|
||||
"webpack-dev-server": "^3.1.9",
|
||||
"webpack-merge": "^4.2.1"
|
||||
"travis-deploy-once": "^5.0.0"
|
||||
},
|
||||
"sass": {
|
||||
"includePaths": [
|
||||
"./node_modules"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@edx/paragon": "^6.0.2",
|
||||
"lodash.pick": "^4.4.0",
|
||||
"query-string": "^5.1.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@edx/frontend-i18n": "^2.1.0",
|
||||
"@edx/frontend-logging": "^2.0.2",
|
||||
"@edx/paragon": "^4.2.4",
|
||||
"prop-types": "^15.5.10",
|
||||
"react": "^16.4.2",
|
||||
"react-dom": "^16.2.0"
|
||||
},
|
||||
"jest": {
|
||||
"setupFiles": [
|
||||
"./src/tests/setupTest.js"
|
||||
"./src/lib/setupTest.js"
|
||||
],
|
||||
"collectCoverageFrom": [
|
||||
"src/lib/**/*.{js,jsx}",
|
||||
"!src/tests/setupTest.js",
|
||||
"!src/index.js",
|
||||
"!**/node_modules/**",
|
||||
"!**/tests/**"
|
||||
"!src/lib/setupTest.js",
|
||||
"!src/lib/index.js",
|
||||
"!**/node_modules/**"
|
||||
],
|
||||
"moduleNameMapper": {
|
||||
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
|
||||
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/src/lib/__mocks__/fileMock.js",
|
||||
"\\.(css|scss)$": "identity-obj-proxy"
|
||||
}
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
192
src/config/index.jsx
Normal file
192
src/config/index.jsx
Normal file
@@ -0,0 +1,192 @@
|
||||
/* eslint-disable */
|
||||
|
||||
import React from 'react';
|
||||
import pick from 'lodash.pick';
|
||||
|
||||
import FooterLogo from './edx-footer.png';
|
||||
|
||||
/* TODO: This file is incomplete/non-functional. It needs some thougth about how to get
|
||||
* messages/intl into it so that we can localize our titles here. I think the right answer is
|
||||
* for this file to directly import messages.js (next door) and be passed the app's `intl`
|
||||
* object, as shown below. Then it can call formatMessage on `intl`. Also, the JSX below
|
||||
* should be evaluated with the IntlProvider when it's actually rendered by the footer, so
|
||||
* that _should_ work.
|
||||
*/
|
||||
|
||||
|
||||
let config = {
|
||||
MARKETING_SITE_BASE_URL: null,
|
||||
};
|
||||
|
||||
let intl = null;
|
||||
|
||||
function validateConfiguration(newConfig) {
|
||||
Object.keys(config).forEach((key) => {
|
||||
if (newConfig[key] === undefined) {
|
||||
throw new Error(`Footer configuration error: ${key} is required.`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
export function getDefaultConfiguration(newConfig, newIntl) {
|
||||
validateConfiguration(newConfig);
|
||||
config = pick(newConfig, Object.keys(config));
|
||||
intl = newIntl;
|
||||
|
||||
const edXLinks = [
|
||||
{
|
||||
title: 'About',
|
||||
url: `${config.MARKETING_SITE_BASE_URL}/about-us`,
|
||||
},
|
||||
{
|
||||
title: 'edX for Business',
|
||||
url: config.ENTERPRISE_MARKETING_URL,
|
||||
queryParams: {
|
||||
utm_campaign: config.ENTERPRISE_MARKETING_UTM_CAMPAIGN,
|
||||
utm_medium: config.ENTERPRISE_MARKETING_FOOTER_UTM_MEDIUM,
|
||||
utm_source: config.ENTERPRISE_MARKETING_UTM_SOURCE,
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Affiliates',
|
||||
url: `${config.MARKETING_SITE_BASE_URL}/affiliate-program`,
|
||||
},
|
||||
{
|
||||
title: 'Open edX',
|
||||
url: `${config.OPEN_SOURCE_URL}`,
|
||||
},
|
||||
{
|
||||
title: 'Careers',
|
||||
url: `${config.MARKETING_SITE_BASE_URL}/careers`,
|
||||
},
|
||||
{
|
||||
title: 'News',
|
||||
url: `${config.MARKETING_SITE_BASE_URL}/news-announcements`,
|
||||
},
|
||||
];
|
||||
|
||||
const legalLinks = [
|
||||
{
|
||||
title: 'Terms of Service & Honor Code',
|
||||
url: `${config.MARKETING_SITE_BASE_URL}/edx-terms-service`,
|
||||
},
|
||||
{
|
||||
title: 'Privacy Policy',
|
||||
url: `${config.MARKETING_SITE_BASE_URL}/edx-privacy-policy`,
|
||||
},
|
||||
{
|
||||
title: 'Accessibility Policy',
|
||||
url: `${config.MARKETING_SITE_BASE_URL}/accessibility`,
|
||||
},
|
||||
{
|
||||
title: 'Trademark Policy',
|
||||
url: `${config.MARKETING_SITE_BASE_URL}/trademarks`,
|
||||
},
|
||||
{
|
||||
title: 'Sitemap',
|
||||
url: `${config.MARKETING_SITE_BASE_URL}/sitemap`,
|
||||
},
|
||||
];
|
||||
|
||||
const connectLinks = [
|
||||
{
|
||||
title: 'Blog',
|
||||
url: `${config.MARKETING_SITE_BASE_URL}/blog`,
|
||||
},
|
||||
{
|
||||
title: 'Contact Us',
|
||||
url: `${config.LMS_BASE_URL}/support/contact_us`,
|
||||
},
|
||||
{
|
||||
title: 'Help Center',
|
||||
url: config.SUPPORT_URL,
|
||||
},
|
||||
{
|
||||
title: 'Media Kit',
|
||||
url: `${config.MARKETING_SITE_BASE_URL}/media-kit`,
|
||||
},
|
||||
{
|
||||
title: 'Donate',
|
||||
url: `${config.MARKETING_SITE_BASE_URL}/donate`,
|
||||
},
|
||||
];
|
||||
|
||||
const socialLinks = [
|
||||
{
|
||||
title: 'Facebook',
|
||||
url: config.FACEBOOK_URL,
|
||||
icon: <FontAwesomeIcon icon={faFacebookSquare} className="social-icon" size="2x" />,
|
||||
screenReaderText: 'Like edX on Facebook',
|
||||
},
|
||||
{
|
||||
title: 'Twitter',
|
||||
url: config.TWITTER_URL,
|
||||
icon: <FontAwesomeIcon icon={faTwitterSquare} className="social-icon" size="2x" />,
|
||||
screenReaderText: 'Follow edX on Twitter',
|
||||
},
|
||||
{
|
||||
title: 'Youtube',
|
||||
url: config.YOU_TUBE_URL,
|
||||
icon: <FontAwesomeIcon icon={faYoutubeSquare} className="social-icon" size="2x" />,
|
||||
screenReaderText: 'Subscribe to the edX YouTube channel',
|
||||
},
|
||||
{
|
||||
title: 'LinkedIn',
|
||||
url: config.LINKED_IN_URL,
|
||||
icon: <FontAwesomeIcon icon={faLinkedin} className="social-icon" size="2x" />,
|
||||
screenReaderText: 'Follow edX on LinkedIn',
|
||||
},
|
||||
{
|
||||
title: 'Reddit',
|
||||
url: config.REDDIT_URL,
|
||||
icon: <FontAwesomeIcon icon={faRedditSquare} className="social-icon" size="2x" />,
|
||||
screenReaderText: 'Subscribe to the edX subreddit',
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
const copyright = <FormattedMessage
|
||||
id="footer.site-footer.copyright-text"
|
||||
defaultMessage="{copyrightSymbol} {startDate}–{endDate} {siteName} Inc."
|
||||
values={{
|
||||
copyrightSymbol: '©',
|
||||
startDate: '2012',
|
||||
endDate: `${new Date().getFullYear()}`,
|
||||
siteName,
|
||||
}}
|
||||
description="Footer copyright text with copyright symbol and dates"
|
||||
/>
|
||||
|
||||
const trademark = <FormattedMessage
|
||||
id="footer.site-footer.trademark-text"
|
||||
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"
|
||||
/>
|
||||
|
||||
return {
|
||||
ariaLabel: "Page Footer",
|
||||
siteLogo: FooterLogo,
|
||||
marketingSiteBaseUrl: config.MARKETING_SITE_BASE_URL,
|
||||
linkSectionOne: edXLinks,
|
||||
linkSectionTwo: legalLinks,
|
||||
linkSectionThree: connectLinks,
|
||||
socialLinks,
|
||||
showMobileLinks: true,
|
||||
appleAppStore: {
|
||||
url: config.APPLE_APP_STORE_URL,
|
||||
altText: "Download the edX mobile app from the Apple App Store",
|
||||
},
|
||||
googlePlayUrl: {
|
||||
url: config.GOOGLE_PLAY_URL,
|
||||
altText: "Download the edX mobile app from Google Play",
|
||||
},
|
||||
supportedLanguages: [],
|
||||
languageForm: null,
|
||||
copyright,
|
||||
trademark,
|
||||
}
|
||||
};
|
||||
|
||||
export default getDefaultConfiguration;
|
||||
91
src/config/messages.js
Normal file
91
src/config/messages.js
Normal file
@@ -0,0 +1,91 @@
|
||||
import { defineMessages } from '@edx/frontend-i18n';
|
||||
|
||||
const messages = defineMessages({
|
||||
'footer.site-footer.site-logo.alt-text': {
|
||||
id: 'footer.site-footer.site-logo.alt-text',
|
||||
defaultMessage: '{siteName} logo',
|
||||
description: 'The alt description of the site logo',
|
||||
},
|
||||
'footer.site-footer.site-logo.aria-label': {
|
||||
id: 'footer.site-footer.site-logo.aria-label',
|
||||
defaultMessage: '{siteName} Home',
|
||||
description: 'Aria label for the site logo which goes to the marketing site',
|
||||
},
|
||||
'footer.site-footer.facebook.title': {
|
||||
id: 'footer.site-footer.facebook.title',
|
||||
defaultMessage: 'Facebook',
|
||||
description: 'Facebook button title',
|
||||
},
|
||||
'footer.site-footer.facebook.screen-reader-text': {
|
||||
id: 'footer.site-footer.facebook.screen-reader-text',
|
||||
defaultMessage: 'Like {siteName} on Facebook',
|
||||
description: 'Facebook button screen reader text',
|
||||
},
|
||||
'footer.site-footer.twitter.title': {
|
||||
id: 'footer.site-footer.twitter.title',
|
||||
defaultMessage: 'Twitter',
|
||||
description: 'Twitter button title',
|
||||
},
|
||||
'footer.site-footer.twitter.screen-reader-text': {
|
||||
id: 'footer.site-footer.twitter.screen-reader-text',
|
||||
defaultMessage: 'Follow {siteName} on Twitter',
|
||||
description: 'Twitter button screen reader text',
|
||||
},
|
||||
'footer.site-footer.youtube.title': {
|
||||
id: 'footer.site-footer.youtube.title',
|
||||
defaultMessage: 'Youtube',
|
||||
description: 'Youtube button title',
|
||||
},
|
||||
'footer.site-footer.youtube.screen-reader-text': {
|
||||
id: 'footer.site-footer.youtube.screen-reader-text',
|
||||
defaultMessage: 'Subscribe to the {siteName} YouTube channel',
|
||||
description: 'Youtube button screen reader text',
|
||||
},
|
||||
'footer.site-footer.linkedin.title': {
|
||||
id: 'footer.site-footer.linkedin.title',
|
||||
defaultMessage: 'LinkedIn',
|
||||
description: 'LinkedIn button title',
|
||||
},
|
||||
'footer.site-footer.linkedin.screen-reader-text': {
|
||||
id: 'footer.site-footer.linkedin.screen-reader-text',
|
||||
defaultMessage: 'Follow {siteName} on LinkedIn',
|
||||
description: 'LinkedIn button screen reader text',
|
||||
},
|
||||
'footer.site-footer.google-plus.title': {
|
||||
id: 'footer.site-footer.google-plus.title',
|
||||
defaultMessage: 'Google+',
|
||||
description: 'Google+ button title',
|
||||
},
|
||||
'footer.site-footer.google-plus.screen-reader-text': {
|
||||
id: 'footer.site-footer.google-plus.screen-reader-text',
|
||||
defaultMessage: 'Follow {siteName} on Google+',
|
||||
description: 'Google+ button screen reader text',
|
||||
},
|
||||
'footer.site-footer.reddit.title': {
|
||||
id: 'footer.site-footer.reddit.title',
|
||||
defaultMessage: 'Reddit',
|
||||
description: 'Reddit button title',
|
||||
},
|
||||
'footer.site-footer.reddit.screen-reader-text': {
|
||||
id: 'footer.site-footer.reddit.screen-reader-text',
|
||||
defaultMessage: 'Subscribe to the {siteName} subreddit',
|
||||
description: 'Reddit button screen reader text',
|
||||
},
|
||||
'footer.site-footer.apple-app-store.alt-text': {
|
||||
id: 'footer.site-footer.apple-app-store.alt-text',
|
||||
defaultMessage: 'Download the {siteName} mobile app from the Apple App Store',
|
||||
description: 'Apple App Store button alt description',
|
||||
},
|
||||
'footer.site-footer.google-play.alt-text': {
|
||||
id: 'footer.site-footer.google-play.alt-text',
|
||||
defaultMessage: 'Download the {siteName} mobile app from Google Play',
|
||||
description: 'Google Play button alt description',
|
||||
},
|
||||
'footer.site-footer.footer.aria-label': {
|
||||
id: 'footer.site-footer.footer.aria-label',
|
||||
defaultMessage: 'Page Footer',
|
||||
description: 'Aria label for the footer',
|
||||
},
|
||||
});
|
||||
|
||||
export default messages;
|
||||
@@ -1,11 +1,12 @@
|
||||
<!doctype html>
|
||||
<html lang="en-us">
|
||||
<head>
|
||||
<title>Footer | edX</title>
|
||||
<title>Example Footer</title>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script src="./index.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -13,9 +13,9 @@ 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 SiteFooter from '../lib/';
|
||||
import './index.scss';
|
||||
import FooterLogo from './edx-footer.png';
|
||||
import FooterLogo from '../config/edx-footer.png';
|
||||
|
||||
|
||||
const edXLinks = [
|
||||
2
src/example/index.scss
Normal file
2
src/example/index.scss
Normal file
@@ -0,0 +1,2 @@
|
||||
@import "~@edx/paragon/scss/edx/theme";
|
||||
@import '../lib/SiteFooter.scss';
|
||||
@@ -1,32 +0,0 @@
|
||||
import arMessages from './messages/ar.json';
|
||||
import caMessages from './messages/ca.json';
|
||||
// no need to import en messages-- they are in the defaultMessage field
|
||||
import es419Messages from './messages/es_419.json';
|
||||
import frMessages from './messages/fr.json';
|
||||
import zhcnMessages from './messages/zh_CN.json';
|
||||
import heMessages from './messages/he.json';
|
||||
import idMessages from './messages/id.json';
|
||||
import kokrMessages from './messages/ko_kr.json';
|
||||
import plMessages from './messages/pl.json';
|
||||
import ptbrMessages from './messages/pt_br.json';
|
||||
import ruMessages from './messages/ru.json';
|
||||
import thMessages from './messages/th.json';
|
||||
import ukMessages from './messages/uk.json';
|
||||
|
||||
const messages = {
|
||||
ar: arMessages,
|
||||
'es-419': es419Messages,
|
||||
fr: frMessages,
|
||||
'zh-cn': zhcnMessages,
|
||||
ca: caMessages,
|
||||
he: heMessages,
|
||||
id: idMessages,
|
||||
'ko-kr': kokrMessages,
|
||||
pl: plMessages,
|
||||
'pt-br': ptbrMessages,
|
||||
ru: ruMessages,
|
||||
th: thMessages,
|
||||
uk: ukMessages,
|
||||
};
|
||||
|
||||
export default messages;
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
@@ -1 +0,0 @@
|
||||
{}
|
||||
5
src/index.js
Normal file
5
src/index.js
Normal file
@@ -0,0 +1,5 @@
|
||||
import SiteFooter from './lib';
|
||||
|
||||
export { default as FooterLogo } from './config/edx-footer.png';
|
||||
export { default as config } from './config';
|
||||
export default SiteFooter;
|
||||
@@ -1,4 +0,0 @@
|
||||
@import "~@edx/edx-bootstrap/scss/edx/theme";
|
||||
@import "~bootstrap/scss/bootstrap";
|
||||
|
||||
@import './lib/scss/_site-footer.scss';
|
||||
@@ -2,12 +2,11 @@ import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import qs from 'query-string';
|
||||
|
||||
const EVENT_NAMES = {
|
||||
export const EVENT_NAMES = {
|
||||
FOOTER_LINK: 'edx.bi.footer.link',
|
||||
};
|
||||
|
||||
|
||||
class SiteFooter extends React.Component {
|
||||
export default class SiteFooter extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.externalLinkClickHandler = this.externalLinkClickHandler.bind(this);
|
||||
@@ -198,7 +197,7 @@ SiteFooter.propTypes = {
|
||||
src: PropTypes.node,
|
||||
altText: PropTypes.string,
|
||||
ariaLabel: PropTypes.string,
|
||||
}),
|
||||
}).isRequired,
|
||||
marketingSiteBaseUrl: PropTypes.string,
|
||||
linkSectionOne: linkSectionShape,
|
||||
linkSectionTwo: linkSectionShape,
|
||||
@@ -246,13 +245,12 @@ const linkSectionDefault = {
|
||||
};
|
||||
|
||||
SiteFooter.defaultProps = {
|
||||
siteLogo: null,
|
||||
marketingSiteBaseUrl: null,
|
||||
linkSectionOne: linkSectionDefault,
|
||||
linkSectionTwo: linkSectionDefault,
|
||||
linkSectionThree: linkSectionDefault,
|
||||
socialLinks: [],
|
||||
showMobileLinks: true,
|
||||
showMobileLinks: false,
|
||||
appleAppStore: null,
|
||||
googlePlay: null,
|
||||
supportedLanguages: [],
|
||||
@@ -260,6 +258,3 @@ SiteFooter.defaultProps = {
|
||||
copyright: null,
|
||||
trademark: null,
|
||||
};
|
||||
|
||||
export default SiteFooter;
|
||||
export { EVENT_NAMES };
|
||||
@@ -12,8 +12,8 @@ import {
|
||||
import { faLanguage } from '@fortawesome/free-solid-svg-icons';
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||
|
||||
import FooterLogo from '../../../edx-footer.png';
|
||||
import SiteFooter, { EVENT_NAMES } from './index';
|
||||
import FooterLogo from '../config/edx-footer.png';
|
||||
import SiteFooter, { EVENT_NAMES } from './SiteFooter';
|
||||
|
||||
|
||||
const edXLinks = [
|
||||
@@ -1,3 +1,3 @@
|
||||
import SiteFooter from './components/SiteFooter';
|
||||
import SiteFooter from './SiteFooter';
|
||||
|
||||
export default SiteFooter;
|
||||
|
||||
1275
stats.json
1275
stats.json
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user