Compare commits

..

3 Commits

Author SHA1 Message Date
Syed Sajjad Hussain Shah
e57994bd85 refactor: move fields specific code to their wrappers 2023-08-25 09:48:21 +05:00
Blue
aeec576d8c fix: apply frontend validations (#1041)
Description:
Applied frontend validations on all the fields
VAN-1614
2023-08-24 15:24:00 +05:00
Blue
90db7ba1d8 fix: embedded registration form (#1026)
Description:
Adding embedded registration form
VAN-1574
2023-08-21 12:08:06 +05:00
202 changed files with 19789 additions and 25502 deletions

8
.env
View File

@@ -15,7 +15,7 @@ SEGMENT_KEY=''
SITE_NAME=null
INFO_EMAIL=''
# ***** Cookies *****
USER_RETENTION_COOKIE_NAME=null
REGISTER_CONVERSION_COOKIE_NAME=null
# ***** Links *****
LOGIN_ISSUE_SUPPORT_LINK=''
AUTHN_PROGRESSIVE_PROFILING_SUPPORT_LINK=null
@@ -23,13 +23,11 @@ POST_REGISTRATION_REDIRECT_URL=''
SEARCH_CATALOG_URL=''
# ***** Features flags *****
DISABLE_ENTERPRISE_LOGIN=''
ENABLE_AUTO_GENERATED_USERNAME=''
ENABLE_DYNAMIC_REGISTRATION_FIELDS=''
ENABLE_PROGRESSIVE_PROFILING_ON_AUTHN=''
ENABLE_POST_REGISTRATION_RECOMMENDATIONS=''
ENABLE_POPULAR_AND_TRENDING_RECOMMENDATIONS=''
MARKETING_EMAILS_OPT_IN=''
SHOW_CONFIGURABLE_EDX_FIELDS=''
ENABLE_IMAGE_LAYOUT=''
# ***** Zendesk related keys *****
ZENDESK_KEY=''
ZENDESK_LOGO_URL=''
@@ -41,5 +39,3 @@ BANNER_IMAGE_EXTRA_SMALL=''
# ***** Miscellaneous *****
APP_ID=''
MFE_CONFIG_API_URL=''
# Fallback in local style files
PARAGON_THEME_URLS={}

View File

@@ -19,10 +19,8 @@ REFRESH_ACCESS_TOKEN_ENDPOINT='http://localhost:18000/login_refresh'
SEGMENT_KEY=''
SITE_NAME='Your Platform Name Here'
INFO_EMAIL='info@example.com'
# ***** Features *****
ENABLE_DYNAMIC_REGISTRATION_FIELDS='true'
ENABLE_PROGRESSIVE_PROFILING_ON_AUTHN='true'
# ***** Cookies *****
REGISTER_CONVERSION_COOKIE_NAME='openedx-user-register-conversion'
SESSION_COOKIE_DOMAIN='localhost'
USER_INFO_COOKIE_NAME='edx-user-info'
# ***** Links *****
@@ -41,5 +39,3 @@ APP_ID=''
MFE_CONFIG_API_URL=''
ZENDESK_KEY=''
ZENDESK_LOGO_URL=''
# Fallback in local style files
PARAGON_THEME_URLS={}

View File

@@ -16,6 +16,6 @@ ORDER_HISTORY_URL='http://localhost:1996/orders'
REFRESH_ACCESS_TOKEN_ENDPOINT='http://localhost:18000/login_refresh'
SEGMENT_KEY=''
SITE_NAME='Your Platform Name Here'
REGISTER_CONVERSION_COOKIE_NAME='openedx-user-register-conversion'
APP_ID=''
MFE_CONFIG_API_URL=''
PARAGON_THEME_URLS={}

View File

@@ -1,12 +1,12 @@
// eslint-disable-next-line import/no-extraneous-dependencies
const { createConfig } = require('@openedx/frontend-build');
const { createConfig } = require('@edx/frontend-build');
module.exports = createConfig('eslint', {
rules: {
// Temporarily update the 'indent', 'template-curly-spacing' and
// 'no-multiple-empty-lines' rules since they are causing eslint
// to fail for no apparent reason since upgrading
// @openedx/frontend-build from v3 to v5:
// @edx/frontend-build from v3 to v5:
// - TypeError: Cannot read property 'range' of null
indent: [
'error',

1
.github/CODEOWNERS vendored
View File

@@ -1 +0,0 @@
* @openedx/2U-infinity

View File

@@ -1,7 +0,0 @@
version: 2
updates:
# Adding new check for github-actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"

View File

@@ -25,5 +25,5 @@ Include a link to the sandbox for design changes or screenshot for before and af
#### Post-merge Checklist
* [ ] Deploy the changes to prod after verifying on stage or ask **@openedx/2u-infinity** to do it.
* [ ] Deploy the changes to prod after verifying on stage or ask **@openedx/vanguards** to do it.
* [ ] 🎉 🙌 Celebrate! Thanks for your contribution.

View File

@@ -10,7 +10,7 @@ on:
jobs:
autoupdate:
name: autoupdate
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- uses: docker://chinthakagodawita/autoupdate-action:v1
env:

View File

@@ -10,15 +10,17 @@ on:
jobs:
tests:
runs-on: ubuntu-latest
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v3
- name: Setup Nodejs Env
run: echo "NODE_VER=`cat .nvmrc`" >> $GITHUB_ENV
- name: Setup Nodejs
uses: actions/setup-node@v4
uses: actions/setup-node@v3
with:
node-version-file: '.nvmrc'
node-version: ${{ env.NODE_VER }}
- name: Install Dependencies
run: npm ci
@@ -39,7 +41,4 @@ jobs:
run: npm run build
- name: Run Code Coverage
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
fail_ci_if_error: true
uses: codecov/codecov-action@v3

1
.gitignore vendored
View File

@@ -18,4 +18,3 @@ temp/babel-plugin-react-intl
*~
/temp
/.vscode
src/i18n/messages

2
.nvmrc
View File

@@ -1 +1 @@
24
18

9
.tx/config Normal file
View File

@@ -0,0 +1,9 @@
[main]
host = https://www.transifex.com
[o:open-edx:p:edx-platform:r:frontend-app-authn]
file_filter = src/i18n/messages/<lang>.json
source_file = src/i18n/transifex_input.json
source_lang = en
type = KEYVALUEJSON

2
CODEOWNERS Normal file
View File

@@ -0,0 +1,2 @@
# The following users are the owners of all frontend-app-authn files
* @openedx/vanguards

View File

@@ -1,17 +1,20 @@
export TRANSIFEX_RESOURCE = frontend-app-authn
transifex_langs = "ar,fr,es_419,zh_CN,pt,it,de,uk,ru,hi,fr_CA,it_IT,pt_PT,de_DE"
intl_imports = ./node_modules/.bin/intl-imports.js
transifex_utils = ./node_modules/.bin/transifex-utils.js
i18n = ./src/i18n
transifex_input = $(i18n)/transifex_input.json
# This directory must match .babelrc .
transifex_temp = ./temp/babel-plugin-formatjs
transifex_temp = ./temp/babel-plugin-react-intl
precommit:
npm run lint
npm audit
requirements:
npm ci
npm install
i18n.extract:
# Pulling display strings from .jsx files into .json files...
@@ -29,16 +32,33 @@ 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/@edx/reactifex/bash_scripts/get_hashed_strings_v3.sh
# Writing out comments to file...
$(transifex_utils) $(transifex_temp) --comments --v3-scripts-path
# Pushing comments to Transifex...
./node_modules/@edx/reactifex/bash_scripts/put_comments_v3.sh
ifeq ($(OPENEDX_ATLAS_PULL),)
# Pulls translations from Transifex.
pull_translations:
tx pull -t -f --mode reviewed --languages=$(transifex_langs)
else
# Experimental: OEP-58 Pulls translations using atlas
pull_translations:
rm -rf src/i18n/messages
mkdir src/i18n/messages
cd src/i18n/messages \
&& atlas pull $(ATLAS_OPTIONS) \
&& atlas pull --filter=$(transifex_langs) \
translations/paragon/src/i18n/messages:paragon \
translations/frontend-platform/src/i18n/messages:frontend-platform \
translations/frontend-app-authn/src/i18n/messages:frontend-app-authn
$(intl_imports) paragon frontend-platform frontend-app-authn
$(intl_imports) paragon frontend-app-authn
endif
# This target is used by Travis.
validate-no-uncommitted-package-lock-changes:

View File

@@ -1,12 +1,12 @@
##################
frontend-app-authn
##################
|Build Status| |ci-badge| |Codecov| |semantic-release|
********
Purpose
********
frontend-app-authn
====================
Please tag **@openedx/vanguards** on any PRs or issues. Thanks!
Introduction
------------
This is a micro-frontend application responsible for the login, registration and password reset functionality.
@@ -22,20 +22,11 @@ This is a micro-frontend application responsible for the login, registration and
- Progressive profiling page
***************
Getting Started
***************
Installation
============
------------
`Tutor`_ is currently recommended as a development environment for your new MFE. Please refer to the `relevant tutor-mfe documentation`_ to get started using it.
.. _Tutor: https://github.com/overhangio/tutor
.. _relevant tutor-mfe documentation: https://github.com/overhangio/tutor-mfe?tab=readme-ov-file#mfe-development
Devstack (Deprecated) instructions
==================================
This MFE is bundled with `Devstack <https://github.com/openedx/devstack>`_, see the `Getting Started <https://github.com/openedx/devstack#getting-started>`_ section for setup instructions.
1. Install Devstack using the `Getting Started <https://github.com/openedx/devstack#getting-started>`_ instructions.
@@ -55,9 +46,9 @@ Devstack (Deprecated) instructions
**Note:** Follow `Enable social auth locally <docs/how_tos/enable_social_auth.rst>`_ for enabling Social Sign-on Buttons (SSO) locally
Environment Variables/Setup Notes
=================================
---------------------------------
This MFE is configured via environment variables supplied at build time. All micro-frontends have a shared set of required environment variables, as documented in the Open edX Developer Guide under `Required Environment Variables <https://github.com/overhangio/tutor-mfe?tab=readme-ov-file#mfe-development>`__.
This MFE is configured via environment variables supplied at build time. All micro-frontends have a shared set of required environment variables, as documented in the Open edX Developer Guide under `Required Environment Variables <https://edx.readthedocs.io/projects/edx-developer-docs/en/latest/developers_guide/micro_frontends_in_open_edx.html#required-environment-variables>`__.
The authentication micro-frontend also requires the following additional variable:
@@ -121,13 +112,9 @@ The authentication micro-frontend also requires the following additional variabl
- Name of MFE, this will be used by the API to get runtime configurations for the specific micro frontend. For a frontend repo `frontend-app-appName`, use `appName` as APP_ID.
- ``authn`` | ``''``
* - ``ENABLE_IMAGE_LAYOUT``
- Enables the image layout feature within the authn. When set to True, this feature allows the inclusion of images in the base container layout. For more details on configuring this feature, please refer to the `Modifying base container <docs/how_tos/modifying_base_container.rst>`_.
- ``true`` | ``''`` (empty strings are falsy)
edX-specific Environment Variables
==================================
**********************************
Furthermore, there are several edX-specific environment variables that enable integrations with closed-source services private to the edX organization, and might be unsupported in Open edX.
@@ -148,13 +135,12 @@ Furthermore, there are several edX-specific environment variables that enable in
- ``true`` | ``''`` (empty strings are falsy)
For more information see the document: `Micro-frontend applications in Open
edX <https://github.com/overhangio/tutor-mfe?tab=readme-ov-file#mfe-development>`__.
edX <https://edx.readthedocs.io/projects/edx-developer-docs/en/latest/developers_guide/micro_frontends_in_open_edx.html#required-environment-variables>`__.
How To Contribute
=================
------------
Contributions are very welcome, and strongly encouraged! We've
put together `some documentation that describes our contribution process <https://docs.openedx.org/en/latest/developers/references/developer_guide/process/index.html>`_.
put together `some documentation that describes our contribution process <https://edx.readthedocs.org/projects/edx-developer-guide/en/latest/process/index.html>`_.
Even though they were written with edx-platform in mind, the guidelines should be followed for Open edX code in general.
@@ -163,58 +149,34 @@ can find it it at `PULL_REQUEST_TEMPLATE.md <https://github.com/openedx/frontend
This project is currently accepting all types of contributions, bug fixes and security fixes.
Getting Help
============
If you're having trouble, we have discussion forums at
https://discuss.openedx.org where you can connect with others in the community.
Our real-time conversations are on Slack. You can request a `Slack
invitation`_, then join our `community Slack workspace`_. Because this is a
frontend repository, the best place to discuss it would be in the `#wg-frontend
channel`_.
For anything non-trivial, the best path is to open an issue in this repository
with as many details about the issue you are facing as you can provide.
https://github.com/openedx/frontend-app-authn/issues
For more information about these options, see the `Getting Help`_ page.
.. _Slack invitation: https://openedx.org/slack
.. _community Slack workspace: https://openedx.slack.com/
.. _#wg-frontend channel: https://openedx.slack.com/archives/C04BM6YC7A6
.. _Getting Help: https://openedx.org/community/connect
The Open edX Code of Conduct
============================
Open edX Code of Conduct
------------------------
All community members are expected to follow the `Open edX Code of Conduct <https://openedx.org/code-of-conduct/>`_.
People
======
------
The assigned maintainers for this component and other project details may be
found in `Backstage <https://backstage.openedx.org/catalog/default/group/2u-infinity>`_. Backstage pulls this data from the ``catalog-info.yaml``
found in `Backstage <https://backstage.openedx.org/catalog/default/group/vanguards>`_. Backstage pulls this data from the ``catalog-info.yaml``
file in this repo.
Reporting Security Issues
=========================
-------------------------
Please do not report security issues in public. Please email security@openedx.org.
Please do not report security issues in public. Please email security@edx.org.
Known Issues
============
------------
None
License
=======
-------
The code in this repository is licensed under the GNU Affero General Public License v3.0, unless
otherwise noted.
Please see `LICENSE <https://github.com/openedx/frontend-app-authn/blob/master/LICENSE>`_ for details.
==============================
.. |Build Status| image:: https://api.travis-ci.com/edx/frontend-app-authn.svg?branch=master

View File

@@ -12,8 +12,7 @@ metadata:
icon: 'Article'
annotations:
openedx.org/arch-interest-groups: ""
openedx.org/release: "master"
spec:
owner: group:2u-infinity
owner: group:vanguards
type: 'service'
lifecycle: 'production'

View File

@@ -3,7 +3,7 @@ Enable Social Auth Locally
Please follow the steps below to enable social auth (SSO) locally.
1. Follow `Enabling Third Party Authentication <https://docs.openedx.org/en/latest/site_ops/install_configure_run_guide/configuration/tpa/index.html>`_ for backend configuration.
1. Follow `Enabling Third Party Authentication <https://edx.readthedocs.io/projects/edx-installing-configuring-and-running/en/latest/configuration/tpa/index.html>`_ for backend configuration.
2. Authn has a component for rendering Social Auth providers at frontend which goes through each provider.

View File

@@ -1,39 +0,0 @@
========================================
Modifying the Base Container in Authn
========================================
The base container in Authn serves as the fundamental layout structure for rendering different components based on configurations. This document outlines the process for modifying the base container to accommodate changes or customize layouts as needed.
Understanding Base Container Versions
--------------------------------------
The base container supports two main versions:
- **Default Layout:** The default layout is the standard layout used when specific configurations do not dictate otherwise.
.. image:: ../images/default_layout.png
- **Image Layout:** The image layout is an alternative layout option that can be enabled based on configurations.
.. image:: ../images/image_layout.png
Enabling the Image Layout
---------------------------
To activate the image layout feature, navigate to your .env file and update the configurations:
**Update Configuration**
Locate the ``ENABLE_IMAGE_LAYOUT`` parameter and set its value to ``true``. Additionally, ensure that the Image configuration settings are provided. Your overall configurations should resemble the following:
.. code-block::
# ***** Image Layout Configuration *****
ENABLE_IMAGE_LAYOUT = True # Set to True to enable image layout feature
# ***** Base Container Images *****
BANNER_IMAGE_LARGE='' # Path to the large banner image
BANNER_IMAGE_MEDIUM='' # Path to the medium-sized banner image
BANNER_IMAGE_SMALL='' # Path to the small banner image
BANNER_IMAGE_EXTRA_SMALL='' # Path to the extra-small banner image
This allows for the customization and adaptation of the base container layout according to specific requirements.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 252 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 MiB

View File

@@ -1,4 +1,4 @@
const { createConfig } = require('@openedx/frontend-build');
const { createConfig } = require('@edx/frontend-build');
module.exports = createConfig('jest', {
setupFiles: [

8
openedx.yaml Normal file
View File

@@ -0,0 +1,8 @@
# This file describes this Open edX repo, as described in OEP-2:
# http://open-edx-proposals.readthedocs.io/en/latest/oeps/oep-0002.html#specification
nick: Authn MFE
oeps: {}
owner: openedx/vanguards
openedx-release:
ref: master

28737
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -11,14 +11,17 @@
],
"scripts": {
"build": "fedx-scripts webpack",
"i18n_extract": "fedx-scripts formatjs extract",
"i18n_extract": "BABEL_ENV=i18n fedx-scripts babel src --quiet > /dev/null",
"lint": "fedx-scripts eslint --ext .js --ext .jsx .",
"lint:fix": "fedx-scripts eslint --fix --ext .js --ext .jsx .",
"snapshot": "fedx-scripts jest --updateSnapshot",
"start": "fedx-scripts webpack-dev-server --progress",
"dev": "PUBLIC_PATH=/authn/ MFE_CONFIG_API_URL='http://localhost:8000/api/mfe_config/v1' fedx-scripts webpack-dev-server --progress --host apps.local.openedx.io",
"test": "fedx-scripts jest --coverage --passWithNoTests"
},
"husky": {
"hooks": {
"pre-commit": "npm run lint"
}
},
"author": "edX",
"license": "AGPL-3.0",
"homepage": "https://github.com/openedx/frontend-app-authn#readme",
@@ -29,53 +32,52 @@
"url": "https://github.com/openedx/frontend-app-authn/issues"
},
"dependencies": {
"@edx/brand": "npm:@openedx/brand-openedx@^1.2.2",
"@edx/frontend-platform": "^8.3.1",
"@edx/openedx-atlas": "^0.6.0",
"@fortawesome/fontawesome-svg-core": "6.7.2",
"@fortawesome/free-brands-svg-icons": "6.7.2",
"@fortawesome/free-solid-svg-icons": "6.7.2",
"@fortawesome/react-fontawesome": "0.2.6",
"@openedx/frontend-plugin-framework": "^1.7.0",
"@openedx/paragon": "^23.4.2",
"@edx/brand": "npm:@edx/brand-openedx@1.2.0",
"@edx/frontend-platform": "^5.0.0",
"@edx/paragon": "20.46.2",
"@fortawesome/fontawesome-svg-core": "6.4.2",
"@fortawesome/free-brands-svg-icons": "6.4.2",
"@fortawesome/free-solid-svg-icons": "6.4.2",
"@fortawesome/react-fontawesome": "0.2.0",
"@optimizely/react-sdk": "^2.9.1",
"@redux-devtools/extension": "3.3.0",
"@testing-library/react": "^16.2.0",
"@redux-devtools/extension": "3.2.5",
"algoliasearch": "^4.14.3",
"algoliasearch-helper": "^3.26.0",
"classnames": "2.5.1",
"core-js": "3.43.0",
"classnames": "2.3.2",
"core-js": "3.32.0",
"fastest-levenshtein": "1.0.16",
"form-urlencoded": "6.1.6",
"form-urlencoded": "6.1.0",
"prop-types": "15.8.1",
"query-string": "7.1.3",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-helmet": "6.1.0",
"react-loading-skeleton": "3.5.0",
"react-loading-skeleton": "3.3.1",
"react-redux": "7.2.9",
"react-responsive": "8.2.0",
"react-router": "6.30.1",
"react-router-dom": "6.30.1",
"react-router": "6.15.0",
"react-router-dom": "6.15.0",
"react-zendesk": "^0.1.13",
"redux": "4.2.1",
"redux": "4.2.0",
"redux-logger": "3.0.6",
"redux-mock-store": "1.5.5",
"redux-saga": "1.4.2",
"redux-mock-store": "1.5.4",
"redux-saga": "1.2.3",
"redux-thunk": "2.4.2",
"regenerator-runtime": "0.14.1",
"reselect": "5.1.1",
"universal-cookie": "7.2.2"
"regenerator-runtime": "0.14.0",
"reselect": "4.1.8",
"universal-cookie": "4.0.4"
},
"devDependencies": {
"@edx/browserslist-config": "^1.1.1",
"@openedx/frontend-build": "^14.6.2",
"babel-plugin-formatjs": "10.5.41",
"eslint-plugin-import": "2.32.0",
"@edx/frontend-build": "12.9.8",
"@edx/reactifex": "1.1.0",
"@wojtekmaj/enzyme-adapter-react-17": "^0.8.0",
"babel-plugin-formatjs": "10.5.3",
"enzyme": "3.11.0",
"eslint-plugin-import": "2.28.0",
"glob": "7.2.3",
"history": "5.3.0",
"jest": "30.2.0",
"react-test-renderer": "^18.3.1",
"ts-jest": "^29.4.0"
"husky": "7.0.4",
"jest": "29.6.2",
"react-test-renderer": "^17.0.2"
}
}

View File

@@ -1,12 +1,11 @@
<!doctype html>
<html lang="en-us">
<head>
<title><%= (process.env.SITE_NAME && process.env.SITE_NAME != 'null') ? 'Authentication | ' + process.env.SITE_NAME : 'Authentication' %></title>
<title>Authn | <%= process.env.SITE_NAME %></title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="<%=htmlWebpackPlugin.options.FAVICON_URL%>" type="image/x-icon"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.4.4/iframeResizer.contentWindow.min.js"
integrity="sha512-IWwZFBvHzN41wNI6etRLLuLrDDj/6AwJcPt7cmKJAzluYTIHHQ1PF8wh0rSy05jxEvvjflVvH2MxeV6riyEEXg=="
<script src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.3.6/iframeResizer.contentWindow.min.js"
integrity="sha512-R7Piufj0/o6jG9ZKrAvS2dblFr2kkuG4XVQwStX+/4P+KwOLUXn2DXy0l1AJDxxqGhkM/FJllZHG2PKOAheYzg=="
crossorigin="anonymous"
referrerpolicy="no-referrer">
</script>

View File

@@ -24,7 +24,7 @@ import { ForgotPasswordPage } from './forgot-password';
import Logistration from './logistration/Logistration';
import { ProgressiveProfiling } from './progressive-profiling';
import { RecommendationsPage } from './recommendations';
import { RegistrationPage } from './register';
import { EmbeddableRegistrationPage } from './register';
import { ResetPasswordPage } from './reset-password';
import './index.scss';
@@ -41,7 +41,7 @@ const MainApp = () => (
<Route path="/" element={<Navigate replace to={updatePathWithQueryParams(REGISTER_PAGE)} />} />
<Route
path={REGISTER_EMBEDDED_PAGE}
element={<EmbeddedRegistrationRoute><RegistrationPage /></EmbeddedRegistrationRoute>}
element={<EmbeddedRegistrationRoute><EmbeddableRegistrationPage /></EmbeddedRegistrationRoute>}
/>
<Route
path={LOGIN_PAGE}

View File

@@ -1,50 +1,50 @@
import React from 'react';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import { render, screen } from '@testing-library/react';
import { mount } from 'enzyme';
import { DefaultLargeLayout, DefaultMediumLayout, DefaultSmallLayout } from './index';
describe('Default Layout tests', () => {
it('should display the form passed as a child in SmallScreenLayout', () => {
render(
const smallScreen = mount(
<IntlProvider locale="en">
<div>
<DefaultSmallLayout />
<form aria-label="form">
<form>
<input type="text" />
</form>
</div>
</IntlProvider>,
);
expect(screen.getByRole('form')).toBeDefined();
expect(smallScreen.find('form').exists()).toEqual(true);
});
it('should display the form passed as a child in MediumScreenLayout', () => {
render(
const mediumScreen = mount(
<IntlProvider locale="en">
<div>
<DefaultMediumLayout />
<form aria-label="form">
<form>
<input type="text" />
</form>
</div>
</IntlProvider>,
);
expect(screen.getByRole('form')).toBeDefined();
expect(mediumScreen.find('form').exists()).toEqual(true);
});
it('should display the form passed as a child in LargeScreenLayout', () => {
render(
const largeScreen = mount(
<IntlProvider locale="en">
<div>
<DefaultLargeLayout />
<form aria-label="form">
<form>
<input type="text" />
</form>
</div>
</IntlProvider>,
);
expect(screen.getByRole('form')).toBeDefined();
expect(largeScreen.find('form').exists()).toEqual(true);
});
});

View File

@@ -2,7 +2,7 @@ import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink, Image } from '@openedx/paragon';
import { Hyperlink, Image } from '@edx/paragon';
import classNames from 'classnames';
import messages from './messages';

View File

@@ -2,7 +2,7 @@ import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink, Image } from '@openedx/paragon';
import { Hyperlink, Image } from '@edx/paragon';
import classNames from 'classnames';
import messages from './messages';
@@ -23,15 +23,13 @@ const MediumLayout = () => {
<div>
<h1
className={classNames(
'display-1 text-white mt-5 mb-5 mr-2 main-heading',
'display-1 text-white mt-5 mb-5 mr-2',
{ 'ml-4.5': getConfig().SITE_NAME !== 'edX' },
)}
>
<span>
{formatMessage(messages['start.learning'])}{' '}
<span className="text-accent-a d-inline-block">
{formatMessage(messages['with.site.name'], { siteName: getConfig().SITE_NAME })}
</span>
<span className="mr-2">{formatMessage(messages['start.learning'])}</span>
<span className="text-accent-a d-inline-block">
{formatMessage(messages['with.site.name'], { siteName: getConfig().SITE_NAME })}
</span>
</h1>
</div>

View File

@@ -2,7 +2,7 @@ import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink, Image } from '@openedx/paragon';
import { Hyperlink, Image } from '@edx/paragon';
import classNames from 'classnames';
import messages from './messages';
@@ -17,18 +17,17 @@ const SmallLayout = () => {
<Hyperlink destination={getConfig().MARKETING_SITE_BASE_URL}>
<Image className="logo-small" alt={getConfig().SITE_NAME} src={getConfig().LOGO_WHITE_URL} />
</Hyperlink>
<div className="d-flex align-items-center m-3.5">
<div className="d-flex align-items-center mb-3 mt-3 mr-3">
<div className={classNames({ 'small-yellow-line mr-n2.5': getConfig().SITE_NAME === 'edX' })} />
<h1
className={classNames(
'text-white mt-3.5 mb-3.5',
{ 'ml-4.5': getConfig().SITE_NAME !== 'edX' },
)}
>
<span>
{formatMessage(messages['start.learning'])}{' '}
<span className="text-accent-a d-inline-block">
{formatMessage(messages['with.site.name'], { siteName: getConfig().SITE_NAME })}
</span>
<span className="mr-1">{formatMessage(messages['start.learning'])}</span>
<span className="text-accent-a d-inline-block">
{formatMessage(messages['with.site.name'], { siteName: getConfig().SITE_NAME })}
</span>
</h1>
</div>

View File

@@ -2,7 +2,7 @@ import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink, Image } from '@openedx/paragon';
import { Hyperlink, Image } from '@edx/paragon';
import messages from './messages';

View File

@@ -2,7 +2,7 @@ import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink, Image } from '@openedx/paragon';
import { Hyperlink, Image } from '@edx/paragon';
import './index.scss';
import messages from './messages';

View File

@@ -2,7 +2,7 @@ import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink, Image } from '@openedx/paragon';
import { Hyperlink, Image } from '@edx/paragon';
import './index.scss';
import messages from './messages';

View File

@@ -2,7 +2,7 @@ import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink, Image } from '@openedx/paragon';
import { Hyperlink, Image } from '@edx/paragon';
import messages from './messages';

View File

@@ -2,12 +2,12 @@ import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink, Image } from '@openedx/paragon';
import { Hyperlink, Image } from '@edx/paragon';
import PropTypes from 'prop-types';
import messages from './messages';
const LargeLayout = ({ fullName }) => {
const LargeLayout = ({ username }) => {
const { formatMessage } = useIntl();
return (
@@ -20,7 +20,7 @@ const LargeLayout = ({ fullName }) => {
<div className="large-screen-left-container mr-n4.5 large-yellow-line mt-5" />
<div>
<h1 className="welcome-to-platform data-hj-suppress">
{formatMessage(messages['welcome.to.platform'], { siteName: getConfig().SITE_NAME, fullName })}
{formatMessage(messages['welcome.to.platform'], { siteName: getConfig().SITE_NAME, username })}
</h1>
<h2 className="complete-your-profile">
{formatMessage(messages['complete.your.profile.1'])}
@@ -43,7 +43,7 @@ const LargeLayout = ({ fullName }) => {
};
LargeLayout.propTypes = {
fullName: PropTypes.string.isRequired,
username: PropTypes.string.isRequired,
};
export default LargeLayout;

View File

@@ -2,12 +2,12 @@ import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink, Image } from '@openedx/paragon';
import { Hyperlink, Image } from '@edx/paragon';
import PropTypes from 'prop-types';
import messages from './messages';
const MediumLayout = ({ fullName }) => {
const MediumLayout = ({ username }) => {
const { formatMessage } = useIntl();
return (
@@ -22,7 +22,7 @@ const MediumLayout = ({ fullName }) => {
<div className="medium-yellow-line mt-5 mr-n2" />
<div>
<h1 className="h3 data-hj-suppress mw-320">
{formatMessage(messages['welcome.to.platform'], { siteName: getConfig().SITE_NAME, fullName })}
{formatMessage(messages['welcome.to.platform'], { siteName: getConfig().SITE_NAME, username })}
</h1>
<h2 className="display-1">
{formatMessage(messages['complete.your.profile.1'])}
@@ -46,7 +46,7 @@ const MediumLayout = ({ fullName }) => {
};
MediumLayout.propTypes = {
fullName: PropTypes.string.isRequired,
username: PropTypes.string.isRequired,
};
export default MediumLayout;

View File

@@ -2,12 +2,12 @@ import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink, Image } from '@openedx/paragon';
import { Hyperlink, Image } from '@edx/paragon';
import PropTypes from 'prop-types';
import messages from './messages';
const SmallLayout = ({ fullName }) => {
const SmallLayout = ({ username }) => {
const { formatMessage } = useIntl();
return (
@@ -16,11 +16,11 @@ const SmallLayout = ({ fullName }) => {
<Hyperlink destination={getConfig().MARKETING_SITE_BASE_URL}>
<Image className="logo-small" alt={getConfig().SITE_NAME} src={getConfig().LOGO_URL} />
</Hyperlink>
<div className="d-flex align-items-center m-3.5">
<div className="d-flex align-items-center mb-3 mt-3 mr-3">
<div className="small-yellow-line mt-4.5" />
<div>
<h1 className="h5 data-hj-suppress">
{formatMessage(messages['welcome.to.platform'], { siteName: getConfig().SITE_NAME, fullName })}
{formatMessage(messages['welcome.to.platform'], { siteName: getConfig().SITE_NAME, username })}
</h1>
<h2 className="h1">
{formatMessage(messages['complete.your.profile.1'])}
@@ -35,7 +35,7 @@ const SmallLayout = ({ fullName }) => {
};
SmallLayout.propTypes = {
fullName: PropTypes.string.isRequired,
username: PropTypes.string.isRequired,
};
export default SmallLayout;

View File

@@ -3,7 +3,7 @@ import { defineMessages } from '@edx/frontend-platform/i18n';
const messages = defineMessages({
'welcome.to.platform': {
id: 'welcome.to.platform',
defaultMessage: 'Welcome to {siteName}, {fullName}!',
defaultMessage: 'Welcome to {siteName}, {username}!',
description: 'Welcome message that appears on progressive profile page',
},
'complete.your.profile.1': {

View File

@@ -0,0 +1,4 @@
const IMAGE_LAYOUT = 'image-layout';
const DEFAULT_LAYOUT = 'default-layout';
export { DEFAULT_LAYOUT, IMAGE_LAYOUT };

View File

@@ -1,7 +1,7 @@
import React from 'react';
import React, { useEffect, useState } from 'react';
import { getConfig } from '@edx/frontend-platform';
import { breakpoints } from '@openedx/paragon';
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
import { breakpoints } from '@edx/paragon';
import classNames from 'classnames';
import PropTypes from 'prop-types';
import MediaQuery from 'react-responsive';
@@ -11,26 +11,45 @@ import {
ImageExtraSmallLayout, ImageLargeLayout, ImageMediumLayout, ImageSmallLayout,
} from './components/image-layout';
import { AuthLargeLayout, AuthMediumLayout, AuthSmallLayout } from './components/welcome-page-layout';
import { DEFAULT_LAYOUT, IMAGE_LAYOUT } from './data/constants';
const BaseContainer = ({ children, showWelcomeBanner, fullName }) => {
const enableImageLayout = getConfig().ENABLE_IMAGE_LAYOUT;
const BaseContainer = ({ children, showWelcomeBanner }) => {
const authenticatedUser = showWelcomeBanner ? getAuthenticatedUser() : null;
const username = authenticatedUser ? authenticatedUser.username : null;
if (enableImageLayout) {
const [baseContainerVersion, setBaseContainerVersion] = useState(DEFAULT_LAYOUT);
useEffect(() => {
const initRebrandExperiment = () => {
if (window.experiments?.rebrandExperiment) {
setBaseContainerVersion(window.experiments?.rebrandExperiment?.variation);
} else {
window.experiments = window.experiments || {};
window.experiments.rebrandExperiment = {};
window.experiments.rebrandExperiment.handleLoaded = () => {
setBaseContainerVersion(window.experiments?.rebrandExperiment?.variation);
};
}
};
initRebrandExperiment();
}, []);
if (baseContainerVersion === IMAGE_LAYOUT) {
return (
<div className="layout">
<MediaQuery maxWidth={breakpoints.extraSmall.maxWidth - 1}>
{showWelcomeBanner ? <AuthSmallLayout fullName={fullName} /> : <ImageExtraSmallLayout />}
{authenticatedUser ? <AuthSmallLayout username={username} /> : <ImageExtraSmallLayout />}
</MediaQuery>
<MediaQuery minWidth={breakpoints.small.minWidth} maxWidth={breakpoints.small.maxWidth - 1}>
{showWelcomeBanner ? <AuthSmallLayout fullName={fullName} /> : <ImageSmallLayout />}
{authenticatedUser ? <AuthSmallLayout username={username} /> : <ImageSmallLayout />}
</MediaQuery>
<MediaQuery minWidth={breakpoints.medium.minWidth} maxWidth={breakpoints.large.maxWidth - 1}>
{showWelcomeBanner ? <AuthMediumLayout fullName={fullName} /> : <ImageMediumLayout />}
{authenticatedUser ? <AuthMediumLayout username={username} /> : <ImageMediumLayout />}
</MediaQuery>
<MediaQuery minWidth={breakpoints.extraLarge.minWidth}>
{showWelcomeBanner ? <AuthLargeLayout fullName={fullName} /> : <ImageLargeLayout />}
{authenticatedUser ? <AuthLargeLayout username={username} /> : <ImageLargeLayout />}
</MediaQuery>
<div className={classNames('content', { 'align-items-center mt-0': showWelcomeBanner })}>
<div className={classNames('content', { 'align-items-center mt-0': authenticatedUser })}>
{children}
</div>
</div>
@@ -42,15 +61,15 @@ const BaseContainer = ({ children, showWelcomeBanner, fullName }) => {
<div className="col-md-12 extra-large-screen-top-stripe" />
<div className="layout">
<MediaQuery maxWidth={breakpoints.small.maxWidth - 1}>
{showWelcomeBanner ? <AuthSmallLayout fullName={fullName} /> : <DefaultSmallLayout />}
{authenticatedUser ? <AuthSmallLayout username={username} /> : <DefaultSmallLayout />}
</MediaQuery>
<MediaQuery minWidth={breakpoints.medium.minWidth} maxWidth={breakpoints.large.maxWidth - 1}>
{showWelcomeBanner ? <AuthMediumLayout fullName={fullName} /> : <DefaultMediumLayout />}
{authenticatedUser ? <AuthMediumLayout username={username} /> : <DefaultMediumLayout />}
</MediaQuery>
<MediaQuery minWidth={breakpoints.extraLarge.minWidth}>
{showWelcomeBanner ? <AuthLargeLayout fullName={fullName} /> : <DefaultLargeLayout />}
{authenticatedUser ? <AuthLargeLayout username={username} /> : <DefaultLargeLayout />}
</MediaQuery>
<div className={classNames('content', { 'align-items-center mt-0': showWelcomeBanner })}>
<div className={classNames('content', { 'align-items-center mt-0': authenticatedUser })}>
{children}
</div>
</div>
@@ -60,13 +79,11 @@ const BaseContainer = ({ children, showWelcomeBanner, fullName }) => {
BaseContainer.defaultProps = {
showWelcomeBanner: false,
fullName: null,
};
BaseContainer.propTypes = {
children: PropTypes.node.isRequired,
showWelcomeBanner: PropTypes.bool,
fullName: PropTypes.string,
};
export default BaseContainer;

View File

@@ -1,8 +1,7 @@
import React from 'react';
import { mergeConfig } from '@edx/frontend-platform';
import { IntlProvider } from '@edx/frontend-platform/i18n';
import { render } from '@testing-library/react';
import { mount } from 'enzyme';
import { Context as ResponsiveContext } from 'react-responsive';
import BaseContainer from '../index';
@@ -13,34 +12,32 @@ const LargeScreen = {
};
describe('Base component tests', () => {
it('should show default layout', () => {
const { container } = render(
it('should should default layout', () => {
const baseContainer = mount(
<IntlProvider locale="en">
<BaseContainer>
<div>Test Content</div>
</BaseContainer>
<BaseContainer />
</IntlProvider>,
LargeScreen,
);
expect(container.querySelector('.banner__image')).toBeNull();
expect(container.querySelector('.large-screen-svg-primary')).toBeDefined();
expect(baseContainer.find('.banner__image').exists()).toBeFalsy();
expect(baseContainer.find('.large-screen-svg-primary').exists()).toBeTruthy();
});
it('renders Image layout when ENABLE_IMAGE_LAYOUT configuration is enabled', () => {
mergeConfig({
ENABLE_IMAGE_LAYOUT: true,
});
it('[experiment] should show image layout for treatment group', () => {
window.experiments = {
rebrandExperiment: {
variation: 'image-layout',
},
};
const { container } = render(
const baseContainer = mount(
<IntlProvider locale="en">
<BaseContainer showWelcomeBanner={false}>
<div>Test Content</div>
</BaseContainer>
<BaseContainer />
</IntlProvider>,
LargeScreen,
);
expect(container.querySelector('.banner__image')).toBeDefined();
expect(baseContainer.find('.banner__image').exists()).toBeTruthy();
});
});

View File

@@ -2,12 +2,12 @@ import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { useIntl } from '@edx/frontend-platform/i18n';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import {
Button, Form,
Icon,
} from '@openedx/paragon';
import { Login } from '@openedx/paragon/icons';
} from '@edx/paragon';
import { Login } from '@edx/paragon/icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import PropTypes from 'prop-types';
import messages from './messages';
@@ -19,8 +19,7 @@ import { LOGIN_PAGE, SUPPORTED_ICON_CLASSES } from '../data/constants';
const EnterpriseSSO = (props) => {
const { formatMessage } = useIntl();
const tpaProvider = props.provider;
const hideRegistrationLink = getConfig().ALLOW_PUBLIC_ACCOUNT_CREATION === false
|| getConfig().SHOW_REGISTRATION_LINKS === false;
const disablePublicAccountCreation = getConfig().ALLOW_PUBLIC_ACCOUNT_CREATION === false;
const handleSubmit = (e, url) => {
e.preventDefault();
@@ -75,7 +74,7 @@ const EnterpriseSSO = (props) => {
className="w-100"
onClick={(e) => handleClick(e)}
>
{hideRegistrationLink
{disablePublicAccountCreation
? formatMessage(messages['enterprisetpa.login.button.text.public.account.creation.disabled'])
: formatMessage(messages['enterprisetpa.login.button.text'])}
</Button>

View File

@@ -2,7 +2,7 @@ import React, { useState } from 'react';
import {
Form, TransitionReplace,
} from '@openedx/paragon';
} from '@edx/paragon';
import PropTypes from 'prop-types';
const FormGroup = (props) => {

View File

@@ -2,8 +2,8 @@ import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Button, Hyperlink, Icon } from '@openedx/paragon';
import { Institution } from '@openedx/paragon/icons';
import { Button, Hyperlink, Icon } from '@edx/paragon';
import { Institution } from '@edx/paragon/icons';
import PropTypes from 'prop-types';
import messages from './messages';

View File

@@ -1,103 +1,41 @@
import React, { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { useIntl } from '@edx/frontend-platform/i18n';
import {
Form, Icon, IconButton, OverlayTrigger, Tooltip, useToggle,
} from '@openedx/paragon';
} from '@edx/paragon';
import {
Check, Remove, Visibility, VisibilityOff,
} from '@openedx/paragon/icons';
} from '@edx/paragon/icons';
import PropTypes from 'prop-types';
import messages from './messages';
import { LETTER_REGEX, NUMBER_REGEX } from '../data/constants';
import { clearRegistrationBackendError, fetchRealtimeValidations } from '../register/data/actions';
import { validatePasswordField } from '../register/data/utils';
const PasswordField = (props) => {
const { formatMessage } = useIntl();
const dispatch = useDispatch();
const validationApiRateLimited = useSelector(state => state.register.validationApiRateLimited);
const [isPasswordHidden, setHiddenTrue, setHiddenFalse] = useToggle(true);
const [showTooltip, setShowTooltip] = useState(false);
const handleBlur = (e) => {
const { name, value } = e.target;
if (name === props.name && e.relatedTarget?.name === 'passwordIcon') {
return; // Do not run validations on password icon click
}
let passwordValue = value;
if (name === 'passwordIcon') {
// To validate actual password value when onBlur is triggered by focusing out the password icon
passwordValue = props.value;
}
if (props.handleBlur) {
props.handleBlur({
target: {
name: props.name,
value: passwordValue,
},
});
}
if (props.handleBlur) { props.handleBlur(e); }
setShowTooltip(props.showRequirements && false);
if (props.handleErrorChange) { // If rendering from register page
const fieldError = validatePasswordField(passwordValue, formatMessage);
if (fieldError) {
props.handleErrorChange('password', fieldError);
} else if (!validationApiRateLimited) {
dispatch(fetchRealtimeValidations({ password: passwordValue }));
}
}
};
const handleFocus = (e) => {
if (e.target?.name === 'passwordIcon') {
return; // Do not clear error on password icon focus
}
if (props.handleFocus) {
props.handleFocus(e);
}
if (props.handleErrorChange) {
props.handleErrorChange('password', '');
dispatch(clearRegistrationBackendError('password'));
}
setTimeout(() => setShowTooltip(props.showRequirements && true), 150);
};
const HideButton = (
<IconButton
onFocus={handleFocus}
onBlur={handleBlur}
name="passwordIcon"
src={VisibilityOff}
iconAs={Icon}
onClick={setHiddenTrue}
size="sm"
variant="secondary"
alt={formatMessage(messages['hide.password'])}
/>
<IconButton onFocus={handleFocus} onBlur={handleBlur} name="password" src={VisibilityOff} iconAs={Icon} onClick={setHiddenTrue} size="sm" variant="secondary" alt={formatMessage(messages['hide.password'])} />
);
const ShowButton = (
<IconButton
onFocus={handleFocus}
onBlur={handleBlur}
name="passwordIcon"
src={Visibility}
iconAs={Icon}
onClick={setHiddenFalse}
size="sm"
variant="secondary"
alt={formatMessage(messages['show.password'])}
/>
<IconButton onFocus={handleFocus} onBlur={handleBlur} name="password" src={Visibility} iconAs={Icon} onClick={setHiddenFalse} size="sm" variant="secondary" alt={formatMessage(messages['show.password'])} />
);
const placement = window.innerWidth < 768 ? 'top' : 'left';
const tooltip = (
<Tooltip id={`password-requirement-${placement}`}>
@@ -138,7 +76,7 @@ const PasswordField = (props) => {
{props.errorMessage !== '' && (
<Form.Control.Feedback key="error" className="form-text-size" hasIcon={false} feedback-for={props.name} type="invalid">
{props.errorMessage}
{props.showScreenReaderText && <span className="sr-only">{formatMessage(messages['password.sr.only.helping.text'])}</span>}
<span className="sr-only">{formatMessage(messages['password.sr.only.helping.text'])}</span>
</Form.Control.Feedback>
)}
</Form.Group>
@@ -151,9 +89,7 @@ PasswordField.defaultProps = {
handleBlur: null,
handleFocus: null,
handleChange: () => {},
handleErrorChange: null,
showRequirements: true,
showScreenReaderText: true,
autoComplete: null,
};
@@ -164,12 +100,10 @@ PasswordField.propTypes = {
handleBlur: PropTypes.func,
handleFocus: PropTypes.func,
handleChange: PropTypes.func,
handleErrorChange: PropTypes.func,
name: PropTypes.string.isRequired,
showRequirements: PropTypes.bool,
value: PropTypes.string.isRequired,
autoComplete: PropTypes.string,
showScreenReaderText: PropTypes.bool,
};
export default PasswordField;

View File

@@ -3,13 +3,12 @@ import PropTypes from 'prop-types';
import { Navigate } from 'react-router-dom';
import {
AUTHN_PROGRESSIVE_PROFILING, RECOMMENDATIONS, REDIRECT,
AUTHN_PROGRESSIVE_PROFILING, RECOMMENDATIONS,
} from '../data/constants';
import { setCookie } from '../data/utils';
const RedirectLogistration = (props) => {
const {
authenticatedUser,
finishAuthUrl,
redirectUrl,
redirectToProgressiveProfilingPage,
@@ -18,8 +17,6 @@ const RedirectLogistration = (props) => {
redirectToRecommendationsPage,
educationLevel,
userId,
registrationEmbedded,
host,
} = props;
let finalRedirectUrl = '';
@@ -39,13 +36,6 @@ const RedirectLogistration = (props) => {
// TODO: Do we still need this cookie?
setCookie('van-504-returning-user', true);
if (registrationEmbedded) {
window.parent.postMessage({
action: REDIRECT,
redirectUrl: getConfig().POST_REGISTRATION_REDIRECT_URL,
}, host);
return null;
}
const registrationResult = { redirectUrl: finalRedirectUrl, success };
return (
<Navigate
@@ -53,7 +43,6 @@ const RedirectLogistration = (props) => {
state={{
registrationResult,
optionalFields,
authenticatedUser,
}}
replace
/>
@@ -83,7 +72,6 @@ const RedirectLogistration = (props) => {
};
RedirectLogistration.defaultProps = {
authenticatedUser: {},
educationLevel: null,
finishAuthUrl: null,
success: false,
@@ -92,12 +80,9 @@ RedirectLogistration.defaultProps = {
optionalFields: {},
redirectToRecommendationsPage: false,
userId: null,
registrationEmbedded: false,
host: '',
};
RedirectLogistration.propTypes = {
authenticatedUser: PropTypes.shape({}),
educationLevel: PropTypes.string,
finishAuthUrl: PropTypes.string,
success: PropTypes.bool,
@@ -106,8 +91,6 @@ RedirectLogistration.propTypes = {
optionalFields: PropTypes.shape({}),
redirectToRecommendationsPage: PropTypes.bool,
userId: PropTypes.number,
registrationEmbedded: PropTypes.bool,
host: PropTypes.string,
};
export default RedirectLogistration;

View File

@@ -2,9 +2,9 @@ import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Icon } from '@edx/paragon';
import { Login } from '@edx/paragon/icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { Icon } from '@openedx/paragon';
import { Login } from '@openedx/paragon/icons';
import PropTypes from 'prop-types';
import messages from './messages';

View File

@@ -2,7 +2,7 @@ import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Alert } from '@openedx/paragon';
import { Alert } from '@edx/paragon';
import PropTypes from 'prop-types';
import messages from './messages';

View File

@@ -9,7 +9,6 @@ export const defaultState = {
},
thirdPartyAuthApiStatus: null,
thirdPartyAuthContext: {
autoSubmitRegForm: false,
currentProvider: null,
finishAuthUrl: null,
countryCode: null,
@@ -31,7 +30,7 @@ const reducer = (state = defaultState, action = {}) => {
case THIRD_PARTY_AUTH_CONTEXT.SUCCESS: {
return {
...state,
fieldDescriptions: action.payload.fieldDescriptions?.fields,
fieldDescriptions: action.payload.fieldDescriptions.fields,
optionalFields: action.payload.optionalFields,
thirdPartyAuthContext: action.payload.thirdPartyAuthContext,
thirdPartyAuthApiStatus: COMPLETE_STATE,

View File

@@ -58,7 +58,7 @@ describe('common components reducer', () => {
providers: [],
secondaryProviders: [],
pipelineUserDetails: null,
errorMessage: 'An error occurred',
errorMessage: 'An error occured',
},
};

Some files were not shown because too many files have changed in this diff Show More