Compare commits

..

216 Commits

Author SHA1 Message Date
Syed Sajjad Hussain Shah
db75d5046d test: temp changes for embedded authn poc 2023-06-06 18:50:45 +05:00
Attiya Ishaque
5aec091156 fix: fix console errors on running test (#930) 2023-06-02 17:49:40 +05:00
renovate[bot]
68993cc21f fix(deps): update dependency @edx/paragon to v20.40.2 2023-06-01 11:16:17 +00:00
renovate[bot]
404fc2b36b fix(deps): update dependency @edx/paragon to v20.40.1 2023-05-31 22:04:26 +00:00
renovate[bot]
7bb06d0bfa fix(deps): update dependency @edx/frontend-platform to v4.5.1 2023-05-30 06:52:39 +00:00
renovate[bot]
abbb64b9c7 fix(deps): update dependency @edx/paragon to v20.40.0 2023-05-30 00:53:33 +00:00
renovate[bot]
99ca582c1a fix(deps): update dependency @edx/frontend-platform to v4.5.0 2023-05-29 10:19:49 +00:00
renovate[bot]
3e4cfc1573 fix(deps): update dependency @edx/paragon to v20.39.3 2023-05-29 08:09:07 +00:00
renovate[bot]
5437e1b7e9 chore(deps): update dependency @edx/frontend-build to v12.8.38 2023-05-29 03:58:43 +00:00
Attiya Ishaque
4d33cd7d69 fix: fix design issue in user name suggestion field (#922) 2023-05-24 18:32:02 +05:00
Attiya Ishaque
cb82e94b53 refactor: BEM convention for modules (#907) 2023-05-23 17:21:29 +05:00
renovate[bot]
dbe14ccedf fix(deps): update dependency @edx/frontend-platform to v4.4.0 2023-05-23 00:09:52 +00:00
renovate[bot]
841edf2d24 fix(deps): update dependency @edx/paragon to v20.39.2 2023-05-22 20:34:23 +00:00
Blue
0c375cc50c refactor: BEM convention for common components (#914)
Description:
Need to apply BEM comvention for common components

VAN-1425
2023-05-22 10:47:53 +05:00
renovate[bot]
50072887d0 fix(deps): update dependency @edx/paragon to v20.39.1 2023-05-19 17:49:26 +00:00
Attiya Ishaque
976814d846 fix: fix console error in login and register's test (#909) 2023-05-19 12:39:52 +05:00
Blue
c22024cf66 refactor: BEM convention for reset password (#906)
Description:

Need to implement BEM convention for reset password page

VAN-1423
2023-05-19 11:16:49 +05:00
Syed Sajjad Hussain Shah
829a219b9f fix: bugs in country field (#913)
VAN-1415
2023-05-19 10:03:39 +05:00
renovate[bot]
13d572ab28 fix(deps): update dependency @edx/paragon to v20.39.0 2023-05-18 15:00:59 +00:00
renovate[bot]
c0c2ffa122 fix(deps): update dependency @edx/paragon to v20.37.0 2023-05-17 21:17:46 +00:00
Syed Sajjad Hussain Shah
84c563fda3 refactor: use paragon Autosuggest field for country field (#911)
VAN-1415

Co-authored-by: Syed Sajjad  Hussain Shah <syed.sajjad@H7FKF7K6XD.local>
2023-05-17 13:13:04 +05:00
Syed Sajjad Hussain Shah
97720d6a46 Revert "refactor: use paragon Autosuggest field for country field (#904)" (#910)
This reverts commit 386982d9c4.
2023-05-17 12:31:21 +05:00
Syed Sajjad Hussain Shah
386982d9c4 refactor: use paragon Autosuggest field for country field (#904)
VAN-1415

Co-authored-by: Syed Sajjad  Hussain Shah <syed.sajjad@H7FKF7K6XD.local>
2023-05-17 12:11:27 +05:00
renovate[bot]
cb38a2a148 fix(deps): update dependency @edx/paragon to v20.36.2 2023-05-16 19:17:29 +00:00
renovate[bot]
07f19209bf fix(deps): update dependency @edx/frontend-platform to v4.3.0 2023-05-16 02:33:21 +00:00
renovate[bot]
69c0ca13fc fix(deps): update dependency @edx/paragon to v20.36.1 2023-05-15 18:26:20 +00:00
Jenkins
e49c50f55c chore(i18n): update translations 2023-05-14 11:16:53 -04:00
Syed Sajjad Hussain Shah
f0105f0094 Revert "refactor: use paragon Autosuggest field for country field (#897)" (#900)
This reverts commit 3c89afea4a.
2023-05-12 13:01:22 +05:00
Syed Sajjad Hussain Shah
3c89afea4a refactor: use paragon Autosuggest field for country field (#897)
VAN-1415

Co-authored-by: Syed Sajjad  Hussain Shah <syed.sajjad@H7FKF7K6XD.local>
2023-05-12 12:45:29 +05:00
renovate[bot]
848f574f3f fix(deps): update dependency @edx/paragon to v20.36.0 2023-05-11 04:41:23 +00:00
Blue
ec9e34cea4 fix: add departments in Zendesk widget (#896)
Description:
Add departments list in Zendesk widget configurations

VAN-1426
2023-05-10 16:58:26 +05:00
Omar Al-Ithawi
f9069df4e6 feat: use atlas in make pull_translations (#890)
Changes
-------
 - Move all i18n imports into `src/i18n/index.js` so `intl-imports.js` can
   override it with latest translations
 - Add `atlas` into `make pull_translations` when `OPENEDX_ATLAS_PULL`
   environment variable is set.

Refs: [FC-0012 project](https://openedx.atlassian.net/l/cp/XGS0iCcQ) implementing Translation Infrastructure OEP-58.
2023-05-09 11:12:36 -04:00
renovate[bot]
9035f3eb7e fix(deps): update dependency core-js to v3.30.2 2023-05-08 05:14:07 +00:00
renovate[bot]
e197e788d1 fix(deps): update dependency @edx/paragon to v20.34.0 2023-05-05 19:58:17 +00:00
renovate[bot]
49d33522a8 chore(deps): update dependency @edx/frontend-build to v12.8.27 2023-05-05 17:21:17 +00:00
renovate[bot]
06f0ec3c0b chore(deps): update dependency @edx/frontend-build to v12.8.22 2023-05-04 21:04:47 +00:00
Attiya Ishaque
54319c6949 fix: remove cookie policy banner from authn (#888) 2023-05-04 17:12:21 +05:00
renovate[bot]
86f875ec3e chore(deps): update dependency @edx/frontend-build to v12.8.17 2023-05-03 00:45:13 +00:00
renovate[bot]
754a6ddb12 fix(deps): update dependency @edx/paragon to v20.33.0 2023-05-02 19:39:19 +00:00
Shahbaz Shabbir
62e8f75b96 fix: eliminate the usage of extra OR condition in MFE context API (#882) 2023-05-02 19:17:28 +05:00
Shahbaz Shabbir
c0deb663a6 chore: upgrade the query-string version to 7.1.3 (#869) 2023-05-02 17:08:35 +05:00
Zainab Amir
ce28add152 fix: conditionally initialize optimizely (#862) 2023-05-02 16:11:55 +05:00
renovate[bot]
5f89315947 chore(deps): update dependency babel-plugin-formatjs to v10.5.1 2023-05-01 08:06:15 +00:00
renovate[bot]
56dd194a1a fix(deps): update dependency @edx/paragon to v20.32.3 2023-04-28 08:31:27 +00:00
Attiya Ishaque
adcdcc4c8b chore: remove fortawesome/free-regular-svg-icons package (#867) 2023-04-26 18:39:06 +05:00
renovate[bot]
7fd45f089d chore(deps): update dependency @edx/frontend-build to v12.8.16 2023-04-26 06:17:05 +00:00
renovate[bot]
65d82b2080 fix(deps): update dependency @edx/paragon to v20.32.0 2023-04-24 14:10:11 +00:00
renovate[bot]
f771935e20 fix(deps): update dependency @edx/paragon to v20.31.1 2023-04-24 00:46:26 +00:00
renovate[bot]
70c255fc4f fix(deps): update font awesome to v6.4.0 2023-04-21 00:49:33 +00:00
renovate[bot]
bd1396fc54 fix(deps): update dependency @edx/frontend-platform to v4.2.0 2023-04-20 18:20:03 +00:00
Stanislav
cba5395d5c fix: Remove horizontal scroll in windows (#760) 2023-04-20 17:55:05 +05:00
Zainab Amir
b42c09d919 chore: remove unused lodash dependency (#870) 2023-04-20 14:51:40 +05:00
Blue
b7af2356fa fix: Remove extract-react-intl-messages (#865)
Remove unused package extract-react-intl-messages from package.json

VAN-1378
2023-04-20 14:32:11 +05:00
Syed Sajjad Hussain Shah
22d477e55f fix: import/no-cycle eslint issue (#875)
VAN-1388

Co-authored-by: Syed Sajjad  Hussain Shah <syed.sajjad@H7FKF7K6XD.local>
2023-04-20 12:33:40 +05:00
renovate[bot]
dfa69c27bb chore(deps): update dependency babel-plugin-formatjs to v10.5.0 2023-04-20 05:12:27 +00:00
renovate[bot]
6b78158db2 fix(deps): update dependency reselect to v4.1.8 2023-04-19 23:28:48 +00:00
renovate[bot]
c92cac0eed fix(deps): update dependency react-loading-skeleton to v3.2.1 2023-04-19 19:35:03 +00:00
Attiya Ishaque
b2dce920fa chore: remove semver-regex package (#868) 2023-04-19 20:42:59 +05:00
Attiya Ishaque
44cec762fb fix: replace faSignInAlt with paragon icon (#863) 2023-04-19 16:33:54 +05:00
Shahbaz Shabbir
a98188ead8 fix: change keys to camelCase for mfe_context response (PR# 835) (#857) 2023-04-19 13:03:26 +05:00
Syed Sajjad Hussain Shah
294b1a469f chore: remove sanitize-html package (#866)
VAN-1381

Co-authored-by: Syed Sajjad  Hussain Shah <syed.sajjad@H7FKF7K6XD.local>
2023-04-19 12:21:10 +05:00
Syed Sajjad Hussain Shah
ebed588c1c chore: remove react-onclickoutside package (#864)
VAN-1380

Co-authored-by: Syed Sajjad  Hussain Shah <syed.sajjad@H7FKF7K6XD.local>
2023-04-18 15:13:10 +05:00
Blue
46f8217e1a fix: reset-password code coverage (#855)
Improve the code coverage of reset-password component

VAN-1369
2023-04-18 13:24:59 +05:00
Blue
9ab23cf485 Merge pull request #849 from openedx/ahtesham/VAN-1368/test-coverage-registation
fix: registration test coverage
2023-04-17 15:46:20 +05:00
ahtesham-quraish
7790660fe8 fix: registration test coverage
Increase test coverage of registration flow

VAN-1368
2023-04-17 15:37:53 +05:00
Jenkins
1dd2726beb chore(i18n): update translations 2023-04-16 11:16:49 -04:00
renovate[bot]
ba9ce89d1b fix(deps): update dependency core-js to v3.30.1 2023-04-14 21:03:27 +00:00
renovate[bot]
c9082ac709 chore(deps): update dependency @edx/frontend-build to v12.8.10 2023-04-14 16:39:01 +00:00
renovate[bot]
27c8fa8986 fix(deps): update dependency @edx/frontend-platform to v4.1.0 2023-04-14 16:28:37 +00:00
Syed Sajjad Hussain Shah
a04289d71b Revert "fix: change keys to camelCase for mfe_context response (#835)" (#856)
This reverts commit b0745de672.
2023-04-14 14:43:01 +05:00
Blue
321859e0f5 Merge pull request #854 from openedx/ahtesham/1349/update-conditional-logic
fix: remove conditional logic
2023-04-13 14:34:20 +05:00
ahtesham-quraish
4b4bf413c1 fix: remove conditional logic
Remove conditional logic from autoupdate label as it does not run on master push

VAN-1349
2023-04-13 14:21:14 +05:00
renovate[bot]
06c4f75b4a chore(deps): update dependency eslint-plugin-import to v2.27.5 (#811)
* chore(deps): update dependency eslint-plugin-import to v2.27.5

* fix: fix eslint tests

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: attiyaishaque <atiya.ishaq@arbisoft.com>
2023-04-13 13:41:10 +05:00
Attiya Ishaque
12dd97af61 fix: [VAN-1367] Remove Optimizely web from Authn (#843) 2023-04-13 12:54:29 +05:00
Zainab Amir
8e77197459 fix: update pull translation command (#852) 2023-04-13 12:23:48 +05:00
Zainab Amir
3cc64cada6 fix: nested components in CountryField (#851) 2023-04-13 12:05:32 +05:00
Yoiber
3ac5874df1 chore(i18n): add more languages (#747) 2023-04-13 11:24:38 +05:00
Shahbaz Shabbir
107dd6f360 fix: Update eslint configuration and resolve linting errors and test failures (#847) 2023-04-12 22:52:49 +05:00
Blue
347e0cd336 Merge pull request #850 from openedx/ahtesham/VAN-1349/update-github-token
fix: update github token
2023-04-12 12:20:07 +05:00
ahtesham-quraish
2ba6058ec7 fix: update github token
update github token in autoupdate workflow

VAN-1349
2023-04-12 12:08:59 +05:00
Blue
683aa258b8 Merge pull request #825 from openedx/ahtesham/VAN-1349/add-label-support
fix: add new flag in autoupdate action
2023-04-12 11:59:22 +05:00
ahtesham-quraish
d7ad7e314d fix: add new flag in autoupdate action
trigger autoupdate workflow when autoupdate label is added

VAN-1349
2023-04-12 11:53:53 +05:00
Blue
ef66eb1c31 Merge pull request #800 from openedx/ahtesham/VAN-1348/replace-getqueryparam-with-useparams-hooks
Ahtesham/van 1348/replace getqueryparam with useparams hooks
2023-04-11 10:35:13 +05:00
ahtesham-quraish
ec8b256852 fix: remove depricated getQueryParams
Replace getQueryParams function with getAllPossibleQueryParams function

VAN-1348
2023-04-11 10:27:55 +05:00
renovate[bot]
5a715b2fb5 chore(deps): update dependency jest to v29 2023-04-11 03:13:35 +00:00
renovate[bot]
e80578e682 fix(deps): update dependency core-js to v3.30.0 2023-04-10 21:31:39 +00:00
renovate[bot]
155a73dc39 fix(deps): update dependency @edx/paragon to v20.30.1 2023-04-10 21:26:12 +00:00
renovate[bot]
f5d0b50d90 chore(deps): update dependency @edx/frontend-build to v12.8.6 2023-04-10 18:04:55 +00:00
Shahbaz Shabbir
b0745de672 fix: change keys to camelCase for mfe_context response (#835) 2023-04-10 17:24:28 +05:00
Shahbaz Shabbir
d54fdbf84f fix: issue of missing user_id on welcome page events (#828) 2023-04-10 17:15:03 +05:00
Blue
0a6432c393 Merge pull request #840 from openedx/ahtesham/VAN-1353/sso-notification-bottom-mergin
fix: margin issue for sso baner
2023-04-10 16:08:23 +05:00
ahtesham-quraish
9e91c382b3 fix: margin issue for sso baner
FIX margin issue for SSO banner on login page.

VAN-1353
2023-04-10 14:39:53 +05:00
renovate[bot]
2cf24761c0 fix(deps): update dependency react-loading-skeleton to v3 (#498)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-10 13:56:08 +05:00
Syed Sajjad Hussain Shah
c2bdc31a03 fix: ripple effect of skip_registeration_form if country not coming from ip (#838)
Co-authored-by: Syed Sajjad  Hussain Shah <syed.sajjad@H7FKF7K6XD.local>
2023-04-10 12:41:03 +05:00
Syed Sajjad Hussain Shah
9d487d7b61 fix: render tpa pipeline error from django messages on mfe (#829)
VAN-1339

Co-authored-by: Syed Sajjad  Hussain Shah <syed.sajjad@H7FKF7K6XD.local>
2023-04-10 12:36:40 +05:00
Attiya Ishaque
a2ab6c196a fix: fix design issue on progressive profiling page (#833) 2023-04-10 12:12:38 +05:00
Mashal Malik
6a5b02e8ad feat: upgraded to node v18, added .nvmrc and updated workflows (#781) 2023-04-10 11:51:45 +05:00
renovate[bot]
e76f214024 fix(deps): update dependency @edx/frontend-platform to v4 (#834)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-04-06 11:34:43 +05:00
Mubbshar Anwar
cb47717b09 fix: window console warning (#830)
remove console log warnings from SocialAuthProviders unit tests by mocking the location object.
Mock localStorage.

VAN-1350
2023-04-06 10:35:46 +05:00
Blue
85dbc9a6ca Merge pull request #826 from openedx/ahtesham/VAN-1351/add-test-cases-for-recommendations
fix: improve test coverage of recommendations
2023-04-03 17:34:36 +05:00
ahtesham-quraish
4aebeaffa7 fix: impmrove test coverage of recommendations
Need to update test cases for recommendations page and recommendation card

VAN-1351
2023-04-03 17:02:04 +05:00
Syed Sajjad Hussain Shah
6a84e2d5b6 feat: add support for skip_registration_form setting for SSO (#789)
VAN-1318

Co-authored-by: Syed Sajjad  Hussain Shah <syed.sajjad@H7FKF7K6XD.local>
2023-04-03 10:11:50 +05:00
Jenkins
e26620e350 chore(i18n): update translations 2023-04-02 11:16:46 -04:00
Zainab Amir
1cabd2a514 fix: sso providers position (#824) 2023-03-31 14:38:42 +05:00
dependabot[bot]
06dd70078e build(deps): bump http-cache-semantics and @edx/frontend-build (#791)
Removes [http-cache-semantics](https://github.com/kornelski/http-cache-semantics). It's no longer used after updating ancestor dependency [@edx/frontend-build](https://github.com/openedx/frontend-build). These dependencies need to be updated together.


Removes `http-cache-semantics`

Updates `@edx/frontend-build` from 11.0.2 to 12.7.0
- [Release notes](https://github.com/openedx/frontend-build/releases)
- [Commits](https://github.com/openedx/frontend-build/compare/v11.0.2...v12.7.0)

---
updated-dependencies:
- dependency-name: http-cache-semantics
  dependency-type: indirect
- dependency-name: "@edx/frontend-build"
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-31 13:33:44 +05:00
renovate[bot]
4b13866e1d fix(deps): update dependency sanitize-html to v2.10.0 2023-03-31 01:38:36 +00:00
renovate[bot]
11142fda25 fix(deps): update dependency react-onclickoutside to v6.13.0 2023-03-30 23:29:26 +00:00
renovate[bot]
b4057f9588 fix(deps): update dependency core-js to v3.29.1 2023-03-30 21:26:37 +00:00
renovate[bot]
9524f030d1 fix(deps): update dependency algoliasearch to v4.16.0 2023-03-30 19:41:25 +00:00
renovate[bot]
3f10dce04f fix(deps): update dependency @edx/paragon to v20.29.0 2023-03-30 16:24:27 +00:00
renovate[bot]
5f8802272d fix(deps): update dependency @edx/brand to v1.2.0 2023-03-30 15:34:41 +00:00
renovate[bot]
0d486c2774 fix(deps): update dependency @edx/frontend-platform to v3.6.1 2023-03-30 12:53:23 +00:00
renovate[bot]
e78a1583c0 chore(deps): update dependency babel-plugin-formatjs to v10.4.0 2023-03-30 11:24:46 +00:00
Shahbaz Shabbir
ea966c48b9 chore: downgrade frontend-platform version from 3.6.1 to 3.6.0 (#812) 2023-03-30 15:11:24 +05:00
renovate[bot]
810b8d46b9 fix(deps): update dependency redux-saga to v1.2.3 2023-03-30 09:23:53 +00:00
Blue
8a00b74863 Merge pull request #792 from openedx/ahtesham/VAN-1343/integrate-zendesk-sdk
fix: add Zendesk SDK rather than loading Zendesk by network call in A…
2023-03-30 12:34:15 +05:00
ahtesham-quraish
94fafe661d fix: add Zendesk SDK
Get rid of Zendesk which is being loaded by network call and integrate Zendesk SDK

VAN-1343
2023-03-30 12:28:19 +05:00
renovate[bot]
7d58a124ab fix(deps): update dependency redux to v4.2.1 2023-03-30 07:08:14 +00:00
renovate[bot]
378a8d95f9 fix(deps): update dependency @redux-devtools/extension to v3.2.5 2023-03-30 05:05:42 +00:00
renovate[bot]
3a2e39af97 fix(deps): update dependency @optimizely/react-sdk to v2.9.2 2023-03-30 01:58:15 +00:00
renovate[bot]
6f6d725126 fix(deps): update dependency @edx/frontend-component-cookie-policy-banner to v2.2.2 2023-03-29 23:11:43 +00:00
dependabot[bot]
3d8eb34d80 Merge pull request #803 from openedx/dependabot/npm_and_yarn/decode-uri-component-0.2.2 2023-03-29 13:01:13 +00:00
dependabot[bot]
2768fc02ea build(deps): bump decode-uri-component from 0.2.0 to 0.2.2
Bumps [decode-uri-component](https://github.com/SamVerschueren/decode-uri-component) from 0.2.0 to 0.2.2.
- [Release notes](https://github.com/SamVerschueren/decode-uri-component/releases)
- [Commits](https://github.com/SamVerschueren/decode-uri-component/compare/v0.2.0...v0.2.2)

---
updated-dependencies:
- dependency-name: decode-uri-component
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-29 12:53:40 +00:00
Shahbaz Shabbir
0902467fa6 chore: update frontend-platform version (#795) 2023-03-29 16:24:48 +05:00
renovate[bot]
1dc999070f fix(deps): update dependency form-urlencoded to v6 (#245)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-29 15:54:40 +05:00
renovate[bot]
7a169715ea chore(deps): update actions/checkout action to v3 (#547)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-03-29 15:45:07 +05:00
Blue
361f6781ee Merge pull request #799 from openedx/ahtesham/VAN-1349/autoupdate-workflow
feat: create autoupdate workflow
2023-03-29 14:55:37 +05:00
Blue
42190a89dd feat: create workflow for autoupdate
VAN-1349
2023-03-29 14:48:29 +05:00
Zainab Amir
2d4c6a1d3b feat: use intl hook for functional components (#796) 2023-03-29 12:21:12 +05:00
Syed Sajjad Hussain Shah
1dd88795c3 fix: update pull request template (#798) 2023-03-29 11:05:26 +05:00
Blue
7cff7311e1 Merge pull request #752 from DmytroAlipov/fix-redirect-reset
fix: incorrect link to password reset page
2023-03-28 20:24:38 +05:00
alipov-dm
bf93959350 fix: link to the password reset page
When using two different deployment
approaches, with one of them we get an
incorrectly working link to the password
reset page.
2023-03-28 18:03:57 +05:00
Syed Sajjad Hussain Shah
94151c2668 fix: pass user id as string in optimizely track event (#794)
Co-authored-by: Syed Sajjad  Hussain Shah <syed.sajjad@H7FKF7K6XD.local>
2023-03-28 15:15:38 +05:00
Zainab Amir
bf650e6d4c feat: track recommendations group (#793) 2023-03-28 14:29:14 +05:00
Blue
575f195970 Merge pull request #786 from openedx/ahtesham/VAN-1284/missing-env-in-readme
docs: add missing configs in readme
2023-03-27 18:56:51 +05:00
ahtesham-quraish
c6bf6c92c1 docs: add missing configs in readme
VAN-1284
2023-03-27 11:41:47 +05:00
Jenkins
b86c31bff8 chore(i18n): update translations 2023-03-26 11:16:50 -04:00
Syed Sajjad Hussain Shah
fc37bbec1d fix: fix recommendations viewed event count anomly (#787)
Co-authored-by: Syed Sajjad  Hussain Shah <syed.sajjad@H7FKF7K6XD.local>
2023-03-24 14:38:52 +05:00
Shahbaz Shabbir
6525c66600 fix: fix missing userId in segment page event call on welcome page (#784) 2023-03-20 18:17:57 +05:00
Attiya Ishaque
145234c5c3 fix: Update the browser title for progressive profiling page (#783) 2023-03-20 17:53:07 +05:00
Attiya Ishaque
a7f816f49a feat: hide signup page on the bases of flag (#779) 2023-03-20 10:52:17 +05:00
Jenkins
694b0a5381 chore(i18n): update translations 2023-03-19 11:16:46 -04:00
Blue
8a0947faf3 Merge pull request #777 from openedx/ahtesham/VAN-1716/validation-issue-on-change
fix: remove validation which comes from backend after clicking regis…
2023-03-15 16:48:22 +05:00
ahtesham-quraish
d1c4b20160 fix: remove validation which comes from backend after clicking registration button
VAN-1716
2023-03-15 16:44:28 +05:00
Shahbaz Shabbir
d81d8419a0 fix: make identify call to pass missing user_id (#778) 2023-03-13 16:37:26 +05:00
Blue
c6acdab7c6 Merge pull request #773 from openedx/ahtesham/VAN-1317/dropdown-issue-in-safari-browser
fix: country dropdown issue on safari
2023-03-13 10:33:47 +05:00
ahtesham-quraish
0374143148 fix: country dropdown issue on safari
VAN-1317
2023-03-13 10:27:38 +05:00
Syed Sajjad Hussain Shah
2d3c5ed761 Revert "fix: make identify call to pass missing user_id (#774)" (#776)
This reverts commit 93dcd8f16e.
2023-03-13 09:38:07 +05:00
Jenkins
a611451233 chore(i18n): update translations 2023-03-12 11:16:48 -04:00
Shahbaz Shabbir
93dcd8f16e fix: make identify call to pass missing user_id (#774) 2023-03-10 18:05:02 +05:00
Syed Sajjad Hussain Shah
294519c7a5 feat: shift recommendations experiment to optimizely full stack (#770)
VAN-1330

Co-authored-by: Syed Sajjad  Hussain Shah <syed.sajjad@H7FKF7K6XD.local>
2023-03-09 15:13:46 +05:00
Blue
f11df1f513 Merge pull request #771 from openedx/card-banner-issue-fix
Card banner image is not centered aligned
2023-03-09 13:36:28 +05:00
ahtesham-quraish
563609e10a fix: course card image fix
fix for card banner issue by adding the css property

VAN-1325
2023-03-09 12:22:32 +05:00
Dmytro
b4d4e36f72 feat: displaying a support link on the welcome page (#762)
This update adds a display dependency
support links on welcome page if variable
AUTHN_PROGRESSIVE_PROFILING_SUPPORT_LINK non-empty
in MFE settings.
2023-03-09 09:31:40 +05:00
Zainab Amir
f291efc428 fix: bottom padding missing unit (#765) 2023-03-01 19:42:56 +05:00
Zainab Amir
1a61ba3cc7 feat: add support for fallback recs in case of error (#764)
* feat: add support for fallback recs in case of error
* feat: update segment event
2023-03-01 17:49:38 +05:00
Zainab Amir
3d10cea137 feat: implement fallback recommendations (#758) 2023-02-27 20:30:41 +05:00
Feanil Patel
6c72e9dad4 Merge pull request #756 from openedx/repo_checks/ensure_workflows
Update standard workflow files.
2023-02-27 09:26:28 -05:00
Feanil Patel
c5d4f6b94d build: Updating a missing workflow file add-depr-ticket-to-depr-board.yml.
The .github/workflows/add-depr-ticket-to-depr-board.yml workflow is missing or needs an update to stay in
sync with the current standard for this workflow as defined in the
`.github` repo of the `openedx` GitHub org.
2023-02-27 09:22:34 -05:00
Feanil Patel
c52d7b6de5 build: Creating a missing workflow file add-remove-label-on-comment.yml.
The .github/workflows/add-remove-label-on-comment.yml workflow is missing or needs an update to stay in
sync with the current standard for this workflow as defined in the
`.github` repo of the `openedx` GitHub org.
2023-02-27 09:22:34 -05:00
Feanil Patel
6ade0a837f build: Creating a missing workflow file self-assign-issue.yml.
The .github/workflows/self-assign-issue.yml workflow is missing or needs an update to stay in
sync with the current standard for this workflow as defined in the
`.github` repo of the `openedx` GitHub org.
2023-02-27 09:22:34 -05:00
Syed Sajjad Hussain Shah
81d69c8e72 feat: add optimizely exp for recommendations page (#754)
VAN-1294

Co-authored-by: Syed Sajjad  Hussain Shah <syed.sajjad@H7FKF7K6XD.local>
2023-02-27 15:39:08 +05:00
Jenkins
ca333e895f chore(i18n): update translations 2023-02-26 10:16:43 -05:00
Zainab Amir
8e527efd07 zamir/van 1295/add tests for recommender (#755)
* feat: VAN-1295 add tests for recommendations
* feat: add test for loading state

VAN-1295
2023-02-23 13:59:21 +05:00
Mubbshar Anwar
c31c03f5a9 feat: personalized recommendations (#751)
configured algolia for recommendations based on user location or education level
VAN-1287

Co-authored-by: Mubbshar Anwar <mubbsharanwar@users.noreply.github.com>
2023-02-22 10:59:00 +05:00
Dmytro
fe34acf314 feat: display or sign in with (#749) 2023-02-20 13:36:04 +05:00
Attiya Ishaque
1f21a874b8 feat: [VAN-1291] add recommendation page (#743) 2023-02-17 17:02:25 +05:00
renovate[bot]
ee6a6f0d2d fix(deps): update dependency @edx/paragon to v20.28.4 2023-02-14 21:01:30 +00:00
Dmytro
8d0181ccca feat: don't show support button (#744)
Do not show the button "Need help logging in?"
if there is no support page for sign-in issues.
2023-02-14 17:18:56 +05:00
Jenkins
e8dba05920 chore(i18n): update translations 2023-02-12 10:16:41 -05:00
Mubbshar Anwar
6652e2f15c fix: syntext error fixed (#742)
A closing bracket was missing in zen-desk settings.
2023-02-06 19:22:08 +05:00
Mubbshar Anwar
578eec8a2d fix: Customiz Zendesk (#741)
Customize the Zendesk Web Widget in authn for separating departments.

VAN-1290
2023-02-06 18:14:36 +05:00
Jenkins
8b116d2234 chore(i18n): update translations 2023-02-05 10:16:42 -05:00
Jenkins
b9aa110440 chore(i18n): update translations 2023-01-29 10:16:39 -05:00
Shahbaz Shabbir
9f50bbda79 fix: Progressive Profiling can't convert undefined to object (#737) 2023-01-23 13:06:04 +05:00
Jenkins
6f2ce69b77 chore(i18n): update translations 2023-01-22 10:16:39 -05:00
Zainab Amir
8ad2678ce2 feat: pick required fields from tpa context (#736) 2023-01-17 15:18:23 +05:00
Syed Sajjad Hussain Shah
49c91262fd fix: update MFE context (#731)
VAN-1231
2023-01-16 18:36:49 +05:00
Zainab Amir
15378682ab feat: add debugging logs (#735) 2023-01-16 11:06:18 +05:00
Zainab Amir
296861ce3a feat: add GTM fired for integration with impact.com (#734) 2023-01-13 15:07:16 +05:00
Zainab Amir
aa59acf0bc fix: sso button not appearing on login page (#733) 2023-01-12 18:32:52 +05:00
dependabot[bot]
83e204f3f8 build(deps): bump json5 from 1.0.1 to 1.0.2 (#732)
Bumps [json5](https://github.com/json5/json5) from 1.0.1 to 1.0.2.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v1.0.1...v1.0.2)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-11 15:00:44 +05:00
Jenkins
497d60e244 chore(i18n): update translations 2023-01-08 10:16:36 -05:00
Syed Sajjad Hussain Shah
e8282d6d4a fix: uncaught exception on progressive profiling (#729)
VAN-1224
2023-01-06 16:42:08 +05:00
Syed Sajjad Hussain Shah
72510047d8 Revert "fix: exception at progressive profiling page (#727)" (#728)
This reverts commit d06290642b.
2023-01-06 15:23:50 +05:00
Attiya Ishaque
7dee21eb72 fix: Remove the deprecated intlShape import and replace its occurrences with PropType.object. (#724) 2023-01-06 15:01:57 +05:00
Syed Sajjad Hussain Shah
d06290642b fix: exception at progressive profiling page (#727)
VAN-1224
2023-01-06 14:39:37 +05:00
Zainab Amir
525abe6b88 feat: update configs (#721) 2023-01-06 10:49:47 +05:00
Syed Sajjad Hussain Shah
a7704edb9c Revert "fix: uncaught exception on progressive profiling (#722)" (#725)
This reverts commit 78693f4fc6.
2023-01-05 17:36:46 +05:00
Syed Sajjad Hussain Shah
78693f4fc6 fix: uncaught exception on progressive profiling (#722)
VAN-1224
2023-01-05 16:55:58 +05:00
Zainab Amir
186484defa chore: remove unused message string (#723) 2023-01-04 13:11:26 +05:00
Attiya Ishaque
f8fe704c42 fix: rename welcome pages and flag to progressive profiling (#720) 2022-12-30 14:00:24 +05:00
Mubbshar Anwar
82857db236 fix: unable to resubmit form (#719)
by replacing url history user will again redirect to dashboard instead progressive profile page.

VAN-1214
2022-12-23 21:41:30 +05:00
Attiya Ishaque
661914b0db fix: add proper error handling for progressive profiling page. (#716) 2022-12-22 12:35:20 +05:00
Edward Zarecor
057299de2b fix: Use repo name, spaces are not allowed. (#717)
Co-authored-by: Edward Zarecor <ed@tcril.org>
2022-12-20 21:55:45 +05:00
Attiya Ishaque
93db1a23e2 fix: fix error banner position on registartion page. (#711) 2022-12-19 14:39:51 +05:00
Jenkins
36ec03b24b chore(i18n): update translations 2022-12-18 10:16:36 -05:00
Attiya Ishaque
1d6f47c49e docs: Update README (#697) 2022-12-15 11:40:02 +05:00
Zainab Amir
10dfab7127 fix: update catalog-info.yaml 2022-12-14 15:55:41 +05:00
Mubbshar Anwar
a8ebe2c096 Revert "test: for stage-frontend-app-authn-e2e-tests job testing (#709)" (#710)
This reverts commit b3dc1c1513.
2022-12-14 14:06:46 +05:00
Mubbshar Anwar
b3dc1c1513 test: for stage-frontend-app-authn-e2e-tests job testing (#709)
- We are creating this PR for stage-frontend-app-authn-e2e-tests gocd pipeline testing.
- We will revert these changes after testing.

VAN-989
2022-12-14 13:22:53 +05:00
Zainab Amir
7cdae09a94 fix: add policy banner settings to config (#708) 2022-12-14 12:14:48 +05:00
Zainab Amir
59c2c2fd5d feat: make policy banner configurable (#707) 2022-12-14 00:57:37 +05:00
Mubbshar Anwar
70000aab75 Revert "test: for stage-frontend-app-authn-e2e-tests job testing (#705)" (#706)
This reverts commit 059d79302d.
2022-12-13 17:53:06 +05:00
Mubbshar Anwar
059d79302d test: for stage-frontend-app-authn-e2e-tests job testing (#705)
- We are creating this PR for stage-frontend-app-authn-e2e-tests gocd pipeline testing.
- We will revert these changes after testing.

VAN-989
2022-12-13 16:20:44 +05:00
Zainab Amir
ee300466aa fix: update set state functions to use prevState (#696) 2022-12-13 11:35:05 +05:00
Attiya Ishaque
c4fb3f72e5 fix: Fix selecting country error while applying translations (#693) 2022-12-13 11:35:05 +05:00
Zainab Amir
ed0da96076 feat: add tests and fix bugs 2022-12-13 11:35:05 +05:00
Zainab Amir
85fbc54384 feat: refactor registration page 2022-12-13 11:35:05 +05:00
renovate[bot]
a6c282520a fix(deps): update dependency sanitize-html to v2.8.0 2022-12-13 03:33:32 +00:00
renovate[bot]
aa4faba4a3 fix(deps): update dependency @edx/paragon to v20.21.2 2022-12-13 03:23:33 +00:00
renovate[bot]
5e864c4ff1 fix(deps): update dependency @edx/frontend-platform to v3.2.0 2022-12-12 21:25:54 +00:00
renovate[bot]
0c4e612e39 fix(deps): update dependency redux-saga to v1.2.2 2022-12-12 21:14:28 +00:00
renovate[bot]
92faa846ac chore(deps): update dependency babel-plugin-formatjs to v10.3.35 2022-12-12 21:04:37 +00:00
Zainab Amir
5bfdd8e1ef fix: remove edx keyword from tests (#698) 2022-12-12 21:23:12 +05:00
Attiya Ishaque
5af93a57c7 feat: make authn-app compliant with OEP-55 (#695) 2022-12-12 19:36:56 +05:00
165 changed files with 12590 additions and 35760 deletions

23
.env
View File

@@ -13,20 +13,23 @@ ORDER_HISTORY_URL=null
REFRESH_ACCESS_TOKEN_ENDPOINT=null
SEGMENT_KEY=''
SITE_NAME=null
USER_INFO_COOKIE_NAME=null
AUTHN_MINIMAL_HEADER=true
LOGIN_ISSUE_SUPPORT_LINK=''
USER_SURVEY_COOKIE_NAME=null
COOKIE_DOMAIN=null
WELCOME_PAGE_SUPPORT_LINK=null
INFO_EMAIL=''
DISABLE_ENTERPRISE_LOGIN=''
# ***** Cookies *****
REGISTER_CONVERSION_COOKIE_NAME=null
ENABLE_PROGRESSIVE_PROFILING=''
USER_SURVEY_COOKIE_NAME=null
# ***** Links *****
LOGIN_ISSUE_SUPPORT_LINK=''
AUTHN_PROGRESSIVE_PROFILING_SUPPORT_LINK=null
# ***** Features flags *****
DISABLE_ENTERPRISE_LOGIN=''
ENABLE_DYNAMIC_REGISTRATION_FIELDS=''
ENABLE_PROGRESSIVE_PROFILING_ON_AUTHN=''
ENABLE_PERSONALIZED_RECOMMENDATIONS=''
MARKETING_EMAILS_OPT_IN=''
ENABLE_COPPA_COMPLIANCE=''
SHOW_CONFIGURABLE_EDX_FIELDS=''
# ***** Zendesk related keys *****
ZENDESK_KEY=''
ZENDESK_LOGO_URL=''
# ***** Miscellaneous *****
APP_ID=''
MFE_CONFIG_API_URL=''
ENABLE_COOKIE_POLICY_BANNER=''

View File

@@ -18,21 +18,20 @@ ORDER_HISTORY_URL='http://localhost:1996/orders'
REFRESH_ACCESS_TOKEN_ENDPOINT='http://localhost:18000/login_refresh'
SEGMENT_KEY=''
SITE_NAME='Your Platform Name Here'
INFO_EMAIL='info@example.com'
# ***** Cookies *****
REGISTER_CONVERSION_COOKIE_NAME='openedx-user-register-conversion'
SESSION_COOKIE_DOMAIN='localhost'
USER_INFO_COOKIE_NAME='edx-user-info'
AUTHN_MINIMAL_HEADER=true
LOGIN_ISSUE_SUPPORT_LINK='/login-issue-support-url'
USER_SURVEY_COOKIE_NAME='openedx-user-survey-type'
# ***** Links *****
LOGIN_ISSUE_SUPPORT_LINK='http://localhost:18000/login-issue-support-url'
TOS_AND_HONOR_CODE='http://localhost:18000/honor'
TOS_LINK='http://localhost:18000/tos'
PRIVACY_POLICY='http://localhost:18000/privacy'
USER_SURVEY_COOKIE_NAME='openedx-user-survey-type'
COOKIE_DOMAIN='localhost'
WELCOME_PAGE_SUPPORT_LINK='http://localhost:1999/welcome'
INFO_EMAIL='info@edx.org'
DISABLE_ENTERPRISE_LOGIN=''
REGISTER_CONVERSION_COOKIE_NAME='openedx-user-register-conversion'
ENABLE_COPPA_COMPLIANCE=''
MARKETING_EMAILS_OPT_IN=''
ZENDESK_KEY=''
ZENDESK_LOGO_URL=''
AUTHN_PROGRESSIVE_PROFILING_SUPPORT_LINK='http://localhost:1999/welcome'
# ***** Miscellaneous *****
APP_ID=''
MFE_CONFIG_API_URL=''
ZENDESK_KEY=''
ZENDESK_LOGO_URL=''

4
.env.private.example Normal file
View File

@@ -0,0 +1,4 @@
# Copy these to the .env.private to enable edX specific functionality on local system
ENABLE_PROGRESSIVE_PROFILING_ON_AUTHN='true'
MARKETING_EMAILS_OPT_IN='true'
SHOW_CONFIGURABLE_EDX_FIELDS='true'

View File

@@ -16,15 +16,7 @@ ORDER_HISTORY_URL='http://localhost:1996/orders'
REFRESH_ACCESS_TOKEN_ENDPOINT='http://localhost:18000/login_refresh'
SEGMENT_KEY=''
SITE_NAME='Your Platform Name Here'
USER_INFO_COOKIE_NAME='edx-user-info'
LOGIN_ISSUE_SUPPORT_LINK='https://login-issue-support-url.com'
USER_SURVEY_COOKIE_NAME='openedx-user-survey-type'
WELCOME_PAGE_SUPPORT_LINK='http://localhost:1999/welcome'
DISABLE_ENTERPRISE_LOGIN=''
REGISTER_CONVERSION_COOKIE_NAME='openedx-user-register-conversion'
MARKETING_EMAILS_OPT_IN=''
ENABLE_COPPA_COMPLIANCE=''
ZENDESK_KEY=''
ZENDESK_LOGO_URL=''
APP_ID=''
MFE_CONFIG_API_URL=''

View File

@@ -1,5 +1,6 @@
coverage/*
dist/
docs
node_modules/
__mocks__/
__snapshots__/

View File

@@ -1,16 +1,17 @@
// eslint-disable-next-line import/no-extraneous-dependencies
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
// to fail for no apparent reason since upgrading
// @edx/frontend-build from v3 to v5:
// - TypeError: Cannot read property 'range' of null
'indent': [
indent: [
'error',
2,
{ 'ignoredNodes': ['TemplateLiteral', 'SwitchCase'] }
{ ignoredNodes: ['TemplateLiteral', 'SwitchCase'] },
],
'template-curly-spacing': 'off',
'jsx-a11y/label-has-associated-control': ['error', {
@@ -18,9 +19,9 @@ module.exports = createConfig('eslint', {
labelAttributes: [],
controlComponents: [],
assert: 'htmlFor',
depth: 25
depth: 25,
}],
'sort-imports': ['error', {ignoreCase: true, ignoreDeclarationSort: true}],
'sort-imports': ['error', { ignoreCase: true, ignoreDeclarationSort: true }],
'import/order': [
'error',
{
@@ -46,5 +47,6 @@ module.exports = createConfig('eslint', {
},
},
],
'function-paren-newline': 'off',
},
});

View File

@@ -2,11 +2,16 @@
Include a description of your changes here, along with a link to any relevant Jira tickets and/or Github issues.
#### JIRA
[XXX-XXXX](https://2u-internal.atlassian.net/browse/XXX-XXXX)
#### How Has This Been Tested?
Please describe in detail how you tested your changes.
#### Screenshots/sandbox (optional):
Include a link to the sandbox for design changes or screenshot for before and after. **Remove this section if its not applicable.**
|Before|After|
@@ -21,4 +26,4 @@ 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/vanguards** to do it.
* [ ] 🎉 🙌 Celebrate! Thanks for your contribution.
* [ ] 🎉 🙌 Celebrate! Thanks for your contribution.

View File

@@ -16,4 +16,4 @@ jobs:
secrets:
GITHUB_APP_ID: ${{ secrets.GRAPHQL_AUTH_APP_ID }}
GITHUB_APP_PRIVATE_KEY: ${{ secrets.GRAPHQL_AUTH_APP_PEM }}
SLACK_BOT_TOKEN: ${{ secrets.SLACK_ISSUE_BOT_TOKEN }}
SLACK_BOT_TOKEN: ${{ secrets.SLACK_ISSUE_BOT_TOKEN }}

View File

@@ -0,0 +1,20 @@
# This workflow runs when a comment is made on the ticket
# If the comment starts with "label: " it tries to apply
# the label indicated in rest of comment.
# If the comment starts with "remove label: ", it tries
# to remove the indicated label.
# Note: Labels are allowed to have spaces and this script does
# not parse spaces (as often a space is legitimate), so the command
# "label: really long lots of words label" will apply the
# label "really long lots of words label"
name: Allows for the adding and removing of labels via comment
on:
issue_comment:
types: [created]
jobs:
add_remove_labels:
uses: openedx/.github/.github/workflows/add-remove-label-on-comment.yml@master

View File

@@ -0,0 +1,25 @@
name: autoupdate
on:
push:
branches:
- master
pull_request:
types: [ labeled ]
branches:
- master
jobs:
autoupdate:
name: autoupdate
runs-on: ubuntu-20.04
steps:
- uses: docker://chinthakagodawita/autoupdate-action:v1
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
DRY_RUN: "false"
PR_FILTER: "labelled"
PR_LABELS: "autoupdate"
EXCLUDED_LABELS: "dependencies,wontfix"
MERGE_MSG: "Branch was auto-updated."
RETRY_COUNT: "5"
RETRY_SLEEP: "300"
MERGE_CONFLICT_ACTION: "fail"

View File

@@ -11,17 +11,16 @@ on:
jobs:
tests:
runs-on: ubuntu-20.04
strategy:
matrix:
node: [16]
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Setup Nodejs Env
run: echo "NODE_VER=`cat .nvmrc`" >> $GITHUB_ENV
- name: Setup Nodejs
uses: actions/setup-node@v2
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
node-version: ${{ env.NODE_VER }}
- name: Install Dependencies
run: npm ci

View File

@@ -10,4 +10,4 @@ on:
jobs:
version-check:
uses: openedx/.github/.github/workflows/lockfileversion-check.yml@master
uses: openedx/.github/.github/workflows/lockfileversion-check-v3.yml@master

12
.github/workflows/self-assign-issue.yml vendored Normal file
View File

@@ -0,0 +1,12 @@
# This workflow runs when a comment is made on the ticket
# If the comment starts with "assign me" it assigns the author to the
# ticket (case insensitive)
name: Assign comment author to ticket if they say "assign me"
on:
issue_comment:
types: [created]
jobs:
self_assign_by_comment:
uses: openedx/.github/.github/workflows/self-assign-issue.yml@master

1
.gitignore vendored
View File

@@ -5,6 +5,7 @@ node_modules
npm-debug.log
coverage
module.config.js
.env.private
dist/
src/i18n/transifex_input.json

1
.nvmrc Normal file
View File

@@ -0,0 +1 @@
18

View File

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

View File

@@ -1,6 +1,7 @@
export TRANSIFEX_RESOURCE = frontend-app-authn
transifex_langs = "ar,fr,es_419,zh_CN,it_IT,pt_PT,de_DE,uk,ru,hi"
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
@@ -42,11 +43,37 @@ push_translations:
# 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 --filter=$(transifex_langs) \
translations/paragon/src/i18n/messages:paragon \
translations/frontend-app-authn/src/i18n/messages:frontend-app-authn
# This target is used by CI.
$(intl_imports) paragon frontend-app-authn
endif
# 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
.PHONY: validate
validate:
make validate-no-uncommitted-package-lock-changes
npm run i18n_extract
npm run lint -- --max-warnings 0
npm run test
npm run build
.PHONY: validate.ci
validate.ci:
npm ci
make validate

View File

@@ -72,8 +72,8 @@ The authentication micro-frontend also requires the following additional variabl
- The fully-qualified URL to the password reset support page in the target environment.
- ``https://support.example.com``
* - ``WELCOME_PAGE_SUPPORT_LINK``
- The fully-qualified URL to the welcome support page in the target environment.
* - ``AUTHN_PROGRESSIVE_PROFILING_SUPPORT_LINK``
- The fully-qualified URL to the progressive profiling support page in the target environment.
- ``https://support.example.com``
* - ``TOS_AND_HONOR_CODE``
@@ -96,7 +96,7 @@ The authentication micro-frontend also requires the following additional variabl
- Enables support for configurable registration fields on the MFE. This flag must be enabled to show any required registration field besides the default fields (name, email, username, password).
- ``true`` | ``''`` (empty strings are falsy)
* - ``ENABLE_PROGRESSIVE_PROFILING``
* - ``ENABLE_PROGRESSIVE_PROFILING_ON_AUTHN``
- Enables support for progressive profiling. If enabled, users are redirected to a second page where data for optional registration fields can be collected.
- ``true`` | ``''`` (empty strings are falsy)
@@ -104,6 +104,15 @@ The authentication micro-frontend also requires the following additional variabl
- Disables the enterprise login from Authn MFE.
- ``true`` | ``''`` (empty strings are falsy)
* - ``MFE_CONFIG_API_URL``
- Link of the API to get runtime mfe configuration variables from the site configuration or django settings.
- ``/api/v1/mfe_config`` | ``''`` (empty strings are falsy)
* - ``APP_ID``
- 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`` | ``''``
edX-specific Environment Variables
**********************************
@@ -121,14 +130,52 @@ Furthermore, there are several edX-specific environment variables that enable in
- Enables support for opting in marketing emails that helps us getting user consent for sending marketing emails.
- ``true`` | ``''`` (empty strings are falsy)
* - ``SHOW_CONFIGURABLE_EDX_FIELDS``
- For edX, country and honor code fields are required by default. This flag enables edX specific required fields.
- ``true`` | ``''`` (empty strings are falsy)
For more information see the document: `Micro-frontend applications in Open
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://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.
PR description template should be automatically applied if you are sending PR from github interface; otherwise you
can find it it at `PULL_REQUEST_TEMPLATE.md <https://github.com/openedx/frontend-app-authn/blob/master/.github/pull_request_template.md>`_
This project is currently accepting all types of contributions, bug fixes and security fixes.
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/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@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.
==============================

18
catalog-info.yaml Normal file
View File

@@ -0,0 +1,18 @@
# This file records information about this repo. Its use is described in OEP-55:
# https://open-edx-proposals.readthedocs.io/en/latest/processes/oep-0055-proc-project-maintainers.html
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: 'frontend-app-authn'
description: "Micro-frontend for authentication service. It contains views for login, registration and password reset functionality."
links:
- url: 'https://github.com/openedx/frontend-app-authn/blob/master/README.rst'
title: 'Documentation'
icon: 'Article'
annotations:
openedx.org/arch-interest-groups: ""
spec:
owner: group:vanguards
type: 'service'
lifecycle: 'production'

View File

@@ -91,7 +91,7 @@ In the data sub-directory, the file names describe what each piece of code does.
/ProfilePhotoUploader.jsx // supporting view
/data // Note: most files here are named with a plural, as they contain many of the things in question.
/actions.js
/constants.js
/mockedData.js
/reducers.js
/sagas.js
/selectors.js

View File

@@ -3,6 +3,6 @@
nick: Authn MFE
oeps: {}
owner: edx/vanguards
owner: openedx/vanguards
openedx-release:
ref: master

37303
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -32,57 +32,52 @@
"url": "https://github.com/openedx/frontend-app-authn/issues"
},
"dependencies": {
"@edx/brand": "npm:@edx/brand-openedx@1.1.0",
"@edx/frontend-component-cookie-policy-banner": "2.2.0",
"@edx/frontend-platform": "4.2.0",
"@edx/paragon": "20.20.0",
"@fortawesome/fontawesome-svg-core": "6.2.1",
"@fortawesome/free-brands-svg-icons": "6.2.1",
"@fortawesome/free-regular-svg-icons": "6.2.1",
"@fortawesome/free-solid-svg-icons": "6.2.1",
"@edx/brand": "npm:@edx/brand-openedx@1.2.0",
"@edx/frontend-platform": "4.5.1",
"@edx/paragon": "20.40.2",
"@fortawesome/fontawesome-svg-core": "6.4.0",
"@fortawesome/free-brands-svg-icons": "6.4.0",
"@fortawesome/free-solid-svg-icons": "6.4.0",
"@fortawesome/react-fontawesome": "0.2.0",
"@redux-devtools/extension": "3.2.3",
"@optimizely/react-sdk": "^2.9.1",
"@redux-devtools/extension": "3.2.5",
"algoliasearch": "^4.14.3",
"classnames": "2.3.2",
"core-js": "3.26.1",
"extract-react-intl-messages": "4.1.1",
"core-js": "3.30.2",
"fastest-levenshtein": "1.0.16",
"form-urlencoded": "4.2.1",
"lodash.camelcase": "4.3.0",
"lodash.snakecase": "4.1.1",
"form-urlencoded": "6.1.0",
"prop-types": "15.8.1",
"query-string": "5.1.1",
"query-string": "7.1.3",
"react": "16.14.0",
"react-dom": "16.14.0",
"react-helmet": "6.1.0",
"react-loading-skeleton": "2.2.0",
"react-onclickoutside": "6.12.2",
"react-loading-skeleton": "3.2.1",
"react-redux": "7.2.9",
"react-responsive": "8.2.0",
"react-router": "5.3.4",
"react-router-dom": "5.3.4",
"react-zendesk": "^0.1.13",
"redux": "4.2.0",
"redux-logger": "3.0.6",
"redux-mock-store": "1.5.4",
"redux-saga": "1.2.1",
"redux-saga": "1.2.3",
"redux-thunk": "2.4.2",
"regenerator-runtime": "0.13.11",
"reselect": "4.1.7",
"sanitize-html": "2.7.3",
"semver-regex": "3.1.4",
"reselect": "4.1.8",
"universal-cookie": "4.0.4"
},
"devDependencies": {
"@edx/browserslist-config": "^1.1.1",
"@edx/frontend-build": "11.0.2",
"@edx/frontend-build": "12.8.38",
"@edx/reactifex": "1.1.0",
"babel-plugin-formatjs": "10.3.31",
"babel-plugin-formatjs": "10.5.1",
"enzyme": "3.11.0",
"enzyme-adapter-react-16": "1.15.7",
"eslint-plugin-import": "2.26.0",
"eslint-plugin-import": "2.27.5",
"glob": "7.2.3",
"history": "5.3.0",
"husky": "7.0.4",
"jest": "27.5.1",
"jest": "29.5.0",
"react-test-renderer": "16.14.0"
}
}

View File

@@ -4,67 +4,6 @@
<title>Authn | <%= process.env.SITE_NAME %></title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<% if (process.env.OPTIMIZELY_URL) { %>
<script
src="<%= process.env.OPTIMIZELY_URL %>"
></script>
<% } else if (process.env.OPTIMIZELY_PROJECT_ID) { %>
<script
src="<%= process.env.MARKETING_SITE_BASE_URL %>/optimizelyjs/<%= process.env.OPTIMIZELY_PROJECT_ID %>.js"
></script>
<% } %>
<% if (process.env.ZENDESK_KEY) { %>
<script
id="ze-snippet"
src="https://static.zdassets.com/ekr/snippet.js?key=<%= process.env.ZENDESK_KEY %>"
>
</script>
<script type="text/javascript">
window.zESettings = {
cookies: true,
webWidget: {
contactOptions: {
enabled: false,
},
chat: {
suppress: false,
},
contactForm: {
ticketForms: [
{
id: 360003368814,
subject: false,
fields: [
{
id: 'description',
prefill: {
'*': '',
},
},
],
},
],
selectTicketForm: {
'*': 'Please choose your request type:',
},
attachments: true,
},
helpCenter: {
originalArticleButton: true,
},
answerBot: {
suppress: false,
contactOnlyAfterQuery: true,
title: { '*': 'edX Support' },
avatar: {
url: '<%= process.env.ZENDESK_LOGO_URL %>',
name: { '*': 'edX Support' },
},
},
},
};
</script>
<% } %>
</head>
<body>
<div id="root"></div>

View File

@@ -6,16 +6,24 @@ import { Helmet } from 'react-helmet';
import { Redirect, Route, Switch } from 'react-router-dom';
import {
Logistration, NotFoundPage, registerIcons, UnAuthOnlyRoute,
NotFoundPage, registerIcons, UnAuthOnlyRoute, Zendesk,
} from './common-components';
import configureStore from './data/configureStore';
import {
LOGIN_PAGE, PAGE_NOT_FOUND, PASSWORD_RESET_CONFIRM, REGISTER_PAGE, RESET_PAGE, WELCOME_PAGE,
AUTHN_PROGRESSIVE_PROFILING,
LOGIN_PAGE,
PAGE_NOT_FOUND,
PASSWORD_RESET_CONFIRM,
RECOMMENDATIONS,
REGISTER_PAGE,
RESET_PAGE,
} from './data/constants';
import { updatePathWithQueryParams } from './data/utils';
import ForgotPasswordPage from './forgot-password';
import ResetPasswordPage from './reset-password';
import { ProgressiveProfiling } from './welcome';
import { ForgotPasswordPage } from './forgot-password';
import Logistration from './logistration/Logistration';
import { ProgressiveProfiling } from './progressive-profiling';
import { RecommendationsPage } from './recommendations';
import { ResetPasswordPage } from './reset-password';
import './index.scss';
registerIcons();
@@ -25,6 +33,7 @@ const MainApp = () => (
<Helmet>
<link rel="shortcut icon" href={getConfig().FAVICON_URL} type="image/x-icon" />
</Helmet>
{getConfig().ZENDESK_KEY && <Zendesk />}
<Switch>
<Route exact path="/">
<Redirect to={updatePathWithQueryParams(REGISTER_PAGE)} />
@@ -33,7 +42,8 @@ const MainApp = () => (
<UnAuthOnlyRoute exact path={REGISTER_PAGE} component={Logistration} />
<UnAuthOnlyRoute exact path={RESET_PAGE} component={ForgotPasswordPage} />
<Route exact path={PASSWORD_RESET_CONFIRM} component={ResetPasswordPage} />
<Route exact path={WELCOME_PAGE} component={ProgressiveProfiling} />
<Route exact path={AUTHN_PROGRESSIVE_PROFILING} component={ProgressiveProfiling} />
<Route exact path={RECOMMENDATIONS} component={RecommendationsPage} />
<Route path={PAGE_NOT_FOUND} component={NotFoundPage} />
<Route path="*">
<Redirect to={PAGE_NOT_FOUND} />

View File

@@ -1,46 +1,49 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink, Image } from '@edx/paragon';
import PropTypes from 'prop-types';
import messages from './messages';
const AuthLargeLayout = ({ intl, username }) => (
<div className="w-50 d-flex">
<div className="col-md-10 bg-light-200 p-0">
<Hyperlink destination={getConfig().MARKETING_SITE_BASE_URL}>
<Image className="logo position-absolute" alt={getConfig().SITE_NAME} src={getConfig().LOGO_URL} />
</Hyperlink>
<div className="min-vh-100 d-flex align-items-center">
<div className="large-screen-left-container mr-n4.5 large-yellow-line mt-5" />
<div>
<h1 className="welcome-to-platform data-hj-suppress">
{intl.formatMessage(messages['welcome.to.platform'], { siteName: getConfig().SITE_NAME, username })}
</h1>
<h2 className="complete-your-profile">
{intl.formatMessage(messages['complete.your.profile.1'])}
<div className="text-accent-a">
{intl.formatMessage(messages['complete.your.profile.2'])}
</div>
</h2>
const AuthLargeLayout = ({ username }) => {
const { formatMessage } = useIntl();
return (
<div className="w-50 d-flex">
<div className="col-md-10 bg-light-200 p-0">
<Hyperlink destination={getConfig().MARKETING_SITE_BASE_URL}>
<Image className="logo position-absolute" alt={getConfig().SITE_NAME} src={getConfig().LOGO_URL} />
</Hyperlink>
<div className="min-vh-100 d-flex align-items-center">
<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, username })}
</h1>
<h2 className="complete-your-profile">
{formatMessage(messages['complete.your.profile.1'])}
<div className="text-accent-a">
{formatMessage(messages['complete.your.profile.2'])}
</div>
</h2>
</div>
</div>
</div>
<div className="col-md-2 bg-white p-0">
<svg className="m1-n1 w-100 h-100 large-screen-svg-light" preserveAspectRatio="xMaxYMin meet">
<g transform="skewX(171.6)">
<rect x="0" y="0" height="100%" width="100%" />
</g>
</svg>
</div>
</div>
<div className="col-md-2 bg-white p-0">
<svg className="m1-n1 w-100 h-100 large-screen-svg-light" preserveAspectRatio="xMaxYMin meet">
<g transform="skewX(171.6)">
<rect x="0" y="0" height="100%" width="100%" />
</g>
</svg>
</div>
</div>
);
);
};
AuthLargeLayout.propTypes = {
intl: intlShape.isRequired,
username: PropTypes.string.isRequired,
};
export default injectIntl(AuthLargeLayout);
export default AuthLargeLayout;

View File

@@ -1,49 +1,52 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink, Image } from '@edx/paragon';
import PropTypes from 'prop-types';
import messages from './messages';
const AuthMediumLayout = ({ intl, username }) => (
<>
<div className="w-100 medium-screen-top-stripe" />
<div className="w-100 p-0 mb-3 d-flex">
<div className="col-md-10 bg-light-200">
<Hyperlink destination={getConfig().MARKETING_SITE_BASE_URL}>
<Image className="logo" alt={getConfig().SITE_NAME} src={getConfig().LOGO_URL} />
</Hyperlink>
<div className="d-flex align-items-center justify-content-center mb-4 ml-5">
<div className="medium-yellow-line mt-5 mr-n2" />
<div>
<h1 className="h3 data-hj-suppress mw-320">
{intl.formatMessage(messages['welcome.to.platform'], { siteName: getConfig().SITE_NAME, username })}
</h1>
<h2 className="display-1">
{intl.formatMessage(messages['complete.your.profile.1'])}
<div className="text-accent-a">
{intl.formatMessage(messages['complete.your.profile.2'])}
</div>
</h2>
const AuthMediumLayout = ({ username }) => {
const { formatMessage } = useIntl();
return (
<>
<div className="w-100 medium-screen-top-stripe" />
<div className="w-100 p-0 mb-3 d-flex">
<div className="col-md-10 bg-light-200">
<Hyperlink destination={getConfig().MARKETING_SITE_BASE_URL}>
<Image className="logo" alt={getConfig().SITE_NAME} src={getConfig().LOGO_URL} />
</Hyperlink>
<div className="d-flex align-items-center justify-content-center mb-4 ml-5">
<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, username })}
</h1>
<h2 className="display-1">
{formatMessage(messages['complete.your.profile.1'])}
<div className="text-accent-a">
{formatMessage(messages['complete.your.profile.2'])}
</div>
</h2>
</div>
</div>
</div>
<div className="col-md-2 bg-white p-0">
<svg className="w-100 h-100 medium-screen-svg-light" preserveAspectRatio="xMaxYMin meet">
<g transform="skewX(168)">
<rect x="0" y="0" height="100%" width="100%" />
</g>
</svg>
</div>
</div>
<div className="col-md-2 bg-white p-0">
<svg className="w-100 h-100 medium-screen-svg-light" preserveAspectRatio="xMaxYMin meet">
<g transform="skewX(168)">
<rect x="0" y="0" height="100%" width="100%" />
</g>
</svg>
</div>
</div>
</>
);
</>
);
};
AuthMediumLayout.propTypes = {
intl: intlShape.isRequired,
username: PropTypes.string.isRequired,
};
export default injectIntl(AuthMediumLayout);
export default AuthMediumLayout;

View File

@@ -1,38 +1,41 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink, Image } from '@edx/paragon';
import PropTypes from 'prop-types';
import messages from './messages';
const AuthSmallLayout = ({ intl, username }) => (
<div className="min-vw-100 bg-light-200">
<div className="col-md-12 small-screen-top-stripe" />
<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 mb-3 mt-3 mr-3">
<div className="small-yellow-line mt-4.5" />
<div>
<h1 className="h5 data-hj-suppress">
{intl.formatMessage(messages['welcome.to.platform'], { siteName: getConfig().SITE_NAME, username })}
</h1>
<h2 className="h1">
{intl.formatMessage(messages['complete.your.profile.1'])}
<div className="text-accent-a">
{intl.formatMessage(messages['complete.your.profile.2'])}
</div>
</h2>
const AuthSmallLayout = ({ username }) => {
const { formatMessage } = useIntl();
return (
<div className="min-vw-100 bg-light-200">
<div className="col-md-12 small-screen-top-stripe" />
<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 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, username })}
</h1>
<h2 className="h1">
{formatMessage(messages['complete.your.profile.1'])}
<div className="text-accent-a">
{formatMessage(messages['complete.your.profile.2'])}
</div>
</h2>
</div>
</div>
</div>
</div>
);
);
};
AuthSmallLayout.propTypes = {
intl: intlShape.isRequired,
username: PropTypes.string.isRequired,
};
export default injectIntl(AuthSmallLayout);
export default AuthSmallLayout;

View File

@@ -1,9 +1,6 @@
import React from 'react';
import CookiePolicyBanner from '@edx/frontend-component-cookie-policy-banner';
import { getConfig } from '@edx/frontend-platform';
import { getAuthenticatedUser } from '@edx/frontend-platform/auth';
import { getLocale } from '@edx/frontend-platform/i18n';
import { breakpoints } from '@edx/paragon';
import classNames from 'classnames';
import PropTypes from 'prop-types';
@@ -22,7 +19,6 @@ const BaseComponent = ({ children, showWelcomeBanner }) => {
return (
<>
{getConfig().ENABLE_COOKIE_POLICY_BANNER ? <CookiePolicyBanner languageCode={getLocale()} /> : null}
<div className="col-md-12 extra-large-screen-top-stripe" />
<div className="layout">
<MediaQuery maxWidth={breakpoints.small.maxWidth - 1}>

View File

@@ -1,45 +1,45 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink, Image } from '@edx/paragon';
import classNames from 'classnames';
import messages from './messages';
const LargeLayout = ({ intl }) => (
<div className="w-50 d-flex">
<div className="col-md-9 bg-primary-400">
<Hyperlink destination={getConfig().MARKETING_SITE_BASE_URL}>
<Image className="logo position-absolute" alt={getConfig().SITE_NAME} src={getConfig().LOGO_WHITE_URL} />
</Hyperlink>
<div className="min-vh-100 d-flex align-items-center">
<div className={classNames({ 'large-yellow-line mr-n4.5': getConfig().SITE_NAME === 'edX' })} />
<h1
className={classNames(
'display-2 text-white mw-xs',
{ 'ml-6': getConfig().SITE_NAME !== 'edX' },
)}
>
{intl.formatMessage(messages['start.learning'])}
<div className="text-accent-a">
{intl.formatMessage(messages['with.site.name'], { siteName: getConfig().SITE_NAME })}
</div>
</h1>
const LargeLayout = () => {
const { formatMessage } = useIntl();
return (
<div className="w-50 d-flex">
<div className="col-md-9 bg-primary-400">
<Hyperlink destination={getConfig().MARKETING_SITE_BASE_URL}>
<Image className="logo position-absolute" alt={getConfig().SITE_NAME} src={getConfig().LOGO_WHITE_URL} />
</Hyperlink>
<div className="min-vh-100 d-flex align-items-center">
<div className={classNames({ 'large-yellow-line mr-n4.5': getConfig().SITE_NAME === 'edX' })} />
<h1
className={classNames(
'display-2 text-white mw-xs',
{ 'ml-6': getConfig().SITE_NAME !== 'edX' },
)}
>
{formatMessage(messages['start.learning'])}
<div className="text-accent-a">
{formatMessage(messages['with.site.name'], { siteName: getConfig().SITE_NAME })}
</div>
</h1>
</div>
</div>
<div className="col-md-3 bg-white p-0">
<svg className="ml-n1 w-100 h-100 large-screen-svg-primary" preserveAspectRatio="xMaxYMin meet">
<g transform="skewX(171.6)">
<rect x="0" y="0" height="100%" width="100%" />
</g>
</svg>
</div>
</div>
<div className="col-md-3 bg-white p-0">
<svg className="ml-n1 w-100 h-100 large-screen-svg-primary" preserveAspectRatio="xMaxYMin meet">
<g transform="skewX(171.6)">
<rect x="0" y="0" height="100%" width="100%" />
</g>
</svg>
</div>
</div>
);
LargeLayout.propTypes = {
intl: intlShape.isRequired,
);
};
export default injectIntl(LargeLayout);
export default LargeLayout;

View File

@@ -1,50 +1,50 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink, Image } from '@edx/paragon';
import classNames from 'classnames';
import messages from './messages';
const MediumLayout = ({ intl }) => (
<>
<div className="w-100 medium-screen-top-stripe" />
<div className="w-100 p-0 mb-3 d-flex">
<div className="col-md-10 bg-primary-400">
<Hyperlink destination={getConfig().MARKETING_SITE_BASE_URL}>
<Image alt={getConfig().SITE_NAME} className="logo" src={getConfig().LOGO_WHITE_URL} />
</Hyperlink>
<div className="d-flex align-items-center justify-content-center mb-4 ">
<div className={classNames({ 'mt-1 medium-yellow-line': getConfig().SITE_NAME === 'edX' })} />
<div>
<h1
className={classNames(
'display-1 text-white mt-5 mb-5 mr-2',
{ 'ml-4.5': getConfig().SITE_NAME !== 'edX' },
)}
>
<span className="mr-2">{intl.formatMessage(messages['start.learning'])}</span>
<span className="text-accent-a d-inline-block">
{intl.formatMessage(messages['with.site.name'], { siteName: getConfig().SITE_NAME })}
</span>
</h1>
const MediumLayout = () => {
const { formatMessage } = useIntl();
return (
<>
<div className="w-100 medium-screen-top-stripe" />
<div className="w-100 p-0 mb-3 d-flex">
<div className="col-md-10 bg-primary-400">
<Hyperlink destination={getConfig().MARKETING_SITE_BASE_URL}>
<Image alt={getConfig().SITE_NAME} className="logo" src={getConfig().LOGO_WHITE_URL} />
</Hyperlink>
<div className="d-flex align-items-center justify-content-center mb-4 ">
<div className={classNames({ 'mt-1 medium-yellow-line': getConfig().SITE_NAME === 'edX' })} />
<div>
<h1
className={classNames(
'display-1 text-white mt-5 mb-5 mr-2',
{ 'ml-4.5': getConfig().SITE_NAME !== 'edX' },
)}
>
<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>
</div>
</div>
<div className="col-md-2 bg-white p-0">
<svg className="w-100 h-100 medium-screen-svg-primary" preserveAspectRatio="xMaxYMin meet">
<g transform="skewX(168)">
<rect x="0" y="0" height="100%" width="100%" />
</g>
</svg>
</div>
</div>
<div className="col-md-2 bg-white p-0">
<svg className="w-100 h-100 medium-screen-svg-primary" preserveAspectRatio="xMaxYMin meet">
<g transform="skewX(168)">
<rect x="0" y="0" height="100%" width="100%" />
</g>
</svg>
</div>
</div>
</>
);
MediumLayout.propTypes = {
intl: intlShape.isRequired,
</>
);
};
export default injectIntl(MediumLayout);
export default MediumLayout;

View File

@@ -1,39 +1,39 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Hyperlink, Image } from '@edx/paragon';
import classNames from 'classnames';
import messages from './messages';
const SmallLayout = ({ intl }) => (
<span className="bg-primary-400 w-100">
<div className="col-md-12 small-screen-top-stripe" />
<div>
<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 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 className="mr-1">{intl.formatMessage(messages['start.learning'])}</span>
<span className="text-accent-a d-inline-block">
{intl.formatMessage(messages['with.site.name'], { siteName: getConfig().SITE_NAME })}
</span>
</h1>
</div>
</div>
</span>
);
const SmallLayout = () => {
const { formatMessage } = useIntl();
SmallLayout.propTypes = {
intl: intlShape.isRequired,
return (
<span className="bg-primary-400 w-100">
<div className="col-md-12 small-screen-top-stripe" />
<div>
<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 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 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>
</div>
</span>
);
};
export default injectIntl(SmallLayout);
export default SmallLayout;

View File

@@ -1 +1,2 @@
export { default } from './BaseComponent';
/* eslint-disable import/prefer-default-export */
export { default as BaseComponent } from './BaseComponent';

View File

@@ -1,19 +1,23 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import {
Button, Form,
Icon,
} from '@edx/paragon';
import { faSignInAlt } from '@fortawesome/free-solid-svg-icons';
import { Login } from '@edx/paragon/icons';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import PropTypes from 'prop-types';
import { LOGIN_PAGE, SUPPORTED_ICON_CLASSES } from '../data/constants';
import messages from './messages';
import { LOGIN_PAGE, SUPPORTED_ICON_CLASSES } from '../data/constants';
/**
* This component renders the Single sign-on (SSO) button only for the tpa provider passed
* */
const EnterpriseSSO = (props) => {
const { intl } = props;
const { formatMessage } = useIntl();
const tpaProvider = props.provider;
const disablePublicAccountCreation = getConfig().ALLOW_PUBLIC_ACCOUNT_CREATION === false;
@@ -33,7 +37,7 @@ const EnterpriseSSO = (props) => {
<div className="d-flex flex-column">
<div className="mw-450">
<Form className="m-0">
<p>{intl.formatMessage(messages['enterprisetpa.title.heading'], { providerName: tpaProvider.name })}</p>
<p>{formatMessage(messages['enterprisetpa.title.heading'], { providerName: tpaProvider.name })}</p>
<Button
id={tpaProvider.id}
key={tpaProvider.id}
@@ -44,16 +48,18 @@ const EnterpriseSSO = (props) => {
>
{tpaProvider.iconImage ? (
<div aria-hidden="true">
<img className="icon-image" src={tpaProvider.iconImage} alt={`icon ${tpaProvider.name}`} />
<img className="btn-tpa__image-icon" src={tpaProvider.iconImage} alt={`icon ${tpaProvider.name}`} />
<span className="pl-2" aria-hidden="true">{ tpaProvider.name }</span>
</div>
)
: (
<>
<div className="font-container" aria-hidden="true">
<FontAwesomeIcon
icon={SUPPORTED_ICON_CLASSES.includes(tpaProvider.iconClass) ? ['fab', tpaProvider.iconClass] : faSignInAlt}
/>
<div className="btn-tpa__font-container" aria-hidden="true">
{SUPPORTED_ICON_CLASSES.includes(tpaProvider.iconClass) ? (
<FontAwesomeIcon icon={['fab', tpaProvider.iconClass]} />)
: (
<Icon className="h-75" src={Login} />
)}
</div>
<span className="pl-2" aria-hidden="true">{ tpaProvider.name }</span>
</>
@@ -69,8 +75,8 @@ const EnterpriseSSO = (props) => {
onClick={(e) => handleClick(e)}
>
{disablePublicAccountCreation
? intl.formatMessage(messages['enterprisetpa.login.button.text.public.account.creation.disabled'])
: intl.formatMessage(messages['enterprisetpa.login.button.text'])}
? formatMessage(messages['enterprisetpa.login.button.text.public.account.creation.disabled'])
: formatMessage(messages['enterprisetpa.login.button.text'])}
</Button>
</Form>
</div>
@@ -101,7 +107,6 @@ EnterpriseSSO.propTypes = {
loginUrl: PropTypes.string,
registerUrl: PropTypes.string,
}),
intl: intlShape.isRequired,
};
export default injectIntl(EnterpriseSSO);
export default EnterpriseSSO;

View File

@@ -27,7 +27,7 @@ const FormGroup = (props) => {
readOnly={props.readOnly}
type={props.type}
aria-invalid={props.errorMessage !== ''}
className="form-field"
className="form-group__form-field"
autoComplete={props.autoComplete}
spellCheck={props.spellCheck}
name={props.name}
@@ -37,7 +37,6 @@ const FormGroup = (props) => {
onClick={handleClick}
onChange={props.handleChange}
controlClassName={props.borderClass}
trailingElement={props.trailingElement}
floatingLabel={props.floatingLabel}
>

View File

@@ -1,13 +1,16 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Button, Hyperlink, Icon } from '@edx/paragon';
import { Institution } from '@edx/paragon/icons';
import PropTypes from 'prop-types';
import messages from './messages';
/**
* This component renders the Institution login button
* */
export const RenderInstitutionButton = props => {
const { onSubmitHandler, buttonTitle } = props;
@@ -24,10 +27,13 @@ export const RenderInstitutionButton = props => {
);
};
/**
* This component renders the page list of available institutions for login
* */
const InstitutionLogistration = props => {
const lmsBaseUrl = getConfig().LMS_BASE_URL;
const { formatMessage } = useIntl();
const {
intl,
secondaryProviders,
headingTitle,
} = props;
@@ -36,11 +42,11 @@ const InstitutionLogistration = props => {
<>
<div className="d-flex justify-content-left mb-4 mt-2">
<div className="flex-column">
<h4 className="mb-2 font-weight-bold institute-heading">
<h4 className="mb-2 font-weight-bold institutions__heading">
{headingTitle}
</h4>
<p className="mb-2">
{intl.formatMessage(messages['institution.login.page.sub.heading'])}
{formatMessage(messages['institution.login.page.sub.heading'])}
</p>
</div>
</div>
@@ -51,7 +57,7 @@ const InstitutionLogistration = props => {
<tr key={provider} className="pgn__data-table-row">
<td>
<Hyperlink
className="btn nav-item p-0 mb-1 secondary-provider-link"
className="btn nav-item p-0 mb-1 institutions--provider-link"
destination={lmsBaseUrl + provider.loginUrl}
>
{provider.name}
@@ -89,7 +95,6 @@ RenderInstitutionButton.defaultProps = {
InstitutionLogistration.propTypes = {
...LogistrationProps,
intl: intlShape.isRequired,
headingTitle: PropTypes.string,
};
InstitutionLogistration.defaultProps = {
@@ -97,4 +102,4 @@ InstitutionLogistration.defaultProps = {
headingTitle: '',
};
export default injectIntl(InstitutionLogistration);
export default InstitutionLogistration;

View File

@@ -1,131 +0,0 @@
import React, { useEffect, useState } from 'react';
import { getConfig } from '@edx/frontend-platform';
import { sendPageEvent, sendTrackEvent } from '@edx/frontend-platform/analytics';
import { getAuthService } from '@edx/frontend-platform/auth';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import {
Icon,
Tab,
Tabs,
} from '@edx/paragon';
import { ChevronLeft } from '@edx/paragon/icons';
import PropTypes from 'prop-types';
import { Redirect } from 'react-router-dom';
import BaseComponent from '../base-component';
import { LOGIN_PAGE, REGISTER_PAGE } from '../data/constants';
import { getTpaHint, updatePathWithQueryParams } from '../data/utils';
import { LoginPage } from '../login';
import { RegistrationPage } from '../register';
import messages from './messages';
const Logistration = (props) => {
const { intl, selectedPage } = props;
const tpa = getTpaHint();
const [institutionLogin, setInstitutionLogin] = useState(false);
const [key, setKey] = useState('');
const disablePublicAccountCreation = getConfig().ALLOW_PUBLIC_ACCOUNT_CREATION === false;
useEffect(() => {
const authService = getAuthService();
if (authService) {
authService.getCsrfTokenService().getCsrfToken(getConfig().LMS_BASE_URL);
}
});
const handleInstitutionLogin = (e) => {
sendTrackEvent('edx.bi.institution_login_form.toggled', { category: 'user-engagement' });
if (typeof e === 'string') {
sendPageEvent('login_and_registration', e === '/login' ? 'login' : 'register');
} else {
sendPageEvent('login_and_registration', e.target.dataset.eventName);
}
setInstitutionLogin(!institutionLogin);
};
const handleOnSelect = (tabKey) => {
sendTrackEvent(`edx.bi.${tabKey.replace('/', '')}_form.toggled`, { category: 'user-engagement' });
setKey(tabKey);
};
const tabTitle = (
<div className="d-flex">
<Icon src={ChevronLeft} className="left-icon" />
<span className="ml-2">
{selectedPage === LOGIN_PAGE
? intl.formatMessage(messages['logistration.sign.in'])
: intl.formatMessage(messages['logistration.register'])}
</span>
</div>
);
return (
<BaseComponent>
<div>
{disablePublicAccountCreation
? (
<>
<Redirect to={updatePathWithQueryParams(LOGIN_PAGE)} />
{institutionLogin && (
<Tabs defaultActiveKey="" id="controlled-tab" onSelect={handleInstitutionLogin}>
<Tab title={tabTitle} eventKey={LOGIN_PAGE} />
</Tabs>
)}
<div id="main-content" className="main-content">
{!institutionLogin && (
<h3 className="mb-4.5">{intl.formatMessage(messages['logistration.sign.in'])}</h3>
)}
<LoginPage institutionLogin={institutionLogin} handleInstitutionLogin={handleInstitutionLogin} />
</div>
</>
)
: (
<div>
{institutionLogin
? (
<Tabs defaultActiveKey="" id="controlled-tab" onSelect={handleInstitutionLogin}>
<Tab title={tabTitle} eventKey={selectedPage === LOGIN_PAGE ? LOGIN_PAGE : REGISTER_PAGE} />
</Tabs>
)
: (
<>
{!tpa && (
<Tabs defaultActiveKey={selectedPage} id="controlled-tab" onSelect={handleOnSelect}>
<Tab title={intl.formatMessage(messages['logistration.register'])} eventKey={REGISTER_PAGE} />
<Tab title={intl.formatMessage(messages['logistration.sign.in'])} eventKey={LOGIN_PAGE} />
</Tabs>
)}
</>
)}
{ key && (
<Redirect to={updatePathWithQueryParams(key)} />
)}
<div id="main-content" className="main-content">
{selectedPage === LOGIN_PAGE
? <LoginPage institutionLogin={institutionLogin} handleInstitutionLogin={handleInstitutionLogin} />
: (
<RegistrationPage
institutionLogin={institutionLogin}
handleInstitutionLogin={handleInstitutionLogin}
/>
)}
</div>
</div>
)}
</div>
</BaseComponent>
);
};
Logistration.propTypes = {
intl: intlShape.isRequired,
selectedPage: PropTypes.string,
};
Logistration.defaultProps = {
selectedPage: REGISTER_PAGE,
};
export default injectIntl(Logistration);

View File

@@ -2,16 +2,16 @@ import React from 'react';
import { FormattedMessage } from '@edx/frontend-platform/i18n';
export default function NotFoundPage() {
return (
<div className="container-fluid d-flex py-5 justify-content-center align-items-start text-center">
<p className="my-0 py-5 text-muted mw-32em">
<FormattedMessage
id="error.notfound.message"
defaultMessage="The page you're looking for is unavailable or there's an error in the URL. Please check the URL and try again."
description="error message when a page does not exist"
/>
</p>
</div>
);
}
const NotFoundPage = () => (
<div className="container-fluid d-flex py-5 justify-content-center align-items-start text-center">
<p className="my-0 py-5 text-muted mw-32em">
<FormattedMessage
id="error.notfound.message"
defaultMessage="The page you're looking for is unavailable or there's an error in the URL. Please check the URL and try again."
description="error message when a page does not exist"
/>
</p>
</div>
);
export default NotFoundPage;

View File

@@ -1,6 +1,6 @@
import React, { useState } from 'react';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import {
Form, Icon, IconButton, OverlayTrigger, Tooltip, useToggle,
} from '@edx/paragon';
@@ -9,11 +9,11 @@ import {
} from '@edx/paragon/icons';
import PropTypes from 'prop-types';
import { LETTER_REGEX, NUMBER_REGEX } from '../data/constants';
import messages from './messages';
import { LETTER_REGEX, NUMBER_REGEX } from '../data/constants';
const PasswordField = (props) => {
const { formatMessage } = props.intl;
const { formatMessage } = useIntl();
const [isPasswordHidden, setHiddenTrue, setHiddenFalse] = useToggle(true);
const [showTooltip, setShowTooltip] = useState(false);
@@ -30,11 +30,11 @@ const PasswordField = (props) => {
};
const HideButton = (
<IconButton onFocus={handleFocus} onBlur={handleBlur} name="passwordValidation" 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="passwordValidation" 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 = (
@@ -59,7 +59,7 @@ const PasswordField = (props) => {
<OverlayTrigger key="tooltip" placement={placement} overlay={tooltip} show={showTooltip}>
<Form.Control
as="input"
className="form-field"
className="form-group__form-field"
type={isPasswordHidden ? 'password' : 'text'}
name={props.name}
value={props.value}
@@ -100,11 +100,10 @@ PasswordField.propTypes = {
handleBlur: PropTypes.func,
handleFocus: PropTypes.func,
handleChange: PropTypes.func,
intl: intlShape.isRequired,
name: PropTypes.string.isRequired,
showRequirements: PropTypes.bool,
value: PropTypes.string.isRequired,
autoComplete: PropTypes.string,
};
export default injectIntl(PasswordField);
export default PasswordField;

View File

@@ -4,12 +4,19 @@ import { getConfig } from '@edx/frontend-platform';
import PropTypes from 'prop-types';
import { Redirect } from 'react-router-dom';
import { WELCOME_PAGE } from '../data/constants';
import { AUTHN_PROGRESSIVE_PROFILING, RECOMMENDATIONS } from '../data/constants';
import { setCookie } from '../data/utils';
function RedirectLogistration(props) {
const RedirectLogistration = (props) => {
const {
finishAuthUrl, redirectUrl, redirectToWelcomePage, success, optionalFields,
finishAuthUrl,
redirectUrl,
redirectToProgressiveProfilingPage,
success,
optionalFields,
redirectToRecommendationsPage,
educationLevel,
userId,
} = props;
let finalRedirectUrl = '';
@@ -24,14 +31,14 @@ function RedirectLogistration(props) {
finalRedirectUrl = redirectUrl;
}
if (redirectToWelcomePage) {
// Redirect to Progressive Profiling after successful registration
if (redirectToProgressiveProfilingPage) {
// TODO: Do we still need this cookie?
setCookie('van-504-returning-user', true);
// use this component to redirect WelcomePage after successful registration
// return <Redirect to={WELCOME_PAGE} />;
const registrationResult = { redirectUrl: finalRedirectUrl, success };
return (
<Redirect to={{
pathname: WELCOME_PAGE,
pathname: AUTHN_PROGRESSIVE_PROFILING,
state: {
registrationResult,
optionalFields,
@@ -41,25 +48,48 @@ function RedirectLogistration(props) {
);
}
// Redirect to Recommendation page
if (redirectToRecommendationsPage) {
const registrationResult = { redirectUrl: finalRedirectUrl, success };
return (
<Redirect to={{
pathname: RECOMMENDATIONS,
state: {
registrationResult,
educationLevel,
userId,
},
}}
/>
);
}
window.location.href = finalRedirectUrl;
}
return <></>;
}
return null;
};
RedirectLogistration.defaultProps = {
educationLevel: null,
finishAuthUrl: null,
success: false,
redirectUrl: '',
redirectToWelcomePage: false,
redirectToProgressiveProfilingPage: false,
optionalFields: {},
redirectToRecommendationsPage: false,
userId: null,
};
RedirectLogistration.propTypes = {
educationLevel: PropTypes.string,
finishAuthUrl: PropTypes.string,
success: PropTypes.bool,
redirectUrl: PropTypes.string,
redirectToWelcomePage: PropTypes.bool,
redirectToProgressiveProfilingPage: PropTypes.bool,
optionalFields: PropTypes.shape({}),
redirectToRecommendationsPage: PropTypes.bool,
userId: PropTypes.number,
};
export default RedirectLogistration;

View File

@@ -1,16 +1,18 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { faSignInAlt } from '@fortawesome/free-solid-svg-icons';
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 PropTypes from 'prop-types';
import { LOGIN_PAGE, SUPPORTED_ICON_CLASSES } from '../data/constants';
import messages from './messages';
import { LOGIN_PAGE, SUPPORTED_ICON_CLASSES } from '../data/constants';
function SocialAuthProviders(props) {
const { intl, referrer, socialAuthProviders } = props;
const SocialAuthProviders = (props) => {
const { formatMessage } = useIntl();
const { referrer, socialAuthProviders } = props;
function handleSubmit(e) {
e.preventDefault();
@@ -30,29 +32,30 @@ function SocialAuthProviders(props) {
>
{provider.iconImage ? (
<div aria-hidden="true">
<img className="icon-image" src={provider.iconImage} alt={`icon ${provider.name}`} />
<img className="btn-tpa__image-icon" src={provider.iconImage} alt={`icon ${provider.name}`} />
</div>
)
: (
<>
<div className="font-container" aria-hidden="true">
<FontAwesomeIcon
icon={SUPPORTED_ICON_CLASSES.includes(provider.iconClass) ? ['fab', provider.iconClass] : faSignInAlt}
/>
</div>
</>
<div className="btn-tpa__font-container" aria-hidden="true">
{SUPPORTED_ICON_CLASSES.includes(provider.iconClass) ? (
<FontAwesomeIcon icon={['fab', provider.iconClass]} />)
: (
<Icon className="h-75" src={Login} />
)}
</div>
)}
<span id="provider-name" className="notranslate mr-auto pl-2" aria-hidden="true">{provider.name}</span>
<span className="sr-only">
{referrer === LOGIN_PAGE
? intl.formatMessage(messages['sso.sign.in.with'], { providerName: provider.name })
: intl.formatMessage(messages['sso.create.account.using'], { providerName: provider.name })}
? formatMessage(messages['sso.sign.in.with'], { providerName: provider.name })
: formatMessage(messages['sso.create.account.using'], { providerName: provider.name })}
</span>
</button>
));
// eslint-disable-next-line react/jsx-no-useless-fragment
return <>{socialAuth}</>;
}
};
SocialAuthProviders.defaultProps = {
referrer: LOGIN_PAGE,
@@ -60,7 +63,6 @@ SocialAuthProviders.defaultProps = {
};
SocialAuthProviders.propTypes = {
intl: intlShape.isRequired,
referrer: PropTypes.string,
socialAuthProviders: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.string,
@@ -69,7 +71,8 @@ SocialAuthProviders.propTypes = {
iconImage: PropTypes.string,
loginUrl: PropTypes.string,
registerUrl: PropTypes.string,
skipRegistrationForm: PropTypes.bool,
})),
};
export default injectIntl(SocialAuthProviders);
export default SocialAuthProviders;

View File

@@ -1,62 +0,0 @@
import React from 'react';
import { TransitionReplace } from '@edx/paragon';
import PropTypes from 'prop-types';
const onChildExit = (htmlNode) => {
// If the leaving child has focus, take control and redirect it
if (htmlNode.contains(document.activeElement)) {
// Get the newly entering sibling.
// It's the previousSibling, but not for any explicit reason. So checking for both.
const enteringChild = htmlNode.previousSibling || htmlNode.nextSibling;
// There's no replacement, do nothing.
if (!enteringChild) return; // eslint-disable-line curly
// Get all the focusable elements in the entering child and focus the first one
const focusableElements = enteringChild.querySelectorAll('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])');
if (focusableElements.length) {
focusableElements[0].focus();
}
}
};
function SwitchContent({ expression, cases, className }) {
const getContent = (caseKey) => {
if (cases[caseKey]) {
if (typeof cases[caseKey] === 'string') {
return getContent(cases[caseKey]);
}
return React.cloneElement(cases[caseKey], { key: caseKey });
} else if (cases.default) { // eslint-disable-line no-else-return
if (typeof cases.default === 'string') {
return getContent(cases.default);
}
React.cloneElement(cases.default, { key: 'default' });
}
return null;
};
return (
<TransitionReplace
className={className}
onChildExit={onChildExit}
>
{getContent(expression)}
</TransitionReplace>
);
}
SwitchContent.propTypes = {
expression: PropTypes.string,
cases: PropTypes.objectOf(PropTypes.node).isRequired,
className: PropTypes.string,
};
SwitchContent.defaultProps = {
expression: null,
className: null,
};
export default SwitchContent;

View File

@@ -1,42 +1,52 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import { Alert } from '@edx/paragon';
import PropTypes from 'prop-types';
import { LOGIN_PAGE, REGISTER_PAGE } from '../data/constants';
import messages from './messages';
import { LOGIN_PAGE, REGISTER_PAGE } from '../data/constants';
const ThirdPartyAuthAlert = (props) => {
const { currentProvider, intl, referrer } = props;
const { formatMessage } = useIntl();
const { currentProvider, referrer } = props;
const platformName = getConfig().SITE_NAME;
let message;
if (referrer === LOGIN_PAGE) {
message = intl.formatMessage(messages['login.third.party.auth.account.not.linked'], { currentProvider, platformName });
message = formatMessage(messages['login.third.party.auth.account.not.linked'], { currentProvider, platformName });
} else {
message = intl.formatMessage(messages['register.third.party.auth.account.not.linked'], { currentProvider, platformName });
message = formatMessage(messages['register.third.party.auth.account.not.linked'], { currentProvider, platformName });
}
if (!currentProvider) {
return null;
}
return (
<Alert id="tpa-alert" className={referrer === REGISTER_PAGE ? 'alert-success mt-n2' : 'alert-warning mt-n2'}>
<>
<Alert id="tpa-alert" className={referrer === REGISTER_PAGE ? 'alert-success mt-n2 mb-5' : 'alert-warning mt-n2 mb-5'}>
{referrer === REGISTER_PAGE ? (
<Alert.Heading>{formatMessage(messages['tpa.alert.heading'])}</Alert.Heading>
) : null}
<p>{ message }</p>
</Alert>
{referrer === REGISTER_PAGE ? (
<Alert.Heading>{intl.formatMessage(messages['tpa.alert.heading'])}</Alert.Heading>
<h4 className="mt-4 mb-4">{formatMessage(messages['registration.using.tpa.form.heading'])}</h4>
) : null}
<p>{ message }</p>
</Alert>
</>
);
};
ThirdPartyAuthAlert.defaultProps = {
currentProvider: '',
referrer: LOGIN_PAGE,
};
ThirdPartyAuthAlert.propTypes = {
currentProvider: PropTypes.string.isRequired,
intl: intlShape.isRequired,
currentProvider: PropTypes.string,
referrer: PropTypes.string,
};
export default injectIntl(ThirdPartyAuthAlert);
export default ThirdPartyAuthAlert;

View File

@@ -23,6 +23,9 @@ const UnAuthOnlyRoute = (props) => {
if (isReady) {
if (authUser && authUser.username) {
if (true) { // check for query param
window.parent.postMessage({ authenticated: true }, 'https://discover.edx.org/social-reg');
}
global.location.href = getConfig().LMS_BASE_URL.concat(DEFAULT_REDIRECT_URL);
return null;
}
@@ -30,7 +33,7 @@ const UnAuthOnlyRoute = (props) => {
return <Route {...props} />;
}
return <></>;
return null;
};
export default UnAuthOnlyRoute;

View File

@@ -0,0 +1,56 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { useIntl } from '@edx/frontend-platform/i18n';
import Zendesk from 'react-zendesk';
import messages from './messages';
const ZendeskHelp = () => {
const { formatMessage } = useIntl();
const setting = {
cookies: true,
webWidget: {
contactOptions: {
enabled: false,
},
chat: {
suppress: false,
departments: {
enabled: ['account settings', 'billing and payments', 'certificates', 'deadlines', 'errors and technical issues', 'other', 'proctoring'],
},
},
contactForm: {
ticketForms: [
{
id: 360003368814,
subject: false,
fields: [{ id: 'description', prefill: { '*': '' } }],
},
],
selectTicketForm: {
'*': formatMessage(messages.selectTicketForm),
},
attachments: true,
},
helpCenter: {
originalArticleButton: true,
},
answerBot: {
suppress: false,
contactOnlyAfterQuery: true,
title: { '*': formatMessage(messages.supportTitle) },
avatar: {
url: getConfig().ZENDESK_LOGO_URL,
name: { '*': formatMessage(messages.supportTitle) },
},
},
},
};
return (
<Zendesk defer zendeskKey={getConfig().ZENDESK_KEY} {...setting} />
);
};
export default ZendeskHelp;

View File

@@ -1,6 +1,7 @@
import { AsyncActionType } from '../../data/utils';
export const THIRD_PARTY_AUTH_CONTEXT = new AsyncActionType('THIRD_PARTY_AUTH', 'GET_THIRD_PARTY_AUTH_CONTEXT');
export const THIRD_PARTY_AUTH_CONTEXT_CLEAR_ERROR_MSG = 'THIRD_PARTY_AUTH_CONTEXT_CLEAR_ERROR_MSG';
// Third party auth context
export const getThirdPartyAuthContext = (urlParams) => ({
@@ -20,3 +21,7 @@ export const getThirdPartyAuthContextSuccess = (fieldDescriptions, optionalField
export const getThirdPartyAuthContextFailure = () => ({
type: THIRD_PARTY_AUTH_CONTEXT.FAILURE,
});
export const clearThirdPartyAuthContextErrorMessage = () => ({
type: THIRD_PARTY_AUTH_CONTEXT_CLEAR_ERROR_MSG,
});

View File

@@ -1,34 +1,51 @@
import { THIRD_PARTY_AUTH_CONTEXT, THIRD_PARTY_AUTH_CONTEXT_CLEAR_ERROR_MSG } from './actions';
import { COMPLETE_STATE, PENDING_STATE } from '../../data/constants';
import { THIRD_PARTY_AUTH_CONTEXT } from './actions';
export const defaultState = {
extendedProfile: [],
fieldDescriptions: {},
optionalFields: {},
thirdPartyAuthApiStatus: null,
thirdPartyAuthContext: {
currentProvider: null,
finishAuthUrl: null,
countryCode: null,
providers: [],
secondaryProviders: [],
pipelineUserDetails: null,
errorMessage: null,
},
};
const reducer = (state = defaultState, action) => {
const reducer = (state = defaultState, action = {}) => {
switch (action.type) {
case THIRD_PARTY_AUTH_CONTEXT.BEGIN:
return {
...state,
thirdPartyAuthApiStatus: PENDING_STATE,
};
case THIRD_PARTY_AUTH_CONTEXT.SUCCESS:
case THIRD_PARTY_AUTH_CONTEXT.SUCCESS: {
return {
...state,
extendedProfile: action.payload.fieldDescriptions.extendedProfile,
fieldDescriptions: action.payload.fieldDescriptions.fields,
optionalFields: action.payload.optionalFields,
thirdPartyAuthContext: action.payload.thirdPartyAuthContext,
thirdPartyAuthApiStatus: COMPLETE_STATE,
};
}
case THIRD_PARTY_AUTH_CONTEXT.FAILURE:
return {
...state,
thirdPartyAuthApiStatus: COMPLETE_STATE,
};
case THIRD_PARTY_AUTH_CONTEXT_CLEAR_ERROR_MSG:
return {
...state,
thirdPartyAuthApiStatus: PENDING_STATE,
thirdPartyAuthContext: {
...state.thirdPartyAuthContext,
errorMessage: null,
},
};
default:
return state;
}

View File

@@ -1,7 +1,6 @@
import { logError } from '@edx/frontend-platform/logging';
import { call, put, takeEvery } from 'redux-saga/effects';
import { setCountryFromThirdPartyAuthContext } from '../../register/data/actions';
import {
getThirdPartyAuthContextBegin,
getThirdPartyAuthContextFailure,
@@ -11,18 +10,17 @@ import {
import {
getThirdPartyAuthContext,
} from './service';
import { setCountryFromThirdPartyAuthContext } from '../../register/data/actions';
export function* fetchThirdPartyAuthContext(action) {
try {
yield put(getThirdPartyAuthContextBegin());
const { fieldDescriptions, optionalFields, thirdPartyAuthContext } = yield call(
getThirdPartyAuthContext, action.payload.urlParams,
);
const {
fieldDescriptions, optionalFields, thirdPartyAuthContext,
} = yield call(getThirdPartyAuthContext, action.payload.urlParams);
yield put(setCountryFromThirdPartyAuthContext(thirdPartyAuthContext.countryCode));
yield put(getThirdPartyAuthContextSuccess(
fieldDescriptions, optionalFields, thirdPartyAuthContext,
));
yield put(getThirdPartyAuthContextSuccess(fieldDescriptions, optionalFields, thirdPartyAuthContext));
} catch (e) {
yield put(getThirdPartyAuthContextFailure());
logError(e);

View File

@@ -14,12 +14,15 @@ export const fieldDescriptionSelector = createSelector(
commonComponents => commonComponents.fieldDescriptions,
);
export const extendedProfileSelector = createSelector(
commonComponentsSelector,
commonComponents => commonComponents.extendedProfile,
);
export const optionalFieldsSelector = createSelector(
commonComponentsSelector,
commonComponents => commonComponents.optionalFields,
);
export const tpaProvidersSelector = createSelector(
commonComponentsSelector,
commonComponents => ({
providers: commonComponents.thirdPartyAuthContext.providers,
secondaryProviders: commonComponents.thirdPartyAuthContext.secondaryProviders,
}),
);

View File

@@ -1,4 +1,4 @@
import { camelCaseObject, convertKeyNames, getConfig } from '@edx/frontend-platform';
import { getConfig } from '@edx/frontend-platform';
import { getAuthenticatedHttpClient } from '@edx/frontend-platform/auth';
// eslint-disable-next-line import/prefer-default-export
@@ -18,12 +18,8 @@ export async function getThirdPartyAuthContext(urlParams) {
throw (e);
});
return {
fieldDescriptions: data.registration_fields || {},
optionalFields: data.optional_fields || {},
// For backward compatibility with the API, once https://github.com/openedx/edx-platform/pull/30198 is merged
// and deployed update it to use data.context_data
thirdPartyAuthContext: camelCaseObject(
convertKeyNames(data.context_data || data, { fullname: 'name' }),
),
fieldDescriptions: data.registrationFields || {},
optionalFields: data.optionalFields || {},
thirdPartyAuthContext: data.contextData || {},
};
}

View File

@@ -0,0 +1,82 @@
import { PENDING_STATE } from '../../../data/constants';
import { THIRD_PARTY_AUTH_CONTEXT, THIRD_PARTY_AUTH_CONTEXT_CLEAR_ERROR_MSG } from '../actions';
import reducer from '../reducers';
describe('common components reducer', () => {
it('test mfe context response', () => {
const state = {
fieldDescriptions: {},
optionalFields: {},
thirdPartyAuthApiStatus: null,
thirdPartyAuthContext: {
currentProvider: null,
finishAuthUrl: null,
countryCode: null,
providers: [],
secondaryProviders: [],
pipelineUserDetails: null,
errorMessage: null,
},
};
const fieldDescriptions = {
fields: [],
};
const optionalFields = {
fields: [],
extended_profile: {},
};
const thirdPartyAuthContext = { ...state.thirdPartyAuthContext };
const action = {
type: THIRD_PARTY_AUTH_CONTEXT.SUCCESS,
payload: { fieldDescriptions, optionalFields, thirdPartyAuthContext },
};
expect(
reducer(state, action),
).toEqual(
{
...state,
fieldDescriptions: [],
optionalFields: {
fields: [],
extended_profile: {},
},
thirdPartyAuthApiStatus: 'complete',
},
);
});
it('should clear tpa context error message', () => {
const state = {
fieldDescriptions: {},
optionalFields: {},
thirdPartyAuthApiStatus: null,
thirdPartyAuthContext: {
currentProvider: null,
finishAuthUrl: null,
countryCode: null,
providers: [],
secondaryProviders: [],
pipelineUserDetails: null,
errorMessage: 'An error occured',
},
};
const action = {
type: THIRD_PARTY_AUTH_CONTEXT_CLEAR_ERROR_MSG,
};
expect(
reducer(state, action),
).toEqual(
{
...state,
thirdPartyAuthApiStatus: PENDING_STATE,
thirdPartyAuthContext: {
...state.thirdPartyAuthContext,
errorMessage: null,
},
},
);
});
});

View File

@@ -11,4 +11,4 @@ export { default as saga } from './data/sagas';
export { storeName } from './data/selectors';
export { default as FormGroup } from './FormGroup';
export { default as PasswordField } from './PasswordField';
export { default as Logistration } from './Logistration';
export { default as Zendesk } from './Zendesk';

View File

@@ -1,29 +1,13 @@
import { defineMessages } from '@edx/frontend-platform/i18n';
const messages = defineMessages({
// institution login strings
'institution.login.page.sub.heading': {
id: 'institution.login.page.sub.heading',
defaultMessage: 'Choose your institution from the list below',
description: 'Heading of the institutions list',
},
// Confirmation Alert Message
'forgot.password.confirmation.title': {
id: 'forgot.password.confirmation.title',
defaultMessage: 'Check your email',
description: 'Forgot password confirmation message title',
},
'forgot.password.confirmation.support.link': {
id: 'forgot.password.confirmation.support.link',
defaultMessage: 'contact technical support',
description: 'Technical support link text',
},
'forgot.password.confirmation.info': {
id: 'forgot.password.confirmation.info',
defaultMessage: 'If you do not receive a password reset message after 1 minute, verify that you entered the correct '
+ 'email address, or check your spam folder.',
description: 'Part of message that appears after user requests password change',
},
// Logistration strinsg
// logistration strings
'logistration.sign.in': {
id: 'logistration.sign.in',
defaultMessage: 'Sign in',
@@ -34,27 +18,12 @@ const messages = defineMessages({
defaultMessage: 'Register',
description: 'Text that appears on the tab to switch between login and register',
},
'internal.server.error.message': {
id: 'internal.server.error.message',
defaultMessage: 'An error has occurred. Try refreshing the page, or check your internet connection.',
description: 'Error message that appears when server responds with 500 error code',
},
'server.ratelimit.error.message': {
id: 'server.ratelimit.error.message',
defaultMessage: 'An error has occurred because of too many requests. Please try again after some time.',
description: 'Error message that appears when server responds with 429 error code',
},
// enterprise sso strings
'enterprisetpa.title.heading': {
id: 'enterprisetpa.title.heading',
defaultMessage: 'Would you like to sign in using your {providerName} credentials?',
description: 'Header text used in enterprise third party authentication',
},
'enterprisetpa.sso.button.title': {
id: 'enterprisetpa.sso.button.title',
defaultMessage: 'Sign in using {providerName}',
description: 'Text for third party auth provider buttons',
},
'enterprisetpa.login.button.text': {
id: 'enterprisetpa.login.button.text',
defaultMessage: 'Show me other ways to sign in or register',
@@ -128,6 +97,21 @@ const messages = defineMessages({
description: 'Message that appears on register page if user has successfully authenticated with TPA '
+ 'but no associated platform account exists',
},
'registration.using.tpa.form.heading': {
id: 'registration.using.tpa.form.heading',
defaultMessage: 'Finish creating your account',
description: 'Heading that appears above form when user is trying to create account using social auth',
},
supportTitle: {
id: 'zendesk.supportTitle',
description: 'Title for the support button',
defaultMessage: 'edX Support',
},
selectTicketForm: {
id: 'zendesk.selectTicketForm',
description: 'Select ticket form',
defaultMessage: 'Please choose your request type:',
},
});
export default messages;

View File

@@ -1,13 +1,20 @@
/* eslint-disable import/no-import-module-exports */
/* eslint-disable react/function-component-definition */
import React from 'react';
import * as auth from '@edx/frontend-platform/auth';
import { fetchAuthenticatedUser, getAuthenticatedUser } from '@edx/frontend-platform/auth';
import { mount } from 'enzyme';
import { MemoryRouter, BrowserRouter as Router, Switch } from 'react-router-dom';
import { act } from 'react-dom/test-utils';
import { UnAuthOnlyRoute } from '..';
import { LOGIN_PAGE } from '../../data/constants';
jest.mock('@edx/frontend-platform/auth');
import { MemoryRouter, BrowserRouter as Router, Switch } from 'react-router-dom';
jest.mock('@edx/frontend-platform/auth', () => ({
getAuthenticatedUser: jest.fn(),
fetchAuthenticatedUser: jest.fn(),
}));
const RRD = require('react-router-dom');
// Just render plain div with its children
@@ -36,25 +43,30 @@ describe('UnAuthOnlyRoute', () => {
jest.clearAllMocks();
});
it('should have called with forceRefresh true', () => {
it('should have called with forceRefresh true', async () => {
const user = {
username: 'gonzo',
other: 'data',
};
auth.getAuthenticatedUser = jest.fn(() => user);
auth.fetchAuthenticatedUser = jest.fn(() => ({ then: () => auth.getAuthenticatedUser() }));
mount(routerWrapper());
getAuthenticatedUser.mockReturnValue(user);
fetchAuthenticatedUser.mockReturnValueOnce(Promise.resolve(user));
expect(auth.fetchAuthenticatedUser).toBeCalledWith({ forceRefresh: true });
await act(async () => {
await mount(routerWrapper());
});
expect(fetchAuthenticatedUser).toBeCalledWith({ forceRefresh: true });
});
it('should have called with forceRefresh false', () => {
auth.getAuthenticatedUser = jest.fn(() => null);
auth.fetchAuthenticatedUser = jest.fn(() => ({ then: () => auth.getAuthenticatedUser() }));
it('should have called with forceRefresh false', async () => {
getAuthenticatedUser.mockReturnValue(null);
fetchAuthenticatedUser.mockReturnValueOnce(Promise.resolve(null));
mount(routerWrapper());
await act(async () => {
await mount(routerWrapper());
});
expect(auth.fetchAuthenticatedUser).toBeCalledWith({ forceRefresh: false });
expect(fetchAuthenticatedUser).toBeCalledWith({ forceRefresh: false });
});
});

View File

@@ -0,0 +1,17 @@
import { IntlProvider } from '@edx/frontend-platform/i18n';
import renderer from 'react-test-renderer';
import Zendesk from '../Zendesk';
jest.mock('react-zendesk', () => 'Zendesk');
describe('Zendesk Help', () => {
it('should match login page third party auth alert message snapshot', () => {
const tree = renderer.create(
<IntlProvider locale="en">
<Zendesk />
</IntlProvider>,
).toJSON();
expect(tree).toMatchSnapshot();
});
});

View File

@@ -10,25 +10,27 @@ exports[`SocialAuthProviders should match social auth provider with default icon
>
<div
aria-hidden="true"
className="font-container"
className="btn-tpa__font-container"
>
<svg
aria-hidden="true"
className="svg-inline--fa fa-right-to-bracket "
data-icon="right-to-bracket"
data-prefix="fas"
focusable="false"
role="img"
style={Object {}}
viewBox="0 0 512 512"
xmlns="http://www.w3.org/2000/svg"
<span
className="pgn__icon h-75"
>
<path
d="M352 96h64c17.7 0 32 14.3 32 32V384c0 17.7-14.3 32-32 32H352c-17.7 0-32 14.3-32 32s14.3 32 32 32h64c53 0 96-43 96-96V128c0-53-43-96-96-96H352c-17.7 0-32 14.3-32 32s14.3 32 32 32zm-7.5 177.4c4.8-4.5 7.5-10.8 7.5-17.4s-2.7-12.9-7.5-17.4l-144-136c-7-6.6-17.2-8.4-26-4.6s-14.5 12.5-14.5 22v72H32c-17.7 0-32 14.3-32 32v64c0 17.7 14.3 32 32 32H160v72c0 9.6 5.7 18.2 14.5 22s19 2 26-4.6l144-136z"
fill="currentColor"
style={Object {}}
/>
</svg>
<svg
aria-hidden={true}
fill="none"
focusable={false}
height={24}
role="img"
viewBox="0 0 24 24"
width={24}
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M11 7L9.6 8.4l2.6 2.6H2v2h10.2l-2.6 2.6L11 17l5-5-5-5zm9 12h-8v2h10V3H12v2h8v14z"
fill="currentColor"
/>
</svg>
</span>
</div>
<span
aria-hidden="true"
@@ -55,7 +57,7 @@ exports[`SocialAuthProviders should match social auth provider with iconClass sn
>
<div
aria-hidden="true"
className="font-container"
className="btn-tpa__font-container"
>
<svg
aria-hidden="true"
@@ -104,7 +106,7 @@ Array [
>
<img
alt="icon Apple"
className="icon-image"
className="btn-tpa__image-icon"
src="https://edx.devstack.lms/logo.png"
/>
</div>
@@ -133,7 +135,7 @@ Array [
>
<img
alt="icon Facebook"
className="icon-image"
className="btn-tpa__image-icon"
src="https://edx.devstack.lms/facebook-logo.png"
/>
</div>

View File

@@ -2,7 +2,7 @@
exports[`ThirdPartyAuthAlert should match login page third party auth alert message snapshot 1`] = `
<div
className="fade alert-content alert-warning mt-n2 alert show"
className="fade alert-content alert-warning mt-n2 mb-5 alert show"
id="tpa-alert"
role="alert"
>
@@ -21,26 +21,33 @@ exports[`ThirdPartyAuthAlert should match login page third party auth alert mess
`;
exports[`ThirdPartyAuthAlert should match register page third party auth alert message snapshot 1`] = `
<div
className="fade alert-content alert-success mt-n2 alert show"
id="tpa-alert"
role="alert"
>
Array [
<div
className="pgn__alert-message-wrapper"
className="fade alert-content alert-success mt-n2 mb-5 alert show"
id="tpa-alert"
role="alert"
>
<div
className="alert-message-content"
className="pgn__alert-message-wrapper"
>
<div
className="alert-heading h4"
className="alert-message-content"
>
Almost done!
<div
className="alert-heading h4"
>
Almost done!
</div>
<p>
You've successfully signed into Google! We just need a little more information before you start learning with Your Platform Name Here.
</p>
</div>
<p>
You've successfully signed into Google! We just need a little more information before you start learning with Your Platform Name Here.
</p>
</div>
</div>
</div>
</div>,
<h4
className="mt-4 mb-4"
>
Finish creating your account
</h4>,
]
`;

View File

@@ -0,0 +1,65 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Zendesk Help should match login page third party auth alert message snapshot 1`] = `
<Zendesk
cookies={true}
defer={true}
webWidget={
Object {
"answerBot": Object {
"avatar": Object {
"name": Object {
"*": "edX Support",
},
"url": undefined,
},
"contactOnlyAfterQuery": true,
"suppress": false,
"title": Object {
"*": "edX Support",
},
},
"chat": Object {
"departments": Object {
"enabled": Array [
"account settings",
"billing and payments",
"certificates",
"deadlines",
"errors and technical issues",
"other",
"proctoring",
],
},
"suppress": false,
},
"contactForm": Object {
"attachments": true,
"selectTicketForm": Object {
"*": "Please choose your request type:",
},
"ticketForms": Array [
Object {
"fields": Array [
Object {
"id": "description",
"prefill": Object {
"*": "",
},
},
],
"id": 360003368814,
"subject": false,
},
],
},
"contactOptions": Object {
"enabled": false,
},
"helpCenter": Object {
"originalArticleButton": true,
},
}
}
/>
`;

28
src/config/index.js Normal file
View File

@@ -0,0 +1,28 @@
const configuration = {
// Cookies related configs
SESSION_COOKIE_DOMAIN: process.env.SESSION_COOKIE_DOMAIN,
REGISTER_CONVERSION_COOKIE_NAME: process.env.REGISTER_CONVERSION_COOKIE_NAME || null,
USER_SURVEY_COOKIE_NAME: process.env.USER_SURVEY_COOKIE_NAME || null,
// Features
DISABLE_ENTERPRISE_LOGIN: process.env.DISABLE_ENTERPRISE_LOGIN || '',
ENABLE_DYNAMIC_REGISTRATION_FIELDS: process.env.ENABLE_DYNAMIC_REGISTRATION_FIELDS || false,
ENABLE_PROGRESSIVE_PROFILING_ON_AUTHN: process.env.ENABLE_PROGRESSIVE_PROFILING_ON_AUTHN || false,
ENABLE_PERSONALIZED_RECOMMENDATIONS: process.env.ENABLE_PERSONALIZED_RECOMMENDATIONS || false,
MARKETING_EMAILS_OPT_IN: process.env.MARKETING_EMAILS_OPT_IN || '',
SHOW_CONFIGURABLE_EDX_FIELDS: process.env.SHOW_CONFIGURABLE_EDX_FIELDS || false,
// Links
ACTIVATION_EMAIL_SUPPORT_LINK: process.env.ACTIVATION_EMAIL_SUPPORT_LINK || null,
AUTHN_PROGRESSIVE_PROFILING_SUPPORT_LINK: process.env.AUTHN_PROGRESSIVE_PROFILING_SUPPORT_LINK || null,
LOGIN_ISSUE_SUPPORT_LINK: process.env.LOGIN_ISSUE_SUPPORT_LINK || null,
PASSWORD_RESET_SUPPORT_LINK: process.env.PASSWORD_RESET_SUPPORT_LINK || null,
PRIVACY_POLICY: process.env.PRIVACY_POLICY || null,
TOS_AND_HONOR_CODE: process.env.TOS_AND_HONOR_CODE || null,
TOS_LINK: process.env.TOS_LINK || null,
// Miscellaneous
GENERAL_RECOMMENDATIONS: process.env.GENERAL_RECOMMENDATIONS || '[]',
INFO_EMAIL: process.env.INFO_EMAIL || '',
ZENDESK_KEY: process.env.ZENDESK_KEY,
ZENDESK_LOGO_URL: process.env.ZENDESK_LOGO_URL,
};
export default configuration;

View File

@@ -2,8 +2,9 @@
export const LOGIN_PAGE = '/login';
export const REGISTER_PAGE = '/register';
export const RESET_PAGE = '/reset';
export const WELCOME_PAGE = '/welcome';
export const AUTHN_PROGRESSIVE_PROFILING = '/welcome';
export const DEFAULT_REDIRECT_URL = '/dashboard';
export const RECOMMENDATIONS = '/recommendations';
export const PASSWORD_RESET_CONFIRM = '/password_reset_confirm/:token/';
export const PAGE_NOT_FOUND = '/notfound';
export const ENTERPRISE_LOGIN_URL = '/enterprise/login';
@@ -30,8 +31,8 @@ export const VALID_EMAIL_REGEX = '(^[-!#$%&\'*+/=?^_`{}|~0-9A-Z]+(\\.[-!#$%&\'*+
+ '|\\[(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)(\\.(25[0-5]|2[0-4]\\d|[0-1]?\\d?\\d)){3}\\]$';
export const LETTER_REGEX = /[a-zA-Z]/;
export const NUMBER_REGEX = /\d/;
export const VALID_NAME_REGEX = /[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)?/gi; // eslint-disable-line no-useless-escape
export const INVALID_NAME_REGEX = /[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)?/gi; // eslint-disable-line no-useless-escape
// Query string parameters that can be passed to LMS to manage
// things like auto-enrollment upon login and registration.
export const AUTH_PARAMS = ['course_id', 'enrollment_action', 'course_mode', 'email_opt_in', 'purchase_workflow', 'next', 'save_for_later', 'register_for_free'];
export const AUTH_PARAMS = ['course_id', 'enrollment_action', 'course_mode', 'email_opt_in', 'purchase_workflow', 'next', 'save_for_later', 'register_for_free', 'track', 'is_account_recovery'];

17
src/data/optimizely.js Normal file
View File

@@ -0,0 +1,17 @@
import {
createInstance,
} from '@optimizely/react-sdk';
const OPTIMIZELY_SDK_KEY = process.env.OPTIMIZELY_FULL_STACK_SDK_KEY;
const getOptimizelyInstance = () => {
if (OPTIMIZELY_SDK_KEY) {
return createInstance({
sdkKey: OPTIMIZELY_SDK_KEY,
});
}
return null;
};
export default getOptimizelyInstance();

View File

@@ -12,6 +12,10 @@ import {
reducer as loginReducer,
storeName as loginStoreName,
} from '../login';
import {
reducer as authnProgressiveProfilingReducers,
storeName as authnProgressiveProfilingStoreName,
} from '../progressive-profiling';
import {
reducer as registerReducer,
storeName as registerStoreName,
@@ -20,10 +24,6 @@ import {
reducer as resetPasswordReducer,
storeName as resetPasswordStoreName,
} from '../reset-password';
import {
reducer as welcomePageReducers,
storeName as welcomePageStoreName,
} from '../welcome';
const createRootReducer = () => combineReducers({
[loginStoreName]: loginReducer,
@@ -31,6 +31,6 @@ const createRootReducer = () => combineReducers({
[commonComponentsStoreName]: commonComponentsReducer,
[forgotPasswordStoreName]: forgotPasswordReducer,
[resetPasswordStoreName]: resetPasswordReducer,
[welcomePageStoreName]: welcomePageReducers,
[authnProgressiveProfilingStoreName]: authnProgressiveProfilingReducers,
});
export default createRootReducer;

View File

@@ -3,9 +3,9 @@ import { all } from 'redux-saga/effects';
import { saga as commonComponentsSaga } from '../common-components';
import { saga as forgotPasswordSaga } from '../forgot-password';
import { saga as loginSaga } from '../login';
import { saga as authnProgressiveProfilingSaga } from '../progressive-profiling';
import { saga as registrationSaga } from '../register';
import { saga as resetPasswordSaga } from '../reset-password';
import { saga as welcomePageSaga } from '../welcome';
export default function* rootSaga() {
yield all([
@@ -14,6 +14,6 @@ export default function* rootSaga() {
commonComponentsSaga(),
forgotPasswordSaga(),
resetPasswordSaga(),
welcomePageSaga(),
authnProgressiveProfilingSaga(),
]);
}

View File

@@ -3,7 +3,7 @@ import Cookies from 'universal-cookie';
export function setCookie(cookieName, cookieValue, cookieExpiry) {
const cookies = new Cookies();
const options = { domain: getConfig().COOKIE_DOMAIN, path: '/' };
const options = { domain: getConfig().SESSION_COOKIE_DOMAIN, path: '/' };
if (cookieExpiry) {
options.expires = cookieExpiry;
}

View File

@@ -49,8 +49,8 @@ export const updatePathWithQueryParams = (path) => {
return `${path}${queryParams}`;
};
export const getAllPossibleQueryParam = () => {
const urlParams = QueryString.parse(window.location.search);
export const getAllPossibleQueryParams = (locationURl = null) => {
const urlParams = locationURl ? QueryString.parseUrl(locationURl).query : QueryString.parse(window.location.search);
const params = {};
Object.entries(urlParams).forEach(([key, value]) => {
if (AUTH_PARAMS.indexOf(key) > -1) {

View File

@@ -1,5 +1,5 @@
import { LOGIN_PAGE } from '../constants';
import { updatePathWithQueryParams } from './dataUtils';
import { LOGIN_PAGE } from '../constants';
describe('updatePathWithQueryParams', () => {
it('should append query params into the path', () => {

View File

@@ -2,7 +2,7 @@ export {
getTpaProvider,
getTpaHint,
updatePathWithQueryParams,
getAllPossibleQueryParam,
getAllPossibleQueryParams,
getActivationStatus,
windowScrollTo,
} from './dataUtils';

View File

@@ -7,7 +7,7 @@ import PropTypes from 'prop-types';
const FormFieldRenderer = (props) => {
let formField = null;
const {
errorMessage, fieldData, onChangeHandler, isRequired, value,
className, errorMessage, fieldData, onChangeHandler, isRequired, value,
} = props;
const handleFocus = (e) => {
@@ -26,6 +26,7 @@ const FormFieldRenderer = (props) => {
formField = (
<Form.Group controlId={fieldData.name} isInvalid={!!(isRequired && errorMessage)}>
<Form.Control
className={className}
as="select"
name={fieldData.name}
value={value}
@@ -54,6 +55,7 @@ const FormFieldRenderer = (props) => {
formField = (
<Form.Group controlId={fieldData.name} isInvalid={!!(isRequired && errorMessage)}>
<Form.Control
className={className}
as="textarea"
name={fieldData.name}
value={value}
@@ -76,6 +78,7 @@ const FormFieldRenderer = (props) => {
formField = (
<Form.Group controlId={fieldData.name} isInvalid={!!(isRequired && errorMessage)}>
<Form.Control
className={className}
name={fieldData.name}
value={value}
aria-invalid={isRequired && Boolean(errorMessage)}
@@ -97,6 +100,7 @@ const FormFieldRenderer = (props) => {
formField = (
<Form.Group isInvalid={!!(isRequired && errorMessage)}>
<Form.Checkbox
className={className}
id={fieldData.name}
checked={!!value}
name={fieldData.name}
@@ -124,6 +128,7 @@ const FormFieldRenderer = (props) => {
return formField;
};
FormFieldRenderer.defaultProps = {
className: '',
value: '',
handleBlur: null,
handleFocus: null,
@@ -132,17 +137,22 @@ FormFieldRenderer.defaultProps = {
};
FormFieldRenderer.propTypes = {
className: PropTypes.string,
fieldData: PropTypes.shape({
type: PropTypes.string,
label: PropTypes.string,
name: PropTypes.string,
options: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.string)),
}).isRequired,
onChangeHandler: PropTypes.func.isRequired,
handleBlur: PropTypes.func,
handleFocus: PropTypes.func,
errorMessage: PropTypes.string,
isRequired: PropTypes.bool,
value: PropTypes.string,
value: PropTypes.oneOfType([
PropTypes.string,
PropTypes.bool,
]),
};
export default FormFieldRenderer;

View File

@@ -1 +1,2 @@
export { default } from './FieldRenderer';
/* eslint-disable import/prefer-default-export */
export { default as FormFieldRenderer } from './FieldRenderer';

View File

@@ -1,5 +1,6 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { mount } from 'enzyme';
import FieldRenderer from '../FieldRenderer';
@@ -24,7 +25,7 @@ describe('FieldRendererTests', () => {
type: 'select',
label: 'Year of Birth',
name: 'yob-field',
options: [['1997', 1997], ['1998', 1998]],
options: [['1997', '1997'], ['1998', '1998']],
};
const fieldRenderer = mount(<FieldRenderer value={value} fieldData={fieldData} onChangeHandler={changeHandler} />);
@@ -82,7 +83,7 @@ describe('FieldRendererTests', () => {
it('should render checkbox field', () => {
const fieldData = {
type: 'checkbox',
label: 'I agree that edX may send me marketing messages.',
label: `I agree that ${getConfig().SITE_NAME} may send me marketing messages.`,
name: 'marketing-emails-opt-in-field',
};
@@ -91,7 +92,7 @@ describe('FieldRendererTests', () => {
field.simulate('change', { target: { checked: true, type: 'checkbox' } });
expect(field.prop('type')).toEqual('checkbox');
expect(fieldRenderer.find('label').text()).toEqual('I agree that edX may send me marketing messages.');
expect(fieldRenderer.find('label').text()).toEqual(fieldData.label);
expect(value).toEqual(true);
});

View File

@@ -1,21 +1,22 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import { Alert } from '@edx/paragon';
import { CheckCircle, Error } from '@edx/paragon/icons';
import PropTypes from 'prop-types';
import messages from './messages';
import {
COMPLETE_STATE, FORBIDDEN_STATE, FORM_SUBMISSION_ERROR, INTERNAL_SERVER_ERROR,
} from '../data/constants';
import { PASSWORD_RESET } from '../reset-password/data/constants';
import messages from './messages';
const ForgotPasswordAlert = (props) => {
const { email, emailError, intl } = props;
const { formatMessage } = useIntl();
const { email, emailError } = props;
let message = '';
let heading = intl.formatMessage(messages['forgot.password.error.alert.title']);
let heading = formatMessage(messages['forgot.password.error.alert.title']);
let { status } = props;
if (emailError) {
@@ -24,7 +25,7 @@ const ForgotPasswordAlert = (props) => {
switch (status) {
case COMPLETE_STATE:
heading = intl.formatMessage(messages['confirmation.message.title']);
heading = formatMessage(messages['confirmation.message.title']);
message = (
<FormattedMessage
id="forgot.password.confirmation.message"
@@ -36,7 +37,7 @@ const ForgotPasswordAlert = (props) => {
email: <span className="data-hj-suppress">{email}</span>,
supportLink: (
<Alert.Link href={getConfig().PASSWORD_RESET_SUPPORT_LINK} target="_blank">
{intl.formatMessage(messages['confirmation.support.link'])}
{formatMessage(messages['confirmation.support.link'])}
</Alert.Link>
),
}}
@@ -44,26 +45,26 @@ const ForgotPasswordAlert = (props) => {
);
break;
case INTERNAL_SERVER_ERROR:
message = intl.formatMessage(messages['internal.server.error']);
message = formatMessage(messages['internal.server.error']);
break;
case FORBIDDEN_STATE:
heading = intl.formatMessage(messages['forgot.password.error.message.title']);
message = intl.formatMessage(messages['forgot.password.request.in.progress.message']);
heading = formatMessage(messages['forgot.password.error.message.title']);
message = formatMessage(messages['forgot.password.request.in.progress.message']);
break;
case FORM_SUBMISSION_ERROR:
message = intl.formatMessage(messages['extend.field.errors'], { emailError });
message = formatMessage(messages['extend.field.errors'], { emailError });
break;
case PASSWORD_RESET.INVALID_TOKEN:
heading = intl.formatMessage(messages['invalid.token.heading']);
message = intl.formatMessage(messages['invalid.token.error.message']);
heading = formatMessage(messages['invalid.token.heading']);
message = formatMessage(messages['invalid.token.error.message']);
break;
case PASSWORD_RESET.FORBIDDEN_REQUEST:
heading = intl.formatMessage(messages['token.validation.rate.limit.error.heading']);
message = intl.formatMessage(messages['token.validation.rate.limit.error']);
heading = formatMessage(messages['token.validation.rate.limit.error.heading']);
message = formatMessage(messages['token.validation.rate.limit.error']);
break;
case PASSWORD_RESET.INTERNAL_SERVER_ERROR:
heading = intl.formatMessage(messages['token.validation.internal.sever.error.heading']);
message = intl.formatMessage(messages['token.validation.internal.sever.error']);
heading = formatMessage(messages['token.validation.internal.sever.error.heading']);
message = formatMessage(messages['token.validation.internal.sever.error']);
break;
default:
break;
@@ -93,8 +94,7 @@ ForgotPasswordAlert.defaultProps = {
ForgotPasswordAlert.propTypes = {
status: PropTypes.string.isRequired,
email: PropTypes.string,
intl: intlShape.isRequired,
emailError: PropTypes.string,
};
export default injectIntl(ForgotPasswordAlert);
export default ForgotPasswordAlert;

View File

@@ -3,7 +3,7 @@ import { connect } from 'react-redux';
import { getConfig } from '@edx/frontend-platform';
import { sendPageEvent, sendTrackEvent } from '@edx/frontend-platform/analytics';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import {
Form,
Hyperlink,
@@ -17,22 +17,23 @@ import PropTypes from 'prop-types';
import { Helmet } from 'react-helmet';
import { Redirect } from 'react-router-dom';
import BaseComponent from '../base-component';
import { FormGroup } from '../common-components';
import { DEFAULT_STATE, LOGIN_PAGE, VALID_EMAIL_REGEX } from '../data/constants';
import { updatePathWithQueryParams, windowScrollTo } from '../data/utils';
import { forgotPassword, setForgotPasswordFormData } from './data/actions';
import { forgotPasswordResultSelector } from './data/selectors';
import ForgotPasswordAlert from './ForgotPasswordAlert';
import messages from './messages';
import { BaseComponent } from '../base-component';
import { FormGroup } from '../common-components';
import { DEFAULT_STATE, LOGIN_PAGE, VALID_EMAIL_REGEX } from '../data/constants';
import { updatePathWithQueryParams, windowScrollTo } from '../data/utils';
const ForgotPasswordPage = (props) => {
const platformName = getConfig().SITE_NAME;
const emailRegex = new RegExp(VALID_EMAIL_REGEX, 'i');
const {
intl, status, submitState, emailValidationError,
status, submitState, emailValidationError,
} = props;
const { formatMessage } = useIntl();
const [email, setEmail] = useState(props.email);
const [bannerEmail, setBannerEmail] = useState('');
const [formErrors, setFormErrors] = useState('');
@@ -58,9 +59,9 @@ const ForgotPasswordPage = (props) => {
let error = '';
if (value === '') {
error = intl.formatMessage(messages['forgot.password.empty.email.field.error']);
error = formatMessage(messages['forgot.password.empty.email.field.error']);
} else if (!emailRegex.test(value)) {
error = intl.formatMessage(messages['forgot.password.page.invalid.email.message']);
error = formatMessage(messages['forgot.password.page.invalid.email.message']);
}
return error;
@@ -89,14 +90,14 @@ const ForgotPasswordPage = (props) => {
const tabTitle = (
<div className="d-inline-flex flex-wrap align-items-center">
<Icon src={ChevronLeft} />
<span className="ml-2">{intl.formatMessage(messages['sign.in.text'])}</span>
<span className="ml-2">{formatMessage(messages['sign.in.text'])}</span>
</div>
);
return (
<BaseComponent>
<Helmet>
<title>{intl.formatMessage(messages['forgot.password.page.title'],
<title>{formatMessage(messages['forgot.password.page.title'],
{ siteName: getConfig().SITE_NAME })}
</title>
</Helmet>
@@ -111,13 +112,13 @@ const ForgotPasswordPage = (props) => {
<Form id="forget-password-form" name="forget-password-form" className="mw-xs">
<ForgotPasswordAlert email={bannerEmail} emailError={formErrors} status={status} />
<h2 className="h4">
{intl.formatMessage(messages['forgot.password.page.heading'])}
{formatMessage(messages['forgot.password.page.heading'])}
</h2>
<p className="mb-4">
{intl.formatMessage(messages['forgot.password.page.instructions'])}
{formatMessage(messages['forgot.password.page.instructions'])}
</p>
<FormGroup
floatingLabel={intl.formatMessage(messages['forgot.password.page.email.field.label'])}
floatingLabel={formatMessage(messages['forgot.password.page.email.field.label'])}
name="email"
value={email}
autoComplete="on"
@@ -125,17 +126,17 @@ const ForgotPasswordPage = (props) => {
handleChange={(e) => setEmail(e.target.value)}
handleBlur={handleBlur}
handleFocus={handleFocus}
helpText={[intl.formatMessage(messages['forgot.password.email.help.text'], { platformName })]}
helpText={[formatMessage(messages['forgot.password.email.help.text'], { platformName })]}
/>
<StatefulButton
id="submit-forget-password"
name="submit-forget-password"
type="submit"
variant="brand"
className="forgot-password-button-width"
className="forgot-password--button"
state={submitState}
labels={{
default: intl.formatMessage(messages['forgot.password.page.submit.button']),
default: formatMessage(messages['forgot.password.page.submit.button']),
pending: '',
}}
onClick={handleSubmit}
@@ -150,11 +151,11 @@ const ForgotPasswordPage = (props) => {
target="_blank"
showLaunchIcon={false}
>
{intl.formatMessage(messages['need.help.sign.in.text'])}
{formatMessage(messages['need.help.sign.in.text'])}
</Hyperlink>
)}
<p className="mt-5.5 small text-gray-700">
{intl.formatMessage(messages['additional.help.text'], { platformName })}
{formatMessage(messages['additional.help.text'], { platformName })}
<span>
<Hyperlink isInline destination={`mailto:${getConfig().INFO_EMAIL}`}>{getConfig().INFO_EMAIL}</Hyperlink>
</span>
@@ -170,7 +171,6 @@ ForgotPasswordPage.propTypes = {
email: PropTypes.string,
emailValidationError: PropTypes.string,
forgotPassword: PropTypes.func.isRequired,
intl: intlShape.isRequired,
setForgotPasswordFormData: PropTypes.func.isRequired,
status: PropTypes.string,
submitState: PropTypes.string,
@@ -189,4 +189,4 @@ export default connect(
forgotPassword,
setForgotPasswordFormData,
},
)(injectIntl(ForgotPasswordPage));
)(ForgotPasswordPage);

View File

@@ -1,6 +1,6 @@
import { FORGOT_PASSWORD, FORGOT_PASSWORD_PERSIST_FORM_DATA } from './actions';
import { INTERNAL_SERVER_ERROR, PENDING_STATE } from '../../data/constants';
import { PASSWORD_RESET_FAILURE } from '../../reset-password/data/actions';
import { FORGOT_PASSWORD, FORGOT_PASSWORD_PERSIST_FORM_DATA } from './actions';
export const defaultState = {
status: '',

View File

@@ -1,4 +1,4 @@
export { default } from './ForgotPasswordPage';
export { default as ForgotPasswordPage } from './ForgotPasswordPage';
export { default as reducer } from './data/reducers';
export { FORGOT_PASSWORD } from './data/actions';
export { default as saga } from './data/sagas';

View File

@@ -51,11 +51,6 @@ const messages = defineMessages({
defaultMessage: 'Enter your email',
description: 'Error message that appears when user tries to submit empty email field',
},
'forgot.password.invalid.email.message': {
id: 'forgot.password.invalid.email.message',
defaultMessage: "The email address you've provided isn't formatted correctly.",
description: 'message for invalid email',
},
'forgot.password.email.help.text': {
id: 'forgot.password.email.help.text',
defaultMessage: 'The email address you used to register with {platformName}',
@@ -129,10 +124,5 @@ const messages = defineMessages({
defaultMessage: 'An error has occurred. Try refreshing the page, or check your internet connection.',
description: 'Error message that appears when server responds with 500 error code',
},
'rate.limit.error': {
id: 'rate.limit.error',
defaultMessage: 'An error has occurred because of too many requests. Please try again after some time.',
description: 'Error message that appears when server responds with 429 error code',
},
});
export default messages;

View File

@@ -1,10 +1,7 @@
import React from 'react';
import { Provider } from 'react-redux';
import CookiePolicyBanner from '@edx/frontend-component-cookie-policy-banner';
import { mergeConfig } from '@edx/frontend-platform';
import * as analytics from '@edx/frontend-platform/analytics';
import * as auth from '@edx/frontend-platform/auth';
import { configure, injectIntl, IntlProvider } from '@edx/frontend-platform/i18n';
import { mount } from 'enzyme';
import { createMemoryHistory } from 'history';
@@ -17,11 +14,12 @@ import { PASSWORD_RESET } from '../../reset-password/data/constants';
import { setForgotPasswordFormData } from '../data/actions';
import ForgotPasswordPage from '../ForgotPasswordPage';
jest.mock('@edx/frontend-platform/analytics');
jest.mock('@edx/frontend-platform/analytics', () => ({
sendPageEvent: jest.fn(),
sendTrackEvent: jest.fn(),
}));
jest.mock('@edx/frontend-platform/auth');
analytics.sendPageEvent = jest.fn();
const IntlForgotPasswordPage = injectIntl(ForgotPasswordPage);
const mockStore = configureStore();
const history = createMemoryHistory();
@@ -51,7 +49,12 @@ describe('ForgotPasswordPage', () => {
beforeEach(() => {
store = mockStore(initialState);
auth.getAuthenticatedUser = jest.fn(() => ({ userId: 3, username: 'edX' }));
jest.mock('@edx/frontend-platform/auth', () => ({
getAuthenticatedUser: jest.fn(() => ({
userId: 3,
username: 'test-user',
})),
}));
configure({
loggingService: { logError: jest.fn() },
config: {
@@ -191,11 +194,6 @@ describe('ForgotPasswordPage', () => {
expect(forgotPasswordPage.find('#email-invalid-feedback').exists()).toEqual(false);
});
it('check cookie rendered', () => {
const forgotPage = mount(reduxWrapper(<IntlForgotPasswordPage {...props} />));
expect(forgotPage.find(<CookiePolicyBanner />)).toBeTruthy();
});
it('should display success message after email is sent', () => {
store = mockStore({
...initialState,

View File

@@ -1,41 +1,39 @@
import { messages as paragonMessages } from '@edx/paragon';
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 dedeMessages from './messages/de_DE.json';
import deMessages from './messages/de.json';
import dedeCAMessages from './messages/de_DE.json';
import es419Messages from './messages/es_419.json';
import frMessages from './messages/fr.json';
import heMessages from './messages/he.json';
import frCAMessages from './messages/fr_CA.json';
import hiMessages from './messages/hi.json';
import idMessages from './messages/id.json';
import ititMessages from './messages/it_IT.json';
import kokrMessages from './messages/ko_kr.json';
import plMessages from './messages/pl.json';
import ptbrMessages from './messages/pt_br.json';
import ptptMessages from './messages/pt_PT.json';
import itMessages from './messages/it.json';
import ititCAMessages from './messages/it_IT.json';
import ptMessages from './messages/pt.json';
import ptptCAMessages from './messages/pt_PT.json';
import ruMessages from './messages/ru.json';
import thMessages from './messages/th.json';
import ukMessages from './messages/uk.json';
import zhcnMessages from './messages/zh_CN.json';
// no need to import en messages-- they are in the defaultMessage field
const messages = {
const appMessages = {
ar: arMessages,
es: es419Messages, // Prospectus uses es language code for spanish, added `es` option and pointed to es-419 strings.
'es-419': es419Messages,
fr: frMessages,
'zh-cn': zhcnMessages,
'it-it': ititMessages,
'pt-pt': ptptMessages,
'de-de': dedeMessages,
ca: caMessages,
he: heMessages,
id: idMessages,
'ko-kr': kokrMessages,
pl: plMessages,
'pt-br': ptbrMessages,
ru: ruMessages,
th: thMessages,
uk: ukMessages,
pt: ptMessages,
it: itMessages,
de: deMessages,
hi: hiMessages,
'fr-ca': frCAMessages,
ru: ruMessages,
uk: ukMessages,
'de-de': dedeCAMessages,
'it-it': ititCAMessages,
'pt-pt': ptptCAMessages,
};
export default messages;
export default [
paragonMessages,
appMessages,
];

View File

@@ -5,16 +5,11 @@
"complete.your.profile.2": "ملفك الشخصي",
"welcome.to.platform": "أهلا بك {username} في {siteName}",
"institution.login.page.sub.heading": "اختر مؤسستك من القائمة أدناه",
"forgot.password.confirmation.title": "تفقّد بريدك الإلكتروني",
"forgot.password.confirmation.support.link": "اتصل بالدعم الفني",
"forgot.password.confirmation.info": "إن لم تستلم رسالة إعادة تعيين كلمة المرور بعد دقيقة واحدة، فتحقق من أنك أدخلت عنوان البريد الإلكتروني الصحيح، أو تفقّد مجلد الرسائل غير المرغوب فيها في بريدك الإلكتروني.",
"logistration.sign.in": "تسجيل الدخول",
"logistration.register": "التسجيل",
"internal.server.error.message": "حدث خطأ ما. جرّب تحديث الصفحة أو تحقق من اتصالك بالانترنت.",
"server.ratelimit.error.message": "حدث خطأ بسبب كثرة الطلبات. رجاءً حاول مرة أخرى بعد مضي بعض الوقت.",
"enterprisetpa.title.heading": "هل ترغب في تسجيل الدخول باستخدام بيانات {providerName} الخاصة بك؟",
"enterprisetpa.sso.button.title": "تسجيل الدخول باستخدام {providerName}",
"enterprisetpa.login.button.text": "أرِني وسائل أخرى لتسجيل الدخول أو للتسجيل",
"enterprisetpa.login.button.text.public.account.creation.disabled": "أرني طرقًا أخرى لتسجيل الدخول",
"sso.sign.in.with": "تسجيل الدخول باستخدام {providerName}",
"sso.create.account.using": "إنشاء حساب باستخدام {providerName}",
"show.password": "إظهار كلمة المرور",
@@ -26,6 +21,9 @@
"tpa.alert.heading": "انتهينا تقريبا!",
"login.third.party.auth.account.not.linked": "لقد نجحت في تسجيل الدخول إلى {currentProvider}، لكن حسابك على {currentProvider} غير موصول بأي حساب على {platformName}. لوصل حساباتك، سجّل الدخول الآن باستخدام كلمة مرورك على {platformName}.",
"register.third.party.auth.account.not.linked": "لقد سجلت دخولك بنجاح إلى {currentProvider}! نحتاج فقط قليلاً بعدُ من المعلومات قبل أن تبدأ التعلم مع {platformName}.",
"registration.using.tpa.form.heading": "إتمام إنشاء حسابك",
"zendesk.supportTitle": "edX Support",
"zendesk.selectTicketForm": "الرجاء اختيار نوع الطلب الخاص بك:",
"error.notfound.message": "الصفحة التي تبحث عنها غير متوفرة أو هناك خطأ في العنوان. رجاءً تحقق من العنوان و حاول مجددًا.",
"forgot.password.confirmation.message": "لقد أرسلنا بريدًا إلكترونيًا إلى {email} به إرشادات لإعادة ضبط كلمة المرور الخاصة بك. إن لم تستلم رسالة إعادة ضبط كلمة المرور بعد دقيقة واحدة، فتحقق من إدخال عنوان البريد الإلكتروني الصحيح، أو تفقد مجلد الرسائل غير المرغوب فيها. إن احتجت مزيدًا من المساعدة، {supportLink}.",
"forgot.password.page.title": "نسيت كلمة المرور | {siteName}",
@@ -38,7 +36,6 @@
"forgot.password.error.message.title": "حدث خطأ ما.",
"forgot.password.request.in.progress.message": "طلبك السابق قيد التنفيذ، يرجى المحاولة مرة أخرى بعد لحظات قليلة.",
"forgot.password.empty.email.field.error": "أدخل بريدك الإلكتروني",
"forgot.password.invalid.email.message": "صيغة عنوان البريد الإلكتروني الذي أدخلته غير صحيحة",
"forgot.password.email.help.text": "عنوان البريد الإلكتروني الذي استخدمته للتسجيل في {platformName}",
"confirmation.message.title": "تفقّد بريدك الإلكتروني",
"confirmation.support.link": "اتصل بالدعم الفني",
@@ -53,7 +50,6 @@
"token.validation.internal.sever.error.heading": "فشل في التحقق من صحة الشارة",
"token.validation.internal.sever.error": "حدث خطأ ما. جرب تحديث الصفحة أو تحقق من اتصالك بالإنترنت.",
"internal.server.error": "حدث خطأ ما. جرب تحديث الصفحة أو تحقق من اتصالك بالإنترنت.",
"rate.limit.error": "حدث خطأ بسبب كثرة الطلبات. رجاءً حاول مرة أخرى بعد مضي بعض الوقت.",
"account.activation.error.message": "شي ما لم يسر على ما يرام، يرجى {supportLink} لحل هذه المشكلة.",
"login.inactive.user.error": "أنت بحاجة لتفعيل حسابك من أجل تسجيل الدخول{lineBreak}\n{lineBreak}لقد أرسلنا للتو رابطًا للتفعيل إلى {email}. إن لم تتلقّ بريدًا إلكترونيا، تفقّد مجلدات الرسائل غير المرغوب فيها أو {supportLink}.",
"allowed.domain.login.error": "كونك مستخدمًا على {allowedDomain}، فإن عليك تسجيل الدخول باستخدام {tpaLink} الخاص بـ {allowedDomain} .",
@@ -65,45 +61,32 @@
"login.user.identity.label": "اسم المستخدم أو البريد الإلكتروني",
"login.password.label": "كلمة المرور",
"sign.in.button": "تسجيل الدخول",
"sign.in.btn.pending.state": "التحميل جارٍ",
"need.help.signing.in.collapsible.menu": "هل تحتاج مساعدة في تسجيل الدخول؟",
"forgot.password.link": "نسيت كلمة مروري",
"forgot.password": "نسيت كلمة المرور",
"other.sign.in.issues": "مشاكل أخرى عند تسجيل الدخول",
"need.other.help.signing.in.collapsible.menu": "هل تحتاج مساعدة أخرى في تسجيل الدخول؟",
"institution.login.button": "بيانات المؤسسة / الجامعة",
"institution.login.page.title": "تسجيل الدخول باستخدام بيانات المؤسسة / الجامعة",
"institution.login.page.back.button": "العودة إلى تسجيل الدخول",
"create.an.account": " أنشئ حساباً جديداً.",
"login.other.options.heading": "أو قم بتسجيل الدخول باستخدام:",
"non.compliant.password.title": "لقد غيرنا متطلبات أمان كلمة المرور مؤخرًا",
"non.compliant.password.message": "كلمة مرورك الحالية لا تستسجيب لمتطلبات الأمان الجديدة. لقد أرسلنا للتو رسالة لإعادة ضبط كلمة المرور إلى عنوان البريد الإلكتروني المرتبط بهذا الحساب. شكرًا لك على مساعدتنا في الحفاظ على سلامة بياناتك.",
"account.locked.out.message.1": "لحماية حسابك، تم إقفاله مؤقتًا. حاول مرة أخرى بعد 30 دقيقة.",
"first.time.here": "أول مرة لك هنا؟",
"email.help.message": "عنوان البريد الإلكتروني الذي استخدمته للتسجيل في edX.",
"enterprise.login.btn.text": "بيانات الشركة أو المدرسة",
"email.format.validation.message": "صيغة عنوان البريد الإلكتروني الذي أدخلته غير صحيحة",
"username.or.email.format.validation.less.chars.message": "يجب أن يحتوي اسم المستخدم أو البريد الإلكتروني على 3 أحرف على الأقل.",
"email.validation.message": "أدخل اسم المستخدم أو البريد الإلكتروني الخاص بك",
"password.validation.message": "لم يتم استيفاء معايير كلمة المرور",
"register.link": " أنشئ حساباً",
"sign.in.heading": "تسجيل الدخول",
"account.activation.success.message.title": "نجح الأمر! لقد قمت بتفعيل حسابك.",
"account.activation.success.message": "ستصلك الآن تحديثات وتنبيهات عبر البريد الإلكتروني منا تتعلق بالمساقات التي قمت بالتسجيل فيها. قم بتسجيل الدخول للمتابعة.",
"account.activation.info.message": "هذا الحساب مفعَّل من قبل.",
"account.activation.error.message.title": "لا يمكن تفعيل حسابك",
"account.activation.support.link": "الاتصال بالدعم",
"tpa.account.link": "حساب {provider}",
"account.confirmation.success.message.title": "نجحت العملية! لقد أكدت بريدك الإلكتروني.",
"account.confirmation.success.message": "سجل دخولك للمتابعة.",
"account.confirmation.info.message": "هذا البريد الإلكتروني مؤكد من قبل.",
"account.confirmation.error.message.title": "لا يمكن تأكيد بريدك الإلكتروني",
"tpa.account.link": "حساب {provider}",
"internal.server.error.message": "حدث خطأ ما. جرّب تحديث الصفحة أو تحقق من اتصالك بالانترنت.",
"login.rate.limit.reached.message": "كثرت محاولات تسجيل الدخول الفاشلة. رجاءً أعد المحاولة لاحقًا.",
"login.failure.header.title": "لم نتمكّن من تسجيل دخولك.",
"contact.support.link": "اتصل بدعم {platformName}",
"login.incorrect.credentials.error": "اسم المستخدم أو البريد الإلكتروني أو كلمة المرور التي أدخلتها غير صحيحة. حاول مرة اخرى.",
"login.failed.attempt.error": "لديك {remainingAttempts, plural,\none {محاولة واحدة}\ntwo {محاولتان}\nfew {# محاولات}\nmany {# محاولة}\nother {# محاولة}\n} أخرى لتسجيل الدخول قبل أن يتم إقفال حسابك مؤقتًا.",
"login.locked.out.error.message": "لحماية حسابك، تم إقفاله مؤقتًا. حاول مرة أخرى بعد {lockedOutPeriod, plural,\n one {دقيقة واحدة}\n two {دقيقتين}\n few {# دقائق}\n many {# دقيقة}\n other {# دقيقة}\n}.",
"login.form.invalid.error.message": "رجاءً املأ الحقول أدناه.",
"login.incorrect.credentials.error.reset.link.text": "إعادة ضبط كلمه المرور",
"login.incorrect.credentials.error.before.account.blocked.text": "انقر هنا لإعادة ضبطها.",
@@ -113,20 +96,21 @@
"password.security.block.body": "اكتشف نظامنا أن كلمة مرورك صعيفة. غيّر كلمة مرورك حتى يظل حسابك آمنًا.",
"password.security.close.button": "إغلاق",
"password.security.redirect.to.reset.password.button": "إعادة ضبط كلمة المرور",
"progressive.profiling.page.title": "الحقول الاختيارية | {siteName}",
"login.tpa.authentication.failure": "عذرًا ، غير مصرح لك بالوصول إلى {platform_name} عبر هذه القناة. يرجى الاتصال بمسؤول التعلم أو المدير من أجل الوصول إلى {platform_name}. {lineBreak} {lineBreak} تفاصيل الخطأ: {lineBreak} {errorMessage}",
"progressive.profiling.page.title": "مرحبا بكم | {siteName}",
"progressive.profiling.page.heading": "بعض الأسئلة الموجهة لك ستساعدنا كي نزداد ذكاءً.",
"optional.fields.information.link": "معرفة المزيد عن كيفية استخدامنا لهذه المعلومات.",
"optional.fields.submit.button": "إرسال",
"optional.fields.skip.button": "التخطي مؤقتا",
"optional.fields.next.button": "Next",
"optional.fields.next.button": "التالي",
"continue.to.platform": "المواصلة إلى {platformName}",
"modal.title": "شكرا لإعلامنا.",
"modal.description": "إن غيرت رأيك، قيمكنك إكمال ملفك الشخصي ضمن الإعدادات في أي وقت.",
"welcome.page.error.heading": "لم نتمكن من تحديث ملفك الشخصي",
"welcome.page.error.message": "حدث خطأ ما. يمكنك إكمال ملفك الشخصي ضمن الإعدادات في أي وقت.",
"recommendation.page.title": "Recommendations| {siteName}",
"recommendation.page.heading": "We have a few recommendations to get you started.",
"recommendation.skip.button": "Skip for now",
"recommendation.page.title": "التوصيات | {siteName}",
"recommendation.page.heading": "لدينا بعض التوصيات لكي تبدأ.",
"recommendation.skip.button": "التخطي مؤقتا",
"register.page.title": "التسجيل | {siteName}",
"registration.fullname.label": "الاسم الكامل",
"registration.email.label": "البريد الإلكتروني",
@@ -139,51 +123,34 @@
"help.text.username.2": "لا يمكن تغيير هذا لاحقًا.",
"help.text.email": "لتفعيل الحساب و التحديثات الهامة",
"create.account.for.free.button": "إنشاء حساب مجانا",
"create.an.account.btn.pending.state": "التحميل جارٍ",
"registration.other.options.heading": "أو سجل باستخدام:",
"register.institution.login.button": "بيانات المؤسسة / الجامعة",
"register.institution.login.page.title": "التسجيل باستخدام بيانات المؤسسة / الجامعة",
"empty.name.field.error": "أدخل اسمك الكامل",
"empty.email.field.error": "أدخل بريدك الإلكتروني",
"email.do.not.match": "عناوين البريد الإلكتروني غير متطابقة.",
"empty.username.field.error": "يجب أن يتكون اسم المستخدم من 2 إلى 30 حرفًا",
"empty.password.field.error": "لم يتم استيفاء معايير كلمة المرور",
"empty.country.field.error": "حدد بلدك أو منطقة إقامتك",
"email.do.not.match": "عناوين البريد الإلكتروني غير متطابقة.",
"email.invalid.format.error": "أدخل بريدا إلكترونيا صحيحا",
"email.ratelimit.less.chars.validation.message": "يجب أن يتكون البريد الإلكتروني من 3 أحرف على الأقل.",
"username.validation.message": "يجب أن يتكون اسم المستخدم من 2 إلى 30 حرفًا",
"name.validation.message": "أدخل اسمًا صحيحا",
"username.format.validation.message": "يمكن أن تحتوي أسماء المستخدمين فقط على أحرف (A-Z، a-z)، و أرقام (0-9)، و أسطر سفلية (_)، و واصلات (-). لا يمكن أن تحتوي أسماء المستخدمين على مسافات",
"support.education.research": "دعم الأبحاث التربوية من خلال توفير معلومات إضافية. (اختياري)",
"registration.request.failure.header": "لم نتمكّن من إنشاء حسابك.",
"registration.empty.form.submission.error": "رجاءً تحقّق من أجوبتك و حاول مجددا.",
"registration.request.server.error": "حدث خطأ ما. جرب تحديث الصفحة أو تحقق من اتصالك بالإنترنت.",
"registration.rate.limit.error": "كثرت محاولات التسجيل الفاشلة. أعد المحاولة لاحقًا.",
"registration.tpa.session.expired": "نفد وقت التسجيل باستخدام {provider}.",
"registration.tpa.authentication.failure": "عذرًا، غير مصرح لك بالوصول إلى {platform_name} عبر هذه القناة. يرجى الاتصال بمسؤول التعلم أو المدير من أجل الوصول إلى {platform_name}. {lineBreak} {lineBreak} تفاصيل الخطأ: {lineBreak} {errorMessage}",
"terms.of.service.and.honor.code": "شروط الخدمة وميثاق الشرف الأكاديمي",
"privacy.policy": "سياسة الخصوصية",
"honor.code": "ميثاق الشرف الأكاديمي",
"terms.of.service": "شروط الخدمة",
"registration.year.of.birth.label": "سنة الميلاد (اختياري)",
"registration.field.gender.options.label": "الجنس (اختياري)",
"registration.goals.label": "أخبرنا عن سبب اهتمامك بـ edX (اختياري)",
"registration.field.gender.options.f": "أنثى",
"registration.field.gender.options.m": "ذكر",
"registration.field.gender.options.o": "آخر / أفضل عدم التصريح",
"registration.field.education.levels.label": "أعلى مستوى تعليمي مكتمل (اختياري)",
"registration.field.education.levels.p": "دكتوراه",
"registration.field.education.levels.m": "ماجستير / ماستر أو شهادة مهنيّة",
"registration.field.education.levels.b": "بكالوريوس / ليسانس",
"registration.field.education.levels.a": "درجة الزمالة / دبلوم الدراسات الجامعية",
"registration.field.education.levels.hs": "الثانوية العامة / البكالوريا",
"registration.field.education.levels.jhs": "المدرسة الإعدادية / المتوسطة",
"registration.field.education.levels.el": "المدرسة الابتدائية / الأساسية",
"registration.field.education.levels.none": "دون تعليم رسمي",
"registration.field.education.levels.other": "نوع آخر من التعليم",
"registration.username.suggestion.label": "مقترح:",
"registration.using.tpa.form.heading": "إتمام إنشاء حسابك",
"did.you.mean.alert.text": "هل تقصد",
"register.page.terms.of.service": "أوافق على {termsOfService} الخاصة بـ{platformName} ",
"register.page.terms.of.service.and.honor.code": "بإنشاءك حسابًا، فإنك توافق على {tosAndHonorCode} و تقر بأن {platformName} و كل عضو يعالج بياناتك الشخصية وفقًا لـ{privacyPolicy}.",
"register.page.honor.code": "اوافق على شروط {platformName} {tosAndHonorCode}",
"register.page.terms.of.service": "اوافق على {platformName} {termsOfService}",
"sign.in": "تسجيل الدخول",
"reset.password.page.title": "إعادة ضبط كلمة المرور | {siteName}",
"reset.password": "إعادة ضبط كلمة المرور",
@@ -192,40 +159,10 @@
"confirm.password.label": "تأكيد كلمة المرور",
"passwords.do.not.match": "كلمتا المرور غير متطابقتين",
"confirm.your.password": "تأكيد كلمة مرورك",
"forgot.password.confirmation.sign.in.link": "تسجيل الدخول",
"reset.password.request.forgot.password.text": "نسيت كلمة المرور",
"reset.password.request.invalid.token.header": "رابط إعادة ضبط كلمة المرور غير صالح",
"reset.password.empty.new.password.field.error": "رجاءً أدخل كلمة مرورك الجديدة.",
"reset.password.failure.heading": "لم نتمكن من إعادة ضبط كلمة مرورك.",
"reset.password.form.submission.error": "رجاءً تحقق من أجوبتك وحاول مجددًا.",
"reset.password.request.server.error": "فشلت إعادة ضبط كلمة المرور",
"reset.password.token.validation.sever.error": "فشل التحقق من صحة الشارة",
"reset.server.rate.limit.error": "طلبات أكثر مما ينبغي.",
"reset.password.success.heading": "تمت إعادة ضبط كلمة المرور.",
"reset.password.success": "تمت إعادة ضبط كلمة مرورك. سجل الدخول إلى حسابك.",
"progressive.profiling.page.title": "الحقول الاختيارية | {siteName}",
"progressive.profiling.page.heading": "بعض الأسئلة الموجهة لك ستساعدنا كي نزداد ذكاءً.",
"gender.options.label": "الجنس (اختياري)",
"gender.options.f": "أنثى",
"gender.options.m": "ذكر",
"gender.options.o": "آخر / أفضل عدم التصريح",
"education.levels.label": "أعلى مستوى تعليمي مكتمل (اختياري)",
"education.levels.p": "دكتوراه",
"education.levels.m": "ماجستير / ماستر أو شهادة مهنيّة",
"education.levels.b": "بكالوريوس / ليسانس",
"education.levels.a": "درجة الزمالة / دبلوم الدراسات الجامعية",
"education.levels.hs": "الثانوية العامة / البكالوريا",
"education.levels.jhs": "المدرسة الإعدادية / المتوسطة",
"education.levels.el": "المدرسة الابتدائية / الأساسية",
"education.levels.none": "دون تعليم رسمي",
"education.levels.other": "نوع آخر من التعليم",
"year.of.birth.label": "سنة الميلاد (اختياري)",
"optional.fields.information.link": "معرفة المزيد عن كيفية استخدامنا لهذه المعلومات.",
"optional.fields.submit.button": "إرسال",
"optional.fields.skip.button": "التخطي مؤقتا",
"continue.to.platform": "المواصلة إلى {platformName}",
"modal.title": "شكرا لإعلامنا.",
"modal.description": "إن غيرت رأيك، قيمكنك إكمال ملفك الشخصي ضمن الإعدادات في أي وقت.",
"welcome.page.error.heading": "لم نتمكن من تحديث ملفك الشخصي",
"welcome.page.error.message": "حدث خطأ ما. يمكنك إكمال ملفك الشخصي ضمن الإعدادات في أي وقت."
"rate.limit.error": "حدث خطأ بسبب كثرة الطلبات. رجاءً حاول مرة أخرى بعد مضي بعض الوقت."
}

168
src/i18n/messages/de.json Normal file
View File

@@ -0,0 +1,168 @@
{
"start.learning": "Start learning",
"with.site.name": "with {siteName}",
"complete.your.profile.1": "Complete",
"complete.your.profile.2": "your profile",
"welcome.to.platform": "Welcome to {siteName}, {username}!",
"institution.login.page.sub.heading": "Choose your institution from the list below",
"logistration.sign.in": "Sign in",
"logistration.register": "Register",
"enterprisetpa.title.heading": "Would you like to sign in using your {providerName} credentials?",
"enterprisetpa.login.button.text": "Show me other ways to sign in or register",
"enterprisetpa.login.button.text.public.account.creation.disabled": "Show me other ways to sign in",
"sso.sign.in.with": "Sign in with {providerName}",
"sso.create.account.using": "Create account using {providerName}",
"show.password": "Show password",
"hide.password": "Hide password",
"one.letter": "1 letter",
"one.number": "1 number",
"eight.characters": "8 characters",
"password.sr.only.helping.text": "Password must contain at least 8 characters, at least one letter, and at least one number",
"tpa.alert.heading": "Almost done!",
"login.third.party.auth.account.not.linked": "You have successfully signed into {currentProvider}, but your {currentProvider} account does not have a linked {platformName} account. To link your accounts, sign in now using your {platformName} password.",
"register.third.party.auth.account.not.linked": "You've successfully signed into {currentProvider}! We just need a little more information before you start learning with {platformName}.",
"registration.using.tpa.form.heading": "Finish creating your account",
"zendesk.supportTitle": "edX Support",
"zendesk.selectTicketForm": "Please choose your request type:",
"error.notfound.message": "The page you're looking for is unavailable or there's an error in the URL. Please check the URL and try again.",
"forgot.password.confirmation.message": "We sent an email to {email} with instructions to reset your password.\n If you do not receive a password reset message after 1 minute, verify that you entered\n the correct email address, or check your spam folder. If you need further assistance, {supportLink}.",
"forgot.password.page.title": "Forgot Password | {siteName}",
"forgot.password.page.heading": "Reset password",
"forgot.password.page.instructions": "Please enter your email address below and we will send you an email with instructions on how to reset your password.",
"forgot.password.page.invalid.email.message": "Enter a valid email address",
"forgot.password.page.email.field.label": "Email",
"forgot.password.page.submit.button": "Submit",
"forgot.password.error.alert.title.": "We were unable to contact you.",
"forgot.password.error.message.title": "An error occurred.",
"forgot.password.request.in.progress.message": "Your previous request is in progress, please try again in a few moments.",
"forgot.password.empty.email.field.error": "Enter your email",
"forgot.password.email.help.text": "The email address you used to register with {platformName}",
"confirmation.message.title": "Check your email",
"confirmation.support.link": "contact technical support",
"need.help.sign.in.text": "Need help signing in?",
"additional.help.text": "For additional help, contact {platformName} support at ",
"sign.in.text": "Sign in",
"extend.field.errors": "{emailError} below.",
"invalid.token.heading": "Invalid password reset link",
"invalid.token.error.message": "This password reset link is invalid. It may have been used already. Enter your email below to receive a new link.",
"token.validation.rate.limit.error.heading": "Too many requests",
"token.validation.rate.limit.error": "An error has occurred because of too many requests. Please try again after some time.",
"token.validation.internal.sever.error.heading": "Token validation failure",
"token.validation.internal.sever.error": "An error has occurred. Try refreshing the page, or check your internet connection.",
"internal.server.error": "An error has occurred. Try refreshing the page, or check your internet connection.",
"account.activation.error.message": "Something went wrong, please {supportLink} to resolve this issue.",
"login.inactive.user.error": "In order to sign in, you need to activate your account.{lineBreak}\n {lineBreak}We just sent an activation link to {email}. If you do not receive an email,\n check your spam folders or {supportLink}.",
"allowed.domain.login.error": "As {allowedDomain} user, You must login with your {allowedDomain} {tpaLink}.",
"login.incorrect.credentials.error.attempts.text.1": "The username, email or password you entered is incorrect. You have {remainingAttempts} more sign in\n attempts before your account is temporarily locked.",
"login.incorrect.credentials.error.attempts.text.2": "If you've forgotten your password, {resetLink}",
"account.locked.out.message.2": "To be on the safe side, you can {resetLink} before trying again.",
"login.incorrect.credentials.error.with.reset.link": "The username, email, or password you entered is incorrect. Please try again or {resetLink}.",
"login.page.title": "Login | {siteName}",
"login.user.identity.label": "Username or email",
"login.password.label": "Password",
"sign.in.button": "Sign in",
"forgot.password": "Forgot password",
"institution.login.button": "Institution/campus credentials",
"institution.login.page.title": "Sign in with institution/campus credentials",
"login.other.options.heading": "Or sign in with:",
"non.compliant.password.title": "We recently changed our password requirements",
"non.compliant.password.message": "Your current password does not meet the new security requirements. We just sent a password-reset message to the email address associated with this account. Thank you for helping us keep your data safe.",
"account.locked.out.message.1": "To protect your account, it's been temporarily locked. Try again in 30 minutes.",
"enterprise.login.btn.text": "Company or school credentials",
"username.or.email.format.validation.less.chars.message": "Username or email must have at least 3 characters.",
"email.validation.message": "Enter your username or email",
"password.validation.message": "Password criteria has not been met",
"account.activation.success.message.title": "Success! You have activated your account.",
"account.activation.success.message": "You will now receive email updates and alerts from us related to the courses you are enrolled in. Sign in to continue.",
"account.activation.info.message": "This account has already been activated.",
"account.activation.error.message.title": "Your account could not be activated",
"account.activation.support.link": "contact support",
"account.confirmation.success.message.title": "Success! You have confirmed your email.",
"account.confirmation.success.message": "Sign in to continue.",
"account.confirmation.info.message": "This email has already been confirmed.",
"account.confirmation.error.message.title": "Your email could not be confirmed",
"tpa.account.link": "{provider} account",
"internal.server.error.message": "An error has occurred. Try refreshing the page, or check your internet connection.",
"login.rate.limit.reached.message": "Too many failed login attempts. Try again later.",
"login.failure.header.title": "We couldn't sign you in.",
"contact.support.link": "contact {platformName} support",
"login.incorrect.credentials.error": "The username, email, or password you entered is incorrect. Please try again.",
"login.form.invalid.error.message": "Please fill in the fields below.",
"login.incorrect.credentials.error.reset.link.text": "reset your password",
"login.incorrect.credentials.error.before.account.blocked.text": "click here to reset it.",
"password.security.nudge.title": "Password security",
"password.security.block.title": "Password change required",
"password.security.nudge.body": "Our system detected that your password is vulnerable. We recommend you change it so that your account stays secure.",
"password.security.block.body": "Our system detected that your password is vulnerable. Change your password so that your account stays secure.",
"password.security.close.button": "Close",
"password.security.redirect.to.reset.password.button": "Reset your password",
"login.tpa.authentication.failure": "We are sorry, you are not authorized to access {platform_name} via this channel. Please contact your learning administrator or manager in order to access {platform_name}.{lineBreak}{lineBreak}Error Details:{lineBreak}{errorMessage}",
"progressive.profiling.page.title": "Welcome | {siteName}",
"progressive.profiling.page.heading": "A few questions for you will help us get smarter.",
"optional.fields.information.link": "Learn more about how we use this information.",
"optional.fields.submit.button": "Submit",
"optional.fields.skip.button": "Skip for now",
"optional.fields.next.button": "Next",
"continue.to.platform": "Continue to {platformName}",
"modal.title": "Thanks for letting us know.",
"modal.description": "You can complete your profile in settings at any time if you change your mind.",
"welcome.page.error.heading": "We couldn't update your profile",
"welcome.page.error.message": "An error occurred. You can complete your profile in settings at any time.",
"recommendation.page.title": "Recommendations | {siteName}",
"recommendation.page.heading": "We have a few recommendations to get you started.",
"recommendation.skip.button": "Skip for now",
"register.page.title": "Register | {siteName}",
"registration.fullname.label": "Full name",
"registration.email.label": "Email",
"registration.username.label": "Public username",
"registration.password.label": "Password",
"registration.country.label": "Country/Region",
"registration.opt.in.label": "I agree that {siteName} may send me marketing messages.",
"help.text.name": "This name will be used by any certificates that you earn.",
"help.text.username.1": "The name that will identify you in your courses.",
"help.text.username.2": "This can not be changed later.",
"help.text.email": "For account activation and important updates",
"create.account.for.free.button": "Create an account for free",
"registration.other.options.heading": "Or register with:",
"register.institution.login.button": "Institution/campus credentials",
"register.institution.login.page.title": "Register with institution/campus credentials",
"empty.name.field.error": "Enter your full name",
"empty.email.field.error": "Enter your email",
"empty.username.field.error": "Username must be between 2 and 30 characters",
"empty.password.field.error": "Password criteria has not been met",
"empty.country.field.error": "Select your country or region of residence",
"email.do.not.match": "The email addresses do not match.",
"email.invalid.format.error": "Enter a valid email address",
"username.validation.message": "Username must be between 2 and 30 characters",
"name.validation.message": "Enter a valid name",
"username.format.validation.message": "Usernames can only contain letters (A-Z, a-z), numerals (0-9), underscores (_), and hyphens (-). Usernames cannot contain spaces",
"registration.request.failure.header": "We couldn't create your account.",
"registration.empty.form.submission.error": "Please check your responses and try again.",
"registration.request.server.error": "An error has occurred. Try refreshing the page, or check your internet connection.",
"registration.rate.limit.error": "Too many failed registration attempts. Try again later.",
"registration.tpa.session.expired": "Registration using {provider} has timed out.",
"registration.tpa.authentication.failure": "We are sorry, you are not authorized to access {platform_name} via this channel. Please contact your learning administrator or manager in order to access {platform_name}.{lineBreak}{lineBreak}Error Details:{lineBreak}{errorMessage}",
"terms.of.service.and.honor.code": "Terms of Service and Honor Code",
"privacy.policy": "Privacy Policy",
"honor.code": "Honor Code",
"terms.of.service": "Terms of Service",
"registration.username.suggestion.label": "Suggested:",
"did.you.mean.alert.text": "Did you mean",
"register.page.terms.of.service.and.honor.code": "By creating an account, you agree to the {tosAndHonorCode} and you acknowledge that {platformName} and each\n Member process your personal data in accordance with the {privacyPolicy}.",
"register.page.honor.code": "I agree to the {platformName} {tosAndHonorCode}",
"register.page.terms.of.service": "I agree to the {platformName} {termsOfService}",
"sign.in": "Sign in",
"reset.password.page.title": "Reset Password | {siteName}",
"reset.password": "Reset password",
"reset.password.page.instructions": "Enter and confirm your new password.",
"new.password.label": "New password",
"confirm.password.label": "Confirm password",
"passwords.do.not.match": "Passwords do not match",
"confirm.your.password": "Confirm your password",
"reset.password.failure.heading": "We couldn't reset your password.",
"reset.password.form.submission.error": "Please check your responses and try again.",
"reset.server.rate.limit.error": "Too many requests.",
"reset.password.success.heading": "Password reset complete.",
"reset.password.success": "Your password has been reset. Sign in to your account.",
"rate.limit.error": "An error has occurred because of too many requests. Please try again after some time."
}

View File

@@ -9,6 +9,7 @@
"logistration.register": "Registrieren",
"enterprisetpa.title.heading": "Möchten Sie sich mit Ihren {providerName}-Anmeldedaten anmelden?",
"enterprisetpa.login.button.text": "Andere Möglichkeiten für die Anmeldung oder Registrierung",
"enterprisetpa.login.button.text.public.account.creation.disabled": "Show me other ways to sign in",
"sso.sign.in.with": "Melden Sie sich mit {providerName} an",
"sso.create.account.using": "Erstellen Sie ein Konto mit {providerName}",
"show.password": "Passwort anzeigen",
@@ -21,6 +22,8 @@
"login.third.party.auth.account.not.linked": "Sie haben sich erfolgreich bei {currentProvider} angemeldet, aber Ihr {currentProvider}-Konto hat kein verknüpftes {platformName}-Konto. Um Ihre Konten zu verknüpfen, melden Sie sich jetzt mit Ihrem {platformName}-Passwort an.",
"register.third.party.auth.account.not.linked": "Sie haben sich erfolgreich bei {currentProvider} angemeldet! Wir brauchen nur ein paar mehr Informationen, bevor Sie anfangen, mit {platformName} zu lernen.",
"registration.using.tpa.form.heading": "Beenden Sie die Erstellung Ihres Kontos",
"zendesk.supportTitle": "edX Support",
"zendesk.selectTicketForm": "Please choose your request type:",
"error.notfound.message": "Die gesuchte Seite ist nicht verfügbar oder es liegt ein Fehler in der URL vor. Bitte überprüfen Sie die URL und versuchen Sie es erneut.",
"forgot.password.confirmation.message": "Wir haben eine E-Mail mit Anweisungen zum Zurücksetzen Ihres Passworts an {email} gesendet. Wenn Sie nach 1 Minute keine Nachricht zum Zurücksetzen des Passworts erhalten, überprüfen Sie, ob Sie die richtige E-Mail-Adresse eingegeben haben, oder überprüfen Sie Ihren Spam-Ordner. Wenn Sie weitere Hilfe benötigen, {supportLink}.",
"forgot.password.page.title": "Passwort vergessen | {siteName}",
@@ -93,20 +96,21 @@
"password.security.block.body": "Unser System hat festgestellt, dass Ihr Passwort angreifbar ist. Ändern Sie Ihr Passwort, damit Ihr Konto sicher bleibt.",
"password.security.close.button": "Schließen",
"password.security.redirect.to.reset.password.button": "Setzen Sie Ihr Passwort zurück",
"progressive.profiling.page.title": "Optionale Felder | {siteName}",
"login.tpa.authentication.failure": "We are sorry, you are not authorized to access {platform_name} via this channel. Please contact your learning administrator or manager in order to access {platform_name}.{lineBreak}{lineBreak}Error Details:{lineBreak}{errorMessage}",
"progressive.profiling.page.title": "Welcome | {siteName}",
"progressive.profiling.page.heading": "Ein paar Fragen an Sie helfen uns, schlauer zu werden.",
"optional.fields.information.link": "Erfahren Sie mehr darüber, wie wir diese Informationen verwenden.",
"optional.fields.submit.button": "Einreichen",
"optional.fields.skip.button": "Überspringen",
"optional.fields.next.button": "Next",
"optional.fields.next.button": "Weiter",
"continue.to.platform": "Weiter zu {platformName}",
"modal.title": "Danke, dass Sie uns das mitteilen.",
"modal.description": "Sie können Ihr Profil jederzeit in den Einstellungen vervollständigen, wenn Sie Ihre Meinung ändern.",
"welcome.page.error.heading": "Wir konnten Ihr Profil nicht aktualisieren",
"welcome.page.error.message": "Ein Fehler ist aufgetreten. Sie können Ihr Profil jederzeit in den Einstellungen vervollständigen.",
"recommendation.page.title": "Recommendations| {siteName}",
"recommendation.page.heading": "We have a few recommendations to get you started.",
"recommendation.skip.button": "Skip for now",
"recommendation.page.title": "Empfehlungen | {siteName}",
"recommendation.page.heading": "Wir haben ein paar Empfehlungen für den Einstieg.",
"recommendation.skip.button": "Überspringen",
"register.page.title": "Registrieren | {siteName}",
"registration.fullname.label": "Vollständiger Name",
"registration.email.label": "E-Mail-Adresse",
@@ -137,6 +141,7 @@
"registration.request.server.error": "Ein Fehler ist aufgetreten. Versuchen Sie, die Seite zu aktualisieren, oder überprüfen Sie Ihre Internetverbindung.",
"registration.rate.limit.error": "Zu viele fehlgeschlagene Registrierungsversuche. Versuchen Sie es später noch einmal.",
"registration.tpa.session.expired": "Die Registrierung mit {provider} ist abgelaufen.",
"registration.tpa.authentication.failure": "We are sorry, you are not authorized to access {platform_name} via this channel. Please contact your learning administrator or manager in order to access {platform_name}.{lineBreak}{lineBreak}Error Details:{lineBreak}{errorMessage}",
"terms.of.service.and.honor.code": "Nutzungsbedingungen und Verhaltenskodex",
"privacy.policy": "Datenschutzbestimmungen",
"honor.code": "Verhaltenskodex",

View File

@@ -5,16 +5,11 @@
"complete.your.profile.2": "tu perfil ",
"welcome.to.platform": "¡Bienvenido a {siteName}, {username}!",
"institution.login.page.sub.heading": "Selecciona tu institución de la lista siguiente",
"forgot.password.confirmation.title": "Verifica tu correo electrónico",
"forgot.password.confirmation.support.link": "contacta con el equipo de soporte técnico",
"forgot.password.confirmation.info": "Si no recibes un mensaje de recuperación de tu contraseña en un minuto, verifica que introduciste la dirección de correo electrónico correcta, o verifica tu carpeta de correo no deseado.",
"logistration.sign.in": "Iniciar sesión",
"logistration.register": "Registrarse",
"internal.server.error.message": "Se ha producido un error. Intenta actualizar la página o comprueba tu conexión a Internet.",
"server.ratelimit.error.message": "Se ha producido un error debido a demasiadas solicitudes. Por favor, inténtalo de nuevo después de algún tiempo.",
"enterprisetpa.title.heading": "¿Deseas iniciar sesión con tus credenciales de {providerName}?",
"enterprisetpa.sso.button.title": "Inicio de sesión con {providerName}",
"enterprisetpa.login.button.text": "Mostrar otras formas de iniciar sesión o de registrarme",
"enterprisetpa.login.button.text.public.account.creation.disabled": "Show me other ways to sign in",
"sso.sign.in.with": "Inicio de sesión con {providerName}",
"sso.create.account.using": "Crear una cuenta con {providerName}",
"show.password": "Mostrar contraseña",
@@ -26,6 +21,9 @@
"tpa.alert.heading": "¡Ya casi has terminado!",
"login.third.party.auth.account.not.linked": "Te has registrado correctamente en {currentProvider}, pero tu cuenta de {currentProvider} no tiene una cuenta de {platformName} asociada. Para asociar tus cuentas, inicia sesión ahora usando tu contraseña de {platformName}.",
"register.third.party.auth.account.not.linked": "¡Has iniciado sesión con éxito en {currentProvider}! Sólo necesitamos un poco más de información antes de que empieces a aprender con {platformName}.",
"registration.using.tpa.form.heading": "Termina de crear tu cuenta",
"zendesk.supportTitle": "edX Support",
"zendesk.selectTicketForm": "Please choose your request type:",
"error.notfound.message": "La página que estas buscando no está disponible o hay un error en la URL. Por favor, verifica la URL y vuelve a intentarlo.",
"forgot.password.confirmation.message": "Hemos enviado un correo electrónico a {email} con instrucciones para restablecer tu contraseña.\n Si no recibes un mensaje de restablecimiento de contraseña después de 1 minuto, verifica que has introducido\n la dirección de correo electrónico correcta, o comprueba tu carpeta de correo no deseado. Si necesitas más ayuda, {supportLink}.",
"forgot.password.page.title": "Olvidé la contraseña | {siteName}",
@@ -38,7 +36,6 @@
"forgot.password.error.message.title": "Ha ocurrido un error.",
"forgot.password.request.in.progress.message": "Su solicitud anterior está en progreso, por favor inténtalo de nuevo en unos minutos.",
"forgot.password.empty.email.field.error": "Introduce tu email",
"forgot.password.invalid.email.message": "La dirección de correo que has ingresado no está en el formato correcto.",
"forgot.password.email.help.text": "El correo electrónico que utilizaste para registrarte en {platformName}",
"confirmation.message.title": "Verifica tu correo electrónico",
"confirmation.support.link": "entra en contacto con el equipo de soporte técnico",
@@ -53,7 +50,6 @@
"token.validation.internal.sever.error.heading": "Fallo de validación del token",
"token.validation.internal.sever.error": "Se ha producido un error. Intenta actualizar la página o verifica tu conexión a Internet.",
"internal.server.error": "Se ha producido un error. Intenta actualizar la página o verifica tu conexión a Internet.",
"rate.limit.error": "Se ha producido un error debido a demasiadas solicitudes. Por favor, inténtalo de nuevo después de algún tiempo.",
"account.activation.error.message": "Algo no funcionó correctamente, por favor {supportLink} para resolver este problema.",
"login.inactive.user.error": "Para iniciar sesión, debes activar tu cuenta..{lineBreak}\n {lineBreak} Acabamos de enviar un enlace de activación a {email}. Si no recibes un correo electrónico,\n revisa tus carpetas de spam o {supportLink}.",
"allowed.domain.login.error": "Como usuario {allowedDomain}, debe iniciar sesión con su {allowedDomain} {tpaLink}.",
@@ -65,45 +61,32 @@
"login.user.identity.label": "Nombre de usuario o correo electrónico",
"login.password.label": "Contraseña",
"sign.in.button": "Iniciar sesión",
"sign.in.btn.pending.state": "Cargando",
"need.help.signing.in.collapsible.menu": "¿Necesitas ayuda para iniciar sesión?",
"forgot.password.link": "Olvidé mi contraseña",
"forgot.password": "Olvidé mi contraseña",
"other.sign.in.issues": "Otros problemas de inicio de sesión ",
"need.other.help.signing.in.collapsible.menu": "¿Necesitas más ayuda para iniciar sesión?",
"institution.login.button": "Credenciales de la institución/campus",
"institution.login.page.title": "Iniciar sesión con las credenciales de la institución/campus",
"institution.login.page.back.button": "Volver al inicio",
"create.an.account": "Crear una cuenta",
"login.other.options.heading": "O bien, inicia sesión con:",
"non.compliant.password.title": "Recientemente hemos cambiado los requisitos de las contraseñas",
"non.compliant.password.message": "Tu contraseña actual no cumple con los nuevos requisitos de seguridad. Acabamos de enviar un mensaje de restablecimiento de contraseña a la dirección de correo electrónico asociada a esta cuenta. Gracias por ayudarnos a mantener tus datos seguros.",
"account.locked.out.message.1": "Para proteger tu cuenta, se ha bloqueado temporalmente. Inténtalo de nuevo en 30 minutos.",
"first.time.here": "Primera vez aquí?",
"email.help.message": "La dirección de correo electrónico que usaste para registrarte en edX.",
"enterprise.login.btn.text": "Credenciales de la empresa o de la institución ",
"email.format.validation.message": "La dirección de correo que has ingresado no está en el formato correcto.",
"username.or.email.format.validation.less.chars.message": "El nombre de usuario o el correo electrónico deben tener al menos 3 caracteres.",
"email.validation.message": "Introduce tu nombre de usuario o correo electrónico",
"password.validation.message": "No se han cumplido los criterios de la contraseña",
"register.link": "Crear una cuenta",
"sign.in.heading": "Iniciar sesión",
"account.activation.success.message.title": "Ha sido un éxito. Has activado tu cuenta.",
"account.activation.success.message": "Ahora recibirás por correo electrónico actualizaciones y alertas relacionadas con los cursos en los que estás inscrito. Inicia sesión para continuar.",
"account.activation.info.message": "La cuenta ya ha sido activada.",
"account.activation.error.message.title": "Tu cuenta no ha podido ser activada",
"account.activation.support.link": "contacta al equipo de soporte de edX",
"tpa.account.link": "{provider} cuenta",
"account.confirmation.success.message.title": "¡Éxito! Has confirmado tu correo electrónico.",
"account.confirmation.success.message": "Inicia sesión para continuar.",
"account.confirmation.info.message": "Este correo electrónico ya ha sido confirmado.",
"account.confirmation.error.message.title": "Tu correo electrónico no pudo ser confirmado",
"tpa.account.link": "{provider} cuenta",
"internal.server.error.message": "Se ha producido un error. Intenta actualizar la página o comprueba tu conexión a Internet.",
"login.rate.limit.reached.message": "Demasiados intentos fallidos de inicio de sesión. Inténtelo de nuevo más tarde.",
"login.failure.header.title": "No se ha podido iniciar tu sesión.",
"contact.support.link": "entrar en contacto con el soporte de {platformName}",
"login.incorrect.credentials.error": "El nombre de usuario, el correo electrónico o la contraseña que has introducido son incorrectos. Por favor, inténtalo de nuevo.",
"login.failed.attempt.error": "Tienes {remainAttempts} más intentos de inicio de sesión antes de que tu cuenta se bloquee temporalmente.",
"login.locked.out.error.message": "Para proteger tu cuenta, se ha bloqueado temporalmente. Inténtalo de nuevo en {lockedOutPeriod} minutos.",
"login.form.invalid.error.message": "Por favor, complete los siguientes campos.",
"login.incorrect.credentials.error.reset.link.text": "restablecer la contraseña",
"login.incorrect.credentials.error.before.account.blocked.text": "Pulse aquí para restablecerla.",
@@ -113,20 +96,21 @@
"password.security.block.body": "Nuestro sistema detectó que su contraseña es vulnerable. Cambie su contraseña para que su cuenta permanezca segura.",
"password.security.close.button": "Cerrar",
"password.security.redirect.to.reset.password.button": "Restablece tu contraseña",
"progressive.profiling.page.title": "Campos opcionales | {siteName}",
"login.tpa.authentication.failure": "We are sorry, you are not authorized to access {platform_name} via this channel. Please contact your learning administrator or manager in order to access {platform_name}.{lineBreak}{lineBreak}Error Details:{lineBreak}{errorMessage}",
"progressive.profiling.page.title": "Welcome | {siteName}",
"progressive.profiling.page.heading": "Unas cuantas preguntas para ti nos ayudarán a mejorar.",
"optional.fields.information.link": "Aprende más sobre cómo usamos esta información.",
"optional.fields.submit.button": "Enviar",
"optional.fields.skip.button": "Saltar por ahora ",
"optional.fields.next.button": "Next",
"optional.fields.next.button": "Siguiente",
"continue.to.platform": "Continuar a {platformName}",
"modal.title": "Gracias por informarnos.",
"modal.description": "Puedes completar tu perfil en los ajustes en cualquier momento si cambias de opinión.",
"welcome.page.error.heading": "No hemos podido actualizar tu perfil",
"welcome.page.error.message": "Se ha producido un error. Puedes completar tu perfil en los ajustes en cualquier momento.",
"recommendation.page.title": "Recommendations| {siteName}",
"recommendation.page.heading": "We have a few recommendations to get you started.",
"recommendation.skip.button": "Skip for now",
"recommendation.page.title": "Recomendaciones | {siteName}",
"recommendation.page.heading": "Tenemos algunas recomendaciones para empezar.",
"recommendation.skip.button": "Saltar por ahora ",
"register.page.title": "Register | {siteName}",
"registration.fullname.label": "Nombre completo",
"registration.email.label": "Correo electrónico",
@@ -139,51 +123,34 @@
"help.text.username.2": "Esto no puede modificarse posteriormente.",
"help.text.email": "Para la activación de la cuenta y las actualizaciones importantes",
"create.account.for.free.button": "Crea una cuenta gratis",
"create.an.account.btn.pending.state": "Cargando",
"registration.other.options.heading": "O regístrese con:",
"register.institution.login.button": "Credenciales de la institución/campus",
"register.institution.login.page.title": "Registro con credenciales de la institución/campus",
"empty.name.field.error": "Introduce tu nombre completo",
"empty.email.field.error": "Introduce tu email",
"email.do.not.match": "Los correos electrónicos no son iguales.",
"empty.username.field.error": "El nombre de usuario debe tener entre 2 y 30 caracteres",
"empty.password.field.error": "No se han cumplido los criterios de la contraseña",
"empty.country.field.error": "Selecciona tu país o región de residencia",
"email.do.not.match": "Los correos electrónicos no son iguales.",
"email.invalid.format.error": "Introduce una dirección de correo electrónico válida",
"email.ratelimit.less.chars.validation.message": "El correo electrónico debe tener 3 caracteres.",
"username.validation.message": "El nombre de usuario debe tener entre 2 y 30 caracteres",
"name.validation.message": "Introduce un nombre válido",
"username.format.validation.message": "Los nombres de usuario solo pueden contener letras (A-Z, a-z), números (0-9), guiones bajos (_) y guiones (-). Los nombres de usuario no pueden contener espacios",
"support.education.research": "Apoya la investigación sobre educación proporcionando información adicional. (Opcional)",
"registration.request.failure.header": "No pudimos crear tu cuenta.",
"registration.empty.form.submission.error": "Por favor, verifica tus respuestas y vuelve a intentarlo.",
"registration.request.server.error": "Se ha producido un error. Intenta actualizar la página o comprueba tu conexión a Internet.",
"registration.rate.limit.error": "Demasiados intentos de registro fallidos. Vuelve a intentarlo más tarde.",
"registration.tpa.session.expired": "Inscripción usando {provider} ha expirado.",
"registration.tpa.authentication.failure": "We are sorry, you are not authorized to access {platform_name} via this channel. Please contact your learning administrator or manager in order to access {platform_name}.{lineBreak}{lineBreak}Error Details:{lineBreak}{errorMessage}",
"terms.of.service.and.honor.code": "Condiciones de servicio y código de honor",
"privacy.policy": "Política de privacidad ",
"honor.code": "Código de Honor",
"terms.of.service": "Términos de servicio",
"registration.year.of.birth.label": "Año de nacimiento (opcional)",
"registration.field.gender.options.label": "Género (opcional)",
"registration.goals.label": "Díganos por qué estás interesado en edX (opcional)",
"registration.field.gender.options.f": "Femenino ",
"registration.field.gender.options.m": "Masculino",
"registration.field.gender.options.o": "Otro/Prefiero no decir",
"registration.field.education.levels.label": "Nivel más alto de educación completado (opcional)",
"registration.field.education.levels.p": "Doctorado",
"registration.field.education.levels.m": "Maestría o magíster",
"registration.field.education.levels.b": "Pregrado o Licenciatura",
"registration.field.education.levels.a": "Grado técnico - tecnológico",
"registration.field.education.levels.hs": "Enseñanza secundaria",
"registration.field.education.levels.jhs": "Formación media",
"registration.field.education.levels.el": "Enseñanza primaria",
"registration.field.education.levels.none": "Ninguna educación formal",
"registration.field.education.levels.other": "Otra educación",
"registration.username.suggestion.label": "Se recomienda:",
"registration.using.tpa.form.heading": "Termina de crear tu cuenta",
"did.you.mean.alert.text": "¿Quieres decir",
"register.page.terms.of.service": "Acepto lo siguiente: {platformName} {termsOfService}",
"register.page.terms.of.service.and.honor.code": "Al crear una cuenta, aceptas el {tosAndHonorCode} y reconoces que {platformName} y cada\n Miembro procesa tus datos personales de acuerdo con la {privacyPolicy}.",
"register.page.honor.code": "Acepto las {platformName} {tosAndHonorCode}",
"register.page.terms.of.service": "Acepto las {platformName} {termsOfService}",
"sign.in": "Iniciar sesión",
"reset.password.page.title": "Restablecer contraseña | {siteName}",
"reset.password": "Restablecer mi contraseña",
@@ -192,40 +159,10 @@
"confirm.password.label": "Confirmar contraseña",
"passwords.do.not.match": "Las contraseñas no coinciden",
"confirm.your.password": "Confirma tu contraseña",
"forgot.password.confirmation.sign.in.link": "iniciar sesión",
"reset.password.request.forgot.password.text": "Olvidé mi contraseña",
"reset.password.request.invalid.token.header": "Enlace de restablecimiento de contraseña inválido",
"reset.password.empty.new.password.field.error": "Por favor, introduce tu nueva contraseña.",
"reset.password.failure.heading": "No hemos podido restablecer tu contraseña.",
"reset.password.form.submission.error": "Por favor, verifica tus respuestas y vuelve a intentarlo.",
"reset.password.request.server.error": "No se ha podido restablecer la contraseña",
"reset.password.token.validation.sever.error": "Fallo de validación del token",
"reset.server.rate.limit.error": "Demasiadas solicitudes.",
"reset.password.success.heading": "Restablecimiento de la contraseña completado.",
"reset.password.success": "Tu contraseña ha sido restablecida. Acceda a tu cuenta.",
"progressive.profiling.page.title": "Campos opcionales | {siteName}",
"progressive.profiling.page.heading": "Unas cuantas preguntas para ti nos ayudarán a mejorar.",
"gender.options.label": "Género (opcional)",
"gender.options.f": "Femenino ",
"gender.options.m": "Masculino",
"gender.options.o": "Otro/Prefiero no decir",
"education.levels.label": "Nivel más alto de educación completado (opcional)",
"education.levels.p": "Doctorado",
"education.levels.m": "Maestría o magíster",
"education.levels.b": "Pregrado o Licenciatura",
"education.levels.a": "Grado técnico - tecnológico",
"education.levels.hs": "Enseñanza secundaria",
"education.levels.jhs": "Formación media",
"education.levels.el": "Enseñanza primaria",
"education.levels.none": "Ninguna educación formal",
"education.levels.other": "Otra educación",
"year.of.birth.label": "Año de nacimiento (opcional)",
"optional.fields.information.link": "Aprende más sobre cómo usamos esta información.",
"optional.fields.submit.button": "Enviar",
"optional.fields.skip.button": "Saltar por ahora ",
"continue.to.platform": "Continuar a {platformName}",
"modal.title": "Gracias por informarnos.",
"modal.description": "Puedes completar tu perfil en los ajustes en cualquier momento si cambias de opinión.",
"welcome.page.error.heading": "No hemos podido actualizar tu perfil",
"welcome.page.error.message": "Se ha producido un error. Puedes completar tu perfil en los ajustes en cualquier momento."
"rate.limit.error": "Se ha producido un error debido a demasiadas solicitudes. Por favor, inténtalo de nuevo después de algún tiempo."
}

View File

@@ -5,16 +5,11 @@
"complete.your.profile.2": "votre profil",
"welcome.to.platform": "Bienvenue sur {siteName}, {username}!",
"institution.login.page.sub.heading": "Sélectionner votre institution dans la liste ci-dessous",
"forgot.password.confirmation.title": "Vérifiez votre email",
"forgot.password.confirmation.support.link": "contacter le support technique",
"forgot.password.confirmation.info": "Si vous ne recevez pas de message de réinitialisation de mot de passe après 1 minute, vérifiez que vous avez entré la bonne adresse courriel ou vérifiez votre dossier de pourriels.",
"logistration.sign.in": "Connectez-vous",
"logistration.register": "S'inscrire",
"internal.server.error.message": "Une erreur est survenue. Essayer de rafraîchir la page, ou vérifier votre connexion Internet.",
"server.ratelimit.error.message": "Une erreur s'est produite en raison d'un trop grand nombre de demandes. Veuillez réessayer après un certain temps.",
"enterprisetpa.title.heading": "Souhaitez-vous vous connecter à l'aide de vos identifiants {providerName} ?",
"enterprisetpa.sso.button.title": "Connectez-vous avec {providerName}",
"enterprisetpa.login.button.text": "Montrez-moi d'autres méthodes pour me connecter ou m'inscrire",
"enterprisetpa.login.button.text.public.account.creation.disabled": "Show me other ways to sign in",
"sso.sign.in.with": "Connectez-vous avec {providerName}",
"sso.create.account.using": "Créer un compte avec {providerName}",
"show.password": "Afficher le mot de passe",
@@ -26,6 +21,9 @@
"tpa.alert.heading": "Presque fini !",
"login.third.party.auth.account.not.linked": "Vous vous êtes connecté avec succès à {currentProvider}, mais votre compte {currentProvider} n'a pas de compte relié à {platformName}. Pour lier vos comptes, connectez-vous en utilisant votre mot de passe {platformName}.",
"register.third.party.auth.account.not.linked": "Vous vous êtes connecté avec succès à {currentProvider} ! Nous avons juste besoin d'un peu plus d'informations avant que vous commenciez à apprendre avec {platformName}.",
"registration.using.tpa.form.heading": "Terminer la création de votre compte",
"zendesk.supportTitle": "edX Support",
"zendesk.selectTicketForm": "Please choose your request type:",
"error.notfound.message": "La page que vous recherchez n'est pas disponible ou il y a une erreur dans l'URL. Veuillez vérifier l'URL et réessayer.",
"forgot.password.confirmation.message": "Nous avons envoyé un courriel à {email} avec des instructions pour réinitialiser votre mot de passe.\n Si vous ne recevez pas de message de réinitialisation de mot de passe après 1 minute, vérifiez que vous avez saisi\nl'adresse courriel correctement, ou vérifiez votre dossier de courriel indésirable. Si vous avez besoin d'aide supplémentaire, {supportLink}.",
"forgot.password.page.title": " Mot de passe oublié | {siteName}",
@@ -38,7 +36,6 @@
"forgot.password.error.message.title": "Une erreur est survenue.",
"forgot.password.request.in.progress.message": "Your previous request is in progress, please try again in a few moments.",
"forgot.password.empty.email.field.error": "Saisissez votre courriel",
"forgot.password.invalid.email.message": "L'adresse email que vous avez fournie est incorrecte.",
"forgot.password.email.help.text": "L'adresse courriel que vous avez utilisée pour vous inscrire sur {platformName}",
"confirmation.message.title": "Vérifiez votre email",
"confirmation.support.link": "contacter le support technique",
@@ -53,7 +50,6 @@
"token.validation.internal.sever.error.heading": "Échec de la validation du jeton",
"token.validation.internal.sever.error": "Une erreur est survenue. Essayer de rafraîchir la page, ou vérifier votre connexion Internet.",
"internal.server.error": "Une erreur est survenue. Essayer de rafraîchir la page, ou vérifier votre connexion Internet.",
"rate.limit.error": "Une erreur s'est produite en raison d'un trop grand nombre de demandes. Veuillez réessayer après un certain temps.",
"account.activation.error.message": "Une erreur s'est produite, veuillez {supportLink} pour résoudre ce problème.",
"login.inactive.user.error": "Pour vous connecter, vous devez activer votre compte.{lineBreak}\n {lineBreak}Nous venons d'envoyer un lien d'activation à {email}. Si vous ne recevez pas de courriel,\n vérifiez vos dossiers de spam ou {supportLink}.",
"allowed.domain.login.error": "As {allowedDomain} user, You must login with your {allowedDomain} {tpaLink}.",
@@ -65,45 +61,32 @@
"login.user.identity.label": "Nom d'utilisateur ou courriel",
"login.password.label": "Mot de passe",
"sign.in.button": "Connectez-vous",
"sign.in.btn.pending.state": "Chargement en cours",
"need.help.signing.in.collapsible.menu": "Besoin d'aide pour vous enregistrer?",
"forgot.password.link": "J'ai oublié mon mot de passe",
"forgot.password": "Mot de passe oublié",
"other.sign.in.issues": "Autres problèmes de connexion",
"need.other.help.signing.in.collapsible.menu": "Encore besoin d'aide pour vous enregistrer?",
"institution.login.button": "Identifiants de l'établissement/du campus",
"institution.login.page.title": "Connectez vous avec les crédentiels d'institution ou de campus",
"institution.login.page.back.button": "Retour à la connexion",
"create.an.account": "Créer un compte",
"login.other.options.heading": "Ou se connecter avec :",
"non.compliant.password.title": "Nous avons récemment modifié nos exigences en matière de mot de passe",
"non.compliant.password.message": "Votre mot de passe actuel ne répond pas aux nouvelles exigences de sécurité. Nous venons d'envoyer un message de réinitialisation de mot de passe à l'adresse courriel associée à ce compte. Merci de nous aider à protéger vos données.",
"account.locked.out.message.1": "Pour protéger votre compte, il a été temporairement verrouillé. Réessayez dans 30 minutes.",
"first.time.here": "C'est votre première visite ?",
"email.help.message": "L'adresse électronique que vous avez utilisée pour vous inscrire à edX.",
"enterprise.login.btn.text": "Identifiants de la compagnie ou de l'école",
"email.format.validation.message": "L'adresse email que vous avez fournie est incorrecte.",
"username.or.email.format.validation.less.chars.message": "Le nom d'utilisateur ou l'adresse courriel doit comporter au moins 3 caractères.",
"email.validation.message": "Entrez votre nom d'utilisateur ou votre adresse courriel",
"password.validation.message": "Les critères de mot de passe n'ont pas été remplis",
"register.link": "Créer un compte",
"sign.in.heading": "Connectez-vous",
"account.activation.success.message.title": "Succès! Vous avez activé votre compte.",
"account.activation.success.message": "Vous recevrez maintenant des mises à jour par courriel et des alertes de notre part concernant les cours auxquels vous êtes inscrit. Connectez-vous pour continuer.",
"account.activation.info.message": "Ce compte a déjà été activé.",
"account.activation.error.message.title": "Votre compte n'a pas pu être activé",
"account.activation.support.link": "contacter le support",
"tpa.account.link": "{provider} account",
"account.confirmation.success.message.title": "Succès ! Vous avez confirmé votre courriel.",
"account.confirmation.success.message": "Se connecter pour continuer.",
"account.confirmation.info.message": "Ce courriel a déjà été confirmé.",
"account.confirmation.error.message.title": "Votre courriel ne peut pas être confirmé.",
"tpa.account.link": "{provider} account",
"internal.server.error.message": "Une erreur est survenue. Essayer de rafraîchir la page, ou vérifier votre connexion Internet.",
"login.rate.limit.reached.message": "Trop de tentatives de connexion échouées. Réessayez plus tard.",
"login.failure.header.title": "Nous n'avons pas pu vous connecter.",
"contact.support.link": "veuillez contacter le support {platformName}",
"login.incorrect.credentials.error": "Le nom d'utilisateur, l'adresse courriel ou le mot de passe que vous avez saisis sont incorrects. Veuillez réessayer.",
"login.failed.attempt.error": "Il vous reste {remainingAttempts} tentatives de connexion supplémentaires avant que votre compte ne soit temporairement verrouillé.",
"login.locked.out.error.message": "Pour protéger votre compte, il a été temporairement verrouillé. Réessayez dans {lockedOutPeriod} minutes.",
"login.form.invalid.error.message": "Veuillez remplir les champs ci-dessous.",
"login.incorrect.credentials.error.reset.link.text": "réinitialiser votre mot de passe",
"login.incorrect.credentials.error.before.account.blocked.text": "cliquez ici pour le réinitialiser.",
@@ -113,7 +96,8 @@
"password.security.block.body": "Notre système a détecté que votre mot de passe est vulnérable. Changez votre mot de passe afin que votre compte reste sécurisé.",
"password.security.close.button": "Fermer",
"password.security.redirect.to.reset.password.button": "Réinitialiser votre mot de passe",
"progressive.profiling.page.title": "Champs optionnels | {siteName}",
"login.tpa.authentication.failure": "We are sorry, you are not authorized to access {platform_name} via this channel. Please contact your learning administrator or manager in order to access {platform_name}.{lineBreak}{lineBreak}Error Details:{lineBreak}{errorMessage}",
"progressive.profiling.page.title": "Welcome | {siteName}",
"progressive.profiling.page.heading": "Quelques questions pour vous nous aideront à devenir plus intelligents.",
"optional.fields.information.link": "En savoir plus sur la façon dont nous utilisons ces informations.",
"optional.fields.submit.button": "Envoyez",
@@ -124,7 +108,7 @@
"modal.description": "Vous pouvez compléter votre profil dans les paramètres à tout moment si vous changez d'avis.",
"welcome.page.error.heading": "Nous n'avons pas pu mettre à jour votre profil",
"welcome.page.error.message": "Une erreur s'est produite. Vous pouvez compléter votre profil dans les paramètres à tout moment.",
"recommendation.page.title": "Recommendations| {siteName}",
"recommendation.page.title": "Recommendations | {siteName}",
"recommendation.page.heading": "We have a few recommendations to get you started.",
"recommendation.skip.button": "Skip for now",
"register.page.title": "S'inscrire | {siteName}",
@@ -139,51 +123,34 @@
"help.text.username.2": "Cela ne peut pas être modifié ultérieurement.",
"help.text.email": "Pour l'activation du compte et les mises à jour importantes",
"create.account.for.free.button": "Créer un compte gratuitement",
"create.an.account.btn.pending.state": "Chargement en cours",
"registration.other.options.heading": "Ou inscrivez-vous avec :",
"register.institution.login.button": "Identifiants de l'établissement/du campus",
"register.institution.login.page.title": "Inscription avec les crédentiels d'institution ou de campus",
"empty.name.field.error": "Saisissez votre nom complet",
"empty.email.field.error": "Saisissez votre courriel",
"email.do.not.match": "The email addresses do not match.",
"empty.username.field.error": "Le nom d'utilisateur doit comporter entre 2 et 30 caractères",
"empty.password.field.error": "Les critères de mot de passe n'ont pas été remplis",
"empty.country.field.error": "Sélectionnez votre pays ou région de résidence",
"email.do.not.match": "The email addresses do not match.",
"email.invalid.format.error": "Enter a valid email address",
"email.ratelimit.less.chars.validation.message": "Le courriel doit comporter 3 caractères.",
"username.validation.message": "Le nom d'utilisateur doit comporter entre 2 et 30 caractères",
"name.validation.message": "Enter a valid name",
"username.format.validation.message": "Usernames can only contain letters (A-Z, a-z), numerals (0-9), underscores (_), and hyphens (-). Usernames cannot contain spaces",
"support.education.research": "Soutenez la recherche en éducation en fournissant des informations additionnelles. (Optionel)",
"registration.request.failure.header": "Nous n'avons pas pu créer votre compte.",
"registration.empty.form.submission.error": "Veuillez vérifier vos réponses et réessayer.",
"registration.request.server.error": "Une erreur est survenue. Essayer de rafraîchir la page, ou vérifier votre connexion Internet.",
"registration.rate.limit.error": "Trop de tentatives d'inscriptions ont échoué. Réessayez plus tard.",
"registration.tpa.session.expired": "L'inscription avec {provider} a échouée.",
"registration.tpa.authentication.failure": "We are sorry, you are not authorized to access {platform_name} via this channel. Please contact your learning administrator or manager in order to access {platform_name}.{lineBreak}{lineBreak}Error Details:{lineBreak}{errorMessage}",
"terms.of.service.and.honor.code": "Conditions d'utilisation et Code d'honneur",
"privacy.policy": "Politique de confidentialité",
"honor.code": "Code d'honneur",
"terms.of.service": " Conditions d'utilisation",
"registration.year.of.birth.label": "Année de naissance (facultatif)",
"registration.field.gender.options.label": "Sexe (facultatif)",
"registration.goals.label": "Dites-nous pourquoi vous êtes intéressé par edX (facultatif)",
"registration.field.gender.options.f": "Femme",
"registration.field.gender.options.m": "Homme",
"registration.field.gender.options.o": "Autre / Préfère ne pas répondre",
"registration.field.education.levels.label": "Plus haut niveau de scolarité atteint (facultatif)",
"registration.field.education.levels.p": "Doctorat",
"registration.field.education.levels.m": "Master ou diplôme professionnel",
"registration.field.education.levels.b": "Diplôme de premier cycle supérieur",
"registration.field.education.levels.a": "Grade de l'associé",
"registration.field.education.levels.hs": "Lycée / enseignement secondaire",
"registration.field.education.levels.jhs": "Collège / enseignement secondaire inférieur",
"registration.field.education.levels.el": "Enseignement primaire",
"registration.field.education.levels.none": "Sans diplôme",
"registration.field.education.levels.other": "Autre niveau d'étude",
"registration.username.suggestion.label": "Suggéré :",
"registration.using.tpa.form.heading": "Terminer la création de votre compte",
"did.you.mean.alert.text": "Vouliez-vous dire",
"register.page.terms.of.service": "J'accepte les {termsOfService} {platformName}",
"register.page.terms.of.service.and.honor.code": "En créant un compte, vous acceptez le {tosAndHonorCode} et vous reconnaissez que {platformName} et chaque\n membre peut traiter vos données personnelles conformément à la {privacyPolicy}.",
"register.page.honor.code": "I agree to the {platformName} {tosAndHonorCode}",
"register.page.terms.of.service": "I agree to the {platformName} {termsOfService}",
"sign.in": "Connectez-vous",
"reset.password.page.title": "Réinitialiser le mot de passe | {siteName}",
"reset.password": "Réinitialiser le mot de passe",
@@ -192,40 +159,10 @@
"confirm.password.label": "Confirmer le mot de passe",
"passwords.do.not.match": "Les mots de passe ne correspondent pas",
"confirm.your.password": "Confirmer votre mot de passe",
"forgot.password.confirmation.sign.in.link": "connexion",
"reset.password.request.forgot.password.text": "Mot de passe oublié",
"reset.password.request.invalid.token.header": "Lien de réinitialisation du mot de passe non valide",
"reset.password.empty.new.password.field.error": "Veuillez entrer votre nouveau mot de passe.",
"reset.password.failure.heading": "Nous n'avons pas pu réinitialiser votre mot de passe.",
"reset.password.form.submission.error": "Veuillez vérifier vos réponses et réessayer.",
"reset.password.request.server.error": "Échec de la réinitialisation du mot de passe",
"reset.password.token.validation.sever.error": "Échec de la validation du jeton",
"reset.server.rate.limit.error": "Trop de demandes.",
"reset.password.success.heading": "Réinitialisation du mot de passe complétée.",
"reset.password.success": "Votre mot de passe a été réinitialisé. Connectez-vous à votre compte.",
"progressive.profiling.page.title": "Champs optionnels | {siteName}",
"progressive.profiling.page.heading": "Quelques questions pour vous nous aideront à devenir plus intelligents.",
"gender.options.label": "Sexe (facultatif)",
"gender.options.f": "Femme",
"gender.options.m": "Homme",
"gender.options.o": "Autre / Préfère ne pas répondre",
"education.levels.label": "Plus haut niveau de scolarité atteint (facultatif)",
"education.levels.p": "Doctorat",
"education.levels.m": "Master ou diplôme professionnel",
"education.levels.b": "Diplôme de premier cycle supérieur",
"education.levels.a": "Grade de l'associé",
"education.levels.hs": "Lycée / enseignement secondaire",
"education.levels.jhs": "Collège / enseignement secondaire inférieur",
"education.levels.el": "Enseignement primaire",
"education.levels.none": "Sans diplôme",
"education.levels.other": "Autre niveau d'étude",
"year.of.birth.label": "Année de naissance (facultatif)",
"optional.fields.information.link": "En savoir plus sur la façon dont nous utilisons ces informations.",
"optional.fields.submit.button": "Envoyez",
"optional.fields.skip.button": "Ignorer pour l'instant",
"continue.to.platform": "Continuer vers {platformName}",
"modal.title": "Merci de nous en informer.",
"modal.description": "Vous pouvez compléter votre profil dans les paramètres à tout moment si vous changez d'avis.",
"welcome.page.error.heading": "Nous n'avons pas pu mettre à jour votre profil",
"welcome.page.error.message": "Une erreur s'est produite. Vous pouvez compléter votre profil dans les paramètres à tout moment."
"rate.limit.error": "Une erreur s'est produite en raison d'un trop grand nombre de demandes. Veuillez réessayer après un certain temps."
}

View File

@@ -0,0 +1,168 @@
{
"start.learning": "Démarrer l'apprentissage",
"with.site.name": "avec {siteName}",
"complete.your.profile.1": "Complet",
"complete.your.profile.2": "votre profil",
"welcome.to.platform": "Bienvenue sur {siteName}, {username}!",
"institution.login.page.sub.heading": "Sélectionner votre institution dans la liste ci-dessous",
"logistration.sign.in": "Connexion",
"logistration.register": "Inscription",
"enterprisetpa.title.heading": "Souhaitez-vous vous connecter à l'aide de vos identifiants {providerName}?",
"enterprisetpa.login.button.text": "Affichez moi d'autres façons de se connecter ou de s'inscrire",
"enterprisetpa.login.button.text.public.account.creation.disabled": "Montrez-moi d'autres façons de me connecter",
"sso.sign.in.with": "Connectez-vous avec {providerName}",
"sso.create.account.using": "Créer un compte avec {providerName}",
"show.password": "Afficher le mot de passe",
"hide.password": "Cacher le mot de passe",
"one.letter": "1 lettre",
"one.number": "1 numéro",
"eight.characters": "8 caractères",
"password.sr.only.helping.text": "Le mot de passe doit contenir au moins 8 caractères, au moins une lettre et au moins un chiffre",
"tpa.alert.heading": "Presque terminé!",
"login.third.party.auth.account.not.linked": "Vous vous êtes connecté avec succès à {currentProvider}, mais votre compte {currentProvider} n'a pas de compte relié à {platformName}. Pour lier vos comptes, connectez-vous en utilisant votre mot de passe {platformName}.",
"register.third.party.auth.account.not.linked": "Vous vous êtes connecté avec succès à {currentProvider}! Nous avons juste besoin d'un peu plus d'informations avant que vous commenciez à apprendre avec {platformName}.",
"registration.using.tpa.form.heading": "Terminer la création de votre compte",
"zendesk.supportTitle": "Prise en charge d&#39;edX",
"zendesk.selectTicketForm": "Veuillez choisir votre type de demande :",
"error.notfound.message": "La page que vous recherchez n'est pas disponible ou il y a une erreur dans l'URL. Veuillez vérifier l'URL et réessayer.",
"forgot.password.confirmation.message": "Nous avons envoyé un courriel à {email} avec des instructions pour réinitialiser votre mot de passe.\n Si vous ne recevez pas de message de réinitialisation de mot de passe après 1 minute, vérifiez que vous avez saisi\nl'adresse courriel correctement, ou vérifiez votre dossier de pourriels. Si vous avez besoin d'aide supplémentaire, {supportLink}.",
"forgot.password.page.title": "Mot de passe oublié | {siteName}",
"forgot.password.page.heading": "Réinitialiser le mot de passe",
"forgot.password.page.instructions": "Veuillez entrer votre adresse courriel ci-dessous et nous vous enverrons un courriel avec les instructions pour réinitialiser votre mot de passe.",
"forgot.password.page.invalid.email.message": "Entrez une adresse de courriel valide",
"forgot.password.page.email.field.label": "Courriel",
"forgot.password.page.submit.button": "Soumettre",
"forgot.password.error.alert.title.": "Nous n'avons pas pu vous contacter.",
"forgot.password.error.message.title": "Une erreur est survenue.",
"forgot.password.request.in.progress.message": "Votre demande précédente est en cours, veuillez réessayer dans quelques instants.",
"forgot.password.empty.email.field.error": "Saisissez votre courriel",
"forgot.password.email.help.text": "L'adresse courriel que vous avez utilisée pour vous inscrire sur {platformName}",
"confirmation.message.title": "Vérifiez votre courriel",
"confirmation.support.link": "contacter le support technique",
"need.help.sign.in.text": "Besoin d'aide pour vous connecter?",
"additional.help.text": "Pour obtenir une aide supplémentaire, contactez l'assistance {platformName} à l'adresse",
"sign.in.text": "Connexion",
"extend.field.errors": "{emailError} ci-dessous.",
"invalid.token.heading": "Lien de réinitialisation du mot de passe non valide",
"invalid.token.error.message": "Ce lien de réinitialisation de mot de passe n'est pas valide. Il a peut-être déjà été utilisé. Entrez votre courriel ci-dessous pour recevoir un nouveau lien.",
"token.validation.rate.limit.error.heading": "Trop de demandes",
"token.validation.rate.limit.error": "Une erreur s'est produite en raison d'un trop grand nombre de demandes. Veuillez réessayer après un certain temps.",
"token.validation.internal.sever.error.heading": "Échec de la validation du jeton",
"token.validation.internal.sever.error": "Une erreur est survenue. Essayer de rafraîchir la page, ou vérifier votre connexion Internet.",
"internal.server.error": "Une erreur est survenue. Essayer de rafraîchir la page, ou vérifier votre connexion Internet.",
"account.activation.error.message": "Une erreur s'est produite, veuillez {supportLink} pour résoudre ce problème.",
"login.inactive.user.error": "Pour vous connecter, vous devez activer votre compte.{lineBreak}\n {lineBreak}Nous venons d'envoyer un lien d'activation à {email}. Si vous ne recevez pas de courriel,\n vérifiez vos dossiers de pourriels ou {supportLink}.",
"allowed.domain.login.error": "En tant qu'utilisateur {allowedDomain}, vous devez vous connecter avec votre {allowedDomain} {tpaLink}.",
"login.incorrect.credentials.error.attempts.text.1": "Le nom d'utilisateur, le courriel ou le mot de passe que vous avez entré sont incorrects. Vous avez {remainingAttempts} tentatives\n de connexion avant que votre compte soit temporairement verrouillé.",
"login.incorrect.credentials.error.attempts.text.2": "Si vous avez oublié votre mot de passe, {resetLink}",
"account.locked.out.message.2": "Par mesure de sécurité, vous pouvez {resetLink} avant de réessayer.",
"login.incorrect.credentials.error.with.reset.link": "Le nom d'utilisateur, l'adresse courriel ou le mot de passe que vous avez saisis sont incorrects. Veuillez réessayer ou {resetLink}.",
"login.page.title": "Connexion | {siteName}",
"login.user.identity.label": "Nom d'utilisateur ou courriel",
"login.password.label": "Mot de passe",
"sign.in.button": "Connexion",
"forgot.password": "Mot de passe oublié",
"institution.login.button": "Identifiants de l'établissement/du campus",
"institution.login.page.title": "Connectez vous avec les crédentiels d'institution ou de campus",
"login.other.options.heading": "Ou se connecter avec :",
"non.compliant.password.title": "Nous avons récemment modifié nos exigences en matière de mot de passe",
"non.compliant.password.message": "Votre mot de passe actuel ne répond pas aux nouvelles exigences de sécurité. Nous venons d'envoyer un message de réinitialisation de mot de passe à l'adresse courriel associée à ce compte. Merci de nous aider à protéger vos données.",
"account.locked.out.message.1": "Pour protéger votre compte, il a été temporairement verrouillé. Réessayez dans 30 minutes.",
"enterprise.login.btn.text": "Identifiants de la compagnie ou de l'école",
"username.or.email.format.validation.less.chars.message": "Le nom d'utilisateur ou l'adresse courriel doit comporter au moins 3 caractères.",
"email.validation.message": "Entrez votre nom d'utilisateur ou votre adresse courriel",
"password.validation.message": "Les critères de mot de passe n'ont pas été remplis",
"account.activation.success.message.title": "Succès! Vous avez activé votre compte.",
"account.activation.success.message": "Vous recevrez maintenant des mises à jour par courriel et des alertes de notre part concernant les cours auxquels vous êtes inscrit. Connectez-vous pour continuer.",
"account.activation.info.message": "Ce compte a déjà été activé.",
"account.activation.error.message.title": "Votre compte n'a pas pu être activé",
"account.activation.support.link": "contacter le support",
"account.confirmation.success.message.title": "Bravo! Vous avez confirmé votre courriel.",
"account.confirmation.success.message": "Se connecter pour continuer.",
"account.confirmation.info.message": "Ce courriel a déjà été confirmé.",
"account.confirmation.error.message.title": "Votre courriel ne peut pas être confirmé",
"tpa.account.link": "compte {provider}",
"internal.server.error.message": "Une erreur est survenue. Essayer de rafraîchir la page, ou vérifier votre connexion Internet.",
"login.rate.limit.reached.message": "Trop de tentatives d'accès refusées. Essayer plus tard.",
"login.failure.header.title": "Nous n'avons pas pu vous connecter.",
"contact.support.link": "veuillez contacter le support {platformName}",
"login.incorrect.credentials.error": "Le nom d'utilisateur, l'adresse courriel ou le mot de passe que vous avez saisis sont incorrects. Veuillez réessayer.",
"login.form.invalid.error.message": "Veuillez remplir les champs ci-dessous.",
"login.incorrect.credentials.error.reset.link.text": "réinitialiser votre mot de passe",
"login.incorrect.credentials.error.before.account.blocked.text": "cliquez ici pour le réinitialiser.",
"password.security.nudge.title": "Sécurité du mot de passe",
"password.security.block.title": "Changement de mot de passe requis",
"password.security.nudge.body": "Notre système a détecté que votre mot de passe est vulnérable. Nous vous recommandons de le modifier afin que votre compte reste sécurisé.",
"password.security.block.body": "Notre système a détecté que votre mot de passe est vulnérable. Changez votre mot de passe afin que votre compte reste sécurisé.",
"password.security.close.button": "Fermer",
"password.security.redirect.to.reset.password.button": "Réinitialiser votre mot de passe",
"login.tpa.authentication.failure": "Nous sommes désolés, vous n'êtes pas autorisé à accéder à {platform_name} via ce canal. Veuillez contacter votre administrateur ou responsable de formation pour accéder à {platform_name}.{lineBreak}{lineBreak}Détails de l'erreur :{lineBreak}{errorMessage}",
"progressive.profiling.page.title": "Bienvenue | {siteName}",
"progressive.profiling.page.heading": "Quelques questions pour vous nous aideront à devenir plus intelligents.",
"optional.fields.information.link": "En savoir plus sur la façon dont nous utilisons ces informations.",
"optional.fields.submit.button": "Soumettre",
"optional.fields.skip.button": "Ignorer pour l'instant",
"optional.fields.next.button": "Suivant",
"continue.to.platform": "Continuer vers {platformName}",
"modal.title": "Merci de nous en informer.",
"modal.description": "Vous pouvez compléter votre profil dans les paramètres à tout moment si vous changez d'avis.",
"welcome.page.error.heading": "Nous n'avons pas pu mettre à jour votre profil",
"welcome.page.error.message": "Une erreur s'est produite. Vous pouvez compléter votre profil dans les paramètres à tout moment.",
"recommendation.page.title": "Recommandations | {siteName}",
"recommendation.page.heading": "Nous avons quelques recommandations pour vous aider à démarrer.",
"recommendation.skip.button": "Ignorer pour l'instant",
"register.page.title": "S'inscrire | {siteName}",
"registration.fullname.label": "Nom complet",
"registration.email.label": "Courriel",
"registration.username.label": "Nom d'utilisateur",
"registration.password.label": "Mot de passe",
"registration.country.label": "Pays/Région",
"registration.opt.in.label": "{siteName} peux m'envoyer des messages de marketing.",
"help.text.name": "Ce nom sera utilisé pour toutes les attestations que vous obtiendrez.",
"help.text.username.1": "Le nom qui vous identifiera dans vos cours.",
"help.text.username.2": "Cela ne peut pas être modifié ultérieurement.",
"help.text.email": "Pour l'activation du compte et les mises à jour importantes",
"create.account.for.free.button": "Créer un compte gratuitement",
"registration.other.options.heading": "Ou inscrivez-vous avec :",
"register.institution.login.button": "Identifiants de l'établissement/du campus",
"register.institution.login.page.title": "Inscription avec les crédentiels d'institution ou de campus",
"empty.name.field.error": "Saisissez votre nom complet",
"empty.email.field.error": "Saisissez votre courriel",
"empty.username.field.error": "Le nom d'utilisateur doit comporter entre 2 et 30 caractères",
"empty.password.field.error": "Les critères de mot de passe n'ont pas été remplis",
"empty.country.field.error": "Sélectionnez votre pays ou région de résidence",
"email.do.not.match": "Les adresses courriel ne correspondent pas.",
"email.invalid.format.error": "Entrez une adresse de courriel valide",
"username.validation.message": "Le nom d'utilisateur doit comporter entre 2 et 30 caractères",
"name.validation.message": "Entrez un nom valide",
"username.format.validation.message": "Les noms d'utilisateur ne peuvent contenir que des lettres (AZ, az), des chiffres (0-9), des traits de soulignement (_) et des traits d'union (-). Les noms d'utilisateur ne peuvent pas contenir d'espaces",
"registration.request.failure.header": "Nous n'avons pas pu créer votre compte.",
"registration.empty.form.submission.error": "Veuillez vérifier vos réponses et réessayer.",
"registration.request.server.error": "Une erreur est survenue. Essayer de rafraîchir la page, ou vérifier votre connexion Internet.",
"registration.rate.limit.error": "Trop de tentatives d'inscriptions ont échoué. Réessayez plus tard.",
"registration.tpa.session.expired": "L'inscription à l'aide de {provider} a expiré.",
"registration.tpa.authentication.failure": "Nous sommes désolés, vous n'êtes pas autorisé à accéder à {platform_name} via ce canal. Veuillez contacter votre administrateur ou responsable de formation pour accéder à {platform_name}.{lineBreak}{lineBreak}Détails de l'erreur :{lineBreak}{errorMessage}",
"terms.of.service.and.honor.code": "Conditions générales du service et code d'honneur",
"privacy.policy": "Politique de confidentialité",
"honor.code": "Code d'honneur",
"terms.of.service": "Conditions générales du service",
"registration.username.suggestion.label": "Suggéré :",
"did.you.mean.alert.text": "Vouliez-vous dire",
"register.page.terms.of.service.and.honor.code": "En créant un compte, vous acceptez le {tosAndHonorCode} et vous reconnaissez que {platformName} et chaque\n membre peut traiter vos données personnelles conformément à la {privacyPolicy}.",
"register.page.honor.code": "J'accepte le {tosAndHonorCode} {platformName}",
"register.page.terms.of.service": "J'accepte les {termsOfService} {platformName}",
"sign.in": "Connexion",
"reset.password.page.title": "Réinitialiser le mot de passe | {siteName}",
"reset.password": "Réinitialiser le mot de passe",
"reset.password.page.instructions": "Saisir et confirmer votre nouveau mot de passe.",
"new.password.label": "Nouveau mot de passe",
"confirm.password.label": "Confirmer le mot de passe",
"passwords.do.not.match": "Les mots de passe ne correspondent pas",
"confirm.your.password": "Confirmer votre mot de passe",
"reset.password.failure.heading": "Nous n'avons pas pu réinitialiser votre mot de passe.",
"reset.password.form.submission.error": "Veuillez vérifier vos réponses et réessayer.",
"reset.server.rate.limit.error": "Trop de demandes.",
"reset.password.success.heading": "Réinitialisation du mot de passe complétée.",
"reset.password.success": "Votre mot de passe a été réinitialisé. Connectez-vous à votre compte.",
"rate.limit.error": "Une erreur s'est produite en raison d'un trop grand nombre de demandes. Veuillez réessayer après un certain temps."
}

View File

@@ -5,16 +5,11 @@
"complete.your.profile.2": "your profile",
"welcome.to.platform": "Welcome to {siteName}, {username}!",
"institution.login.page.sub.heading": "Choose your institution from the list below",
"forgot.password.confirmation.title": "Check your email",
"forgot.password.confirmation.support.link": "contact technical support",
"forgot.password.confirmation.info": "If you do not receive a password reset message after 1 minute, verify that you entered the correct email address, or check your spam folder.",
"logistration.sign.in": "Sign in",
"logistration.register": "Register",
"internal.server.error.message": "An error has occurred. Try refreshing the page, or check your internet connection.",
"server.ratelimit.error.message": "An error has occurred because of too many requests. Please try again after some time.",
"enterprisetpa.title.heading": "Would you like to sign in using your {providerName} credentials?",
"enterprisetpa.sso.button.title": "Sign in using {providerName}",
"enterprisetpa.login.button.text": "Show me other ways to sign in or register",
"enterprisetpa.login.button.text.public.account.creation.disabled": "Show me other ways to sign in",
"sso.sign.in.with": "Sign in with {providerName}",
"sso.create.account.using": "Create account using {providerName}",
"show.password": "Show password",
@@ -26,6 +21,9 @@
"tpa.alert.heading": "Almost done!",
"login.third.party.auth.account.not.linked": "You have successfully signed into {currentProvider}, but your {currentProvider} account does not have a linked {platformName} account. To link your accounts, sign in now using your {platformName} password.",
"register.third.party.auth.account.not.linked": "You've successfully signed into {currentProvider}! We just need a little more information before you start learning with {platformName}.",
"registration.using.tpa.form.heading": "Finish creating your account",
"zendesk.supportTitle": "edX Support",
"zendesk.selectTicketForm": "Please choose your request type:",
"error.notfound.message": "The page you're looking for is unavailable or there's an error in the URL. Please check the URL and try again.",
"forgot.password.confirmation.message": "We sent an email to {email} with instructions to reset your password.\n If you do not receive a password reset message after 1 minute, verify that you entered\n the correct email address, or check your spam folder. If you need further assistance, {supportLink}.",
"forgot.password.page.title": "Forgot Password | {siteName}",
@@ -38,7 +36,6 @@
"forgot.password.error.message.title": "An error occurred.",
"forgot.password.request.in.progress.message": "Your previous request is in progress, please try again in a few moments.",
"forgot.password.empty.email.field.error": "Enter your email",
"forgot.password.invalid.email.message": "The email address you've provided isn't formatted correctly.",
"forgot.password.email.help.text": "The email address you used to register with {platformName}",
"confirmation.message.title": "Check your email",
"confirmation.support.link": "contact technical support",
@@ -53,7 +50,6 @@
"token.validation.internal.sever.error.heading": "Token validation failure",
"token.validation.internal.sever.error": "An error has occurred. Try refreshing the page, or check your internet connection.",
"internal.server.error": "An error has occurred. Try refreshing the page, or check your internet connection.",
"rate.limit.error": "An error has occurred because of too many requests. Please try again after some time.",
"account.activation.error.message": "Something went wrong, please {supportLink} to resolve this issue.",
"login.inactive.user.error": "In order to sign in, you need to activate your account.{lineBreak}\n {lineBreak}We just sent an activation link to {email}. If you do not receive an email,\n check your spam folders or {supportLink}.",
"allowed.domain.login.error": "As {allowedDomain} user, You must login with your {allowedDomain} {tpaLink}.",
@@ -65,45 +61,32 @@
"login.user.identity.label": "Username or email",
"login.password.label": "Password",
"sign.in.button": "Sign in",
"sign.in.btn.pending.state": "Loading",
"need.help.signing.in.collapsible.menu": "Need help signing in?",
"forgot.password.link": "Forgot my password",
"forgot.password": "Forgot password",
"other.sign.in.issues": "Other sign in issues",
"need.other.help.signing.in.collapsible.menu": "Need other help signing in?",
"institution.login.button": "Institution/campus credentials",
"institution.login.page.title": "Sign in with institution/campus credentials",
"institution.login.page.back.button": "Back to sign in",
"create.an.account": "Create an account",
"login.other.options.heading": "Or sign in with:",
"non.compliant.password.title": "We recently changed our password requirements",
"non.compliant.password.message": "Your current password does not meet the new security requirements. We just sent a password-reset message to the email address associated with this account. Thank you for helping us keep your data safe.",
"account.locked.out.message.1": "To protect your account, it's been temporarily locked. Try again in 30 minutes.",
"first.time.here": "First time here?",
"email.help.message": "The email address you used to register with edX.",
"enterprise.login.btn.text": "Company or school credentials",
"email.format.validation.message": "The email address you've provided isn't formatted correctly.",
"username.or.email.format.validation.less.chars.message": "Username or email must have at least 3 characters.",
"email.validation.message": "Enter your username or email",
"password.validation.message": "Password criteria has not been met",
"register.link": "Create an account",
"sign.in.heading": "Sign in",
"account.activation.success.message.title": "Success! You have activated your account.",
"account.activation.success.message": "You will now receive email updates and alerts from us related to the courses you are enrolled in. Sign in to continue.",
"account.activation.info.message": "This account has already been activated.",
"account.activation.error.message.title": "Your account could not be activated",
"account.activation.support.link": "contact support",
"tpa.account.link": "{provider} account",
"account.confirmation.success.message.title": "Success! You have confirmed your email.",
"account.confirmation.success.message": "Sign in to continue.",
"account.confirmation.info.message": "This email has already been confirmed.",
"account.confirmation.error.message.title": "Your email could not be confirmed",
"tpa.account.link": "{provider} account",
"internal.server.error.message": "An error has occurred. Try refreshing the page, or check your internet connection.",
"login.rate.limit.reached.message": "Too many failed login attempts. Try again later.",
"login.failure.header.title": "We couldn't sign you in.",
"contact.support.link": "contact {platformName} support",
"login.incorrect.credentials.error": "The username, email, or password you entered is incorrect. Please try again.",
"login.failed.attempt.error": "You have {remainingAttempts} more sign in attempts before your account is temporarily locked.",
"login.locked.out.error.message": "To protect your account, its been temporarily locked. Try again in {lockedOutPeriod} minutes.",
"login.form.invalid.error.message": "Please fill in the fields below.",
"login.incorrect.credentials.error.reset.link.text": "reset your password",
"login.incorrect.credentials.error.before.account.blocked.text": "click here to reset it.",
@@ -113,7 +96,8 @@
"password.security.block.body": "Our system detected that your password is vulnerable. Change your password so that your account stays secure.",
"password.security.close.button": "Close",
"password.security.redirect.to.reset.password.button": "Reset your password",
"progressive.profiling.page.title": "Optional Fields | {siteName}",
"login.tpa.authentication.failure": "We are sorry, you are not authorized to access {platform_name} via this channel. Please contact your learning administrator or manager in order to access {platform_name}.{lineBreak}{lineBreak}Error Details:{lineBreak}{errorMessage}",
"progressive.profiling.page.title": "Welcome | {siteName}",
"progressive.profiling.page.heading": "A few questions for you will help us get smarter.",
"optional.fields.information.link": "Learn more about how we use this information.",
"optional.fields.submit.button": "Submit",
@@ -124,7 +108,7 @@
"modal.description": "You can complete your profile in settings at any time if you change your mind.",
"welcome.page.error.heading": "We couldn't update your profile",
"welcome.page.error.message": "An error occurred. You can complete your profile in settings at any time.",
"recommendation.page.title": "Recommendations| {siteName}",
"recommendation.page.title": "Recommendations | {siteName}",
"recommendation.page.heading": "We have a few recommendations to get you started.",
"recommendation.skip.button": "Skip for now",
"register.page.title": "Register | {siteName}",
@@ -139,51 +123,34 @@
"help.text.username.2": "This can not be changed later.",
"help.text.email": "For account activation and important updates",
"create.account.for.free.button": "Create an account for free",
"create.an.account.btn.pending.state": "Loading",
"registration.other.options.heading": "Or register with:",
"register.institution.login.button": "Institution/campus credentials",
"register.institution.login.page.title": "Register with institution/campus credentials",
"empty.name.field.error": "Enter your full name",
"empty.email.field.error": "Enter your email",
"email.do.not.match": "The email addresses do not match.",
"empty.username.field.error": "Username must be between 2 and 30 characters",
"empty.password.field.error": "Password criteria has not been met",
"empty.country.field.error": "Select your country or region of residence",
"email.do.not.match": "The email addresses do not match.",
"email.invalid.format.error": "Enter a valid email address",
"email.ratelimit.less.chars.validation.message": "Email must have 3 characters.",
"username.validation.message": "Username must be between 2 and 30 characters",
"name.validation.message": "Enter a valid name",
"username.format.validation.message": "Usernames can only contain letters (A-Z, a-z), numerals (0-9), underscores (_), and hyphens (-). Usernames cannot contain spaces",
"support.education.research": "Support education research by providing additional information. (Optional)",
"registration.request.failure.header": "We couldn't create your account.",
"registration.empty.form.submission.error": "Please check your responses and try again.",
"registration.request.server.error": "An error has occurred. Try refreshing the page, or check your internet connection.",
"registration.rate.limit.error": "Too many failed registration attempts. Try again later.",
"registration.tpa.session.expired": "Registration using {provider} has timed out.",
"registration.tpa.authentication.failure": "We are sorry, you are not authorized to access {platform_name} via this channel. Please contact your learning administrator or manager in order to access {platform_name}.{lineBreak}{lineBreak}Error Details:{lineBreak}{errorMessage}",
"terms.of.service.and.honor.code": "Terms of Service and Honor Code",
"privacy.policy": "Privacy Policy",
"honor.code": "Honor Code",
"terms.of.service": "Terms of Service",
"registration.year.of.birth.label": "Year of birth (optional)",
"registration.field.gender.options.label": "Gender (optional)",
"registration.goals.label": "Tell us why you're interested in edX (optional)",
"registration.field.gender.options.f": "Female",
"registration.field.gender.options.m": "Male",
"registration.field.gender.options.o": "Other/Prefer not to say",
"registration.field.education.levels.label": "Highest level of education completed (optional)",
"registration.field.education.levels.p": "Doctorate",
"registration.field.education.levels.m": "Master's or professional degree",
"registration.field.education.levels.b": "Bachelor's degree",
"registration.field.education.levels.a": "Associate's degree",
"registration.field.education.levels.hs": "Secondary/high school",
"registration.field.education.levels.jhs": "Junior secondary/junior high/middle school",
"registration.field.education.levels.el": "Elementary/primary school",
"registration.field.education.levels.none": "No formal education",
"registration.field.education.levels.other": "Other education",
"registration.username.suggestion.label": "Suggested:",
"registration.using.tpa.form.heading": "Finish creating your account",
"did.you.mean.alert.text": "Did you mean",
"register.page.terms.of.service": "I agree to the {platformName} {termsOfService}",
"register.page.terms.of.service.and.honor.code": "By creating an account, you agree to the {tosAndHonorCode} and you acknowledge that {platformName} and each\n Member process your personal data in accordance with the {privacyPolicy}.",
"register.page.honor.code": "I agree to the {platformName} {tosAndHonorCode}",
"register.page.terms.of.service": "I agree to the {platformName} {termsOfService}",
"sign.in": "Sign in",
"reset.password.page.title": "Reset Password | {siteName}",
"reset.password": "Reset password",
@@ -192,40 +159,10 @@
"confirm.password.label": "Confirm password",
"passwords.do.not.match": "Passwords do not match",
"confirm.your.password": "Confirm your password",
"forgot.password.confirmation.sign.in.link": "sign in",
"reset.password.request.forgot.password.text": "Forgot password",
"reset.password.request.invalid.token.header": "Invalid password reset link",
"reset.password.empty.new.password.field.error": "Please enter your new password.",
"reset.password.failure.heading": "We couldn't reset your password.",
"reset.password.form.submission.error": "Please check your responses and try again.",
"reset.password.request.server.error": "Failed to reset password",
"reset.password.token.validation.sever.error": "Token validation failure",
"reset.server.rate.limit.error": "Too many requests.",
"reset.password.success.heading": "Password reset complete.",
"reset.password.success": "Your password has been reset. Sign in to your account.",
"progressive.profiling.page.title": "Optional Fields | {siteName}",
"progressive.profiling.page.heading": "A few questions for you will help us get smarter.",
"gender.options.label": "Gender (optional)",
"gender.options.f": "Female",
"gender.options.m": "Male",
"gender.options.o": "Other/Prefer not to say",
"education.levels.label": "Highest level of education completed (optional)",
"education.levels.p": "Doctorate",
"education.levels.m": "Master's or professional degree",
"education.levels.b": "Bachelor's degree",
"education.levels.a": "Associate's degree",
"education.levels.hs": "Secondary/high school",
"education.levels.jhs": "Junior secondary/junior high/middle school",
"education.levels.el": "Elementary/primary school",
"education.levels.none": "No formal education",
"education.levels.other": "Other education",
"year.of.birth.label": "Year of birth (optional)",
"optional.fields.information.link": "Learn more about how we use this information.",
"optional.fields.submit.button": "Submit",
"optional.fields.skip.button": "Skip for now",
"continue.to.platform": "Continue to {platformName}",
"modal.title": "Thanks for letting us know.",
"modal.description": "You can complete your profile in settings at any time if you change your mind.",
"welcome.page.error.heading": "We couldn't update your profile",
"welcome.page.error.message": "An error occurred. You can complete your profile in settings at any time."
"rate.limit.error": "An error has occurred because of too many requests. Please try again after some time."
}

168
src/i18n/messages/it.json Normal file
View File

@@ -0,0 +1,168 @@
{
"start.learning": "Start learning",
"with.site.name": "with {siteName}",
"complete.your.profile.1": "Complete",
"complete.your.profile.2": "your profile",
"welcome.to.platform": "Welcome to {siteName}, {username}!",
"institution.login.page.sub.heading": "Choose your institution from the list below",
"logistration.sign.in": "Sign in",
"logistration.register": "Register",
"enterprisetpa.title.heading": "Would you like to sign in using your {providerName} credentials?",
"enterprisetpa.login.button.text": "Show me other ways to sign in or register",
"enterprisetpa.login.button.text.public.account.creation.disabled": "Show me other ways to sign in",
"sso.sign.in.with": "Sign in with {providerName}",
"sso.create.account.using": "Create account using {providerName}",
"show.password": "Show password",
"hide.password": "Hide password",
"one.letter": "1 letter",
"one.number": "1 number",
"eight.characters": "8 characters",
"password.sr.only.helping.text": "Password must contain at least 8 characters, at least one letter, and at least one number",
"tpa.alert.heading": "Almost done!",
"login.third.party.auth.account.not.linked": "You have successfully signed into {currentProvider}, but your {currentProvider} account does not have a linked {platformName} account. To link your accounts, sign in now using your {platformName} password.",
"register.third.party.auth.account.not.linked": "You've successfully signed into {currentProvider}! We just need a little more information before you start learning with {platformName}.",
"registration.using.tpa.form.heading": "Finish creating your account",
"zendesk.supportTitle": "edX Support",
"zendesk.selectTicketForm": "Please choose your request type:",
"error.notfound.message": "The page you're looking for is unavailable or there's an error in the URL. Please check the URL and try again.",
"forgot.password.confirmation.message": "We sent an email to {email} with instructions to reset your password.\n If you do not receive a password reset message after 1 minute, verify that you entered\n the correct email address, or check your spam folder. If you need further assistance, {supportLink}.",
"forgot.password.page.title": "Forgot Password | {siteName}",
"forgot.password.page.heading": "Reset password",
"forgot.password.page.instructions": "Please enter your email address below and we will send you an email with instructions on how to reset your password.",
"forgot.password.page.invalid.email.message": "Enter a valid email address",
"forgot.password.page.email.field.label": "Email",
"forgot.password.page.submit.button": "Submit",
"forgot.password.error.alert.title.": "We were unable to contact you.",
"forgot.password.error.message.title": "An error occurred.",
"forgot.password.request.in.progress.message": "Your previous request is in progress, please try again in a few moments.",
"forgot.password.empty.email.field.error": "Enter your email",
"forgot.password.email.help.text": "The email address you used to register with {platformName}",
"confirmation.message.title": "Check your email",
"confirmation.support.link": "contact technical support",
"need.help.sign.in.text": "Need help signing in?",
"additional.help.text": "For additional help, contact {platformName} support at ",
"sign.in.text": "Sign in",
"extend.field.errors": "{emailError} below.",
"invalid.token.heading": "Invalid password reset link",
"invalid.token.error.message": "This password reset link is invalid. It may have been used already. Enter your email below to receive a new link.",
"token.validation.rate.limit.error.heading": "Too many requests",
"token.validation.rate.limit.error": "An error has occurred because of too many requests. Please try again after some time.",
"token.validation.internal.sever.error.heading": "Token validation failure",
"token.validation.internal.sever.error": "An error has occurred. Try refreshing the page, or check your internet connection.",
"internal.server.error": "An error has occurred. Try refreshing the page, or check your internet connection.",
"account.activation.error.message": "Something went wrong, please {supportLink} to resolve this issue.",
"login.inactive.user.error": "In order to sign in, you need to activate your account.{lineBreak}\n {lineBreak}We just sent an activation link to {email}. If you do not receive an email,\n check your spam folders or {supportLink}.",
"allowed.domain.login.error": "As {allowedDomain} user, You must login with your {allowedDomain} {tpaLink}.",
"login.incorrect.credentials.error.attempts.text.1": "The username, email or password you entered is incorrect. You have {remainingAttempts} more sign in\n attempts before your account is temporarily locked.",
"login.incorrect.credentials.error.attempts.text.2": "If you've forgotten your password, {resetLink}",
"account.locked.out.message.2": "To be on the safe side, you can {resetLink} before trying again.",
"login.incorrect.credentials.error.with.reset.link": "The username, email, or password you entered is incorrect. Please try again or {resetLink}.",
"login.page.title": "Login | {siteName}",
"login.user.identity.label": "Username or email",
"login.password.label": "Password",
"sign.in.button": "Sign in",
"forgot.password": "Forgot password",
"institution.login.button": "Institution/campus credentials",
"institution.login.page.title": "Sign in with institution/campus credentials",
"login.other.options.heading": "Or sign in with:",
"non.compliant.password.title": "We recently changed our password requirements",
"non.compliant.password.message": "Your current password does not meet the new security requirements. We just sent a password-reset message to the email address associated with this account. Thank you for helping us keep your data safe.",
"account.locked.out.message.1": "To protect your account, it's been temporarily locked. Try again in 30 minutes.",
"enterprise.login.btn.text": "Company or school credentials",
"username.or.email.format.validation.less.chars.message": "Username or email must have at least 3 characters.",
"email.validation.message": "Enter your username or email",
"password.validation.message": "Password criteria has not been met",
"account.activation.success.message.title": "Success! You have activated your account.",
"account.activation.success.message": "You will now receive email updates and alerts from us related to the courses you are enrolled in. Sign in to continue.",
"account.activation.info.message": "This account has already been activated.",
"account.activation.error.message.title": "Your account could not be activated",
"account.activation.support.link": "contact support",
"account.confirmation.success.message.title": "Success! You have confirmed your email.",
"account.confirmation.success.message": "Sign in to continue.",
"account.confirmation.info.message": "This email has already been confirmed.",
"account.confirmation.error.message.title": "Your email could not be confirmed",
"tpa.account.link": "{provider} account",
"internal.server.error.message": "An error has occurred. Try refreshing the page, or check your internet connection.",
"login.rate.limit.reached.message": "Too many failed login attempts. Try again later.",
"login.failure.header.title": "We couldn't sign you in.",
"contact.support.link": "contact {platformName} support",
"login.incorrect.credentials.error": "The username, email, or password you entered is incorrect. Please try again.",
"login.form.invalid.error.message": "Please fill in the fields below.",
"login.incorrect.credentials.error.reset.link.text": "reset your password",
"login.incorrect.credentials.error.before.account.blocked.text": "click here to reset it.",
"password.security.nudge.title": "Password security",
"password.security.block.title": "Password change required",
"password.security.nudge.body": "Our system detected that your password is vulnerable. We recommend you change it so that your account stays secure.",
"password.security.block.body": "Our system detected that your password is vulnerable. Change your password so that your account stays secure.",
"password.security.close.button": "Close",
"password.security.redirect.to.reset.password.button": "Reset your password",
"login.tpa.authentication.failure": "We are sorry, you are not authorized to access {platform_name} via this channel. Please contact your learning administrator or manager in order to access {platform_name}.{lineBreak}{lineBreak}Error Details:{lineBreak}{errorMessage}",
"progressive.profiling.page.title": "Welcome | {siteName}",
"progressive.profiling.page.heading": "A few questions for you will help us get smarter.",
"optional.fields.information.link": "Learn more about how we use this information.",
"optional.fields.submit.button": "Submit",
"optional.fields.skip.button": "Skip for now",
"optional.fields.next.button": "Next",
"continue.to.platform": "Continue to {platformName}",
"modal.title": "Thanks for letting us know.",
"modal.description": "You can complete your profile in settings at any time if you change your mind.",
"welcome.page.error.heading": "We couldn't update your profile",
"welcome.page.error.message": "An error occurred. You can complete your profile in settings at any time.",
"recommendation.page.title": "Recommendations | {siteName}",
"recommendation.page.heading": "We have a few recommendations to get you started.",
"recommendation.skip.button": "Skip for now",
"register.page.title": "Register | {siteName}",
"registration.fullname.label": "Full name",
"registration.email.label": "Email",
"registration.username.label": "Public username",
"registration.password.label": "Password",
"registration.country.label": "Country/Region",
"registration.opt.in.label": "I agree that {siteName} may send me marketing messages.",
"help.text.name": "This name will be used by any certificates that you earn.",
"help.text.username.1": "The name that will identify you in your courses.",
"help.text.username.2": "This can not be changed later.",
"help.text.email": "For account activation and important updates",
"create.account.for.free.button": "Create an account for free",
"registration.other.options.heading": "Or register with:",
"register.institution.login.button": "Institution/campus credentials",
"register.institution.login.page.title": "Register with institution/campus credentials",
"empty.name.field.error": "Enter your full name",
"empty.email.field.error": "Enter your email",
"empty.username.field.error": "Username must be between 2 and 30 characters",
"empty.password.field.error": "Password criteria has not been met",
"empty.country.field.error": "Select your country or region of residence",
"email.do.not.match": "The email addresses do not match.",
"email.invalid.format.error": "Enter a valid email address",
"username.validation.message": "Username must be between 2 and 30 characters",
"name.validation.message": "Enter a valid name",
"username.format.validation.message": "Usernames can only contain letters (A-Z, a-z), numerals (0-9), underscores (_), and hyphens (-). Usernames cannot contain spaces",
"registration.request.failure.header": "We couldn't create your account.",
"registration.empty.form.submission.error": "Please check your responses and try again.",
"registration.request.server.error": "An error has occurred. Try refreshing the page, or check your internet connection.",
"registration.rate.limit.error": "Too many failed registration attempts. Try again later.",
"registration.tpa.session.expired": "Registration using {provider} has timed out.",
"registration.tpa.authentication.failure": "We are sorry, you are not authorized to access {platform_name} via this channel. Please contact your learning administrator or manager in order to access {platform_name}.{lineBreak}{lineBreak}Error Details:{lineBreak}{errorMessage}",
"terms.of.service.and.honor.code": "Terms of Service and Honor Code",
"privacy.policy": "Privacy Policy",
"honor.code": "Honor Code",
"terms.of.service": "Terms of Service",
"registration.username.suggestion.label": "Suggested:",
"did.you.mean.alert.text": "Did you mean",
"register.page.terms.of.service.and.honor.code": "By creating an account, you agree to the {tosAndHonorCode} and you acknowledge that {platformName} and each\n Member process your personal data in accordance with the {privacyPolicy}.",
"register.page.honor.code": "I agree to the {platformName} {tosAndHonorCode}",
"register.page.terms.of.service": "I agree to the {platformName} {termsOfService}",
"sign.in": "Sign in",
"reset.password.page.title": "Reset Password | {siteName}",
"reset.password": "Reset password",
"reset.password.page.instructions": "Enter and confirm your new password.",
"new.password.label": "New password",
"confirm.password.label": "Confirm password",
"passwords.do.not.match": "Passwords do not match",
"confirm.your.password": "Confirm your password",
"reset.password.failure.heading": "We couldn't reset your password.",
"reset.password.form.submission.error": "Please check your responses and try again.",
"reset.server.rate.limit.error": "Too many requests.",
"reset.password.success.heading": "Password reset complete.",
"reset.password.success": "Your password has been reset. Sign in to your account.",
"rate.limit.error": "An error has occurred because of too many requests. Please try again after some time."
}

View File

@@ -5,16 +5,11 @@
"complete.your.profile.2": "Il tuo profilo",
"welcome.to.platform": "Benvenuto in {siteName}, {username}!",
"institution.login.page.sub.heading": "Scegli il tuo istituto dall&#39;elenco sottostante",
"forgot.password.confirmation.title": "Controlla la tua casella di posta",
"forgot.password.confirmation.support.link": "contatta il supporto tecnico",
"forgot.password.confirmation.info": "Se non ricevi un messaggio di reimpostazione della password entro 1 minuto, verifica di aver inserito l'indirizzo e-mail corretto o controlla la cartella della posta indesiderata.",
"logistration.sign.in": "Accedi",
"logistration.register": "Registrazione",
"internal.server.error.message": "Si è verificato un errore. Prova ad aggiornare la pagina oppure verifica la connessione internet.",
"server.ratelimit.error.message": "Si è verificato un errore dovuto alle troppe richieste. Prova di nuovo più tardi.",
"enterprisetpa.title.heading": "Vuoi accedere utilizzando le credenziali {providerName}?",
"enterprisetpa.sso.button.title": "Accedi utilizzando {providerName}",
"enterprisetpa.login.button.text": "Mostrami altre modalità di accesso o registrazione",
"enterprisetpa.login.button.text.public.account.creation.disabled": "Show me other ways to sign in",
"sso.sign.in.with": "Accedi con {providerName}",
"sso.create.account.using": "Crea un account utilizzando {providerName}",
"show.password": "Mostra password",
@@ -26,6 +21,9 @@
"tpa.alert.heading": "Quasi fatto!",
"login.third.party.auth.account.not.linked": "Hai correttamente effettuato l'accesso in {currentProvider}, ma il tuo account {currentProvider} non ha un account {platformName} ad esso abbinato. Per collegare i tuoi account accesi utilizzando la password {platformName}. ",
"register.third.party.auth.account.not.linked": "Hai eseguito correttamente l&#39;accesso a {a03f0f8cfb85cz0}! Abbiamo solo bisogno di un po&#39; più di informazioni prima di iniziare a imparare con {platformName}.",
"registration.using.tpa.form.heading": "Completa la creazione del tuo account",
"zendesk.supportTitle": "edX Support",
"zendesk.selectTicketForm": "Please choose your request type:",
"error.notfound.message": "La pagina che stai cercando non è disponibile o si è verificato un errore nell'URL. Controlla l'URL e riprova. ",
"forgot.password.confirmation.message": "Abbiamo inviato un&#39;email a {email} con le istruzioni per reimpostare la password. Se non ricevi un messaggio di reimpostazione della password dopo 1 minuto, verifica di aver inserito l&#39;indirizzo e-mail corretto o controlla la cartella spam. Se hai bisogno di ulteriore assistenza, {supportLink}.",
"forgot.password.page.title": "Dimenticato la password | {siteName}",
@@ -38,7 +36,6 @@
"forgot.password.error.message.title": "Si è verificato un errore. ",
"forgot.password.request.in.progress.message": "La tua richiesta precedente è in corso di elaborazione, riprova tra qualche istante. ",
"forgot.password.empty.email.field.error": "Inserisci il tuo indirizzo email",
"forgot.password.invalid.email.message": "L'indirizzo email che hai fornito non è formattato correttamente. ",
"forgot.password.email.help.text": "L'indirizzo email che hai utilizzato per registrarti con {platformName}",
"confirmation.message.title": "Controlla la tua casella di posta",
"confirmation.support.link": "contatta il supporto tecnico",
@@ -53,7 +50,6 @@
"token.validation.internal.sever.error.heading": "Errore di convalida del token",
"token.validation.internal.sever.error": "Si è verificato un errore. Prova ad aggiornare la pagina oppure verifica la connessione internet.",
"internal.server.error": "Si è verificato un errore. Prova ad aggiornare la pagina oppure verifica la connessione internet.",
"rate.limit.error": "Si è verificato un errore dovuto alle troppe richieste. Prova di nuovo più tardi.",
"account.activation.error.message": "Si è verificato un errore, seleziona {supportLink} per risolvere il problema. ",
"login.inactive.user.error": "Per accedere, devi attivare il tuo account.{lineBreak} {lineBreak}Abbiamo appena inviato un link di attivazione a {email}. Se non ricevi un'email, controlla la cartella della posta indesiderata oppure seleziona {supportLink}.",
"allowed.domain.login.error": "As {allowedDomain} user, You must login with your {allowedDomain} {tpaLink}.",
@@ -65,45 +61,32 @@
"login.user.identity.label": "Nome utente o email ",
"login.password.label": "Password",
"sign.in.button": "Accedi",
"sign.in.btn.pending.state": "Caricamento",
"need.help.signing.in.collapsible.menu": "Hai bisogno di aiuto per l'accesso?",
"forgot.password.link": "Ho dimenticato la mia password",
"forgot.password": "Password dimenticata",
"other.sign.in.issues": "Altri problemi legati all'accesso",
"need.other.help.signing.in.collapsible.menu": "Hai bisogno di ulteriore aiuto per l'accesso?",
"institution.login.button": "Credenziali dell&#39;istituto/campus",
"institution.login.page.title": "Accedi con le credenziali dell'istituzione/campus",
"institution.login.page.back.button": "Torna all'accesso",
"create.an.account": "Crea un account",
"login.other.options.heading": "Oppure accedi con:",
"non.compliant.password.title": "Abbiamo di recente modificato i requisiti per la password ",
"non.compliant.password.message": "La tua password attuale non soddisfa i nuovi requisiti di sicurezza. Abbiamo appena inviato un messaggio di reimpostazione della password all&#39;indirizzo e-mail associato a questo account. Grazie per averci aiutato a mantenere i tuoi dati al sicuro.",
"account.locked.out.message.1": "Per proteggere il tuo account, è stato temporaneamente bloccato. Riprova tra 30 minuti.",
"first.time.here": "È la prima volta che ci visiti?",
"email.help.message": "L'indirizzo email che hai utilizzato per registrarti con edX.",
"enterprise.login.btn.text": "Credenziali aziendali o scolastiche",
"email.format.validation.message": "L'indirizzo email che hai fornito non è formattato correttamente. ",
"username.or.email.format.validation.less.chars.message": "Il nome utente o l&#39;e-mail deve contenere almeno 3 caratteri.",
"email.validation.message": "Inserisci il tuo nome utente o e-mail",
"password.validation.message": "I criteri della password non sono stati soddisfatti",
"register.link": "Crea un account",
"sign.in.heading": "Accedi",
"account.activation.success.message.title": "Completato correttamente! Hai attivato il tuo account. ",
"account.activation.success.message": "A breve ti invieremo avvisi e aggiornamenti via email relativi al corso a cui ti sei iscritto. Accedi per proseguire.",
"account.activation.info.message": "Questo account è già stato attivato.",
"account.activation.error.message.title": "Impossibile attivare il tuo account.",
"account.activation.support.link": "contatta il supporto",
"tpa.account.link": "{provider} account",
"account.confirmation.success.message.title": "Successo! Hai confermato la tua email.",
"account.confirmation.success.message": "Accedi per continuare.",
"account.confirmation.info.message": "Questa email è già stata confermata.",
"account.confirmation.error.message.title": "Impossibile confermare la tua email",
"tpa.account.link": "{provider} account",
"internal.server.error.message": "Si è verificato un errore. Prova ad aggiornare la pagina oppure verifica la connessione internet.",
"login.rate.limit.reached.message": "Troppi tentativi di login falliti. Riprova più tardi.",
"login.failure.header.title": "Impossibile autorizzare il tuo accesso.",
"contact.support.link": "contatta il supporto {platformName} ",
"login.incorrect.credentials.error": "Il nome utente, l&#39;e-mail o la password inseriti non sono corretti. Per favore riprova.",
"login.failed.attempt.error": "Hai a disposizione altri {remainingAttempts} tentativi di accesso prima che il tuo account venga temporaneamente bloccato.",
"login.locked.out.error.message": "Il tuo account è stato temporaneamente bloccato per motivi di sicurezza. Riprova tra {lockedOutPeriod} minuti.",
"login.form.invalid.error.message": "Si prega di compilare i campi sottostanti.",
"login.incorrect.credentials.error.reset.link.text": "reimposta la tua password",
"login.incorrect.credentials.error.before.account.blocked.text": "clicca qui per ripristinarlo.",
@@ -113,7 +96,8 @@
"password.security.block.body": "Il nostro sistema ha rilevato che la tua password è vulnerabile. Cambia la tua password in modo che il tuo account rimanga sicuro.",
"password.security.close.button": "Chiudi",
"password.security.redirect.to.reset.password.button": "Ripristina la tua password",
"progressive.profiling.page.title": "Campi facoltativi | {siteName}",
"login.tpa.authentication.failure": "We are sorry, you are not authorized to access {platform_name} via this channel. Please contact your learning administrator or manager in order to access {platform_name}.{lineBreak}{lineBreak}Error Details:{lineBreak}{errorMessage}",
"progressive.profiling.page.title": "Welcome | {siteName}",
"progressive.profiling.page.heading": "Alcune domande per te ci aiuteranno a diventare più intelligenti.",
"optional.fields.information.link": "Ulteriori informazioni su come utilizziamo queste informazioni.",
"optional.fields.submit.button": "Invia",
@@ -124,7 +108,7 @@
"modal.description": "Puoi completare il tuo profilo nelle impostazioni in qualsiasi momento se cambi idea.",
"welcome.page.error.heading": "Impossibile aggiornare il tuo profilo",
"welcome.page.error.message": "Si è verificato un errore. Puoi completare il tuo profilo nelle impostazioni in qualsiasi momento.",
"recommendation.page.title": "Recommendations| {siteName}",
"recommendation.page.title": "Recommendations | {siteName}",
"recommendation.page.heading": "We have a few recommendations to get you started.",
"recommendation.skip.button": "Skip for now",
"register.page.title": "Registrazione | {siteName}",
@@ -139,51 +123,34 @@
"help.text.username.2": "Questo non può essere modificato in seguito.",
"help.text.email": "Per l&#39;attivazione dell&#39;account e aggiornamenti importanti",
"create.account.for.free.button": "Crea un account gratis",
"create.an.account.btn.pending.state": "Caricamento",
"registration.other.options.heading": "Oppure registrati con:",
"register.institution.login.button": "Credenziali dell&#39;istituto/campus",
"register.institution.login.page.title": "Registrati con le credenziali dell'istituzione/campus",
"empty.name.field.error": "Inserisci il tuo nome e cognome",
"empty.email.field.error": "Inserisci il tuo indirizzo email",
"email.do.not.match": "Gli indirizzi email non corrispondono.",
"empty.username.field.error": "Il nome utente deve essere compreso tra 2 e 30 caratteri",
"empty.password.field.error": "I criteri della password non sono stati soddisfatti",
"empty.country.field.error": "Seleziona il tuo paese o regione di residenza",
"email.do.not.match": "Gli indirizzi email non corrispondono.",
"email.invalid.format.error": "Inserisci un indirizzo email valido",
"email.ratelimit.less.chars.validation.message": "Email deve avere 3 caratteri.",
"username.validation.message": "Il nome utente deve essere compreso tra 2 e 30 caratteri",
"name.validation.message": "Inserisci un nome valido",
"username.format.validation.message": "I nomi utente possono contenere solo lettere (AZ, az), numeri (0-9), trattini bassi (_) e trattini (-). I nomi utente non possono contenere spazi",
"support.education.research": "Supportare la ricerca del livello di istruzione fornendo informazioni aggiuntive. (Facoltativo)",
"registration.request.failure.header": "Impossibile creare il tuo account.",
"registration.empty.form.submission.error": "Controlla le tue risposte e riprova.",
"registration.request.server.error": "Si è verificato un errore. Prova ad aggiornare la pagina oppure verifica la connessione internet.",
"registration.rate.limit.error": "Troppi tentativi di registrazione non riusciti. Prova di nuovo più tardi.",
"registration.tpa.session.expired": "La registrazione mediante {provider} è andata in timeout.",
"registration.tpa.authentication.failure": "We are sorry, you are not authorized to access {platform_name} via this channel. Please contact your learning administrator or manager in order to access {platform_name}.{lineBreak}{lineBreak}Error Details:{lineBreak}{errorMessage}",
"terms.of.service.and.honor.code": "Termini e Condizioni del Servizio",
"privacy.policy": "Informativa sulla privacy",
"honor.code": "Codice d'Onore",
"terms.of.service": "Termini di Servizio",
"registration.year.of.birth.label": "Anno di nascita (facoltativo)",
"registration.field.gender.options.label": "Genere (facoltativo)",
"registration.goals.label": "Dicci perché sei interessato a edX (facoltativo)",
"registration.field.gender.options.f": "Femmina",
"registration.field.gender.options.m": "Maschio",
"registration.field.gender.options.o": "Altro/Preferisco non dire",
"registration.field.education.levels.label": "Livello di istruzione più elevato raggiunto (opzionale) ",
"registration.field.education.levels.p": "Dottorato",
"registration.field.education.levels.m": "Laurea magistrale o titolo accademico professionale",
"registration.field.education.levels.b": "Laurea di primo livello ",
"registration.field.education.levels.a": "Diploma Professionale",
"registration.field.education.levels.hs": "Scuola Superiore/Liceo",
"registration.field.education.levels.jhs": "Scuola Media",
"registration.field.education.levels.el": "Scuola Primaria/Elementare",
"registration.field.education.levels.none": "Nessun livello educativo formale",
"registration.field.education.levels.other": "Altro tipo di formazione",
"registration.username.suggestion.label": "Suggerito:",
"registration.using.tpa.form.heading": "Completa la creazione del tuo account",
"did.you.mean.alert.text": "Intendevi",
"register.page.terms.of.service": "Accetto il {platformName} {termsOfService}",
"register.page.terms.of.service.and.honor.code": "Creando un account, accetti il {tosAndHonorCode} e riconosci che {platformName} e ciascun Membro trattano i tuoi dati personali in conformità con l' {privacyPolicy}.",
"register.page.honor.code": "Accetto {platformName} {tosAndHonorCode}",
"register.page.terms.of.service": "Accetto {platformName} {termsOfService}",
"sign.in": "Accedi",
"reset.password.page.title": "Ripristina password | {siteName}",
"reset.password": "Resetta la password",
@@ -192,40 +159,10 @@
"confirm.password.label": "Conferma password",
"passwords.do.not.match": "le passwords non corrispondono",
"confirm.your.password": "Conferma la tua password",
"forgot.password.confirmation.sign.in.link": "accedi",
"reset.password.request.forgot.password.text": "Dimenticato la password",
"reset.password.request.invalid.token.header": "Link di ripristino della password non valido",
"reset.password.empty.new.password.field.error": "Immetti la nuova password.",
"reset.password.failure.heading": "Impossibile ripristinare la tua password.",
"reset.password.form.submission.error": "Controlla le tue risposte e riprova.",
"reset.password.request.server.error": "Ripristino della password non riuscito",
"reset.password.token.validation.sever.error": "Errore di convalida del token",
"reset.server.rate.limit.error": "Troppe richieste.",
"reset.password.success.heading": "Ripristino della password completato.",
"reset.password.success": "La tua password è stata resettata. Accedi al tuo account.",
"progressive.profiling.page.title": "Campi facoltativi | {siteName}",
"progressive.profiling.page.heading": "Alcune domande per te ci aiuteranno a diventare più intelligenti.",
"gender.options.label": "Genere (facoltativo)",
"gender.options.f": "Femmina",
"gender.options.m": "Maschio",
"gender.options.o": "Altro/Preferisco non dire",
"education.levels.label": "Livello di istruzione più elevato raggiunto (opzionale) ",
"education.levels.p": "Dottorato",
"education.levels.m": "Laurea magistrale o titolo accademico professionale",
"education.levels.b": "Laurea di primo livello ",
"education.levels.a": "Diploma Professionale",
"education.levels.hs": "Scuola Superiore/Liceo",
"education.levels.jhs": "Scuola Media",
"education.levels.el": "Scuola Primaria/Elementare",
"education.levels.none": "Nessun livello educativo formale",
"education.levels.other": "Altro livello educativo",
"year.of.birth.label": "Anno di nascita (facoltativo)",
"optional.fields.information.link": "Ulteriori informazioni su come utilizziamo queste informazioni.",
"optional.fields.submit.button": "Invia",
"optional.fields.skip.button": "Salta per ora",
"continue.to.platform": "Continua con {platformName}",
"modal.title": "Grazie per averci fatto sapere.",
"modal.description": "Puoi completare il tuo profilo nelle impostazioni in qualsiasi momento se cambi idea.",
"welcome.page.error.heading": "Impossibile aggiornare il tuo profilo",
"welcome.page.error.message": "Si è verificato un errore. Puoi completare il tuo profilo nelle impostazioni in qualsiasi momento."
"rate.limit.error": "Si è verificato un errore dovuto alle troppe richieste. Prova di nuovo più tardi."
}

168
src/i18n/messages/pt.json Normal file
View File

@@ -0,0 +1,168 @@
{
"start.learning": "Start learning",
"with.site.name": "with {siteName}",
"complete.your.profile.1": "Complete",
"complete.your.profile.2": "your profile",
"welcome.to.platform": "Welcome to {siteName}, {username}!",
"institution.login.page.sub.heading": "Choose your institution from the list below",
"logistration.sign.in": "Sign in",
"logistration.register": "Register",
"enterprisetpa.title.heading": "Would you like to sign in using your {providerName} credentials?",
"enterprisetpa.login.button.text": "Show me other ways to sign in or register",
"enterprisetpa.login.button.text.public.account.creation.disabled": "Show me other ways to sign in",
"sso.sign.in.with": "Sign in with {providerName}",
"sso.create.account.using": "Create account using {providerName}",
"show.password": "Show password",
"hide.password": "Hide password",
"one.letter": "1 letter",
"one.number": "1 number",
"eight.characters": "8 characters",
"password.sr.only.helping.text": "Password must contain at least 8 characters, at least one letter, and at least one number",
"tpa.alert.heading": "Almost done!",
"login.third.party.auth.account.not.linked": "You have successfully signed into {currentProvider}, but your {currentProvider} account does not have a linked {platformName} account. To link your accounts, sign in now using your {platformName} password.",
"register.third.party.auth.account.not.linked": "You've successfully signed into {currentProvider}! We just need a little more information before you start learning with {platformName}.",
"registration.using.tpa.form.heading": "Finish creating your account",
"zendesk.supportTitle": "edX Support",
"zendesk.selectTicketForm": "Please choose your request type:",
"error.notfound.message": "The page you're looking for is unavailable or there's an error in the URL. Please check the URL and try again.",
"forgot.password.confirmation.message": "We sent an email to {email} with instructions to reset your password.\n If you do not receive a password reset message after 1 minute, verify that you entered\n the correct email address, or check your spam folder. If you need further assistance, {supportLink}.",
"forgot.password.page.title": "Forgot Password | {siteName}",
"forgot.password.page.heading": "Reset password",
"forgot.password.page.instructions": "Please enter your email address below and we will send you an email with instructions on how to reset your password.",
"forgot.password.page.invalid.email.message": "Enter a valid email address",
"forgot.password.page.email.field.label": "Email",
"forgot.password.page.submit.button": "Submit",
"forgot.password.error.alert.title.": "We were unable to contact you.",
"forgot.password.error.message.title": "An error occurred.",
"forgot.password.request.in.progress.message": "Your previous request is in progress, please try again in a few moments.",
"forgot.password.empty.email.field.error": "Enter your email",
"forgot.password.email.help.text": "The email address you used to register with {platformName}",
"confirmation.message.title": "Check your email",
"confirmation.support.link": "contact technical support",
"need.help.sign.in.text": "Need help signing in?",
"additional.help.text": "For additional help, contact {platformName} support at ",
"sign.in.text": "Sign in",
"extend.field.errors": "{emailError} below.",
"invalid.token.heading": "Invalid password reset link",
"invalid.token.error.message": "This password reset link is invalid. It may have been used already. Enter your email below to receive a new link.",
"token.validation.rate.limit.error.heading": "Too many requests",
"token.validation.rate.limit.error": "An error has occurred because of too many requests. Please try again after some time.",
"token.validation.internal.sever.error.heading": "Token validation failure",
"token.validation.internal.sever.error": "An error has occurred. Try refreshing the page, or check your internet connection.",
"internal.server.error": "An error has occurred. Try refreshing the page, or check your internet connection.",
"account.activation.error.message": "Something went wrong, please {supportLink} to resolve this issue.",
"login.inactive.user.error": "In order to sign in, you need to activate your account.{lineBreak}\n {lineBreak}We just sent an activation link to {email}. If you do not receive an email,\n check your spam folders or {supportLink}.",
"allowed.domain.login.error": "As {allowedDomain} user, You must login with your {allowedDomain} {tpaLink}.",
"login.incorrect.credentials.error.attempts.text.1": "The username, email or password you entered is incorrect. You have {remainingAttempts} more sign in\n attempts before your account is temporarily locked.",
"login.incorrect.credentials.error.attempts.text.2": "If you've forgotten your password, {resetLink}",
"account.locked.out.message.2": "To be on the safe side, you can {resetLink} before trying again.",
"login.incorrect.credentials.error.with.reset.link": "The username, email, or password you entered is incorrect. Please try again or {resetLink}.",
"login.page.title": "Login | {siteName}",
"login.user.identity.label": "Username or email",
"login.password.label": "Password",
"sign.in.button": "Sign in",
"forgot.password": "Forgot password",
"institution.login.button": "Institution/campus credentials",
"institution.login.page.title": "Sign in with institution/campus credentials",
"login.other.options.heading": "Or sign in with:",
"non.compliant.password.title": "We recently changed our password requirements",
"non.compliant.password.message": "Your current password does not meet the new security requirements. We just sent a password-reset message to the email address associated with this account. Thank you for helping us keep your data safe.",
"account.locked.out.message.1": "To protect your account, it's been temporarily locked. Try again in 30 minutes.",
"enterprise.login.btn.text": "Company or school credentials",
"username.or.email.format.validation.less.chars.message": "Username or email must have at least 3 characters.",
"email.validation.message": "Enter your username or email",
"password.validation.message": "Password criteria has not been met",
"account.activation.success.message.title": "Success! You have activated your account.",
"account.activation.success.message": "You will now receive email updates and alerts from us related to the courses you are enrolled in. Sign in to continue.",
"account.activation.info.message": "This account has already been activated.",
"account.activation.error.message.title": "Your account could not be activated",
"account.activation.support.link": "contact support",
"account.confirmation.success.message.title": "Success! You have confirmed your email.",
"account.confirmation.success.message": "Sign in to continue.",
"account.confirmation.info.message": "This email has already been confirmed.",
"account.confirmation.error.message.title": "Your email could not be confirmed",
"tpa.account.link": "{provider} account",
"internal.server.error.message": "An error has occurred. Try refreshing the page, or check your internet connection.",
"login.rate.limit.reached.message": "Too many failed login attempts. Try again later.",
"login.failure.header.title": "We couldn't sign you in.",
"contact.support.link": "contact {platformName} support",
"login.incorrect.credentials.error": "The username, email, or password you entered is incorrect. Please try again.",
"login.form.invalid.error.message": "Please fill in the fields below.",
"login.incorrect.credentials.error.reset.link.text": "reset your password",
"login.incorrect.credentials.error.before.account.blocked.text": "click here to reset it.",
"password.security.nudge.title": "Password security",
"password.security.block.title": "Password change required",
"password.security.nudge.body": "Our system detected that your password is vulnerable. We recommend you change it so that your account stays secure.",
"password.security.block.body": "Our system detected that your password is vulnerable. Change your password so that your account stays secure.",
"password.security.close.button": "Close",
"password.security.redirect.to.reset.password.button": "Reset your password",
"login.tpa.authentication.failure": "We are sorry, you are not authorized to access {platform_name} via this channel. Please contact your learning administrator or manager in order to access {platform_name}.{lineBreak}{lineBreak}Error Details:{lineBreak}{errorMessage}",
"progressive.profiling.page.title": "Welcome | {siteName}",
"progressive.profiling.page.heading": "A few questions for you will help us get smarter.",
"optional.fields.information.link": "Learn more about how we use this information.",
"optional.fields.submit.button": "Submit",
"optional.fields.skip.button": "Skip for now",
"optional.fields.next.button": "Next",
"continue.to.platform": "Continue to {platformName}",
"modal.title": "Thanks for letting us know.",
"modal.description": "You can complete your profile in settings at any time if you change your mind.",
"welcome.page.error.heading": "We couldn't update your profile",
"welcome.page.error.message": "An error occurred. You can complete your profile in settings at any time.",
"recommendation.page.title": "Recommendations | {siteName}",
"recommendation.page.heading": "We have a few recommendations to get you started.",
"recommendation.skip.button": "Skip for now",
"register.page.title": "Register | {siteName}",
"registration.fullname.label": "Full name",
"registration.email.label": "Email",
"registration.username.label": "Public username",
"registration.password.label": "Password",
"registration.country.label": "Country/Region",
"registration.opt.in.label": "I agree that {siteName} may send me marketing messages.",
"help.text.name": "This name will be used by any certificates that you earn.",
"help.text.username.1": "The name that will identify you in your courses.",
"help.text.username.2": "This can not be changed later.",
"help.text.email": "For account activation and important updates",
"create.account.for.free.button": "Create an account for free",
"registration.other.options.heading": "Or register with:",
"register.institution.login.button": "Institution/campus credentials",
"register.institution.login.page.title": "Register with institution/campus credentials",
"empty.name.field.error": "Enter your full name",
"empty.email.field.error": "Enter your email",
"empty.username.field.error": "Username must be between 2 and 30 characters",
"empty.password.field.error": "Password criteria has not been met",
"empty.country.field.error": "Select your country or region of residence",
"email.do.not.match": "The email addresses do not match.",
"email.invalid.format.error": "Enter a valid email address",
"username.validation.message": "Username must be between 2 and 30 characters",
"name.validation.message": "Enter a valid name",
"username.format.validation.message": "Usernames can only contain letters (A-Z, a-z), numerals (0-9), underscores (_), and hyphens (-). Usernames cannot contain spaces",
"registration.request.failure.header": "We couldn't create your account.",
"registration.empty.form.submission.error": "Please check your responses and try again.",
"registration.request.server.error": "An error has occurred. Try refreshing the page, or check your internet connection.",
"registration.rate.limit.error": "Too many failed registration attempts. Try again later.",
"registration.tpa.session.expired": "Registration using {provider} has timed out.",
"registration.tpa.authentication.failure": "We are sorry, you are not authorized to access {platform_name} via this channel. Please contact your learning administrator or manager in order to access {platform_name}.{lineBreak}{lineBreak}Error Details:{lineBreak}{errorMessage}",
"terms.of.service.and.honor.code": "Terms of Service and Honor Code",
"privacy.policy": "Privacy Policy",
"honor.code": "Honor Code",
"terms.of.service": "Terms of Service",
"registration.username.suggestion.label": "Suggested:",
"did.you.mean.alert.text": "Did you mean",
"register.page.terms.of.service.and.honor.code": "By creating an account, you agree to the {tosAndHonorCode} and you acknowledge that {platformName} and each\n Member process your personal data in accordance with the {privacyPolicy}.",
"register.page.honor.code": "I agree to the {platformName} {tosAndHonorCode}",
"register.page.terms.of.service": "I agree to the {platformName} {termsOfService}",
"sign.in": "Sign in",
"reset.password.page.title": "Reset Password | {siteName}",
"reset.password": "Reset password",
"reset.password.page.instructions": "Enter and confirm your new password.",
"new.password.label": "New password",
"confirm.password.label": "Confirm password",
"passwords.do.not.match": "Passwords do not match",
"confirm.your.password": "Confirm your password",
"reset.password.failure.heading": "We couldn't reset your password.",
"reset.password.form.submission.error": "Please check your responses and try again.",
"reset.server.rate.limit.error": "Too many requests.",
"reset.password.success.heading": "Password reset complete.",
"reset.password.success": "Your password has been reset. Sign in to your account.",
"rate.limit.error": "An error has occurred because of too many requests. Please try again after some time."
}

View File

@@ -1,231 +1,168 @@
{
"start.learning": "Começar a aprender",
"with.site.name": "with {siteName}",
"with.site.name": "com {siteName}",
"complete.your.profile.1": "Concluído",
"complete.your.profile.2": "o seu perfil",
"welcome.to.platform": "Bem vindo a {siteName}, {username}!",
"institution.login.page.sub.heading": "Choose your institution from the list below",
"forgot.password.confirmation.title": "Verifique o seu email",
"forgot.password.confirmation.support.link": "contacto o suporte técnico",
"forgot.password.confirmation.info": "Se não receber uma mensagem para alterar a palavra-passe após 1 minuto, verifique se introduziu o endereço de correio electrónico correcto, ou verifique a sua pasta de spam.",
"institution.login.page.sub.heading": "Escolha a sua instituição a partir da lista abaixo",
"logistration.sign.in": "Iniciar sessão",
"logistration.register": "Registe-se",
"internal.server.error.message": "Ocorreu um erro. Tente actualizar a página, ou verifique a sua ligação à Internet.",
"server.ratelimit.error.message": "Ocorreu um erro devido a demasiados pedidos. Por favor, tente novamente após algum tempo.",
"enterprisetpa.title.heading": "Gostaria de iniciar sessão usando as suas {providerName} credenciais?",
"enterprisetpa.sso.button.title": "Inicie a sessão utilizando {providerName}",
"enterprisetpa.login.button.text": "Mostre-me outras formas de iniciar sessão ou registar-se",
"enterprisetpa.login.button.text.public.account.creation.disabled": "Mostre-me outras formas de iniciar sessão",
"sso.sign.in.with": "Inicie sessão com {providerName}",
"sso.create.account.using": "Criar conta usando {providerName}",
"show.password": "Show password",
"hide.password": "Hide password",
"one.letter": "1 letter",
"one.number": "1 number",
"eight.characters": "8 characters",
"password.sr.only.helping.text": "Password must contain at least 8 characters, at least one letter, and at least one number",
"tpa.alert.heading": "Almost done!",
"show.password": "Mostrar palavra-passe",
"hide.password": "Ocultar palavra-passe",
"one.letter": "1 letra",
"one.number": "1 número",
"eight.characters": "8 caracteres",
"password.sr.only.helping.text": "A palavra-passe deve conter pelo menos 8 carateres, pelo menos uma letra, e pelo menos um número",
"tpa.alert.heading": "Quase pronto!",
"login.third.party.auth.account.not.linked": "Iniciou sessão com sucesso em {currentProvider}, mas a sua conta {currentProvider} não está vinculada a uma conta {platformName}. Para vincular as suas contas, inicie sessão através da sua palavra-passe em {platformName}.",
"register.third.party.auth.account.not.linked": "You've successfully signed into {currentProvider}! We just need a little more information before you start learning with {platformName}.",
"register.third.party.auth.account.not.linked": "Entrou com sucesso em {currentProvider}! Só precisamos de um pouco mais de informação antes de começar a aprender com {platformName}.",
"registration.using.tpa.form.heading": "Acabe de criar a sua conta",
"zendesk.supportTitle": "Apoio edX",
"zendesk.selectTicketForm": "Por favor, escolha o seu tipo de pedido:",
"error.notfound.message": "A página que procura não está disponível ou há um erro no URL. Por favor, verifique o URL e tente novamente.",
"forgot.password.confirmation.message": "We sent an email to {email} with instructions to reset your password.\n If you do not receive a password reset message after 1 minute, verify that you entered\n the correct email address, or check your spam folder. If you need further assistance, {supportLink}.",
"forgot.password.confirmation.message": "Enviámos um email para {email} com instruções para redefinir a sua palavra-passe.\n Se não receber uma mensagem de redefinição de palavra-passe após 1 minuto, verifique se introduziu\n o endereço de correio electrónico correto, ou verifique a sua pasta de spam. Se precisar de mais assistência, {supportLink}.",
"forgot.password.page.title": "Esqueceu a Senha | {siteName}",
"forgot.password.page.heading": "Reset password",
"forgot.password.page.instructions": "Please enter your email address below and we will send you an email with instructions on how to reset your password.",
"forgot.password.page.heading": "Redefinir palavra-passe",
"forgot.password.page.instructions": "Por favor introduza o seu endereço de email abaixo e enviar-lhe-emos um email com instruções sobre como redefinir a sua palavra-passe.",
"forgot.password.page.invalid.email.message": "Introduzir um endereço de correio electrónico válido",
"forgot.password.page.email.field.label": "Email",
"forgot.password.page.submit.button": "Submeter",
"forgot.password.error.alert.title.": "We were unable to contact you.",
"forgot.password.error.alert.title.": "Não nos foi possível contactá-lo.",
"forgot.password.error.message.title": "Ocorreu um erro.",
"forgot.password.request.in.progress.message": "O seu pedido anterior está a ser processado, por favor tente novamente dentro de momentos.",
"forgot.password.empty.email.field.error": "Enter your email",
"forgot.password.invalid.email.message": "O endereço de email fornecido não está formatado correctamente.",
"forgot.password.empty.email.field.error": "Digite o seu email",
"forgot.password.email.help.text": "O endereço de e-mail que usou para se registar em {platformName}",
"confirmation.message.title": "Verifique o seu email",
"confirmation.support.link": "contact technical support",
"need.help.sign.in.text": "Need help signing in?",
"additional.help.text": "For additional help, contact {platformName} support at ",
"sign.in.text": "Sign in",
"extend.field.errors": "{emailError} below.",
"invalid.token.heading": "Invalid password reset link",
"invalid.token.error.message": "This password reset link is invalid. It may have been used already. Enter your email below to receive a new link.",
"token.validation.rate.limit.error.heading": "Too many requests",
"token.validation.rate.limit.error": "An error has occurred because of too many requests. Please try again after some time.",
"token.validation.internal.sever.error.heading": "Token validation failure",
"token.validation.internal.sever.error": "An error has occurred. Try refreshing the page, or check your internet connection.",
"internal.server.error": "An error has occurred. Try refreshing the page, or check your internet connection.",
"rate.limit.error": "An error has occurred because of too many requests. Please try again after some time.",
"confirmation.support.link": "contacto o suporte técnico",
"need.help.sign.in.text": "Precisa de ajuda para entrar?",
"additional.help.text": "Para ajuda adicional, contacte o apoio {platformName} em",
"sign.in.text": "Iniciar sessão",
"extend.field.errors": "{emailError} abaixo.",
"invalid.token.heading": "Link para Redefinir Palavra-passe inválido",
"invalid.token.error.message": "Este link de redefinição de palavra-passe é inválido. Pode já ter sido utilizada. Introduza o seu email abaixo para receber um novo link.",
"token.validation.rate.limit.error.heading": "Demasiados pedidos",
"token.validation.rate.limit.error": "Ocorreu um erro devido a demasiados pedidos. Por favor, tente novamente após algum tempo.",
"token.validation.internal.sever.error.heading": "Falha na validação do Token",
"token.validation.internal.sever.error": "Ocorreu um erro. Tente actualizar a página, ou verifique a sua ligação à Internet.",
"internal.server.error": "Ocorreu um erro. Tente actualizar a página, ou verifique a sua ligação à Internet.",
"account.activation.error.message": "Alguma coisa correu mal, siga {supportLink} para resolver esta questão.",
"login.inactive.user.error": "Para iniciar sessão, precisa ativar a sua conta. {lineBreak}\n {lineBreak} Acabámos de enviar um link de ativação para {email}. Se não receber um e-mail,\n verifique as suas pastas de spam ou {supportLink}.",
"allowed.domain.login.error": "As {allowedDomain} user, You must login with your {allowedDomain} {tpaLink}.",
"login.incorrect.credentials.error.attempts.text.1": "The username, email or password you entered is incorrect. You have {remainingAttempts} more sign in\n attempts before your account is temporarily locked.",
"login.incorrect.credentials.error.attempts.text.2": "If you've forgotten your password, {resetLink}",
"account.locked.out.message.2": "To be on the safe side, you can {resetLink} before trying again.",
"login.incorrect.credentials.error.with.reset.link": "The username, email, or password you entered is incorrect. Please try again or {resetLink}.",
"allowed.domain.login.error": "Como utilizador do {allowedDomain}, deve iniciar sessão com o seu {allowedDomain} {tpaLink}.",
"login.incorrect.credentials.error.attempts.text.1": "O nome de utilizador, email ou palavra-passe que introduziu está incorreto. Tem {remainingAttempts} mais tentativas\n de login antes da sua conta ser temporariamente bloqueada.",
"login.incorrect.credentials.error.attempts.text.2": "Se esqueceu a sua palavra-passe, {resetLink}",
"account.locked.out.message.2": "Por precaução, pode {resetLink} antes de tentar novamente.",
"login.incorrect.credentials.error.with.reset.link": "O nome de utilizador, email ou senha que introduziu está incorreto. Por favor, tente novamente ou {resetLink}.",
"login.page.title": "Iniciar sessão | {siteName}",
"login.user.identity.label": "Username or email",
"login.password.label": "Password",
"login.user.identity.label": "Nome de utilizador ou e-mail",
"login.password.label": "Palavra-passe",
"sign.in.button": "Iniciar Sessão",
"sign.in.btn.pending.state": "Loading",
"need.help.signing.in.collapsible.menu": "Precisa de ajuda para entrar?",
"forgot.password.link": "Esqueci-me da minha palavra-passe",
"forgot.password": "Forgot password",
"other.sign.in.issues": "Outros problemas de inicio de sessão",
"need.other.help.signing.in.collapsible.menu": "Precisa de outra ajuda para entrar?",
"institution.login.button": "Institution/campus credentials",
"forgot.password": "Esqueci-me da palavra-passe",
"institution.login.button": "Credenciais da instituição/campus",
"institution.login.page.title": "Inicie sessão com credenciais de instituição/campus",
"institution.login.page.back.button": "Voltar para iniciar sessão",
"create.an.account": "Criar uma conta",
"login.other.options.heading": "Or sign in with:",
"login.other.options.heading": "Ou faça login com:",
"non.compliant.password.title": "Recentemente mudámos os nossos requisitos de palavra-passe",
"non.compliant.password.message": "Your current password does not meet the new security requirements. We just sent a password-reset message to the email address associated with this account. Thank you for helping us keep your data safe.",
"account.locked.out.message.1": "To protect your account, it's been temporarily locked. Try again in 30 minutes.",
"first.time.here": "Está a entrar pela primeira vez?",
"email.help.message": "O endereço de e-mail que usou para se registrar no edX.",
"enterprise.login.btn.text": "Company or school credentials",
"email.format.validation.message": "O endereço de e-mail fornecido não está formatado correctamente.",
"username.or.email.format.validation.less.chars.message": "Username or email must have at least 3 characters.",
"email.validation.message": "Enter your username or email",
"password.validation.message": "Password criteria has not been met",
"register.link": "Criar uma conta",
"sign.in.heading": "Iniciar Sessão",
"non.compliant.password.message": "A sua palavra-passe atual não satisfaz os novos requisitos de segurança. Acabámos de enviar uma mensagem de redefinição da palavra-passe para o endereço de email associado a esta conta. Obrigado por nos ajudar a manter os seus dados em segurança.",
"account.locked.out.message.1": "Para proteger sua conta, esta foi temporariamente bloqueada. Tente novamente dentro de 30 minutos.",
"enterprise.login.btn.text": "Credenciais da empresa ou escola",
"username.or.email.format.validation.less.chars.message": "O nome de utilizador ou email deve ter pelo menos 3 carateres.",
"email.validation.message": "Insira o seu nome de utilizador ou email",
"password.validation.message": "Os critérios de palavra-passe não foram cumpridos",
"account.activation.success.message.title": "Sucesso! Você ativou a sua conta.",
"account.activation.success.message": "Receberá agora actualizações por e-mail e alertas nossos relacionados com os cursos em que está inscrito. Inicie a sessão para continuar.",
"account.activation.info.message": "This account has already been activated.",
"account.activation.info.message": "Esta conta já foi ativada.",
"account.activation.error.message.title": "A sua conta não pôde ser ativada",
"account.activation.support.link": "contato de suporte",
"tpa.account.link": "{provider} account",
"account.confirmation.success.message.title": "Success! You have confirmed your email.",
"account.confirmation.success.message": "Sign in to continue.",
"account.confirmation.info.message": "This email has already been confirmed.",
"account.confirmation.error.message.title": "Your email could not be confirmed",
"account.confirmation.success.message.title": "Sucesso! Confirmou o seu email.",
"account.confirmation.success.message": "Inicie sessão para continuar.",
"account.confirmation.info.message": "Este email já foi confirmado.",
"account.confirmation.error.message.title": "Não foi possível confirmar o seu email",
"tpa.account.link": "Conta {provider}",
"internal.server.error.message": "Ocorreu um erro. Tente actualizar a página, ou verifique a sua ligação à Internet.",
"login.rate.limit.reached.message": "Muitas tentativas de login sem sucesso. Tente novamente mais tarde.",
"login.failure.header.title": "O seu acesso não foi possível.",
"contact.support.link": "contactar o suporte {platformName}",
"login.incorrect.credentials.error": "The username, email, or password you entered is incorrect. Please try again.",
"login.failed.attempt.error": "Tem mais {remainingAttempts} tentativas de inicio sessão antes que a sua conta seja temporariamente bloqueada.",
"login.locked.out.error.message": "Para proteger a sua conta, esta foi temporariamente bloqueada. Tente novamente em {lockedOutPeriod} minutos.",
"login.form.invalid.error.message": "Please fill in the fields below.",
"login.incorrect.credentials.error.reset.link.text": "reset your password",
"login.incorrect.credentials.error.before.account.blocked.text": "click here to reset it.",
"password.security.nudge.title": "Password security",
"password.security.block.title": "Password change required",
"password.security.nudge.body": "Our system detected that your password is vulnerable. We recommend you change it so that your account stays secure.",
"password.security.block.body": "Our system detected that your password is vulnerable. Change your password so that your account stays secure.",
"password.security.close.button": "Close",
"password.security.redirect.to.reset.password.button": "Reset your password",
"progressive.profiling.page.title": "Optional Fields | {siteName}",
"progressive.profiling.page.heading": "A few questions for you will help us get smarter.",
"optional.fields.information.link": "Learn more about how we use this information.",
"optional.fields.submit.button": "Submit",
"optional.fields.skip.button": "Skip for now",
"optional.fields.next.button": "Next",
"continue.to.platform": "Continue to {platformName}",
"modal.title": "Thanks for letting us know.",
"modal.description": "You can complete your profile in settings at any time if you change your mind.",
"welcome.page.error.heading": "We couldn't update your profile",
"welcome.page.error.message": "An error occurred. You can complete your profile in settings at any time.",
"recommendation.page.title": "Recommendations| {siteName}",
"recommendation.page.heading": "We have a few recommendations to get you started.",
"recommendation.skip.button": "Skip for now",
"login.incorrect.credentials.error": "O nome de utilizador, email, ou palavra-passe que introduziu está incorreto. Por favor, tente novamente.",
"login.form.invalid.error.message": "Por favor, preencha os campos abaixo.",
"login.incorrect.credentials.error.reset.link.text": "redefinir a sua palavra-passe",
"login.incorrect.credentials.error.before.account.blocked.text": "clique aqui para a redefinir.",
"password.security.nudge.title": "Segurança da palavra-passe",
"password.security.block.title": "Alteração de palavra-passe necessária",
"password.security.nudge.body": "O nosso sistema detectou que a sua palavra-passe é vulnerável. Recomendamos que a altere para que a sua conta permaneça segura.",
"password.security.block.body": "O nosso sistema detectou que a sua palavra-passe é vulnerável. Altere a sua palavra-passe para que a sua conta permaneça segura.",
"password.security.close.button": "Fechar",
"password.security.redirect.to.reset.password.button": "Redefinir a sua palavra-passe",
"login.tpa.authentication.failure": "Lamentamos, mas não tem autorização para aceder à plataforma {platform_name} através deste canal. Pedimos-lhe que entre em contacto com o administrador ou gestor do curso para aceder à plataforma {platform_name}. {line_break}{line_break}Detalhes do erro: {line_break}{error_message}",
"progressive.profiling.page.title": "Welcome | {siteName}",
"progressive.profiling.page.heading": "Algumas perguntas para si vão ajudar a tornar-nos mais espertos.",
"optional.fields.information.link": "Saiba mais sobre a forma como utilizamos esta informação.",
"optional.fields.submit.button": "Submeter",
"optional.fields.skip.button": "Saltar por enquanto",
"optional.fields.next.button": "Seguinte",
"continue.to.platform": "Continue para {platformName}",
"modal.title": "Obrigado por nos informar.",
"modal.description": "Pode completar o seu perfil nas configurações em qualquer altura se mudar de ideias.",
"welcome.page.error.heading": "Não foi possível atualizar o seu perfil",
"welcome.page.error.message": "Ocorreu um erro. Pode completar o seu perfil nas configurações em qualquer altura.",
"recommendation.page.title": "Recomendações | {siteName}",
"recommendation.page.heading": "Temos algumas recomendações para o ajudar a começar.",
"recommendation.skip.button": "Saltar por enquanto",
"register.page.title": "Registar | {siteName}",
"registration.fullname.label": "Full name",
"registration.email.label": "Email",
"registration.username.label": "Public username",
"registration.password.label": "Password",
"registration.country.label": "Country/Region",
"registration.opt.in.label": "I agree that {siteName} may send me marketing messages.",
"help.text.name": "This name will be used by any certificates that you earn.",
"help.text.username.1": "The name that will identify you in your courses.",
"help.text.username.2": "This can not be changed later.",
"help.text.email": "For account activation and important updates",
"create.account.for.free.button": "Create an account for free",
"create.an.account.btn.pending.state": "Loading",
"registration.other.options.heading": "Or register with:",
"register.institution.login.button": "Institution/campus credentials",
"registration.fullname.label": "Nome completo",
"registration.email.label": "E-mail",
"registration.username.label": "Nome de utilizador público",
"registration.password.label": "Palavra-passe",
"registration.country.label": "País/Região",
"registration.opt.in.label": "Concordo que {siteName} pode enviar-me mensagens de marketing.",
"help.text.name": "Este nome será usado por quaisquer certificados que conseguir obter.",
"help.text.username.1": "O nome que o irá identificar nos seus cursos.",
"help.text.username.2": "Isto não pode ser alterado mais tarde.",
"help.text.email": "Para ativação de contas e atualizações importantes",
"create.account.for.free.button": "Criar uma conta gratuitamente",
"registration.other.options.heading": "Ou registe-se com:",
"register.institution.login.button": "Credenciais da instituição/campus",
"register.institution.login.page.title": "Registo com credenciais da instituição/campus",
"empty.name.field.error": "Enter your full name",
"empty.email.field.error": "Enter your email",
"email.do.not.match": "The email addresses do not match.",
"empty.username.field.error": "Username must be between 2 and 30 characters",
"empty.password.field.error": "Password criteria has not been met",
"empty.country.field.error": "Select your country or region of residence",
"email.invalid.format.error": "Enter a valid email address",
"email.ratelimit.less.chars.validation.message": "O e-mail deve ter 3 carateres.",
"username.validation.message": "Username must be between 2 and 30 characters",
"name.validation.message": "Enter a valid name",
"username.format.validation.message": "Usernames can only contain letters (A-Z, a-z), numerals (0-9), underscores (_), and hyphens (-). Usernames cannot contain spaces",
"support.education.research": "Apoie a pesquisa em educação fornecendo informações adicionais. (Opcional)",
"empty.name.field.error": "Insira o seu nome completo",
"empty.email.field.error": "Insira o seu email",
"empty.username.field.error": "O nome de utilizador deve ter entre 2 e 30 carateres",
"empty.password.field.error": "Os critérios de palavra-passe não foram cumpridos",
"empty.country.field.error": "Selecione o seu país ou região de residência",
"email.do.not.match": "Os endereços de email não correspondem.",
"email.invalid.format.error": "Introduzir um endereço de correio electrónico válido",
"username.validation.message": "O nome de utilizador deve ter entre 2 e 30 carateres",
"name.validation.message": "Introduza um nome válido",
"username.format.validation.message": "Os nomes de utilizador só podem conter letras (A-Z, a-z), numerais (0-9), sublinhados (_), e hífenes (-). Os nomes de utilizador não podem conter espaços",
"registration.request.failure.header": "Não foi possível criar a sua conta.",
"registration.empty.form.submission.error": "Please check your responses and try again.",
"registration.empty.form.submission.error": "Verifique as suas respostas e tente novamente.",
"registration.request.server.error": "Ocorreu um erro. Tente actualizar a página, ou verifique a sua ligação à Internet.",
"registration.rate.limit.error": "Too many failed registration attempts. Try again later.",
"registration.tpa.session.expired": "Registration using {provider} has timed out.",
"registration.rate.limit.error": "Demasiadas tentativas de registo falhadas. Tente novamente mais tarde.",
"registration.tpa.session.expired": "O tempo para registo utilizando {provider} expirou.",
"registration.tpa.authentication.failure": "Lamentamos, mas não tem autorização para aceder à plataforma {platform_name} através deste canal. Pedimos-lhe que entre em contacto com o administrador ou gestor do curso para aceder à plataforma {platform_name}. {line_break}{line_break}Detalhes do erro: {line_break}{error_message}",
"terms.of.service.and.honor.code": "Termos de Serviço e Código de Honra",
"privacy.policy": "Política de Privacidade",
"honor.code": "Honor Code",
"terms.of.service": "Terms of Service",
"registration.year.of.birth.label": "Ano de Nascimento (opcional)",
"registration.field.gender.options.label": "Género (opcional)",
"registration.goals.label": "Diga-nos porque está interessado no edX (opcional)",
"registration.field.gender.options.f": "Feminino",
"registration.field.gender.options.m": "Masculino",
"registration.field.gender.options.o": "Outros/Prefere não dizer",
"registration.field.education.levels.label": "Nível mais elevado de escolaridade concluído (opcional)",
"registration.field.education.levels.p": "Doutoramento",
"registration.field.education.levels.m": "Mestrado ou Grau Profissional",
"registration.field.education.levels.b": "Licenciatura",
"registration.field.education.levels.a": "Pós-graduação",
"registration.field.education.levels.hs": "Secundário",
"registration.field.education.levels.jhs": "2ªciclo/3ºciclo",
"registration.field.education.levels.el": "Primária",
"registration.field.education.levels.none": "Sem estudos",
"registration.field.education.levels.other": "Outra educação",
"registration.username.suggestion.label": "Suggested:",
"registration.using.tpa.form.heading": "Finish creating your account",
"did.you.mean.alert.text": "Did you mean",
"register.page.terms.of.service": "I agree to the {platformName} {termsOfService}",
"sign.in": "Sign in",
"honor.code": "Código de Honra",
"terms.of.service": "Termos do Serviço",
"registration.username.suggestion.label": "Sugerido:",
"did.you.mean.alert.text": "Quis dizer",
"register.page.terms.of.service.and.honor.code": "Ao criar uma conta, concorda com o {tosAndHonorCode} e reconhece que {platformName} e cada\n Membro processa os seus dados pessoais em conformidade com a {privacyPolicy}.",
"register.page.honor.code": "Concordo com a {tosAndHonorCode} {platformName}",
"register.page.terms.of.service": "Concordo com os {termsOfService} {platformName}",
"sign.in": "Iniciar sessão",
"reset.password.page.title": "Redefinir Palavra-passe | {siteName}",
"reset.password": "Reset password",
"reset.password": "Redefinir palavra-passe",
"reset.password.page.instructions": "Insira e confirme a sua nova palavra-passe.",
"new.password.label": "New password",
"confirm.password.label": "Confirm password",
"passwords.do.not.match": "Passwords do not match",
"confirm.your.password": "Confirm your password",
"forgot.password.confirmation.sign.in.link": "inicie a sessão",
"reset.password.request.forgot.password.text": "Esqueci-me da palavra-passe",
"reset.password.request.invalid.token.header": "Link para Redefinir Palavra-passe inválido",
"reset.password.empty.new.password.field.error": "Por favor, introduza a sua nova palavra-passe.",
"reset.password.failure.heading": "We couldn't reset your password.",
"reset.password.form.submission.error": "Please check your responses and try again.",
"reset.password.request.server.error": "Falha na redefinição da palavra-passe",
"reset.password.token.validation.sever.error": "Falha na validação do Token",
"reset.server.rate.limit.error": "Too many requests.",
"reset.password.success.heading": "Password reset complete.",
"reset.password.success": "Your password has been reset. Sign in to your account.",
"progressive.profiling.page.title": "Optional Fields | {siteName}",
"progressive.profiling.page.heading": "A few questions for you will help us get smarter.",
"gender.options.label": "Gender (optional)",
"gender.options.f": "Female",
"gender.options.m": "Male",
"gender.options.o": "Other/Prefer not to say",
"education.levels.label": "Highest level of education completed (optional)",
"education.levels.p": "Doctorate",
"education.levels.m": "Master's or professional degree",
"education.levels.b": "Bachelor's degree",
"education.levels.a": "Associate's degree",
"education.levels.hs": "Secondary/high school",
"education.levels.jhs": "Junior secondary/junior high/middle school",
"education.levels.el": "Elementary/primary school",
"education.levels.none": "No formal education",
"education.levels.other": "Other education",
"year.of.birth.label": "Year of birth (optional)",
"optional.fields.information.link": "Learn more about how we use this information.",
"optional.fields.submit.button": "Submit",
"optional.fields.skip.button": "Skip for now",
"continue.to.platform": "Continue to {platformName}",
"modal.title": "Thanks for letting us know.",
"modal.description": "You can complete your profile in settings at any time if you change your mind.",
"welcome.page.error.heading": "We couldn't update your profile",
"welcome.page.error.message": "An error occurred. You can complete your profile in settings at any time."
"new.password.label": "Nova palavra-passe",
"confirm.password.label": "Confirmar palavra-passe",
"passwords.do.not.match": "As palavras-passe não coincidem",
"confirm.your.password": "Confirme a sua palavra-passe",
"reset.password.failure.heading": "Não conseguimos redefinir sua palavra-passe.",
"reset.password.form.submission.error": "Por favor, verifique as suas respostas e tente novamente.",
"reset.server.rate.limit.error": "Demasiados pedidos.",
"reset.password.success.heading": "Redefinição de palavra-passe concluída",
"reset.password.success": "A sua palavra-passe foi redefinida. Inicie sessão na sua conta.",
"rate.limit.error": "Ocorreu um erro devido a demasiados pedidos. Por favor, tente novamente após algum tempo."
}

View File

@@ -5,16 +5,11 @@
"complete.your.profile.2": "your profile",
"welcome.to.platform": "Welcome to {siteName}, {username}!",
"institution.login.page.sub.heading": "Choose your institution from the list below",
"forgot.password.confirmation.title": "Check your email",
"forgot.password.confirmation.support.link": "contact technical support",
"forgot.password.confirmation.info": "If you do not receive a password reset message after 1 minute, verify that you entered the correct email address, or check your spam folder.",
"logistration.sign.in": "Sign in",
"logistration.register": "Register",
"internal.server.error.message": "An error has occurred. Try refreshing the page, or check your internet connection.",
"server.ratelimit.error.message": "An error has occurred because of too many requests. Please try again after some time.",
"enterprisetpa.title.heading": "Would you like to sign in using your {providerName} credentials?",
"enterprisetpa.sso.button.title": "Sign in using {providerName}",
"enterprisetpa.login.button.text": "Show me other ways to sign in or register",
"enterprisetpa.login.button.text.public.account.creation.disabled": "Show me other ways to sign in",
"sso.sign.in.with": "Sign in with {providerName}",
"sso.create.account.using": "Create account using {providerName}",
"show.password": "Show password",
@@ -26,6 +21,9 @@
"tpa.alert.heading": "Almost done!",
"login.third.party.auth.account.not.linked": "You have successfully signed into {currentProvider}, but your {currentProvider} account does not have a linked {platformName} account. To link your accounts, sign in now using your {platformName} password.",
"register.third.party.auth.account.not.linked": "You've successfully signed into {currentProvider}! We just need a little more information before you start learning with {platformName}.",
"registration.using.tpa.form.heading": "Finish creating your account",
"zendesk.supportTitle": "edX Support",
"zendesk.selectTicketForm": "Please choose your request type:",
"error.notfound.message": "The page you're looking for is unavailable or there's an error in the URL. Please check the URL and try again.",
"forgot.password.confirmation.message": "We sent an email to {email} with instructions to reset your password.\n If you do not receive a password reset message after 1 minute, verify that you entered\n the correct email address, or check your spam folder. If you need further assistance, {supportLink}.",
"forgot.password.page.title": "Forgot Password | {siteName}",
@@ -38,7 +36,6 @@
"forgot.password.error.message.title": "An error occurred.",
"forgot.password.request.in.progress.message": "Your previous request is in progress, please try again in a few moments.",
"forgot.password.empty.email.field.error": "Enter your email",
"forgot.password.invalid.email.message": "The email address you've provided isn't formatted correctly.",
"forgot.password.email.help.text": "The email address you used to register with {platformName}",
"confirmation.message.title": "Check your email",
"confirmation.support.link": "contact technical support",
@@ -53,7 +50,6 @@
"token.validation.internal.sever.error.heading": "Token validation failure",
"token.validation.internal.sever.error": "An error has occurred. Try refreshing the page, or check your internet connection.",
"internal.server.error": "An error has occurred. Try refreshing the page, or check your internet connection.",
"rate.limit.error": "An error has occurred because of too many requests. Please try again after some time.",
"account.activation.error.message": "Something went wrong, please {supportLink} to resolve this issue.",
"login.inactive.user.error": "In order to sign in, you need to activate your account.{lineBreak}\n {lineBreak}We just sent an activation link to {email}. If you do not receive an email,\n check your spam folders or {supportLink}.",
"allowed.domain.login.error": "As {allowedDomain} user, You must login with your {allowedDomain} {tpaLink}.",
@@ -65,45 +61,32 @@
"login.user.identity.label": "Username or email",
"login.password.label": "Password",
"sign.in.button": "Sign in",
"sign.in.btn.pending.state": "Loading",
"need.help.signing.in.collapsible.menu": "Need help signing in?",
"forgot.password.link": "Forgot my password",
"forgot.password": "Forgot password",
"other.sign.in.issues": "Other sign in issues",
"need.other.help.signing.in.collapsible.menu": "Need other help signing in?",
"institution.login.button": "Institution/campus credentials",
"institution.login.page.title": "Sign in with institution/campus credentials",
"institution.login.page.back.button": "Back to sign in",
"create.an.account": "Create an account",
"login.other.options.heading": "Or sign in with:",
"non.compliant.password.title": "We recently changed our password requirements",
"non.compliant.password.message": "Your current password does not meet the new security requirements. We just sent a password-reset message to the email address associated with this account. Thank you for helping us keep your data safe.",
"account.locked.out.message.1": "To protect your account, it's been temporarily locked. Try again in 30 minutes.",
"first.time.here": "First time here?",
"email.help.message": "The email address you used to register with edX.",
"enterprise.login.btn.text": "Company or school credentials",
"email.format.validation.message": "The email address you've provided isn't formatted correctly.",
"username.or.email.format.validation.less.chars.message": "Username or email must have at least 3 characters.",
"email.validation.message": "Enter your username or email",
"password.validation.message": "Password criteria has not been met",
"register.link": "Create an account",
"sign.in.heading": "Sign in",
"account.activation.success.message.title": "Success! You have activated your account.",
"account.activation.success.message": "You will now receive email updates and alerts from us related to the courses you are enrolled in. Sign in to continue.",
"account.activation.info.message": "This account has already been activated.",
"account.activation.error.message.title": "Your account could not be activated",
"account.activation.support.link": "contact support",
"tpa.account.link": "{provider} account",
"account.confirmation.success.message.title": "Success! You have confirmed your email.",
"account.confirmation.success.message": "Sign in to continue.",
"account.confirmation.info.message": "This email has already been confirmed.",
"account.confirmation.error.message.title": "Your email could not be confirmed",
"tpa.account.link": "{provider} account",
"internal.server.error.message": "An error has occurred. Try refreshing the page, or check your internet connection.",
"login.rate.limit.reached.message": "Too many failed login attempts. Try again later.",
"login.failure.header.title": "We couldn't sign you in.",
"contact.support.link": "contact {platformName} support",
"login.incorrect.credentials.error": "The username, email, or password you entered is incorrect. Please try again.",
"login.failed.attempt.error": "You have {remainingAttempts} more sign in attempts before your account is temporarily locked.",
"login.locked.out.error.message": "To protect your account, its been temporarily locked. Try again in {lockedOutPeriod} minutes.",
"login.form.invalid.error.message": "Please fill in the fields below.",
"login.incorrect.credentials.error.reset.link.text": "reset your password",
"login.incorrect.credentials.error.before.account.blocked.text": "click here to reset it.",
@@ -113,7 +96,8 @@
"password.security.block.body": "Our system detected that your password is vulnerable. Change your password so that your account stays secure.",
"password.security.close.button": "Close",
"password.security.redirect.to.reset.password.button": "Reset your password",
"progressive.profiling.page.title": "Optional Fields | {siteName}",
"login.tpa.authentication.failure": "We are sorry, you are not authorized to access {platform_name} via this channel. Please contact your learning administrator or manager in order to access {platform_name}.{lineBreak}{lineBreak}Error Details:{lineBreak}{errorMessage}",
"progressive.profiling.page.title": "Welcome | {siteName}",
"progressive.profiling.page.heading": "A few questions for you will help us get smarter.",
"optional.fields.information.link": "Learn more about how we use this information.",
"optional.fields.submit.button": "Submit",
@@ -124,7 +108,7 @@
"modal.description": "You can complete your profile in settings at any time if you change your mind.",
"welcome.page.error.heading": "We couldn't update your profile",
"welcome.page.error.message": "An error occurred. You can complete your profile in settings at any time.",
"recommendation.page.title": "Recommendations| {siteName}",
"recommendation.page.title": "Recommendations | {siteName}",
"recommendation.page.heading": "We have a few recommendations to get you started.",
"recommendation.skip.button": "Skip for now",
"register.page.title": "Register | {siteName}",
@@ -139,51 +123,34 @@
"help.text.username.2": "This can not be changed later.",
"help.text.email": "For account activation and important updates",
"create.account.for.free.button": "Create an account for free",
"create.an.account.btn.pending.state": "Loading",
"registration.other.options.heading": "Or register with:",
"register.institution.login.button": "Institution/campus credentials",
"register.institution.login.page.title": "Register with institution/campus credentials",
"empty.name.field.error": "Enter your full name",
"empty.email.field.error": "Enter your email",
"email.do.not.match": "The email addresses do not match.",
"empty.username.field.error": "Username must be between 2 and 30 characters",
"empty.password.field.error": "Password criteria has not been met",
"empty.country.field.error": "Select your country or region of residence",
"email.do.not.match": "The email addresses do not match.",
"email.invalid.format.error": "Enter a valid email address",
"email.ratelimit.less.chars.validation.message": "Email must have 3 characters.",
"username.validation.message": "Username must be between 2 and 30 characters",
"name.validation.message": "Enter a valid name",
"username.format.validation.message": "Usernames can only contain letters (A-Z, a-z), numerals (0-9), underscores (_), and hyphens (-). Usernames cannot contain spaces",
"support.education.research": "Support education research by providing additional information. (Optional)",
"registration.request.failure.header": "We couldn't create your account.",
"registration.empty.form.submission.error": "Please check your responses and try again.",
"registration.request.server.error": "An error has occurred. Try refreshing the page, or check your internet connection.",
"registration.rate.limit.error": "Too many failed registration attempts. Try again later.",
"registration.tpa.session.expired": "Registration using {provider} has timed out.",
"registration.tpa.authentication.failure": "We are sorry, you are not authorized to access {platform_name} via this channel. Please contact your learning administrator or manager in order to access {platform_name}.{lineBreak}{lineBreak}Error Details:{lineBreak}{errorMessage}",
"terms.of.service.and.honor.code": "Terms of Service and Honor Code",
"privacy.policy": "Privacy Policy",
"honor.code": "Honor Code",
"terms.of.service": "Terms of Service",
"registration.year.of.birth.label": "Year of birth (optional)",
"registration.field.gender.options.label": "Gender (optional)",
"registration.goals.label": "Tell us why you're interested in edX (optional)",
"registration.field.gender.options.f": "Female",
"registration.field.gender.options.m": "Male",
"registration.field.gender.options.o": "Other/Prefer not to say",
"registration.field.education.levels.label": "Highest level of education completed (optional)",
"registration.field.education.levels.p": "Doctorate",
"registration.field.education.levels.m": "Master's or professional degree",
"registration.field.education.levels.b": "Bachelor's degree",
"registration.field.education.levels.a": "Associate's degree",
"registration.field.education.levels.hs": "Secondary/high school",
"registration.field.education.levels.jhs": "Junior secondary/junior high/middle school",
"registration.field.education.levels.el": "Elementary/primary school",
"registration.field.education.levels.none": "No formal education",
"registration.field.education.levels.other": "Other education",
"registration.username.suggestion.label": "Suggested:",
"registration.using.tpa.form.heading": "Finish creating your account",
"did.you.mean.alert.text": "Did you mean",
"register.page.terms.of.service": "I agree to the {platformName} {termsOfService}",
"register.page.terms.of.service.and.honor.code": "By creating an account, you agree to the {tosAndHonorCode} and you acknowledge that {platformName} and each\n Member process your personal data in accordance with the {privacyPolicy}.",
"register.page.honor.code": "I agree to the {platformName} {tosAndHonorCode}",
"register.page.terms.of.service": "I agree to the {platformName} {termsOfService}",
"sign.in": "Sign in",
"reset.password.page.title": "Reset Password | {siteName}",
"reset.password": "Reset password",
@@ -192,40 +159,10 @@
"confirm.password.label": "Confirm password",
"passwords.do.not.match": "Passwords do not match",
"confirm.your.password": "Confirm your password",
"forgot.password.confirmation.sign.in.link": "sign in",
"reset.password.request.forgot.password.text": "Forgot password",
"reset.password.request.invalid.token.header": "Invalid password reset link",
"reset.password.empty.new.password.field.error": "Please enter your new password.",
"reset.password.failure.heading": "We couldn't reset your password.",
"reset.password.form.submission.error": "Please check your responses and try again.",
"reset.password.request.server.error": "Failed to reset password",
"reset.password.token.validation.sever.error": "Token validation failure",
"reset.server.rate.limit.error": "Too many requests.",
"reset.password.success.heading": "Password reset complete.",
"reset.password.success": "Your password has been reset. Sign in to your account.",
"progressive.profiling.page.title": "Optional Fields | {siteName}",
"progressive.profiling.page.heading": "A few questions for you will help us get smarter.",
"gender.options.label": "Gender (optional)",
"gender.options.f": "Female",
"gender.options.m": "Male",
"gender.options.o": "Other/Prefer not to say",
"education.levels.label": "Highest level of education completed (optional)",
"education.levels.p": "Doctorate",
"education.levels.m": "Master's or professional degree",
"education.levels.b": "Bachelor's degree",
"education.levels.a": "Associate's degree",
"education.levels.hs": "Secondary/high school",
"education.levels.jhs": "Junior secondary/junior high/middle school",
"education.levels.el": "Elementary/primary school",
"education.levels.none": "No formal education",
"education.levels.other": "Other education",
"year.of.birth.label": "Year of birth (optional)",
"optional.fields.information.link": "Learn more about how we use this information.",
"optional.fields.submit.button": "Submit",
"optional.fields.skip.button": "Skip for now",
"continue.to.platform": "Continue to {platformName}",
"modal.title": "Thanks for letting us know.",
"modal.description": "You can complete your profile in settings at any time if you change your mind.",
"welcome.page.error.heading": "We couldn't update your profile",
"welcome.page.error.message": "An error occurred. You can complete your profile in settings at any time."
"rate.limit.error": "An error has occurred because of too many requests. Please try again after some time."
}

View File

@@ -5,16 +5,11 @@
"complete.your.profile.2": "your profile",
"welcome.to.platform": "Welcome to {siteName}, {username}!",
"institution.login.page.sub.heading": "Choose your institution from the list below",
"forgot.password.confirmation.title": "Check your email",
"forgot.password.confirmation.support.link": "contact technical support",
"forgot.password.confirmation.info": "If you do not receive a password reset message after 1 minute, verify that you entered the correct email address, or check your spam folder.",
"logistration.sign.in": "Sign in",
"logistration.register": "Register",
"internal.server.error.message": "An error has occurred. Try refreshing the page, or check your internet connection.",
"server.ratelimit.error.message": "An error has occurred because of too many requests. Please try again after some time.",
"enterprisetpa.title.heading": "Would you like to sign in using your {providerName} credentials?",
"enterprisetpa.sso.button.title": "Sign in using {providerName}",
"enterprisetpa.login.button.text": "Show me other ways to sign in or register",
"enterprisetpa.login.button.text.public.account.creation.disabled": "Show me other ways to sign in",
"sso.sign.in.with": "Sign in with {providerName}",
"sso.create.account.using": "Create account using {providerName}",
"show.password": "Show password",
@@ -26,6 +21,9 @@
"tpa.alert.heading": "Almost done!",
"login.third.party.auth.account.not.linked": "You have successfully signed into {currentProvider}, but your {currentProvider} account does not have a linked {platformName} account. To link your accounts, sign in now using your {platformName} password.",
"register.third.party.auth.account.not.linked": "You've successfully signed into {currentProvider}! We just need a little more information before you start learning with {platformName}.",
"registration.using.tpa.form.heading": "Finish creating your account",
"zendesk.supportTitle": "edX Support",
"zendesk.selectTicketForm": "Please choose your request type:",
"error.notfound.message": "The page you're looking for is unavailable or there's an error in the URL. Please check the URL and try again.",
"forgot.password.confirmation.message": "We sent an email to {email} with instructions to reset your password.\n If you do not receive a password reset message after 1 minute, verify that you entered\n the correct email address, or check your spam folder. If you need further assistance, {supportLink}.",
"forgot.password.page.title": "Forgot Password | {siteName}",
@@ -38,7 +36,6 @@
"forgot.password.error.message.title": "An error occurred.",
"forgot.password.request.in.progress.message": "Your previous request is in progress, please try again in a few moments.",
"forgot.password.empty.email.field.error": "Enter your email",
"forgot.password.invalid.email.message": "The email address you've provided isn't formatted correctly.",
"forgot.password.email.help.text": "The email address you used to register with {platformName}",
"confirmation.message.title": "Check your email",
"confirmation.support.link": "contact technical support",
@@ -53,7 +50,6 @@
"token.validation.internal.sever.error.heading": "Token validation failure",
"token.validation.internal.sever.error": "An error has occurred. Try refreshing the page, or check your internet connection.",
"internal.server.error": "An error has occurred. Try refreshing the page, or check your internet connection.",
"rate.limit.error": "An error has occurred because of too many requests. Please try again after some time.",
"account.activation.error.message": "Something went wrong, please {supportLink} to resolve this issue.",
"login.inactive.user.error": "In order to sign in, you need to activate your account.{lineBreak}\n {lineBreak}We just sent an activation link to {email}. If you do not receive an email,\n check your spam folders or {supportLink}.",
"allowed.domain.login.error": "As {allowedDomain} user, You must login with your {allowedDomain} {tpaLink}.",
@@ -65,45 +61,32 @@
"login.user.identity.label": "Username or email",
"login.password.label": "Password",
"sign.in.button": "Sign in",
"sign.in.btn.pending.state": "Loading",
"need.help.signing.in.collapsible.menu": "Need help signing in?",
"forgot.password.link": "Forgot my password",
"forgot.password": "Forgot password",
"other.sign.in.issues": "Other sign in issues",
"need.other.help.signing.in.collapsible.menu": "Need other help signing in?",
"institution.login.button": "Institution/campus credentials",
"institution.login.page.title": "Sign in with institution/campus credentials",
"institution.login.page.back.button": "Back to sign in",
"create.an.account": "Create an account",
"login.other.options.heading": "Or sign in with:",
"non.compliant.password.title": "We recently changed our password requirements",
"non.compliant.password.message": "Your current password does not meet the new security requirements. We just sent a password-reset message to the email address associated with this account. Thank you for helping us keep your data safe.",
"account.locked.out.message.1": "To protect your account, it's been temporarily locked. Try again in 30 minutes.",
"first.time.here": "First time here?",
"email.help.message": "The email address you used to register with edX.",
"enterprise.login.btn.text": "Company or school credentials",
"email.format.validation.message": "The email address you've provided isn't formatted correctly.",
"username.or.email.format.validation.less.chars.message": "Username or email must have at least 3 characters.",
"email.validation.message": "Enter your username or email",
"password.validation.message": "Password criteria has not been met",
"register.link": "Create an account",
"sign.in.heading": "Sign in",
"account.activation.success.message.title": "Success! You have activated your account.",
"account.activation.success.message": "You will now receive email updates and alerts from us related to the courses you are enrolled in. Sign in to continue.",
"account.activation.info.message": "This account has already been activated.",
"account.activation.error.message.title": "Your account could not be activated",
"account.activation.support.link": "contact support",
"tpa.account.link": "{provider} account",
"account.confirmation.success.message.title": "Success! You have confirmed your email.",
"account.confirmation.success.message": "Sign in to continue.",
"account.confirmation.info.message": "This email has already been confirmed.",
"account.confirmation.error.message.title": "Your email could not be confirmed",
"tpa.account.link": "{provider} account",
"internal.server.error.message": "An error has occurred. Try refreshing the page, or check your internet connection.",
"login.rate.limit.reached.message": "Too many failed login attempts. Try again later.",
"login.failure.header.title": "We couldn't sign you in.",
"contact.support.link": "contact {platformName} support",
"login.incorrect.credentials.error": "The username, email, or password you entered is incorrect. Please try again.",
"login.failed.attempt.error": "You have {remainingAttempts} more sign in attempts before your account is temporarily locked.",
"login.locked.out.error.message": "To protect your account, its been temporarily locked. Try again in {lockedOutPeriod} minutes.",
"login.form.invalid.error.message": "Please fill in the fields below.",
"login.incorrect.credentials.error.reset.link.text": "reset your password",
"login.incorrect.credentials.error.before.account.blocked.text": "click here to reset it.",
@@ -113,7 +96,8 @@
"password.security.block.body": "Our system detected that your password is vulnerable. Change your password so that your account stays secure.",
"password.security.close.button": "Close",
"password.security.redirect.to.reset.password.button": "Reset your password",
"progressive.profiling.page.title": "Optional Fields | {siteName}",
"login.tpa.authentication.failure": "We are sorry, you are not authorized to access {platform_name} via this channel. Please contact your learning administrator or manager in order to access {platform_name}.{lineBreak}{lineBreak}Error Details:{lineBreak}{errorMessage}",
"progressive.profiling.page.title": "Welcome | {siteName}",
"progressive.profiling.page.heading": "A few questions for you will help us get smarter.",
"optional.fields.information.link": "Learn more about how we use this information.",
"optional.fields.submit.button": "Submit",
@@ -124,7 +108,7 @@
"modal.description": "You can complete your profile in settings at any time if you change your mind.",
"welcome.page.error.heading": "We couldn't update your profile",
"welcome.page.error.message": "An error occurred. You can complete your profile in settings at any time.",
"recommendation.page.title": "Recommendations| {siteName}",
"recommendation.page.title": "Recommendations | {siteName}",
"recommendation.page.heading": "We have a few recommendations to get you started.",
"recommendation.skip.button": "Skip for now",
"register.page.title": "Register | {siteName}",
@@ -139,51 +123,34 @@
"help.text.username.2": "This can not be changed later.",
"help.text.email": "For account activation and important updates",
"create.account.for.free.button": "Create an account for free",
"create.an.account.btn.pending.state": "Loading",
"registration.other.options.heading": "Or register with:",
"register.institution.login.button": "Institution/campus credentials",
"register.institution.login.page.title": "Register with institution/campus credentials",
"empty.name.field.error": "Enter your full name",
"empty.email.field.error": "Enter your email",
"email.do.not.match": "The email addresses do not match.",
"empty.username.field.error": "Username must be between 2 and 30 characters",
"empty.password.field.error": "Password criteria has not been met",
"empty.country.field.error": "Select your country or region of residence",
"email.do.not.match": "The email addresses do not match.",
"email.invalid.format.error": "Enter a valid email address",
"email.ratelimit.less.chars.validation.message": "Email must have 3 characters.",
"username.validation.message": "Username must be between 2 and 30 characters",
"name.validation.message": "Enter a valid name",
"username.format.validation.message": "Usernames can only contain letters (A-Z, a-z), numerals (0-9), underscores (_), and hyphens (-). Usernames cannot contain spaces",
"support.education.research": "Support education research by providing additional information. (Optional)",
"registration.request.failure.header": "We couldn't create your account.",
"registration.empty.form.submission.error": "Please check your responses and try again.",
"registration.request.server.error": "An error has occurred. Try refreshing the page, or check your internet connection.",
"registration.rate.limit.error": "Too many failed registration attempts. Try again later.",
"registration.tpa.session.expired": "Registration using {provider} has timed out.",
"registration.tpa.authentication.failure": "We are sorry, you are not authorized to access {platform_name} via this channel. Please contact your learning administrator or manager in order to access {platform_name}.{lineBreak}{lineBreak}Error Details:{lineBreak}{errorMessage}",
"terms.of.service.and.honor.code": "Terms of Service and Honor Code",
"privacy.policy": "Privacy Policy",
"honor.code": "Honor Code",
"terms.of.service": "Terms of Service",
"registration.year.of.birth.label": "Year of birth (optional)",
"registration.field.gender.options.label": "Gender (optional)",
"registration.goals.label": "Tell us why you're interested in edX (optional)",
"registration.field.gender.options.f": "Female",
"registration.field.gender.options.m": "Male",
"registration.field.gender.options.o": "Other/Prefer not to say",
"registration.field.education.levels.label": "Highest level of education completed (optional)",
"registration.field.education.levels.p": "Doctorate",
"registration.field.education.levels.m": "Master's or professional degree",
"registration.field.education.levels.b": "Bachelor's degree",
"registration.field.education.levels.a": "Associate's degree",
"registration.field.education.levels.hs": "Secondary/high school",
"registration.field.education.levels.jhs": "Junior secondary/junior high/middle school",
"registration.field.education.levels.el": "Elementary/primary school",
"registration.field.education.levels.none": "No formal education",
"registration.field.education.levels.other": "Other education",
"registration.username.suggestion.label": "Suggested:",
"registration.using.tpa.form.heading": "Finish creating your account",
"did.you.mean.alert.text": "Did you mean",
"register.page.terms.of.service": "I agree to the {platformName} {termsOfService}",
"register.page.terms.of.service.and.honor.code": "By creating an account, you agree to the {tosAndHonorCode} and you acknowledge that {platformName} and each\n Member process your personal data in accordance with the {privacyPolicy}.",
"register.page.honor.code": "I agree to the {platformName} {tosAndHonorCode}",
"register.page.terms.of.service": "I agree to the {platformName} {termsOfService}",
"sign.in": "Sign in",
"reset.password.page.title": "Reset Password | {siteName}",
"reset.password": "Reset password",
@@ -192,40 +159,10 @@
"confirm.password.label": "Confirm password",
"passwords.do.not.match": "Passwords do not match",
"confirm.your.password": "Confirm your password",
"forgot.password.confirmation.sign.in.link": "sign in",
"reset.password.request.forgot.password.text": "Forgot password",
"reset.password.request.invalid.token.header": "Invalid password reset link",
"reset.password.empty.new.password.field.error": "Please enter your new password.",
"reset.password.failure.heading": "We couldn't reset your password.",
"reset.password.form.submission.error": "Please check your responses and try again.",
"reset.password.request.server.error": "Failed to reset password",
"reset.password.token.validation.sever.error": "Token validation failure",
"reset.server.rate.limit.error": "Too many requests.",
"reset.password.success.heading": "Password reset complete.",
"reset.password.success": "Your password has been reset. Sign in to your account.",
"progressive.profiling.page.title": "Optional Fields | {siteName}",
"progressive.profiling.page.heading": "A few questions for you will help us get smarter.",
"gender.options.label": "Gender (optional)",
"gender.options.f": "Female",
"gender.options.m": "Male",
"gender.options.o": "Other/Prefer not to say",
"education.levels.label": "Highest level of education completed (optional)",
"education.levels.p": "Doctorate",
"education.levels.m": "Master's or professional degree",
"education.levels.b": "Bachelor's degree",
"education.levels.a": "Associate's degree",
"education.levels.hs": "Secondary/high school",
"education.levels.jhs": "Junior secondary/junior high/middle school",
"education.levels.el": "Elementary/primary school",
"education.levels.none": "No formal education",
"education.levels.other": "Other education",
"year.of.birth.label": "Year of birth (optional)",
"optional.fields.information.link": "Learn more about how we use this information.",
"optional.fields.submit.button": "Submit",
"optional.fields.skip.button": "Skip for now",
"continue.to.platform": "Continue to {platformName}",
"modal.title": "Thanks for letting us know.",
"modal.description": "You can complete your profile in settings at any time if you change your mind.",
"welcome.page.error.heading": "We couldn't update your profile",
"welcome.page.error.message": "An error occurred. You can complete your profile in settings at any time."
"rate.limit.error": "An error has occurred because of too many requests. Please try again after some time."
}

View File

@@ -5,16 +5,11 @@
"complete.your.profile.2": "your profile",
"welcome.to.platform": "Welcome to {siteName}, {username}!",
"institution.login.page.sub.heading": "Choose your institution from the list below",
"forgot.password.confirmation.title": "Check your email",
"forgot.password.confirmation.support.link": "contact technical support",
"forgot.password.confirmation.info": "If you do not receive a password reset message after 1 minute, verify that you entered the correct email address, or check your spam folder.",
"logistration.sign.in": "Sign in",
"logistration.register": "Register",
"internal.server.error.message": "An error has occurred. Try refreshing the page, or check your internet connection.",
"server.ratelimit.error.message": "An error has occurred because of too many requests. Please try again after some time.",
"enterprisetpa.title.heading": "Would you like to sign in using your {providerName} credentials?",
"enterprisetpa.sso.button.title": "Sign in using {providerName}",
"enterprisetpa.login.button.text": "Show me other ways to sign in or register",
"enterprisetpa.login.button.text.public.account.creation.disabled": "Show me other ways to sign in",
"sso.sign.in.with": "Sign in with {providerName}",
"sso.create.account.using": "Create account using {providerName}",
"show.password": "Show password",
@@ -26,6 +21,9 @@
"tpa.alert.heading": "Almost done!",
"login.third.party.auth.account.not.linked": "You have successfully signed into {currentProvider}, but your {currentProvider} account does not have a linked {platformName} account. To link your accounts, sign in now using your {platformName} password.",
"register.third.party.auth.account.not.linked": "You've successfully signed into {currentProvider}! We just need a little more information before you start learning with {platformName}.",
"registration.using.tpa.form.heading": "Finish creating your account",
"zendesk.supportTitle": "edX Support",
"zendesk.selectTicketForm": "Please choose your request type:",
"error.notfound.message": "The page you're looking for is unavailable or there's an error in the URL. Please check the URL and try again.",
"forgot.password.confirmation.message": "We sent an email to {email} with instructions to reset your password.\n If you do not receive a password reset message after 1 minute, verify that you entered\n the correct email address, or check your spam folder. If you need further assistance, {supportLink}.",
"forgot.password.page.title": "Forgot Password | {siteName}",
@@ -38,7 +36,6 @@
"forgot.password.error.message.title": "An error occurred.",
"forgot.password.request.in.progress.message": "Your previous request is in progress, please try again in a few moments.",
"forgot.password.empty.email.field.error": "Enter your email",
"forgot.password.invalid.email.message": "The email address you've provided isn't formatted correctly.",
"forgot.password.email.help.text": "The email address you used to register with {platformName}",
"confirmation.message.title": "Check your email",
"confirmation.support.link": "contact technical support",
@@ -53,7 +50,6 @@
"token.validation.internal.sever.error.heading": "Token validation failure",
"token.validation.internal.sever.error": "An error has occurred. Try refreshing the page, or check your internet connection.",
"internal.server.error": "An error has occurred. Try refreshing the page, or check your internet connection.",
"rate.limit.error": "An error has occurred because of too many requests. Please try again after some time.",
"account.activation.error.message": "Something went wrong, please {supportLink} to resolve this issue.",
"login.inactive.user.error": "In order to sign in, you need to activate your account.{lineBreak}\n {lineBreak}We just sent an activation link to {email}. If you do not receive an email,\n check your spam folders or {supportLink}.",
"allowed.domain.login.error": "As {allowedDomain} user, You must login with your {allowedDomain} {tpaLink}.",
@@ -65,45 +61,32 @@
"login.user.identity.label": "Username or email",
"login.password.label": "Password",
"sign.in.button": "Sign in",
"sign.in.btn.pending.state": "Loading",
"need.help.signing.in.collapsible.menu": "Need help signing in?",
"forgot.password.link": "Forgot my password",
"forgot.password": "Forgot password",
"other.sign.in.issues": "Other sign in issues",
"need.other.help.signing.in.collapsible.menu": "Need other help signing in?",
"institution.login.button": "Institution/campus credentials",
"institution.login.page.title": "Sign in with institution/campus credentials",
"institution.login.page.back.button": "Back to sign in",
"create.an.account": "Create an account",
"login.other.options.heading": "Or sign in with:",
"non.compliant.password.title": "We recently changed our password requirements",
"non.compliant.password.message": "Your current password does not meet the new security requirements. We just sent a password-reset message to the email address associated with this account. Thank you for helping us keep your data safe.",
"account.locked.out.message.1": "To protect your account, it's been temporarily locked. Try again in 30 minutes.",
"first.time.here": "First time here?",
"email.help.message": "The email address you used to register with edX.",
"enterprise.login.btn.text": "Company or school credentials",
"email.format.validation.message": "The email address you've provided isn't formatted correctly.",
"username.or.email.format.validation.less.chars.message": "Username or email must have at least 3 characters.",
"email.validation.message": "Enter your username or email",
"password.validation.message": "Password criteria has not been met",
"register.link": "Create an account",
"sign.in.heading": "Sign in",
"account.activation.success.message.title": "Success! You have activated your account.",
"account.activation.success.message": "You will now receive email updates and alerts from us related to the courses you are enrolled in. Sign in to continue.",
"account.activation.info.message": "This account has already been activated.",
"account.activation.error.message.title": "Your account could not be activated",
"account.activation.support.link": "contact support",
"tpa.account.link": "{provider} account",
"account.confirmation.success.message.title": "Success! You have confirmed your email.",
"account.confirmation.success.message": "Sign in to continue.",
"account.confirmation.info.message": "This email has already been confirmed.",
"account.confirmation.error.message.title": "Your email could not be confirmed",
"tpa.account.link": "{provider} account",
"internal.server.error.message": "An error has occurred. Try refreshing the page, or check your internet connection.",
"login.rate.limit.reached.message": "Too many failed login attempts. Try again later.",
"login.failure.header.title": "We couldn't sign you in.",
"contact.support.link": "contact {platformName} support",
"login.incorrect.credentials.error": "The username, email, or password you entered is incorrect. Please try again.",
"login.failed.attempt.error": "You have {remainingAttempts} more sign in attempts before your account is temporarily locked.",
"login.locked.out.error.message": "To protect your account, its been temporarily locked. Try again in {lockedOutPeriod} minutes.",
"login.form.invalid.error.message": "Please fill in the fields below.",
"login.incorrect.credentials.error.reset.link.text": "reset your password",
"login.incorrect.credentials.error.before.account.blocked.text": "click here to reset it.",
@@ -113,7 +96,8 @@
"password.security.block.body": "Our system detected that your password is vulnerable. Change your password so that your account stays secure.",
"password.security.close.button": "Close",
"password.security.redirect.to.reset.password.button": "Reset your password",
"progressive.profiling.page.title": "Optional Fields | {siteName}",
"login.tpa.authentication.failure": "We are sorry, you are not authorized to access {platform_name} via this channel. Please contact your learning administrator or manager in order to access {platform_name}.{lineBreak}{lineBreak}Error Details:{lineBreak}{errorMessage}",
"progressive.profiling.page.title": "Welcome | {siteName}",
"progressive.profiling.page.heading": "A few questions for you will help us get smarter.",
"optional.fields.information.link": "Learn more about how we use this information.",
"optional.fields.submit.button": "Submit",
@@ -124,7 +108,7 @@
"modal.description": "You can complete your profile in settings at any time if you change your mind.",
"welcome.page.error.heading": "We couldn't update your profile",
"welcome.page.error.message": "An error occurred. You can complete your profile in settings at any time.",
"recommendation.page.title": "Recommendations| {siteName}",
"recommendation.page.title": "Recommendations | {siteName}",
"recommendation.page.heading": "We have a few recommendations to get you started.",
"recommendation.skip.button": "Skip for now",
"register.page.title": "Register | {siteName}",
@@ -139,51 +123,34 @@
"help.text.username.2": "This can not be changed later.",
"help.text.email": "For account activation and important updates",
"create.account.for.free.button": "Create an account for free",
"create.an.account.btn.pending.state": "Loading",
"registration.other.options.heading": "Or register with:",
"register.institution.login.button": "Institution/campus credentials",
"register.institution.login.page.title": "Register with institution/campus credentials",
"empty.name.field.error": "Enter your full name",
"empty.email.field.error": "Enter your email",
"email.do.not.match": "The email addresses do not match.",
"empty.username.field.error": "Username must be between 2 and 30 characters",
"empty.password.field.error": "Password criteria has not been met",
"empty.country.field.error": "Select your country or region of residence",
"email.do.not.match": "The email addresses do not match.",
"email.invalid.format.error": "Enter a valid email address",
"email.ratelimit.less.chars.validation.message": "Email must have 3 characters.",
"username.validation.message": "Username must be between 2 and 30 characters",
"name.validation.message": "Enter a valid name",
"username.format.validation.message": "Usernames can only contain letters (A-Z, a-z), numerals (0-9), underscores (_), and hyphens (-). Usernames cannot contain spaces",
"support.education.research": "Support education research by providing additional information. (Optional)",
"registration.request.failure.header": "We couldn't create your account.",
"registration.empty.form.submission.error": "Please check your responses and try again.",
"registration.request.server.error": "An error has occurred. Try refreshing the page, or check your internet connection.",
"registration.rate.limit.error": "Too many failed registration attempts. Try again later.",
"registration.tpa.session.expired": "Registration using {provider} has timed out.",
"registration.tpa.authentication.failure": "We are sorry, you are not authorized to access {platform_name} via this channel. Please contact your learning administrator or manager in order to access {platform_name}.{lineBreak}{lineBreak}Error Details:{lineBreak}{errorMessage}",
"terms.of.service.and.honor.code": "Terms of Service and Honor Code",
"privacy.policy": "Privacy Policy",
"honor.code": "Honor Code",
"terms.of.service": "Terms of Service",
"registration.year.of.birth.label": "Year of birth (optional)",
"registration.field.gender.options.label": "Gender (optional)",
"registration.goals.label": "Tell us why you're interested in edX (optional)",
"registration.field.gender.options.f": "Female",
"registration.field.gender.options.m": "Male",
"registration.field.gender.options.o": "Other/Prefer not to say",
"registration.field.education.levels.label": "Highest level of education completed (optional)",
"registration.field.education.levels.p": "Doctorate",
"registration.field.education.levels.m": "Master's or professional degree",
"registration.field.education.levels.b": "Bachelor's degree",
"registration.field.education.levels.a": "Associate's degree",
"registration.field.education.levels.hs": "Secondary/high school",
"registration.field.education.levels.jhs": "Junior secondary/junior high/middle school",
"registration.field.education.levels.el": "Elementary/primary school",
"registration.field.education.levels.none": "No formal education",
"registration.field.education.levels.other": "Other education",
"registration.username.suggestion.label": "Suggested:",
"registration.using.tpa.form.heading": "Finish creating your account",
"did.you.mean.alert.text": "Did you mean",
"register.page.terms.of.service": "I agree to the {platformName} {termsOfService}",
"register.page.terms.of.service.and.honor.code": "By creating an account, you agree to the {tosAndHonorCode} and you acknowledge that {platformName} and each\n Member process your personal data in accordance with the {privacyPolicy}.",
"register.page.honor.code": "I agree to the {platformName} {tosAndHonorCode}",
"register.page.terms.of.service": "I agree to the {platformName} {termsOfService}",
"sign.in": "Sign in",
"reset.password.page.title": "Reset Password | {siteName}",
"reset.password": "Reset password",
@@ -192,40 +159,10 @@
"confirm.password.label": "Confirm password",
"passwords.do.not.match": "Passwords do not match",
"confirm.your.password": "Confirm your password",
"forgot.password.confirmation.sign.in.link": "sign in",
"reset.password.request.forgot.password.text": "Forgot password",
"reset.password.request.invalid.token.header": "Invalid password reset link",
"reset.password.empty.new.password.field.error": "Please enter your new password.",
"reset.password.failure.heading": "We couldn't reset your password.",
"reset.password.form.submission.error": "Please check your responses and try again.",
"reset.password.request.server.error": "Failed to reset password",
"reset.password.token.validation.sever.error": "Token validation failure",
"reset.server.rate.limit.error": "Too many requests.",
"reset.password.success.heading": "Password reset complete.",
"reset.password.success": "Your password has been reset. Sign in to your account.",
"progressive.profiling.page.title": "Optional Fields | {siteName}",
"progressive.profiling.page.heading": "A few questions for you will help us get smarter.",
"gender.options.label": "Gender (optional)",
"gender.options.f": "Female",
"gender.options.m": "Male",
"gender.options.o": "Other/Prefer not to say",
"education.levels.label": "Highest level of education completed (optional)",
"education.levels.p": "Doctorate",
"education.levels.m": "Master's or professional degree",
"education.levels.b": "Bachelor's degree",
"education.levels.a": "Associate's degree",
"education.levels.hs": "Secondary/high school",
"education.levels.jhs": "Junior secondary/junior high/middle school",
"education.levels.el": "Elementary/primary school",
"education.levels.none": "No formal education",
"education.levels.other": "Other education",
"year.of.birth.label": "Year of birth (optional)",
"optional.fields.information.link": "Learn more about how we use this information.",
"optional.fields.submit.button": "Submit",
"optional.fields.skip.button": "Skip for now",
"continue.to.platform": "Continue to {platformName}",
"modal.title": "Thanks for letting us know.",
"modal.description": "You can complete your profile in settings at any time if you change your mind.",
"welcome.page.error.heading": "We couldn't update your profile",
"welcome.page.error.message": "An error occurred. You can complete your profile in settings at any time."
"rate.limit.error": "An error has occurred because of too many requests. Please try again after some time."
}

View File

@@ -8,9 +8,9 @@ import {
APP_INIT_ERROR, APP_READY, initialize, mergeConfig, subscribe,
} from '@edx/frontend-platform';
import { ErrorPage } from '@edx/frontend-platform/react';
import { messages as paragonMessages } from '@edx/paragon';
import appMessages from './i18n';
import configuration from './config';
import messages from './i18n';
import MainApp from './MainApp';
subscribe(APP_READY, () => {
@@ -27,29 +27,8 @@ subscribe(APP_INIT_ERROR, (error) => {
initialize({
handlers: {
config: () => {
mergeConfig({
LOGIN_ISSUE_SUPPORT_LINK: process.env.LOGIN_ISSUE_SUPPORT_LINK || null,
ACTIVATION_EMAIL_SUPPORT_LINK: process.env.ACTIVATION_EMAIL_SUPPORT_LINK || null,
PASSWORD_RESET_SUPPORT_LINK: process.env.PASSWORD_RESET_SUPPORT_LINK || null,
TOS_AND_HONOR_CODE: process.env.TOS_AND_HONOR_CODE || null,
TOS_LINK: process.env.TOS_LINK || null,
PRIVACY_POLICY: process.env.PRIVACY_POLICY || null,
USER_SURVEY_COOKIE_NAME: process.env.USER_SURVEY_COOKIE_NAME || null,
COOKIE_DOMAIN: process.env.COOKIE_DOMAIN,
WELCOME_PAGE_SUPPORT_LINK: process.env.WELCOME_PAGE_SUPPORT_LINK || null,
DISABLE_ENTERPRISE_LOGIN: process.env.DISABLE_ENTERPRISE_LOGIN || '',
INFO_EMAIL: process.env.INFO_EMAIL || '',
REGISTER_CONVERSION_COOKIE_NAME: process.env.REGISTER_CONVERSION_COOKIE_NAME || null,
ENABLE_PROGRESSIVE_PROFILING: process.env.ENABLE_PROGRESSIVE_PROFILING || false,
MARKETING_EMAILS_OPT_IN: process.env.MARKETING_EMAILS_OPT_IN || '',
ENABLE_COPPA_COMPLIANCE: process.env.ENABLE_COPPA_COMPLIANCE || '',
ENABLE_DYNAMIC_REGISTRATION_FIELDS: process.env.ENABLE_DYNAMIC_REGISTRATION_FIELDS || false,
ENABLE_COOKIE_POLICY_BANNER: process.env.ENABLE_COOKIE_POLICY_BANNER || false,
});
mergeConfig(configuration);
},
},
messages: [
appMessages,
paragonMessages,
],
messages,
});

View File

@@ -3,5 +3,4 @@
@import "~@edx/paragon/scss/core/core";
@import "~@edx/brand/paragon/overrides";
@import "@edx/frontend-component-cookie-policy-banner/build/_cookie-policy-banner";
@import "sass/style";

View File

@@ -1,7 +1,7 @@
import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import { Alert } from '@edx/paragon';
import { CheckCircle, Error } from '@edx/paragon/icons';
import PropTypes from 'prop-types';
@@ -10,7 +10,8 @@ import { ACCOUNT_ACTIVATION_MESSAGE } from './data/constants';
import messages from './messages';
const AccountActivationMessage = (props) => {
const { intl, messageType } = props;
const { formatMessage } = useIntl();
const { messageType } = props;
const variant = messageType === ACCOUNT_ACTIVATION_MESSAGE.ERROR ? 'danger' : messageType;
const activationOrVerification = getConfig().MARKETING_EMAILS_OPT_IN ? 'confirmation' : 'activation';
@@ -25,22 +26,22 @@ const AccountActivationMessage = (props) => {
switch (messageType) {
case ACCOUNT_ACTIVATION_MESSAGE.SUCCESS: {
heading = intl.formatMessage(messages[`account.${activationOrVerification}.success.message.title`]);
activationMessage = <span>{intl.formatMessage(messages[`account.${activationOrVerification}.success.message`])}</span>;
heading = formatMessage(messages[`account.${activationOrVerification}.success.message.title`]);
activationMessage = <span>{formatMessage(messages[`account.${activationOrVerification}.success.message`])}</span>;
break;
}
case ACCOUNT_ACTIVATION_MESSAGE.INFO: {
activationMessage = intl.formatMessage(messages[`account.${activationOrVerification}.info.message`]);
activationMessage = formatMessage(messages[`account.${activationOrVerification}.info.message`]);
break;
}
case ACCOUNT_ACTIVATION_MESSAGE.ERROR: {
const supportLink = (
<Alert.Link href={getConfig().ACTIVATION_EMAIL_SUPPORT_LINK}>
{intl.formatMessage(messages['account.activation.support.link'])}
{formatMessage(messages['account.activation.support.link'])}
</Alert.Link>
);
heading = intl.formatMessage(messages[`account.${activationOrVerification}.error.message.title`]);
heading = formatMessage(messages[`account.${activationOrVerification}.error.message.title`]);
activationMessage = (
<FormattedMessage
id="account.activation.error.message"
@@ -70,7 +71,6 @@ const AccountActivationMessage = (props) => {
AccountActivationMessage.propTypes = {
messageType: PropTypes.string.isRequired,
intl: intlShape.isRequired,
};
export default injectIntl(AccountActivationMessage);
export default AccountActivationMessage;

View File

@@ -1,7 +1,7 @@
import React, { useState } from 'react';
import { getConfig } from '@edx/frontend-platform';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { useIntl } from '@edx/frontend-platform/i18n';
import {
ActionRow, ModalDialog, useToggle,
} from '@edx/paragon';
@@ -9,12 +9,12 @@ import classNames from 'classnames';
import PropTypes from 'prop-types';
import { Link, Redirect } from 'react-router-dom';
import messages from './messages';
import { DEFAULT_REDIRECT_URL, RESET_PAGE } from '../data/constants';
import { updatePathWithQueryParams } from '../data/utils';
import useMobileResponsive from '../data/utils/useMobileResponsive';
import messages from './messages';
const ChangePasswordPrompt = ({ intl, variant, redirectUrl }) => {
const ChangePasswordPrompt = ({ variant, redirectUrl }) => {
const isMobileView = useMobileResponsive();
const [redirectToResetPasswordPage, setRedirectToResetPasswordPage] = useState(false);
const handlers = {
@@ -28,6 +28,7 @@ const ChangePasswordPrompt = ({ intl, variant, redirectUrl }) => {
};
// eslint-disable-next-line no-unused-vars
const [isOpen, open, close] = useToggle(true, handlers);
const { formatMessage } = useIntl();
if (redirectToResetPasswordPage) {
return <Redirect to={updatePathWithQueryParams(RESET_PAGE)} />;
@@ -42,11 +43,11 @@ const ChangePasswordPrompt = ({ intl, variant, redirectUrl }) => {
>
<ModalDialog.Header>
<ModalDialog.Title>
{intl.formatMessage(messages[`password.security.${variant}.title`])}
{formatMessage(messages[`password.security.${variant}.title`])}
</ModalDialog.Title>
</ModalDialog.Header>
<ModalDialog.Body>
{intl.formatMessage(messages[`password.security.${variant}.body`])}
{formatMessage(messages[`password.security.${variant}.body`])}
</ModalDialog.Body>
<ModalDialog.Footer>
<ActionRow className={classNames(
@@ -55,7 +56,7 @@ const ChangePasswordPrompt = ({ intl, variant, redirectUrl }) => {
>
{variant === 'nudge' ? (
<ModalDialog.CloseButton id="password-security-close" variant="tertiary">
{intl.formatMessage(messages['password.security.close.button'])}
{formatMessage(messages['password.security.close.button'])}
</ModalDialog.CloseButton>
) : null}
<Link
@@ -66,7 +67,7 @@ const ChangePasswordPrompt = ({ intl, variant, redirectUrl }) => {
)}
to={updatePathWithQueryParams(RESET_PAGE)}
>
{intl.formatMessage(messages['password.security.redirect.to.reset.password.button'])}
{formatMessage(messages['password.security.redirect.to.reset.password.button'])}
</Link>
</ActionRow>
</ModalDialog.Footer>
@@ -80,9 +81,8 @@ ChangePasswordPrompt.defaultProps = {
};
ChangePasswordPrompt.propTypes = {
intl: intlShape.isRequired,
variant: PropTypes.oneOf(['nudge', 'block']),
redirectUrl: PropTypes.string,
};
export default injectIntl(ChangePasswordPrompt);
export default ChangePasswordPrompt;

View File

@@ -2,7 +2,7 @@ import React from 'react';
import { getConfig } from '@edx/frontend-platform';
import { getAuthService } from '@edx/frontend-platform/auth';
import { FormattedMessage, injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { FormattedMessage, useIntl } from '@edx/frontend-platform/i18n';
import { Alert, Hyperlink } from '@edx/paragon';
import { Error } from '@edx/paragon/icons';
import PropTypes from 'prop-types';
@@ -20,17 +20,19 @@ import {
NON_COMPLIANT_PASSWORD_EXCEPTION,
NUDGE_PASSWORD_CHANGE,
REQUIRE_PASSWORD_CHANGE,
TPA_AUTHENTICATION_FAILURE,
} from './data/constants';
import messages from './messages';
const LoginFailureMessage = (props) => {
const { intl } = props;
const { formatMessage } = useIntl();
const { context, errorCode } = props.loginError;
const authService = getAuthService();
let errorList;
let resetLink = (
<Hyperlink destination="reset" isInline>
{intl.formatMessage(messages['login.incorrect.credentials.error.reset.link.text'])}
{formatMessage(messages['login.incorrect.credentials.error.reset.link.text'])}
</Hyperlink>
);
@@ -38,19 +40,19 @@ const LoginFailureMessage = (props) => {
case NON_COMPLIANT_PASSWORD_EXCEPTION: {
errorList = (
<>
<strong>{intl.formatMessage(messages['non.compliant.password.title'])}</strong>
<p>{intl.formatMessage(messages['non.compliant.password.message'])}</p>
<strong>{formatMessage(messages['non.compliant.password.title'])}</strong>
<p>{formatMessage(messages['non.compliant.password.message'])}</p>
</>
);
break;
}
case FORBIDDEN_REQUEST:
errorList = <p>{intl.formatMessage(messages['login.rate.limit.reached.message'])}</p>;
errorList = <p>{formatMessage(messages['login.rate.limit.reached.message'])}</p>;
break;
case INACTIVE_USER: {
const supportLink = (
<a href={context.supportLink}>
{intl.formatMessage(messages['contact.support.link'], { platformName: context.platformName })}
{formatMessage(messages['contact.support.link'], { platformName: context.platformName })}
</a>
);
errorList = (
@@ -74,7 +76,7 @@ const LoginFailureMessage = (props) => {
const url = `${getConfig().LMS_BASE_URL}/dashboard/?tpa_hint=${context.tpaHint}`;
const tpaLink = (
<a href={url}>
{intl.formatMessage(messages['tpa.account.link'], { provider: context.provider })}
{formatMessage(messages['tpa.account.link'], { provider: context.provider })}
</a>
);
errorList = (
@@ -90,12 +92,12 @@ const LoginFailureMessage = (props) => {
break;
}
case INVALID_FORM:
errorList = <p>{intl.formatMessage(messages['login.form.invalid.error.message'])}</p>;
errorList = <p>{formatMessage(messages['login.form.invalid.error.message'])}</p>;
break;
case FAILED_LOGIN_ATTEMPT: {
resetLink = (
<Hyperlink destination="reset" isInline>
{intl.formatMessage(messages['login.incorrect.credentials.error.before.account.blocked.text'])}
{formatMessage(messages['login.incorrect.credentials.error.before.account.blocked.text'])}
</Hyperlink>
);
errorList = (
@@ -124,7 +126,7 @@ const LoginFailureMessage = (props) => {
case ACCOUNT_LOCKED_OUT: {
errorList = (
<>
<p>{intl.formatMessage(messages['account.locked.out.message.1'])}</p>
<p>{formatMessage(messages['account.locked.out.message.1'])}</p>
<p>
<FormattedMessage
id="account.locked.out.message.2"
@@ -139,7 +141,7 @@ const LoginFailureMessage = (props) => {
}
case INCORRECT_EMAIL_PASSWORD:
if (context.failureCount <= 1) {
errorList = <p>{intl.formatMessage(messages['login.incorrect.credentials.error'])}</p>;
errorList = <p>{formatMessage(messages['login.incorrect.credentials.error'])}</p>;
} else if (context.failureCount === 2) {
errorList = (
<p>
@@ -165,15 +167,25 @@ const LoginFailureMessage = (props) => {
);
case REQUIRE_PASSWORD_CHANGE:
return <ChangePasswordPrompt />;
case TPA_AUTHENTICATION_FAILURE:
errorList = (
<p>{formatMessage(messages['login.tpa.authentication.failure'], {
platform_name: getConfig().SITE_NAME,
lineBreak: <br />,
errorMessage: context.errorMessage,
})}
</p>
);
break;
case INTERNAL_SERVER_ERROR:
default:
errorList = <p>{intl.formatMessage(messages['internal.server.error.message'])}</p>;
errorList = <p>{formatMessage(messages['internal.server.error.message'])}</p>;
break;
}
return (
<Alert id="login-failure-alert" className="mb-5" variant="danger" icon={Error}>
<Alert.Heading>{intl.formatMessage(messages['login.failure.header.title'])}</Alert.Heading>
<Alert.Heading>{formatMessage(messages['login.failure.header.title'])}</Alert.Heading>
{ errorList }
</Alert>
);
@@ -183,17 +195,26 @@ LoginFailureMessage.defaultProps = {
loginError: {
redirectUrl: null,
errorCode: null,
errorMessage: null,
},
};
LoginFailureMessage.propTypes = {
loginError: PropTypes.shape({
context: PropTypes.object,
context: PropTypes.shape({
supportLink: PropTypes.string,
platformName: PropTypes.string,
tpaHint: PropTypes.string,
provider: PropTypes.string,
allowedDomain: PropTypes.string,
remainingAttempts: PropTypes.number,
failureCount: PropTypes.number,
errorMessage: PropTypes.string,
}),
email: PropTypes.string,
errorCode: PropTypes.string,
redirectUrl: PropTypes.string,
}),
intl: intlShape.isRequired,
};
export default injectIntl(LoginFailureMessage);
export default LoginFailureMessage;

View File

@@ -3,7 +3,7 @@ import { connect } from 'react-redux';
import { getConfig } from '@edx/frontend-platform';
import { sendPageEvent, sendTrackEvent } from '@edx/frontend-platform/analytics';
import { injectIntl, intlShape } from '@edx/frontend-platform/i18n';
import { injectIntl } from '@edx/frontend-platform/i18n';
import {
Form, Hyperlink, Icon, StatefulButton,
} from '@edx/paragon';
@@ -13,6 +13,14 @@ import { Helmet } from 'react-helmet';
import Skeleton from 'react-loading-skeleton';
import { Link } from 'react-router-dom';
import AccountActivationMessage from './AccountActivationMessage';
import {
loginRemovePasswordResetBanner, loginRequest, loginRequestFailure, loginRequestReset, setLoginFormData,
} from './data/actions';
import { INVALID_FORM, TPA_AUTHENTICATION_FAILURE } from './data/constants';
import { loginErrorSelector, loginFormDataSelector, loginRequestSelector } from './data/selectors';
import LoginFailureMessage from './LoginFailure';
import messages from './messages';
import {
FormGroup, InstitutionLogistration, PasswordField, RedirectLogistration,
RenderInstitutionButton, SocialAuthProviders, ThirdPartyAuthAlert,
@@ -25,7 +33,7 @@ import {
} from '../data/constants';
import {
getActivationStatus,
getAllPossibleQueryParam,
getAllPossibleQueryParams,
getTpaHint,
getTpaProvider,
setSurveyCookie,
@@ -33,14 +41,6 @@ import {
windowScrollTo,
} from '../data/utils';
import ResetPasswordSuccess from '../reset-password/ResetPasswordSuccess';
import AccountActivationMessage from './AccountActivationMessage';
import {
loginRemovePasswordResetBanner, loginRequest, loginRequestFailure, loginRequestReset, setLoginFormData,
} from './data/actions';
import { INVALID_FORM } from './data/constants';
import { loginErrorSelector, loginFormDataSelector, loginRequestSelector } from './data/selectors';
import LoginFailureMessage from './LoginFailure';
import messages from './messages';
class LoginPage extends React.Component {
constructor(props, context) {
@@ -54,7 +54,7 @@ class LoginPage extends React.Component {
},
isSubmitted: false,
};
this.queryParams = getAllPossibleQueryParam();
this.queryParams = getAllPossibleQueryParams();
this.tpaHint = getTpaHint();
}
@@ -122,7 +122,7 @@ class LoginPage extends React.Component {
email_or_username: emailOrUsername, password, ...this.queryParams,
};
this.props.loginRequest(payload);
}
};
handleOnFocus = (e) => {
const { errors } = this.state;
@@ -130,14 +130,14 @@ class LoginPage extends React.Component {
this.props.setLoginFormData({
errors,
});
}
};
handleOnBlur = (e) => {
const payload = {
[e.target.name]: e.target.value,
};
this.props.setLoginFormData(payload);
}
};
handleForgotPasswordLinkClickEvent = () => {
sendTrackEvent('edx.bi.password-reset_form.toggled', { category: 'user-engagement' });
@@ -167,7 +167,6 @@ class LoginPage extends React.Component {
const isInstitutionAuthActive = !!secondaryProviders.length && !currentProvider;
const isSocialAuthActive = !!providers.length && !currentProvider;
const isEnterpriseLoginDisabled = getConfig().DISABLE_ENTERPRISE_LOGIN;
const isThirdPartyAuthActive = isSocialAuthActive || (isEnterpriseLoginDisabled && isInstitutionAuthActive);
return (
<>
@@ -185,7 +184,7 @@ class LoginPage extends React.Component {
</Hyperlink>
)}
{thirdPartyAuthApiStatus === PENDING_STATE && isThirdPartyAuthActive ? (
{thirdPartyAuthApiStatus === PENDING_STATE ? (
<Skeleton className="tpa-skeleton mb-3" height={30} count={2} />
) : (
<>
@@ -224,16 +223,17 @@ class LoginPage extends React.Component {
/>
);
}
const tpaAuthenticationError = {};
if (thirdPartyAuthContext.errorMessage) {
tpaAuthenticationError.context = {
errorMessage: thirdPartyAuthContext.errorMessage,
};
tpaAuthenticationError.errorCode = TPA_AUTHENTICATION_FAILURE;
}
if (this.props.loginResult.success) {
window.parent.postMessage({ loggedin: true, redirectUrl: this.props.loginResult.redirectUrl }, 'https://discover.edx.org/social-reg');
setSurveyCookie('login');
// Fire optimizely events
window.optimizely = window.optimizely || [];
window.optimizely.push({
type: 'event',
eventName: 'authn-login-coversion',
});
return null;
}
return (
@@ -243,20 +243,18 @@ class LoginPage extends React.Component {
{ siteName: getConfig().SITE_NAME })}
</title>
</Helmet>
<RedirectLogistration
success={this.props.loginResult.success}
redirectUrl={this.props.loginResult.redirectUrl}
finishAuthUrl={thirdPartyAuthContext.finishAuthUrl}
/>
{/*<RedirectLogistration*/}
{/* success={this.props.loginResult.success}*/}
{/* redirectUrl={this.props.loginResult.redirectUrl}*/}
{/* finishAuthUrl={thirdPartyAuthContext.finishAuthUrl}*/}
{/*/>*/}
<div className="mw-xs mt-3">
{thirdPartyAuthContext.currentProvider
&& (
<ThirdPartyAuthAlert
currentProvider={thirdPartyAuthContext.currentProvider}
platformName={thirdPartyAuthContext.platformName}
/>
)}
<ThirdPartyAuthAlert
currentProvider={thirdPartyAuthContext.currentProvider}
platformName={thirdPartyAuthContext.platformName}
/>
{this.props.loginError ? <LoginFailureMessage loginError={this.props.loginError} /> : null}
{thirdPartyAuthContext.errorMessage ? <LoginFailureMessage loginError={tpaAuthenticationError} /> : null}
{submitState === DEFAULT_STATE && this.state.isSubmitted ? windowScrollTo({ left: 0, top: 0, behavior: 'smooth' }) : null}
{activationMsgType && <AccountActivationMessage messageType={activationMsgType} />}
{this.props.resetPassword && !this.props.loginError ? <ResetPasswordSuccess /> : null}
@@ -296,16 +294,16 @@ class LoginPage extends React.Component {
onClick={this.handleSubmit}
onMouseDown={(e) => e.preventDefault()}
/>
<Link
id="forgot-password"
name="forgot-password"
className="btn btn-link font-weight-500 text-body"
to={updatePathWithQueryParams(RESET_PAGE)}
onClick={this.handleForgotPasswordLinkClickEvent}
>
{intl.formatMessage(messages['forgot.password'])}
</Link>
{this.renderThirdPartyAuth(providers, secondaryProviders, currentProvider, thirdPartyAuthApiStatus, intl)}
{/*<Link*/}
{/* id="forgot-password"*/}
{/* name="forgot-password"*/}
{/* className="btn btn-link font-weight-500 text-body"*/}
{/* to={updatePathWithQueryParams(RESET_PAGE)}*/}
{/* onClick={this.handleForgotPasswordLinkClickEvent}*/}
{/*>*/}
{/* {intl.formatMessage(messages['forgot.password'])}*/}
{/*</Link>*/}
{/*{this.renderThirdPartyAuth(providers, secondaryProviders, currentProvider, thirdPartyAuthApiStatus, intl)}*/}
</Form>
</div>
</>
@@ -365,6 +363,7 @@ LoginPage.defaultProps = {
thirdPartyAuthApiStatus: 'pending',
thirdPartyAuthContext: {
currentProvider: null,
errorMessage: null,
finishAuthUrl: null,
providers: [],
secondaryProviders: [],
@@ -373,8 +372,10 @@ LoginPage.defaultProps = {
LoginPage.propTypes = {
getThirdPartyAuthContext: PropTypes.func.isRequired,
intl: intlShape.isRequired,
loginError: PropTypes.objectOf(PropTypes.any),
intl: PropTypes.shape({
formatMessage: PropTypes.func,
}).isRequired,
loginError: PropTypes.shape({}),
loginRequest: PropTypes.func.isRequired,
loginRequestFailure: PropTypes.func.isRequired,
loginRequestReset: PropTypes.func.isRequired,
@@ -397,9 +398,10 @@ LoginPage.propTypes = {
thirdPartyAuthApiStatus: PropTypes.string,
thirdPartyAuthContext: PropTypes.shape({
currentProvider: PropTypes.string,
errorMessage: PropTypes.string,
platformName: PropTypes.string,
providers: PropTypes.array,
secondaryProviders: PropTypes.array,
providers: PropTypes.arrayOf(PropTypes.shape({})),
secondaryProviders: PropTypes.arrayOf(PropTypes.shape({})),
finishAuthUrl: PropTypes.string,
}),
institutionLogin: PropTypes.bool.isRequired,

View File

@@ -10,6 +10,7 @@ export const INCORRECT_EMAIL_PASSWORD = 'incorrect-email-or-password';
export const NUDGE_PASSWORD_CHANGE = 'nudge-password-change';
export const REQUIRE_PASSWORD_CHANGE = 'require-password-change';
export const ALLOWED_DOMAIN_LOGIN_ERROR = 'allowed-domain-login-error';
export const TPA_AUTHENTICATION_FAILURE = 'tpa-authentication-failure';
// Account Activation Message
export const ACCOUNT_ACTIVATION_MESSAGE = {

View File

@@ -1,6 +1,6 @@
import { LOGIN_PERSIST_FORM_DATA, LOGIN_REMOVE_PASSWORD_RESET_BANNER, LOGIN_REQUEST } from './actions';
import { DEFAULT_STATE, PENDING_STATE } from '../../data/constants';
import { RESET_PASSWORD } from '../../reset-password';
import { LOGIN_PERSIST_FORM_DATA, LOGIN_REMOVE_PASSWORD_RESET_BANNER, LOGIN_REQUEST } from './actions';
export const defaultState = {
loginError: null,
@@ -16,7 +16,7 @@ export const defaultState = {
},
};
const reducer = (state = defaultState, action) => {
const reducer = (state = defaultState, action = {}) => {
switch (action.type) {
case LOGIN_REQUEST.BEGIN:
return {

View File

@@ -22,36 +22,11 @@ const messages = defineMessages({
defaultMessage: 'Sign in',
description: 'Sign in button label that appears on login page',
},
'sign.in.btn.pending.state': {
id: 'sign.in.btn.pending.state',
defaultMessage: 'Loading',
description: 'Title of icon that appears when button is in pending state',
},
'need.help.signing.in.collapsible.menu': {
id: 'need.help.signing.in.collapsible.menu',
defaultMessage: 'Need help signing in?',
description: 'A button for collapsible need help signing in menu on login page',
},
'forgot.password.link': {
id: 'forgot.password.link',
defaultMessage: 'Forgot my password',
description: 'Forgot password link',
},
'forgot.password': {
id: 'forgot.password',
defaultMessage: 'Forgot password',
description: 'Button text for forgot password',
},
'other.sign.in.issues': {
id: 'other.sign.in.issues',
defaultMessage: 'Other sign in issues',
description: 'A link that redirects to sign-in issues help',
},
'need.other.help.signing.in.collapsible.menu': {
id: 'need.other.help.signing.in.collapsible.menu',
defaultMessage: 'Need other help signing in?',
description: 'A button for collapsible need other help signing in menu on forgot password page',
},
'institution.login.button': {
id: 'institution.login.button',
defaultMessage: 'Institution/campus credentials',
@@ -67,16 +42,6 @@ const messages = defineMessages({
defaultMessage: 'Choose your institution from the list below',
description: 'Heading of the institutions list',
},
'institution.login.page.back.button': {
id: 'institution.login.page.back.button',
defaultMessage: 'Back to sign in',
description: 'return to login page',
},
'create.an.account': {
id: 'create.an.account',
defaultMessage: 'Create an account',
description: 'Message on button to return to register page',
},
'login.other.options.heading': {
id: 'login.other.options.heading',
defaultMessage: 'Or sign in with:',
@@ -99,26 +64,11 @@ const messages = defineMessages({
defaultMessage: 'To protect your account, it\'s been temporarily locked. Try again in 30 minutes.',
description: 'Part of message for when user account has been locked out after multiple failed login attempts',
},
'first.time.here': {
id: 'first.time.here',
defaultMessage: 'First time here?',
description: 'A question that appears before sign up link',
},
'email.help.message': {
id: 'email.help.message',
defaultMessage: 'The email address you used to register with edX.',
description: 'Message that appears below email field on login page',
},
'enterprise.login.btn.text': {
id: 'enterprise.login.btn.text',
defaultMessage: 'Company or school credentials',
description: 'Company or school login link text.',
},
'email.format.validation.message': {
id: 'email.format.validation.message',
defaultMessage: 'The email address you\'ve provided isn\'t formatted correctly.',
description: 'Validation message that appears when email address format is incorrect',
},
'username.or.email.format.validation.less.chars.message': {
id: 'username.or.email.format.validation.less.chars.message',
defaultMessage: 'Username or email must have at least 3 characters.',
@@ -134,16 +84,6 @@ const messages = defineMessages({
defaultMessage: 'Enter your password',
description: 'Validation message that appears when password is empty',
},
'register.link': {
id: 'register.link',
defaultMessage: 'Create an account',
description: 'Register page link',
},
'sign.in.heading': {
id: 'sign.in.heading',
defaultMessage: 'Sign in',
description: 'Sign in text',
},
// Account Activation Strings
'account.activation.success.message.title': {
id: 'account.activation.success.message.title',
@@ -170,11 +110,6 @@ const messages = defineMessages({
defaultMessage: 'contact support',
description: 'Link text used in account activation error message to go to learner help center',
},
'tpa.account.link': {
id: 'tpa.account.link',
defaultMessage: '{provider} account',
description: 'Link text error message used to go to SSO when staff user try to login through password.',
},
// Email Confirmation Strings
'account.confirmation.success.message.title': {
id: 'account.confirmation.success.message.title',
@@ -196,6 +131,11 @@ const messages = defineMessages({
defaultMessage: 'Your email could not be confirmed',
description: 'Account verification error message title',
},
'tpa.account.link': {
id: 'tpa.account.link',
defaultMessage: '{provider} account',
description: 'Link text error message used to go to SSO when staff user try to login through password.',
},
'internal.server.error.message': {
id: 'internal.server.error.message',
defaultMessage: 'An error has occurred. Try refreshing the page, or check your internet connection.',
@@ -221,16 +161,6 @@ const messages = defineMessages({
defaultMessage: 'The username, email, or password you entered is incorrect. Please try again.',
description: 'Error message for incorrect email or password',
},
'login.failed.attempt.error': {
id: 'login.failed.attempt.error',
defaultMessage: 'You have {remainingAttempts} more sign in attempts before your account is temporarily locked.',
description: 'Failed login attempts error message',
},
'login.locked.out.error.message': {
id: 'login.locked.out.error.message',
defaultMessage: 'To protect your account, its been temporarily locked. Try again in {lockedOutPeriod} minutes.',
description: 'Account locked out user message',
},
'login.form.invalid.error.message': {
id: 'login.form.invalid.error.message',
defaultMessage: 'Please fill in the fields below.',
@@ -279,6 +209,13 @@ const messages = defineMessages({
defaultMessage: 'Reset your password',
description: 'Button to redirect users to Reset Password page',
},
'login.tpa.authentication.failure': {
id: 'login.tpa.authentication.failure',
defaultMessage: 'We are sorry, you are not authorized to access {platform_name} via this channel. '
+ 'Please contact your learning administrator or manager in order to access {platform_name}.'
+ '{lineBreak}{lineBreak}Error Details:{lineBreak}{errorMessage}',
description: 'Error message third party authentication pipeline fails',
},
});
export default messages;

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