diff --git a/package-lock.json b/package-lock.json
index b8be729c..1b7a4821 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3877,6 +3877,19 @@
"babel-polyfill": "6.26.0",
"react-responsive": "8.0.3",
"react-transition-group": "4.3.0"
+ },
+ "dependencies": {
+ "react-responsive": {
+ "version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/react-responsive/-/react-responsive-8.0.3.tgz",
+ "integrity": "sha512-F9VXyLao7O8XHXbLjQbIr4+mC6Zr0RDTwNjd7ixTmYEAyKyNanBkLkFchNaMZgszoSK6PgSs/3m/QDWw33/gpg==",
+ "requires": {
+ "hyphenate-style-name": "^1.0.0",
+ "matchmediaquery": "^0.3.0",
+ "prop-types": "^15.6.1",
+ "shallow-equal": "^1.1.0"
+ }
+ }
}
},
"@edx/frontend-platform": {
@@ -21058,9 +21071,9 @@
}
},
"react-responsive": {
- "version": "8.0.3",
- "resolved": "https://registry.npmjs.org/react-responsive/-/react-responsive-8.0.3.tgz",
- "integrity": "sha512-F9VXyLao7O8XHXbLjQbIr4+mC6Zr0RDTwNjd7ixTmYEAyKyNanBkLkFchNaMZgszoSK6PgSs/3m/QDWw33/gpg==",
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/react-responsive/-/react-responsive-8.2.0.tgz",
+ "integrity": "sha512-iagCqVrw4QSjhxKp3I/YK6+ODkWY6G+YPElvdYKiUUbywwh9Ds0M7r26Fj2/7dWFFbOpcGnJE6uE7aMck8j5Qg==",
"requires": {
"hyphenate-style-name": "^1.0.0",
"matchmediaquery": "^0.3.0",
diff --git a/package.json b/package.json
index 2f84164d..963a4532 100644
--- a/package.json
+++ b/package.json
@@ -58,6 +58,7 @@
"react-helmet": "6.1.0",
"react-loading-skeleton": "2.2.0",
"react-redux": "7.2.3",
+ "react-responsive": "8.2.0",
"react-router": "5.2.0",
"react-router-dom": "5.2.0",
"redux": "4.0.5",
diff --git a/src/_style.scss b/src/_style.scss
index f907c0f7..1468872c 100644
--- a/src/_style.scss
+++ b/src/_style.scss
@@ -13,6 +13,7 @@ $microsoft-black: #2f2f2f;
$microsoft-focus-black: #000;
$apple-black: #000000;
$apple-focus-black: $apple-black;
+$accent-a-light: #c9f2f5;
.sr-only {
position: absolute;
@@ -282,6 +283,10 @@ $apple-focus-black: $apple-black;
margin-top: 10px;
}
+.mt-7 {
+ margin-top: 7rem;
+}
+
.pt-10 {
padding-top: 10px;
}
@@ -323,6 +328,92 @@ $apple-focus-black: $apple-black;
}
}
-.custom-select-size {
- background-size: 8px 10px;
+.large-screen-container {
+ background-color: $white;
+ background-image: linear-gradient(102.02deg, $primary 45%, $white 45%);
+ width: 100%;
+}
+
+.medium-screen-header {
+ background-color: $white;
+ background-image: linear-gradient(102.02deg, $primary 93%, $white 7%);
+ width: 100%;
+}
+
+.large-screen-top-stripe {
+ height: 0.5rem;
+ background-image: linear-gradient(
+ 102.02deg,
+ $brand-700,
+ $brand-700 10%,
+ $brand 10%,
+ $brand 40%,
+ $primary-700 40%,
+ $primary-700 50%,
+ $accent-a 50%,
+ $accent-a 72%,
+ $accent-a-light 72%,
+ );
+ background-repeat: no-repeat;
+}
+
+.medium-screen-top-stripe {
+ height: 0.5rem;
+ background-image: linear-gradient(
+ 102.02deg,
+ $brand-700,
+ $brand-700 10%,
+ $brand 10%,
+ $brand 90%,
+ $primary-700 90%,
+ $primary-700 100%,
+ );
+ background-repeat: no-repeat;
+}
+
+.small-screen-top-stripe {
+ height: 0.5rem;
+ background-image: linear-gradient(
+ 102.02deg,
+ $brand-700,
+ $brand-700 20%,
+ $brand 20%,
+ );
+ background-repeat: no-repeat;
+}
+
+.svg-line {
+ padding-top: 0.5rem;
+ stroke: $accent-b;
+ stroke-width: 0.5rem;
+ width: 7em;
+}
+
+.small-screen-svg-line {
+ padding-top: 0.5rem;
+ stroke: $accent-b;
+ stroke-width: 0.25rem;
+ width: 4em;
+ height: 72px;
+}
+
+.large-heading {
+ padding-left: 1rem;
+ color: $white;
+ max-width: 24rem;
+ line-height: 78px;
+ font-size: 78px;
+}
+
+.small-heading {
+ padding-left: 0.5rem;
+ color: $white;
+ line-height: 40px;
+ font-size: 36px;
+}
+
+.logo {
+ width: 4.5rem;
+ padding-top: 2rem;
+ padding-left: 25px;
}
diff --git a/src/common-components/BaseComponent.jsx b/src/common-components/BaseComponent.jsx
new file mode 100644
index 00000000..6fbde355
--- /dev/null
+++ b/src/common-components/BaseComponent.jsx
@@ -0,0 +1,34 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import Responsive from 'react-responsive';
+
+import SmallScreenLayout from './SmallScreenLayout';
+import MediumScreenLayout from './MediumScreenLayout';
+import LargeScreenLayout from './LargeScreenLayout';
+
+const BaseComponent = ({ children }) => (
+ <>
+
+
+ {children}
+
+
+
+
+ {children}
+
+
+
+
+ {children}
+
+
+ >
+);
+
+BaseComponent.propTypes = {
+ children: PropTypes.node.isRequired,
+};
+
+export default BaseComponent;
diff --git a/src/common-components/LargeScreenLayout.jsx b/src/common-components/LargeScreenLayout.jsx
new file mode 100644
index 00000000..a26bb9de
--- /dev/null
+++ b/src/common-components/LargeScreenLayout.jsx
@@ -0,0 +1,29 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import { Row } from '@edx/paragon';
+
+import LargeScreenLeftLayout from './LargeScreenLeftLayout';
+import LargeScreenRightLayout from './LargeScreenRightLayout';
+
+const LargeScreenLayout = (props) => {
+ const { children } = props;
+
+ return (
+ <>
+
+
+
+
+ { children }
+
+
+ >
+ );
+};
+
+LargeScreenLayout.propTypes = {
+ children: PropTypes.node.isRequired,
+};
+
+export default LargeScreenLayout;
diff --git a/src/common-components/LargeScreenLeftLayout.jsx b/src/common-components/LargeScreenLeftLayout.jsx
new file mode 100644
index 00000000..263a7803
--- /dev/null
+++ b/src/common-components/LargeScreenLeftLayout.jsx
@@ -0,0 +1,34 @@
+import React from 'react';
+
+import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
+import { getConfig } from '@edx/frontend-platform';
+import { Col } from '@edx/paragon';
+
+import messages from './messages';
+
+const LargeScreenLeftLayout = (props) => {
+ const { intl } = props;
+
+ return (
+
+
+
+
+
+ {intl.formatMessage(messages['start.learning'])}
+
+ {intl.formatMessage(messages['with.site.name'], { siteName: getConfig().SITE_NAME })}
+
+
+
+
+ );
+};
+
+LargeScreenLeftLayout.propTypes = {
+ intl: intlShape.isRequired,
+};
+
+export default injectIntl(LargeScreenLeftLayout);
diff --git a/src/common-components/LargeScreenRightLayout.jsx b/src/common-components/LargeScreenRightLayout.jsx
new file mode 100644
index 00000000..a682cdd5
--- /dev/null
+++ b/src/common-components/LargeScreenRightLayout.jsx
@@ -0,0 +1,20 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import { Col } from '@edx/paragon';
+
+const LargeScreenRightLayout = (props) => {
+ const { children } = props;
+
+ return (
+
+ { children }
+
+ );
+};
+
+LargeScreenRightLayout.propTypes = {
+ children: PropTypes.node.isRequired,
+};
+
+export default LargeScreenRightLayout;
diff --git a/src/common-components/MediumScreenHeader.jsx b/src/common-components/MediumScreenHeader.jsx
new file mode 100644
index 00000000..1fcbb849
--- /dev/null
+++ b/src/common-components/MediumScreenHeader.jsx
@@ -0,0 +1,36 @@
+import React from 'react';
+
+import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
+import { getConfig } from '@edx/frontend-platform';
+
+import messages from './messages';
+
+const MediumScreenHeader = (props) => {
+ const { intl } = props;
+
+ return (
+ <>
+
+
+
.LOGO_WHITE_URL})
+
+
+
+ {intl.formatMessage(messages['start.learning'])}
+
+ {intl.formatMessage(messages['with.site.name'], { siteName: getConfig().SITE_NAME })}
+
+
+
+
+ >
+ );
+};
+
+MediumScreenHeader.propTypes = {
+ intl: intlShape.isRequired,
+};
+
+export default injectIntl(MediumScreenHeader);
diff --git a/src/common-components/MediumScreenLayout.jsx b/src/common-components/MediumScreenLayout.jsx
new file mode 100644
index 00000000..ab5fa1c5
--- /dev/null
+++ b/src/common-components/MediumScreenLayout.jsx
@@ -0,0 +1,21 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import MediumScreenHeader from './MediumScreenHeader';
+
+const MediumScreenLayout = (props) => {
+ const { children } = props;
+
+ return (
+ <>
+
+ { children }
+ >
+ );
+};
+
+MediumScreenLayout.propTypes = {
+ children: PropTypes.node.isRequired,
+};
+
+export default MediumScreenLayout;
diff --git a/src/common-components/SmallScreenHeader.jsx b/src/common-components/SmallScreenHeader.jsx
new file mode 100644
index 00000000..68c131c3
--- /dev/null
+++ b/src/common-components/SmallScreenHeader.jsx
@@ -0,0 +1,37 @@
+import React from 'react';
+
+import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
+import { getConfig } from '@edx/frontend-platform';
+
+import messages from './messages';
+
+const SmallScreenHeader = (props) => {
+ const { intl } = props;
+
+ return (
+ <>
+
+
+
.LOGO_WHITE_URL})
+
+
+
+ {intl.formatMessage(messages['start.learning'])}
+
+
+ {intl.formatMessage(messages['with.site.name'], { siteName: getConfig().SITE_NAME })}
+
+
+
+
+ >
+ );
+};
+
+SmallScreenHeader.propTypes = {
+ intl: intlShape.isRequired,
+};
+
+export default injectIntl(SmallScreenHeader);
diff --git a/src/common-components/SmallScreenLayout.jsx b/src/common-components/SmallScreenLayout.jsx
new file mode 100644
index 00000000..503cd4f8
--- /dev/null
+++ b/src/common-components/SmallScreenLayout.jsx
@@ -0,0 +1,21 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import SmallScreenHeader from './SmallScreenHeader';
+
+const SmallScreenLayout = (props) => {
+ const { children } = props;
+
+ return (
+ <>
+
+ { children }
+ >
+ );
+};
+
+SmallScreenLayout.propTypes = {
+ children: PropTypes.node.isRequired,
+};
+
+export default SmallScreenLayout;
diff --git a/src/common-components/index.jsx b/src/common-components/index.jsx
index 20894220..0b31641e 100644
--- a/src/common-components/index.jsx
+++ b/src/common-components/index.jsx
@@ -12,3 +12,4 @@ export { default as APIFailureMessage } from './APIFailureMessage';
export { default as reducer } from './data/reducers';
export { default as saga } from './data/sagas';
export { storeName } from './data/selectors';
+export { default as BaseComponent } from './BaseComponent';
diff --git a/src/common-components/messages.jsx b/src/common-components/messages.jsx
index d667457d..ab1d6433 100644
--- a/src/common-components/messages.jsx
+++ b/src/common-components/messages.jsx
@@ -60,6 +60,16 @@ const messages = defineMessages({
defaultMessage: 'Create account using {providerName}',
description: 'Screen reader text that appears before social auth provider name',
},
+ 'start.learning': {
+ id: 'start.learning',
+ defaultMessage: 'Start Learning',
+ description: 'Header text for logistration MFE pages',
+ },
+ 'with.site.name': {
+ id: 'with.site.name',
+ defaultMessage: 'with {siteName}',
+ description: 'Header text with site name for logistration MFE pages',
+ },
});
export default messages;
diff --git a/src/index.jsx b/src/index.jsx
index 3c3e4f5d..faae7450 100755
--- a/src/index.jsx
+++ b/src/index.jsx
@@ -19,7 +19,7 @@ import {
} from './data/constants';
import ForgotPasswordPage from './forgot-password';
import {
- HeaderLayout, UnAuthOnlyRoute, registerIcons, NotFoundPage,
+ BaseComponent, UnAuthOnlyRoute, registerIcons, NotFoundPage,
} from './common-components';
import ResetPasswordPage from './reset-password';
import WelcomePage from './welcome';
@@ -32,7 +32,7 @@ registerIcons();
subscribe(APP_READY, () => {
ReactDOM.render(
-
+
@@ -47,7 +47,7 @@ subscribe(APP_READY, () => {
-
+
,
document.getElementById('root'),
);