diff --git a/Dockerfile b/Dockerfile index 7691feebdc..123609baf1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -4,10 +4,14 @@ FROM node:8.11.2 LABEL app="Community App" version="1.0" +RUN useradd -m -s /bin/bash appuser WORKDIR /opt/app COPY . . +RUN chown -R appuser:appuser /opt/app +USER appuser + ################################################################################ # Receiving of build arguments. diff --git a/__tests__/shared/components/Settings/Account/__snapshots__/index.jsx.snap b/__tests__/shared/components/Settings/Account/__snapshots__/index.jsx.snap deleted file mode 100644 index 207666379e..0000000000 --- a/__tests__/shared/components/Settings/Account/__snapshots__/index.jsx.snap +++ /dev/null @@ -1,2132 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`renders account setting page correctly 1`] = ` - -
-
-

- Account information & Security -

-
- - - -
-
- - Save Changes - -
-
-`; diff --git a/__tests__/shared/components/Settings/Account/index.jsx b/__tests__/shared/components/Settings/Account/index.jsx deleted file mode 100644 index 0bd72d407d..0000000000 --- a/__tests__/shared/components/Settings/Account/index.jsx +++ /dev/null @@ -1,32 +0,0 @@ -import React from 'react'; -import Renderer from 'react-test-renderer/shallow'; - -import Account from 'components/Settings/Account'; - -import userProfile from '../__mocks__/user-profile.json'; -import profileState from '../__mocks__/profile-state.json'; - -const rnd = new Renderer(); - -const settingsUI = { - TABS: { - ACCOUNT: { - MYACCOUNT: 'my account', - // LINKEDACCOUNT: 'linked account', - }, - }, -}; - -it('renders account setting page correctly', () => { - rnd.render(( {}} - clearIncorrectPassword={() => {}} - updateProfile={() => {}} - settingsUI={settingsUI} - />)); - expect(rnd.getRenderOutput()).toMatchSnapshot(); -}); diff --git a/__tests__/shared/components/challenge-listing/Sidebar/__snapshots__/Footer.jsx.snap b/__tests__/shared/components/challenge-listing/Sidebar/__snapshots__/Footer.jsx.snap index 88fbc5b716..d5a3513f5d 100644 --- a/__tests__/shared/components/challenge-listing/Sidebar/__snapshots__/Footer.jsx.snap +++ b/__tests__/shared/components/challenge-listing/Sidebar/__snapshots__/Footer.jsx.snap @@ -69,7 +69,7 @@ exports[`Matches shallow shapshot 1`] = ` className="src-shared-components-challenge-listing-Sidebar-Footer-___style__copyright___ghkHg" > Topcoder © - 2024 + 2025

`; diff --git a/automated-smoke-test/Dockerfile b/automated-smoke-test/Dockerfile index b228769e64..a5ad40ec6a 100644 --- a/automated-smoke-test/Dockerfile +++ b/automated-smoke-test/Dockerfile @@ -1,4 +1,5 @@ FROM node:10.17.0-stretch +RUN useradd -m -s /bin/bash appuser RUN apt update RUN apt install sudo RUN sudo apt-get update; sudo apt-get install -y openjdk-8-jre openjdk-8-jre-headless openjdk-8-jdk openjdk-8-jdk-headless; @@ -26,6 +27,8 @@ RUN printf '#!/bin/sh\nXvfb :99 -screen 0 1280x1024x24 &\nexec "$@"\n' > /tmp/en COPY . /automated-smoke-test WORKDIR /automated-smoke-test +RUN chown -R appuser:appuser /automated-smoke-test +USER appuser RUN npm install RUN ./node_modules/.bin/webdriver-manager update --versions.chrome=="$(google-chrome -version)" ENTRYPOINT ["/docker-entrypoint.sh"] diff --git a/automated-smoke-test/config/automation-config-dev.json b/automated-smoke-test/config/automation-config-dev.json index 4df4b85ad3..9ac9bf711d 100644 --- a/automated-smoke-test/config/automation-config-dev.json +++ b/automated-smoke-test/config/automation-config-dev.json @@ -86,7 +86,6 @@ "allNotificationsUrl": "https://community-app.topcoder-dev.com/notifications", "policiesUrl": "https://community-app.topcoder-dev.com/policy", "username": "tester1234", - "password": "appirio123", "email": "sathya.jayabal@gmail.com", "challangesLinks": { "rssFeedUrl": "http://feeds.topcoder-dev.com/challenges/feed", diff --git a/automated-smoke-test/config/automation-config-local.json b/automated-smoke-test/config/automation-config-local.json index 79f61ba285..c2ca342f56 100644 --- a/automated-smoke-test/config/automation-config-local.json +++ b/automated-smoke-test/config/automation-config-local.json @@ -81,7 +81,6 @@ "allNotificationsUrl": "http://localhost:3000/notifications", "policiesUrl": "http://localhost:3000/policy", "username": "Tonyj", - "password": "appirio123", "email": "topcoderconnect@gmail.com", "challangesLinks": { "rssFeedUrl": "http://feeds.topcoder.com/challenges/feed", diff --git a/automated-smoke-test/config/automation-config-prod.json b/automated-smoke-test/config/automation-config-prod.json index ed2fc420de..d05c56008c 100644 --- a/automated-smoke-test/config/automation-config-prod.json +++ b/automated-smoke-test/config/automation-config-prod.json @@ -81,7 +81,6 @@ "allNotificationsUrl": "https://www.topcoder.com/notifications", "policiesUrl": "https://www.topcoder.com/policy", "username": "CustomerUser", - "password": "appirio123", "email": "topcoderconnect@gmail.com", "challangesLinks": { "rssFeedUrl": "http://feeds.topcoder.com/challenges/feed", diff --git a/automated-smoke-test/test-data/test-data.json b/automated-smoke-test/test-data/test-data.json index 02aa602405..98fcf8a0bc 100644 --- a/automated-smoke-test/test-data/test-data.json +++ b/automated-smoke-test/test-data/test-data.json @@ -1,7 +1,6 @@ { "login": { - "invalidUsername": "gjhhvv", - "invalidPassword": "invalidpassword" + "invalidUsername": "gjhhvv" }, "tools": { "subscription": "Sample A", diff --git a/src/shared/components/Contentful/Article/Article.jsx b/src/shared/components/Contentful/Article/Article.jsx index d15b08c260..772a0afb0a 100644 --- a/src/shared/components/Contentful/Article/Article.jsx +++ b/src/shared/components/Contentful/Article/Article.jsx @@ -139,7 +139,7 @@ class Article extends React.Component { } = this.state || {}; let shareUrl; if (isomorphy.isClientSide()) { - shareUrl = encodeURIComponent(window.location.href); + shareUrl = encodeURIComponent(`${window.location.origin}${window.location.pathname}`); } const description = htmlToText.fromString( ReactDOMServer.renderToString(markdown(fields.content)), diff --git a/src/shared/components/Gigs/GigApply/index.jsx b/src/shared/components/Gigs/GigApply/index.jsx index a36919c2bf..53d6b557bc 100644 --- a/src/shared/components/Gigs/GigApply/index.jsx +++ b/src/shared/components/Gigs/GigApply/index.jsx @@ -36,7 +36,7 @@ export default function GigApply(props) { recruitProfile, auth, } = props; - const retUrl = window.location.href; + const retUrl = encodeURIComponent(`${window.location.origin}${window.location.pathname}`); const duration = getCustomField(job.custom_fields, 'Duration'); const isPlaced = _.find(_.isEmpty(recruitProfile) ? [] : recruitProfile.custom_fields, { field_id: 12 }); const fetchSkills = useMemo(() => _.debounce((inputValue, callback) => { @@ -353,9 +353,9 @@ export default function GigApply(props) {

You must be a Topcoder member to apply!

- Login + Login
-

Not a member? Register here.

+

Not a member? Register here.

diff --git a/src/shared/components/Settings/Account/LinkedAccount/AddWebLink.jsx b/src/shared/components/Settings/Account/LinkedAccount/AddWebLink.jsx deleted file mode 100644 index d807114ece..0000000000 --- a/src/shared/components/Settings/Account/LinkedAccount/AddWebLink.jsx +++ /dev/null @@ -1,234 +0,0 @@ -/** - * Renders 'Add a Web Link' section. - */ -/* eslint-disable jsx-a11y/label-has-for */ -import React from 'react'; -import _ from 'lodash'; -import PT from 'prop-types'; -import { PrimaryButton } from 'topcoder-react-ui-kit'; -import './styles.scss'; - -export default class AddWebLink extends React.Component { - constructor(props) { - super(props); - this.state = { - webLink: '', - webLinkEmpty: false, - }; - - this.onUpdateWebLink = this.onUpdateWebLink.bind(this); - this.onAddWebLink = this.onAddWebLink.bind(this); - this.isWebLinkValid = this.isWebLinkValid.bind(this); - this.webLinkExist = this.webLinkExist.bind(this); - this.onAddWebLinkButton = this.onAddWebLinkButton.bind(this); - } - - componentWillReceiveProps(nextProps) { - const { profileState } = this.props; - if (profileState.addingWebLink && !nextProps.profileState.addingWebLink) { - this.setState({ webLink: '' }); - } - } - - // Set web link - onUpdateWebLink(e) { - e.preventDefault(); - if (e.target.value) { - this.setState({ - webLinkEmpty: false, - }); - } - this.setState({ webLink: e.target.value }); - } - - // Add web link - onAddWebLink(e) { - if (e.keyCode === 13 && e.shiftKey === false) { - e.preventDefault(); - e.stopPropagation(); - const { - addWebLink, - handle, - tokenV3, - } = this.props; - const { webLink } = this.state; - if (webLink && this.isWebLinkValid() && !this.webLinkExist()) { - addWebLink(handle, tokenV3, webLink); - } - } - } - - // Add web link - onAddWebLinkButton(e) { - e.preventDefault(); - e.stopPropagation(); - const { - addWebLink, - handle, - tokenV3, - } = this.props; - const { webLink } = this.state; - if (!webLink) { - this.setState({ - webLinkEmpty: true, - }); - } - if (webLink && this.isWebLinkValid() && !this.webLinkExist()) { - addWebLink(handle, tokenV3, webLink); - } - } - - isWebLinkValid() { - const { webLink } = this.state; - return !webLink - || /^(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$/.test(webLink); /* eslint-disable-line no-useless-escape */ - } - - webLinkExist() { - const { webLink } = this.state; - const { - allLinks, - } = this.props; - return _.some(allLinks, link => link.URL && (link.URL.toLowerCase().replace(/https?:\/\//, '') === webLink.toLowerCase().replace(/https?:\/\//, ''))); - } - - render() { - const { webLink, webLinkEmpty } = this.state; - - const webLinkValid = this.isWebLinkValid(); - const webLinkExist = this.webLinkExist(); - - return ( -
-
-
-
-
-
- Add Link -
-
-
-
- -
- - { - !webLinkValid && !webLinkExist - && ( -
-

- Please enter a valid URL -

-
- ) - } - { - webLinkExist - && ( -
-

- {`The URL ${webLink} already exists`} -

-
- ) - } -
-
-
-
-
- - Add Link - -
-
-
- Add a new external link -
-
- -
- - { - webLinkEmpty && ( -
-

- Please Enter External Link -

-
- ) - } - { - !webLinkValid && !webLinkExist - && ( -
-

- Please enter a valid URL -

-
- ) - } - { - webLinkExist - && ( -
-

- {`The URL ${webLink} already exists`} -

-
- ) - } -
- Add Link -
-
-
- ); - } -} - -AddWebLink.defaultProps = { - allLinks: [], -}; - -AddWebLink.propTypes = { - handle: PT.string.isRequired, - tokenV3: PT.string.isRequired, - profileState: PT.shape().isRequired, - addWebLink: PT.func.isRequired, - allLinks: PT.arrayOf(PT.shape), -}; diff --git a/src/shared/components/Settings/Account/LinkedAccount/ExistingLink.jsx b/src/shared/components/Settings/Account/LinkedAccount/ExistingLink.jsx deleted file mode 100644 index 27fb7c9019..0000000000 --- a/src/shared/components/Settings/Account/LinkedAccount/ExistingLink.jsx +++ /dev/null @@ -1,286 +0,0 @@ -/** - * Renders an existing link. - */ -/* global window */ -/* eslint-disable jsx-a11y/interactive-supports-focus */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ -import _ from 'lodash'; - -import React from 'react'; -import PT from 'prop-types'; -import SocialIcons from './SocialIcons'; - -import './styles.scss'; - -/** - * Prepend http protocol to url link if not already exist. - * @param {String} link The url link - * @returns {String} url link with http protocol prepend - */ -function prependProtocol(link) { - if (!link) { - return link; - } - const httpProtocol = 'http://'; - const httpsProtocol = 'https://'; - if (link.startsWith(httpProtocol) || link.startsWith(httpsProtocol)) { - return link; - } - return httpProtocol + link; -} - -/** - * Open user's external link (like github profile page) in new tab - * @param {Event} e The click event - * @param {Object} user's external link - */ -function openLink(e, link) { - if (!link) { - return; - } - - if (e.target.id === 'link-url') { - return; - } - - let url = null; - if (link.data && link.data.profileURL) { - url = link.data.profileURL; - } else if (link.URL) { - url = link.URL; - } - - if (url) { - window.open(prependProtocol(url), '_blank'); - } -} - -export default function ExistingLink(props) { - const { link, supportedAccounts, onConfirmDeleteLink } = props; - - const pending = link.status === 'pending'; - const logoClass = _.result(_.find(supportedAccounts, a => a.providerType === link.providerType), 'className') || 'fa-globe'; - - return ( -
openLink(e, link)}> -
-
{ - e.preventDefault(); - e.stopPropagation(); - onConfirmDeleteLink(e, link); - }} - styleName={`ext-link-tile_edit-header_delete ${link.deleting ? 'ext-link-tile_edit-header_delete--disabled' : ''}`} - /> -
-
-
- {link.providerType === 'weblink' - ? - : icon - } -
-

- {link.providerType} -

-
-
- { - link.deleting - && ( -
- ) - } - { - !link.deleting && link.providerType === 'weblink' - && ( -
-

- {link.title} -

-

- Loading data. This will take a few minutes. -

- - {prependProtocol(link.URL)} - -
- ) - } - { - !link.deleting && link.providerType === 'linkedin' - && ( -
-
- {link.data.handle} -
-
- {link.data.title} -
-
- ) - } - { - !link.deleting && link.providerType !== 'weblink' && link.providerType !== 'linkedin' - && ( -
-
- {link.data.handle} -
-
-

- Loading data. This will take a few minutes. -

-
- { - link.providerType === 'github' - && ( -
    -
  • -
    - {link.data.followers || 0} -
    -
    - followers -
    -
  • -
  • -
    - {link.data.publicRepos || 0} -
    -
    - repositories -
    -
  • -
- ) - } - { - link.providerType === 'stackoverflow' - && ( -
    -
  • -
    - {link.data.reputation || 0} -
    -
    - reputation -
    -
  • -
  • -
    - {link.data.answers || 0} -
    -
    - answers -
    -
  • -
- ) - } - { - link.providerType === 'behance' - && ( -
    -
  • -
    - {link.data.projectViews || 0} -
    -
    - views -
    -
  • -
  • -
    - {link.data.projectAppreciations || 0} -
    -
    - likes -
    -
  • -
- ) - } - { - link.providerType === 'dribbble' - && ( -
    -
  • -
    - {link.data.followers || 0} -
    -
    - followers -
    -
  • -
  • -
    - {link.data.likes || 0} -
    -
    - likes -
    -
  • -
- ) - } - { - link.providerType === 'bitbucket' - && ( -
    -
  • -
    - {link.data.followers || 0} -
    -
    - followers -
    -
  • -
  • -
    - {link.data.repos || 0} -
    -
    - repositories -
    -
  • -
- ) - } - { - link.providerType === 'twitter' - && ( -
    -
  • -
    - {link.data.noOfTweets || 0} -
    -
    - tweets -
    -
  • -
  • -
    - TBD -
    -
    - followers -
    -
  • -
- ) - } -
- ) - } -
-
- ); -} - -ExistingLink.propTypes = { - link: PT.shape().isRequired, - supportedAccounts: PT.arrayOf(PT.shape()).isRequired, - onConfirmDeleteLink: PT.func.isRequired, -}; diff --git a/src/shared/components/Settings/Account/LinkedAccount/ExistingLinks.jsx b/src/shared/components/Settings/Account/LinkedAccount/ExistingLinks.jsx deleted file mode 100644 index 976a9ec519..0000000000 --- a/src/shared/components/Settings/Account/LinkedAccount/ExistingLinks.jsx +++ /dev/null @@ -1,145 +0,0 @@ -/** - * Renders 'Existing Links' section. - */ -/* eslint-disable no-unused-vars */ -import _ from 'lodash'; -import React from 'react'; -import PT from 'prop-types'; - -import ConsentComponent from 'components/Settings/ConsentComponent'; -import { Modal, PrimaryButton, GhostButton } from 'topcoder-react-ui-kit'; - -import ExistingLink from './ExistingLink'; - -import Styles from './styles.scss'; -import modal from './modal.scss'; - -export default class ExistingLinks extends ConsentComponent { - constructor(props) { - super(props); - this.state = { - linkToConfirmDelete: null, - }; - this.onHandleConfirmDeleteLink = this.onHandleConfirmDeleteLink.bind(this); - this.onConfirmDeleteLink = this.onConfirmDeleteLink.bind(this); - this.onDeleteLink = this.onDeleteLink.bind(this); - } - - onHandleConfirmDeleteLink(e, link) { - e.preventDefault(); - e.stopPropagation(); - this.showConsent(this.onConfirmDeleteLink.bind(this, link)); - } - - // Confirm delete link function - onConfirmDeleteLink(link) { - if (!link || link.deleting) { - return; - } - this.setState({ linkToConfirmDelete: link }); - } - - // Delete link function - onDeleteLink(e) { - e.preventDefault(); - e.stopPropagation(); - const { - deleteWebLink, - handle, - profile, - tokenV3, - unlinkExternalAccount, - } = this.props; - - const { linkToConfirmDelete } = this.state; - - if (!linkToConfirmDelete || linkToConfirmDelete.deleting) { - return; - } - this.setState({ linkToConfirmDelete: null }); - - if (linkToConfirmDelete.providerType === 'weblink') { - deleteWebLink(handle, tokenV3, linkToConfirmDelete); - } else { - unlinkExternalAccount( - profile, - tokenV3, - linkToConfirmDelete.providerType, - ); - } - } - - render() { - const { - allLinks, - supportedAccounts, - } = this.props; - - const { linkToConfirmDelete } = this.state; - - return ( -
- { - this.shouldRenderConsent() && this.renderConsent() - } - { - linkToConfirmDelete - && ( - -
-
-
- DELETE CONFIRMATION -
-
- Are you sure you want to delete the external link - - " - {linkToConfirmDelete.providerType === 'weblink' ? linkToConfirmDelete.URL : linkToConfirmDelete.providerType} - " - - ? This action can't be undone later. -
-
-
- - Yes, Delete Link - -
-
- this.setState({ linkToConfirmDelete: null })}> - Cancel - -
-
-
-
-
- ) - } -
- { - _.map(allLinks, link => ( - - )) - } -
-
- ); - } -} - -ExistingLinks.propTypes = { - handle: PT.string.isRequired, - tokenV3: PT.string.isRequired, - profile: PT.shape().isRequired, - allLinks: PT.arrayOf(PT.shape()).isRequired, - supportedAccounts: PT.arrayOf(PT.shape()).isRequired, - deleteWebLink: PT.func.isRequired, - unlinkExternalAccount: PT.func.isRequired, -}; diff --git a/src/shared/components/Settings/Account/LinkedAccount/LinkAccounts.jsx b/src/shared/components/Settings/Account/LinkedAccount/LinkAccounts.jsx deleted file mode 100644 index 476120b357..0000000000 --- a/src/shared/components/Settings/Account/LinkedAccount/LinkAccounts.jsx +++ /dev/null @@ -1,125 +0,0 @@ -/** - * Renders 'Link Your Accounts' section. - */ -/* eslint-disable jsx-a11y/interactive-supports-focus */ -/* eslint-disable jsx-a11y/click-events-have-key-events */ -import _ from 'lodash'; -import React from 'react'; -import PT from 'prop-types'; -import ImageFilter from 'react-image-filter'; -import SocialIcons from './SocialIcons'; - -import './styles.scss'; - -function getStyleName(account) { - let style = 'ext-tile'; - if (account.disabled) { - style += ' disabled'; - } else { - style += ' enabled'; - } - - if (account.status === 'linked') { - style += ' connected'; - } else if (account.status === 'pending') { - style += ' connecting'; - } else if (account.status === 'unlinked' && !account.disabled) { - style += ' connect'; - } - return style; -} - -export default class LinkAccounts extends React.Component { - constructor(props) { - super(props); - this.handleClick = this.handleClick.bind(this); - } - - handleClick(e, account) { - const { - linkExternalAccount, - profile, - tokenV3, - unlinkExternalAccount, - } = this.props; - e.preventDefault(); - if (account.status === 'linked') { - unlinkExternalAccount( - profile, - tokenV3, - account.providerType, - ); - } else if (!account.disabled && account.status === 'unlinked') { - linkExternalAccount( - profile, - tokenV3, - account.providerType, - ); - } - } - - render() { - const { - allLinks, - supportedAccounts, - } = this.props; - - let accounts = _.cloneDeep(supportedAccounts); - - _.remove(accounts, al => al.order < 0); - - _.forEach(accounts, (account) => { - const linkedAccount = _.find(allLinks, p => p.providerType === account.providerType); - - if (!linkedAccount) { - account.status = 'unlinked'; /* eslint-disable-line no-param-reassign */ - } else { - account.status = linkedAccount.status; /* eslint-disable-line no-param-reassign */ - } - }); - accounts = _.sortBy(accounts, 'order'); - - const FILTER_GRAYSCALE = [ - 1, 0, 0, 0, 0, - 1, 0, 0, 0, 0, - 1, 0, 0, 0, 0, - 0, 0, 0, 1, 0, - ]; - - const FILTER_NONE = [ - 1, 0, 0, 0, 0, - 0, 1, 0, 0, 0, - 0, 0, 1, 0, 0, - 0, 0, 0, 1, 0, - ]; - - return ( -
- { - _.map(accounts, account => ( -
this.handleClick(e, account)} styleName={getStyleName(account)}> -
- -
-
- { account.displayName } -
-
- )) - } -
- ); - } -} - -LinkAccounts.propTypes = { - tokenV3: PT.string.isRequired, - profile: PT.shape().isRequired, - allLinks: PT.arrayOf(PT.shape()).isRequired, - supportedAccounts: PT.arrayOf(PT.shape()).isRequired, - linkExternalAccount: PT.func.isRequired, - unlinkExternalAccount: PT.func.isRequired, -}; diff --git a/src/shared/components/Settings/Account/LinkedAccount/SocialIcons.jsx b/src/shared/components/Settings/Account/LinkedAccount/SocialIcons.jsx deleted file mode 100644 index b2bc170fc1..0000000000 --- a/src/shared/components/Settings/Account/LinkedAccount/SocialIcons.jsx +++ /dev/null @@ -1,20 +0,0 @@ -/** - * Load all social icons - */ -import github from 'assets/images/account/socials/github.png'; -import linkedin from 'assets/images/account/socials/linkedin.png'; -import behance from 'assets/images/account/socials/behance.png'; -import bitbucket from 'assets/images/account/socials/bitbucket.png'; -import stackoverflow from 'assets/images/account/socials/stackoverflow.png'; -import twitter from 'assets/images/account/socials/twitter.png'; -import dribbble from 'assets/images/account/socials/dribble.png'; - -export default { - github, - behance, - stackoverflow, - twitter, - linkedin, - dribbble, - bitbucket, -}; diff --git a/src/shared/components/Settings/Account/LinkedAccount/index.jsx b/src/shared/components/Settings/Account/LinkedAccount/index.jsx deleted file mode 100644 index 4c7008cd88..0000000000 --- a/src/shared/components/Settings/Account/LinkedAccount/index.jsx +++ /dev/null @@ -1,194 +0,0 @@ -/** - * Child component of Settings/Account/LinkedAccount renders - * "Linked Account" section of account setting page. - */ -/* eslint-disable no-undef */ -import _ from 'lodash'; -import React from 'react'; -import PT from 'prop-types'; - -import AddWebLink from './AddWebLink'; -import LinkAccounts from './LinkAccounts'; -import ExistingLinks from './ExistingLinks'; - -import './styles.scss'; - -const supportedAccounts = [ - { - providerType: 'dribbble', - className: 'fa-dribbble', - displayName: 'Dribbble', - disabled: false, - order: 6, - colorClass: 'el-dribble', - featured: true, - }, - { - providerType: 'stackoverflow', - className: 'fa-stack-overflow', - displayName: 'Stack Overflow', - disabled: false, - order: 3, - colorClass: 'el-stackoverflow', - }, - { - providerType: 'github', - className: 'fa-github', - displayName: 'Github', - disabled: false, - order: 1, - colorClass: 'el-github', - featured: true, - }, - { - providerType: 'bitbucket', - className: 'fa-bitbucket', - displayName: 'Bitbucket', - disabled: false, - order: 7, - colorClass: 'el-bitbucket', - }, - { - providerType: 'weblink', - className: 'fa-globe', - displayName: 'Web Links', - disabled: true, - order: -1, - colorClass: 'el-weblinks', - }, -]; - -export default class LinkedAccount extends React.Component { - constructor(props) { - super(props); - this.updatePredicate = this.updatePredicate.bind(this); - - this.state = { - isMobileView: false, - screenSM: 767, - }; - } - - /* Add this to resolve checkbox checked issue when switch mobile to other device */ - componentDidMount() { - this.updatePredicate(); - window.addEventListener('resize', this.updatePredicate); - } - - componentWillUnmount() { - window.removeEventListener('resize', this.updatePredicate); - } - - updatePredicate() { - const { screenSM } = this.state; - this.setState({ isMobileView: window.innerWidth <= screenSM }); - } - - render() { - const { - profileState, - settingsPageState, - settingsUI, - } = this.props; - - const { isMobileView } = this.state; - - const tabs = settingsUI.TABS.ACCOUNT; - const currentTab = settingsUI.currentAccountTab; - const containerStyle = currentTab === tabs.LINKEDACCOUNT ? '' : 'hide'; - - // Construct all links - const allLinks = []; - const linkedAccounts = profileState.linkedAccounts || []; - const externalAccountsData = profileState.externalAccounts || {}; - - if (!linkedAccounts.length) { - const providers = _.omit(externalAccountsData, ['userId', 'updatedAt', 'createdAt', 'createdBy', 'updatedBy']); - - if (_.keys(_.omitBy(providers, _.isNil)).length > 1) { - _.forEach(_.keys(providers), (p) => { - if (providers[p]) { - linkedAccounts.push({ providerType: p }); - } - }); - } - } - _.forEach(linkedAccounts, (linkedAccount) => { - const providerType = linkedAccount.providerType || linkedAccount.provider; - - let account; - if (externalAccountsData[providerType]) { - // add external account data - account = { - providerType, - data: externalAccountsData[providerType], - status: 'linked', - }; - } else { - // account data not available yet, add pending card - account = { - providerType, - data: { handle: linkedAccount.name }, - status: 'pending', - }; - } - if (_.find( - settingsPageState.deletingLinks, - l => l.providerType === account.providerType, - )) { - account.deleting = true; - } - allLinks.push(account); - }); - - // Append web links - _.forEach(profileState.externalLinks, (el) => { - const link = _.clone(el); - link.providerType = 'weblink'; - link.status = link.synchronizedAt ? 'linked' : 'pending'; - if (_.find(settingsPageState.deletingLinks, l => l.key === link.key)) { - link.deleting = true; - } - allLinks.push(link); - }); - - return ( -
-
-

- Linked Accounts -

-
- Your linked accounts -
- { - isMobileView && ( - - ) - } - - - { - !isMobileView && ( - - ) - } -
-
- ); - } -} - -LinkedAccount.propTypes = { - profileState: PT.shape().isRequired, - settingsPageState: PT.shape().isRequired, - settingsUI: PT.shape().isRequired, -}; diff --git a/src/shared/components/Settings/Account/LinkedAccount/modal.scss b/src/shared/components/Settings/Account/LinkedAccount/modal.scss deleted file mode 100644 index 992095f9be..0000000000 --- a/src/shared/components/Settings/Account/LinkedAccount/modal.scss +++ /dev/null @@ -1,114 +0,0 @@ -@import "~styles/mixins"; - -.container { - @include roboto-regular; - - padding: 0; - position: fixed; - overflow: auto; - z-index: 10000; - top: 0; - right: 0; - bottom: 0; - left: 0; - box-sizing: border-box; - width: auto; - max-width: none; - transform: none; - background: transparent; - - .deletion-confirmation-container { - background: transparent; - opacity: 1; - position: relative; - padding: 30px; - width: 100%; - height: 100%; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - border-radius: 0; - color: #444; - font-family: Helvetica, sans-serif; - font-size: 1.1em; - line-height: 1.5em; - margin: 0 auto; - max-width: 100%; - } -} - -.deletion-confirmation { - display: flex; - flex-flow: column wrap; - justify-content: space-around; - align-items: center; - background-color: $tc-white; - opacity: 1; - border-radius: 4px; - padding: 40px; - max-width: 100%; -} - -@media (min-width: 768px) { - .deletion-confirmation { - width: 520px; - min-height: 256px; - } -} - -.deletion-confirmation-title { - @include roboto-medium; - - font-size: 20px; - line-height: 24px; - color: $tc-gray-90; - text-transform: uppercase; -} - -.deletion-confirmation-message { - @include merriweather-sans-light; - - margin: 10px 0; - width: 100%; - - .deletion-confirmation-account-title { - font-style: italic; - word-wrap: break-word; - } -} - -.deletion-confirmation-buttons { - display: flex; - flex-flow: row wrap; - - .deletion-confirmation-button-no { - margin-left: 10px; - - button { - text-transform: uppercase; - height: 40px; - - @include roboto-medium; - - font-size: 12px; - } - } - - .deletion-confirmation-button-yes { - button { - border: 1px solid $tc-dark-blue; - text-transform: uppercase; - height: 40px; - - @include roboto-medium; - - font-size: 12px; - - &:hover { - color: $tc-white; - background-color: $tc-dark-blue; - } - } - } -} diff --git a/src/shared/components/Settings/Account/LinkedAccount/styles.scss b/src/shared/components/Settings/Account/LinkedAccount/styles.scss deleted file mode 100644 index f4f29f4dbd..0000000000 --- a/src/shared/components/Settings/Account/LinkedAccount/styles.scss +++ /dev/null @@ -1,907 +0,0 @@ -@import "../../style"; - -.links { - border-bottom: none; -} - -.external-link-list { - display: flex; - flex-direction: column; - justify-content: space-between; - //margin-top: 10px; - - @include upto-sm { - flex-flow: row wrap; - flex-direction: row; - } - - .external-link-tile { - border: 1px solid $tc-gray-20; - border-radius: 6px; - width: 280px; - height: 90px; - display: flex; - flex-direction: row; - text-align: center; - margin-bottom: 10px; - //border-radius: 4px; - position: relative; - - @include roboto-medium; - - i { - color: #7f7f7f; - } - - &:hover { - cursor: pointer; - background-color: #fbfbfb; - - i { - color: black; - } - } - - i.fa-globe { - color: #82a0aa; - cursor: pointer; - } - - i.fa-weblinks { - color: #82a0aa; - cursor: pointer; - } - - i.fa-bitbucket { - color: #205081; - } - - i.fa-dribble { - color: #ea4c89; - } - - i.fa-linkedin { - color: #127cb5; - } - - i.fa-twitter { - color: #62aadc; - } - - i.fa-stack-overflow { - color: #e5712a; - } - - i.fa-behance { - color: #188cfc; - } - - i.fa-github { - color: #4b3d74; - } - - .top { - display: flex; - flex-direction: column; - align-items: center; - width: 30%; - height: 88px; - background-color: $tc-gray-neutral-light; - border-radius: 4px 0 0 4px; - position: relative; - - i { - font-size: 40px; - margin-top: 15px; - } - - h2 { - margin-top: 5px; - flex-basis: 40px; - font-weight: normal; - text-transform: uppercase; - color: #a3a3ae; - font-size: 10px; - } - } - - .bottom { - width: 70%; - margin-top: 10px; - - .handle { - @include roboto-light; - - font-size: 18px; - height: 20px; - overflow: hidden; - text-overflow: ellipsis; - } - - .title { - // placeholder - margin-top: 10px; - color: #9e9e9e; - font-size: 12px; - line-height: 14px; - - @include roboto-medium; - } - - .pending { - p { - @include roboto-regular; - - font-size: 16px; - color: $tc-gray-90; - margin-bottom: 15px; - padding: 0 10px; - } - } - - ul { - margin-top: 10px; - height: 40px; - display: flex; - flex-direction: row; - justify-content: center; - - li { - justify-content: space-between; - margin: 10px 0 10px 0; - width: 90px; - color: #9e9e9e; - - .key { - font-size: 11px; - text-transform: capitalize; - } - - .value { - font-size: 14px; - // placeholder - } - } - } - - .logo { - padding: 10px; - font-size: 50px; - } - - .link-title { - @include roboto-medium; - - font-size: 12px; - line-height: 20px; - color: $tc-gray-90; - margin-top: 10px; - height: 40px; - overflow: hidden; - padding: 0 20px; - text-transform: uppercase; - } - - .link-url { - font-size: 12px; - line-height: 14px; - word-wrap: break-word; - display: block; - overflow: hidden; - max-height: 14px; - padding: 0 20px; - text-transform: uppercase; - color: $tc-dark-blue-110; - white-space: nowrap; - text-overflow: ellipsis; - - &:hover { - color: $tc-light-blue-110; - } - } - } - - img { - margin-top: 15px; - height: 40px; - width: auto; - } - } - - div.external-link-tile:nth-child(3n+1) { - margin-left: 0; - } -} - -// Add web link section -.external-web-link { - margin-bottom: 30px; - width: 100%; - - input.url { - max-width: 100%; - margin: 5px 0 0 0; - border-radius: 4px; - - @include placeholder { - @include roboto-regular; - - color: $tc-gray-40; - font-size: 12px; - } - - &:disabled { - color: #b7b7b7; - } - } - - .web-link { - .form-container-default { - @include upto-sm { - display: none; - } - - display: flex; - flex-direction: row; - min-height: 40px; - justify-content: space-between; - align-items: flex-start; - - label { - @include roboto-bold; - - font-size: 15px; - line-height: 40px; - font-weight: 700; - color: $tc-gray-80; - max-width: 152px; - margin-right: 14px; - align-self: left; - margin-top: auto; - margin-bottom: auto; - } - - // Error and Success styles - .validation-bar { - flex: 1; - width: 80%; - position: relative; - - &::before { - border-radius: 3px 0 0 3px; - content: ''; - display: none; - height: 40px; - width: 2px; - left: 1px; - position: absolute; - top: 0; - } - - &.error-bar::before { - background-color: $tc-red; - display: block; - } - } - - .form-input-error { - background-color: $tc-red-10; - border: 1px solid $tc-red-30; - color: $tc-red; - font-size: 12px; - line-height: 20px; - margin-bottom: 10px; - padding: 10px; - text-align: left; - - p { - @include merriweather-sans-regular; - } - } - - .add-button { - width: auto; - height: 40px; - margin-top: 0; - margin-left: 10px; - text-transform: uppercase; - } - } - - .form-container-mobile { - display: none; - - @include upto-sm { - border: 0; - border-radius: 0; - display: flex; - flex-direction: column; - padding: 20px; - background-color: $tc-gray-neutral-light; - width: 100%; - border-bottom: 1px solid #d5d5d5; - } - - label { - @include roboto-bold; - - font-size: 15px; - line-height: 40px; - font-weight: 700; - color: $tc-gray-80; - max-width: 152px; - margin-right: 14px; - align-self: left; - margin-top: auto; - margin-bottom: auto; - } - - .title-mobile { - @include roboto-regular; - - font-size: 20px; - line-height: 30px; - font-weight: 400; - color: $tc-black; - - @include upto-sm { - margin-bottom: 20px; - } - } - - .row { - display: flex; - flex-direction: row; - margin-bottom: 20px; - align-content: space-between; - - @include upto-sm { - width: 100%; - display: block; - margin-bottom: 0; - } - - .field { - display: flex; - flex-direction: column; - margin-right: 10px; - - @include upto-sm { - display: block; - padding-bottom: 10px; - } - - label { - @include roboto-medium; - - font-size: 12px; - line-height: 15px; - font-weight: 500; - color: $tc-gray-80; - margin-bottom: 5px; - } - - &.col-1 { - width: 100%; - //max-width: 156px; - //min-width: 156px; - } - - &.col-2 { - width: 100%; - } - } - - div.field:last-child { - margin-right: 0; - } - } - - // Error and Success styles - .validation-bar { - flex: 1; - position: relative; - - &::before { - border-radius: 3px 0 0 3px; - content: ''; - display: none; - height: 40px; - width: 2px; - left: 1px; - position: absolute; - top: 0; - } - - &.error-bar::before { - background-color: $tc-red; - display: block; - } - - .form-input-error { - background-color: $tc-red-10; - border: 1px solid $tc-red-30; - color: $tc-red; - font-size: 12px; - line-height: 20px; - margin-bottom: 10px; - padding: 10px; - text-align: left; - - p { - @include merriweather-sans-regular; - } - } - - @include upto-sm { - width: 100%; - } - } - } - } -} - -@media (min-width: 768px) { - .external-link-list { - display: flex; - flex-direction: row; - flex-wrap: wrap; - justify-content: flex-start; - padding: 0; - - .external-link-tile { - border: 1px solid #f0f0f0; - background-color: $tc-gray-neutral-light; - margin-left: 15px; - margin-bottom: 30px; - // &:nth-child(3n+1) { - // margin-left: 0px; - // } - width: 218px; - height: 240px; - display: flex; - flex-direction: column; - text-align: center; - padding: 0; - position: relative; - - @include roboto-medium; - - i { - color: #7f7f7f; - } - - &:hover { - cursor: pointer; - background-color: #fbfbfb; - - i { - color: black; - } - } - - .top { - padding-top: 15px; - background-color: transparent; - width: auto; - - h2 { - flex-basis: 40px; - font-weight: normal; - text-transform: uppercase; - color: #a3a3ae; - font-size: 12px; - line-height: 14px; - } - } - - .bottom { - margin-top: 15px; - width: auto; - - .handle { - margin-top: 20px; - margin-bottom: 20px; - overflow: hidden; - text-overflow: ellipsis; - } - - .title { - // placeholder - height: 40px; - margin-top: 15px; - margin-bottom: 30px; - } - - ul { - margin-left: 10px; - margin-bottom: 10px; - height: 40px; - display: flex; - flex-direction: row; - - li { - justify-content: space-between; - margin: 10px 0 10px 0; - width: 90px; - - @include roboto-medium; - - .value { - color: $tc-gray-90; - font-size: 18px; - } - - .key { - text-transform: uppercase; - font-size: 12px; - margin-top: 4px; - color: $tc-gray-40; - } - } - } - - .logo { - padding: 10px; - font-size: 50px; - } - - .link-title { - margin-top: 15px; - margin-bottom: 20px; - height: 60px; - } - - .link-url { - max-height: 28px; - white-space: normal; - } - } - } - - .external-link-tile--pending { - &:hover { - cursor: default; - } - } - } -} - -.existing-links { - margin-bottom: 30px; - display: flex; - flex-flow: row wrap; - border-bottom: none; - - @include upto-sm { - display: block; - padding: 0 20px; - } - - .ext-link-tile_edit-header { - display: flex; - justify-content: flex-end; - position: absolute; - top: -10px; - right: -15px; - z-index: 1; - - @media only screen and (min-width: 768px) { - top: 0; - right: 0; - } - - &:hover { - .show-on-profile_label { - color: $tc-gray-90; - } - } - } - - .ext-link-tile_edit-header_delete { - background-image: url(assets/images/ico-delete.svg); - background-position: center; - background-size: 16px 16px; - background-repeat: no-repeat; - height: 43px; - width: 51px; - cursor: pointer; - opacity: 0.7; - - &:hover:not(.ext-link-tile_edit-header_delete--disabled) { - // border-left: 1px solid $tc-gray-20; - // border-bottom: 1px solid $tc-gray-20; - opacity: 1; - } - } - - .ext-link-tile_edit-header_delete--disabled { - cursor: default; - opacity: 0.4; - } -} - -@media only screen and (min-width: 768px) { - .links { - & .external-link-list { - padding: 0; - } - - .existing-links { - display: flex; - flex-direction: row; - justify-content: flex-start; - flex-wrap: wrap; - } - } -} - -.external-links { - margin-bottom: 30px; - display: flex; - flex-flow: row wrap; - - .ext-tile { - display: flex; - flex-direction: column; - align-items: center; - margin: 0 20px 15px 0; - cursor: pointer; - - .external-account-box { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - width: 90px; - height: 90px; - border: 1px solid $tc-gray-20; - border-radius: 6px; - - .provider { - margin-top: 8px; - - @include roboto-medium; - - font-size: 12px; - line-height: 13px; - text-align: center; - text-transform: uppercase; - color: $tc-gray-40; - padding: 0 10px; - } - } - - &.connect { - .external-account-box { - background-color: #fbfbfb; - } - } - - .status { - font-size: 15px; - line-height: 20px; - max-width: 90.2px; - min-width: 90.2px; - text-align: center; - - @include roboto-regular; - - margin-top: 10px; - text-transform: capitalize; - color: $tc-gray-90; - - &.disconnect { - display: none; - color: #f06; - } - } - - &.connected { - .status { - color: $tc-gray-80; - } - - &:hover { - .external-account-box { - border: 1px solid #ff99c2; - background-color: #ffcce1; - } - - .already-connected { - display: none; - } - - .disconnect { - display: block; - } - } - - .el-bitbucket i { - color: #205081; - } - - .el-dribble i { - color: #ea4c89; - } - - .el-linkedin i { - color: #127cb5; - } - - .el-twitter i { - color: #62aadc; - } - - .el-stackoverflow i { - color: #e5712a; - } - - .el-behance i { - color: #188cfc; - } - - .el-github i { - color: #4b3d74; - } - - .el-weblinks i { - color: #82a0aa; - } - } - - &.enabled:hover { - .el-bitbucket i { - color: #205081; - } - - .el-dribble i { - color: #ea4c89; - } - - .el-linkedin i { - color: #127cb5; - } - - .el-twitter i { - color: #62aadc; - } - - .el-stackoverflow i { - color: #e5712a; - } - - .el-behance i { - color: #188cfc; - } - - .el-github i { - color: #4b3d74; - } - - .el-weblinks i { - color: #82a0aa; - } - } - - &.connecting { - cursor: default; - } - - &.disabled { - cursor: default; - opacity: 0.4; - } - - &.enabled.connect:hover { - .external-account-box { - background-color: #f2faff; - border: 1px solid #85ccff; - } - } - } - - @include upto-sm { - padding: 20px; - } -} - -.section-loading { - background: url(assets/images/ripple.gif) no-repeat center center; - width: 100%; - min-height: 50px; -} - -.hide { - display: none; -} - -.linked-account-container { - display: flex; - flex-direction: column; - align-items: left; - - h1 { - @include roboto-regular; - - font-size: 28px; - line-height: 35px; - font-weight: 400; - color: $tc-black; - margin-bottom: 20px; - - @include upto-sm { - display: none; - } - } - - .sub-title { - @include roboto-light; - - color: #888894; - line-height: 35px; - font-weight: 300; - font-size: 28px; - margin-bottom: 30px; - margin-top: 10px; - - @include upto-sm { - display: none; - } - } -} - -.button-save { - align-self: center; - - @include upto-sm { - margin-top: 10px; - } - - .complete { - @include roboto-medium; - - color: $tc-white; - - button { - height: 40px; - font-size: 15px; - font-weight: 500; - line-height: 40px; - margin: 0; - padding: 0 0; - width: 200px; - } - } -} - -.buttons { - margin-top: auto; - margin-bottom: auto; - - .button-add-link { - align-self: center; - color: $tc-white; - margin: 0; - - div:first-child { - margin-top: 0; - } - - button, - a { - @include roboto-medium; - - height: 40px; - font-size: 15px; - font-weight: 500; - margin: 0; - padding: 0; - width: 155px; - } - - @include upto-sm { - display: none; - } - } -} diff --git a/src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/AlmostDone/index.jsx b/src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/AlmostDone/index.jsx deleted file mode 100644 index 052b48644f..0000000000 --- a/src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/AlmostDone/index.jsx +++ /dev/null @@ -1,61 +0,0 @@ -/** - * Render Email verification almost done page - */ -import _ from 'lodash'; -import React from 'react'; -import PT from 'prop-types'; -import { Redirect } from 'react-router'; -import { PrimaryButton } from 'topcoder-react-ui-kit'; -import { isomorphy } from 'topcoder-react-utils'; -import './styles.scss'; - -let asset; -if (isomorphy.isClientSide()) { - asset = require.context('assets/images/account/email', false, /svg/)('./email-confirmation-icon.svg'); -} - -const VERIFIED_EMAIL_OPTIONS = ['old', 'new']; -const AlmostDone = ({ location }) => { - const verifiedEmail = _.get(location, 'state.verifiedEmail'); - if (!verifiedEmail || VERIFIED_EMAIL_OPTIONS.indexOf(verifiedEmail) < 0) { - return ; - } - const [firstEmail, secondEmail] = verifiedEmail === VERIFIED_EMAIL_OPTIONS[0] - ? VERIFIED_EMAIL_OPTIONS - : VERIFIED_EMAIL_OPTIONS.reverse(); - return ( -
-
-
- almost-done-icon -

- Almost done! One more step! -

-
- The action was verified from your {firstEmail} email account.  - Please
- click the link from your {secondEmail} account to complete the change. -
-
- - Back to My Dashboard - -
-
-
-
- ); -}; - -AlmostDone.defaultProps = { - location: {}, -}; - -AlmostDone.propTypes = { - location: PT.shape(), -}; - -export default AlmostDone; diff --git a/src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/AlmostDone/styles.scss b/src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/AlmostDone/styles.scss deleted file mode 100644 index 571445b8b9..0000000000 --- a/src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/AlmostDone/styles.scss +++ /dev/null @@ -1,50 +0,0 @@ -@import "../mixins"; - -.outer-container { - @include outer-container; -} - -.page { - @include page; -} - -.container { - @include inner-container; - - padding-top: 151px; - padding-bottom: 220px; -} - -.text { - @include text; - - margin-left: auto; - margin-right: auto; - max-width: 546px; - min-width: 546px; -} - -.button-back { - max-height: 40px; - margin-left: auto; - margin-right: auto; - - button, - a { - color: #fafafb; - font-size: 15px; - font-weight: bold; - height: 40px; - line-height: 40px; - margin: 0; - padding: 0; - } - - .white { - color: $tc-white; - } -} - -strong { - font-weight: bold; -} diff --git a/src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/Failed/index.jsx b/src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/Failed/index.jsx deleted file mode 100644 index 027cb52616..0000000000 --- a/src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/Failed/index.jsx +++ /dev/null @@ -1,55 +0,0 @@ -import React from 'react'; -import { isomorphy } from 'topcoder-react-utils'; -import { PrimaryButton } from 'topcoder-react-ui-kit'; -/** - * Render Email verification failed page - */ -import './styles.scss'; - -let failureAsset; -if (isomorphy.isClientSide()) { - failureAsset = require.context('assets/images/account/email', false, /svg/)('./failed.svg'); -} - -const Failed = () => ( -
-
-
- failed-icon -

- Email Verification Failed -

-
- Sorry, this verification link is no longer valid due to one of the following reasons: -
-
    -
  • - - It has already been verified. - -
  • -
  • - - It has expired or has been cancelled, any pending email - change that is cancelled is no longer subject to verification. - -
  • -
-
- Make sure you're logged in with the right account - or try updating your email again -
-
- - Back to My Dashboard - -
-
-
-
-); - -export default Failed; diff --git a/src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/Failed/styles.scss b/src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/Failed/styles.scss deleted file mode 100644 index 0595261e31..0000000000 --- a/src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/Failed/styles.scss +++ /dev/null @@ -1,88 +0,0 @@ -@import "../mixins"; - -.outer-container { - @include outer-container; -} - -.page { - @include page; -} - -.text { - @include text; - - margin-left: auto; - margin-right: auto; - max-width: 500px; - min-width: 500px; - - span { - color: #037dff; - } -} - -.container { - @include inner-container; - - padding-top: 162px; - padding-bottom: 184px; - - ul { - @include roboto-regular; - - list-style: none; - font-size: 13px; - line-height: 25px; - border: 1px solid #ededf2; - background-color: #fafafb; - border-radius: 6px; - padding: 20px; - max-width: 450px; - min-width: 450px; - margin-left: auto; - margin-right: auto; - margin-bottom: 20px; - text-align: left; - } - - li { - list-style-type: disc; - margin-left: 2em; - color: #c3c3c8; - - span { - color: #47474f; - } - } -} - -.tip { - @include text; - - margin-left: auto; - margin-right: auto; - max-width: 500px; - min-width: 500px; - color: $tc-gray-40; -} - -.button-back { - max-height: 40px; - margin-left: auto; - margin-right: auto; - - button, - a { - color: #fafafb; - font-size: 15px; - font-weight: bold; - height: 40px; - line-height: 40px; - margin: 0; - padding: 0; - } - - .white { - color: $tc-white; - } -} diff --git a/src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/Success/index.jsx b/src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/Success/index.jsx deleted file mode 100644 index 8afaabdc56..0000000000 --- a/src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/Success/index.jsx +++ /dev/null @@ -1,39 +0,0 @@ -/** - * Render Email verification success page - */ - -import React from 'react'; -import { isomorphy } from 'topcoder-react-utils'; -import { PrimaryButton } from 'topcoder-react-ui-kit'; -import './styles.scss'; - -let assets; -if (isomorphy.isClientSide()) { - assets = require.context('assets/images/account/email', false, /svg/)('./success.svg'); -} - -const Success = () => ( -
-
-
- success-icon -

- Email Verification Success -

-
- Congratulations! Your email verification has been completed. -
-
- - Back to My Dashboard - -
-
-
-
-); - -export default Success; diff --git a/src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/Success/styles.scss b/src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/Success/styles.scss deleted file mode 100644 index 00746f88a0..0000000000 --- a/src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/Success/styles.scss +++ /dev/null @@ -1,46 +0,0 @@ -@import "../mixins"; - -.outer-container { - @include outer-container; -} - -.page { - @include page; -} - -.container { - @include inner-container; - - padding-top: 151px; - padding-bottom: 220px; -} - -.text { - @include text; - - margin-left: auto; - margin-right: auto; - max-width: 546px; - min-width: 546px; -} - -.button-back { - max-height: 40px; - margin-left: auto; - margin-right: auto; - - button, - a { - color: #fafafb; - font-size: 15px; - font-weight: bold; - height: 40px; - line-height: 40px; - margin: 0; - padding: 0; - } - - .white { - color: $tc-white; - } -} diff --git a/src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/mixins.scss b/src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/mixins.scss deleted file mode 100644 index a1a118b2a5..0000000000 --- a/src/shared/components/Settings/Account/MyAccount/EmailVerifiResult/mixins.scss +++ /dev/null @@ -1,68 +0,0 @@ -/* - Common mixins for Email Verification Result Page - */ - -@import '../../../style'; - -@mixin outer-container { - background-color: $tc-gray-neutral-dark; - display: block; - width: 100%; - - @include xs-to-lg { - width: calc(100vw); - } - - @include xs-to-lg { - padding: 7px 10px 20px 10px; - } - - @include lg-to-xl { - padding: 30px 64px 50px 64px; - } -} - -@mixin page { - background-color: $tc-white; - border-radius: 4 * $corner-radius; - box-shadow: 0 0 8px #ccc; - margin: auto; - max-width: 1246px; - text-align: center; - width: 100%; - overflow: hidden; - - h1, - h2, - h3, - h4 { - @include roboto-regular; - } -} - -@mixin text { - @include roboto-regular; - - font-size: 13px; - line-height: 25px; - color: $tc-black; - max-width: 600px; - margin-bottom: 20px; - - p { - margin: 0; - } -} - -@mixin inner-container { - background: $tc-white; - display: flex; - flex-direction: column; - - h1 { - font-size: 28px; - line-height: 35px; - margin-top: 22px; - margin-bottom: 3px; - } -} diff --git a/src/shared/components/Settings/Account/MyAccount/index.jsx b/src/shared/components/Settings/Account/MyAccount/index.jsx deleted file mode 100644 index dd5134daa4..0000000000 --- a/src/shared/components/Settings/Account/MyAccount/index.jsx +++ /dev/null @@ -1,711 +0,0 @@ -/* eslint-disable max-len */ -/** - * Child component of Settings/Account/ renders the - * 'My Account' page. - */ -/* eslint-disable jsx-a11y/label-has-for */ -/* eslint-disable no-useless-escape */ -/* eslint-disable no-undef */ -import React from 'react'; -import PT from 'prop-types'; -import { omit, get } from 'lodash'; -import ConsentComponent from 'components/Settings/ConsentComponent'; -import { Modal, PrimaryButton } from 'topcoder-react-ui-kit'; -import { SettingBannerV2 as Collapse } from 'components/Settings/SettingsBanner'; -import FormField from 'components/Settings/FormField'; -import FormInputText from 'components/Settings/FormInputText'; -import Personalization from 'components/Settings/Preferences/Personalization'; -import { config } from 'topcoder-react-utils'; - -import Style from './styles.scss'; - -const theme = { - container: Style.modalContainer, -}; - -export default class MyAccount extends ConsentComponent { - constructor(props) { - super(props); - - this.state = { - newEmail: '', - currentEmail: '', - isValidEmail: false, - btnChangeEmailVisible: true, - btnVerifiEmailVisible: false, - btnVerifiAgainlVisible: false, - hasLength: false, - hasLetter: false, - hasSymbolNumber: false, - differentOldPassword: false, - passwordValid: false, - rePasswordValid: false, - showNewTips: false, - showRePasswordTips: false, - showEmailTips: false, - newEmailSameAsCurrent: false, - focus: { - 'new-password-input': false, - 'new-email-input': false, - 'current-password-input': false, - 're-new-password-input': false, - }, - passwordInputType: { - 'new-password-input': 'password', - 'new-email-input': 'text', - 'current-password-input': 'password', - 're-new-password-input': 'password', - }, - newPassword: '', - currentPassword: '', - reNewPassword: '', - isMobileView: false, - screenSM: 767, - isSent: false, - isOpen: false, - }; - this.reNewPasswordRef = React.createRef(); - this.newPasswordRef = React.createRef(); - this.currentPasswordRef = React.createRef(); - - this.onNewEmailFocus = this.onNewEmailFocus.bind(this); - this.onNewEmailBlur = this.onNewEmailBlur.bind(this); - - this.onPasswordFocus = this.onPasswordFocus.bind(this); - this.onPasswordBlur = this.onPasswordBlur.bind(this); - this.onUpdatePassword = this.onUpdatePassword.bind(this); - this.checkPassword = this.checkPassword.bind(this); - this.toggleTypeAttribute = this.toggleTypeAttribute.bind(this); - this.onSendVerificationEmail = this.onSendVerificationEmail.bind(this); - this.onCancelVerificationEmail = this.onCancelVerificationEmail.bind(this); - this.onUpdateNewEmailInput = this.onUpdateNewEmailInput.bind(this); - this.onChangeEmail = this.onChangeEmail.bind(this); - this.updatePredicate = this.updatePredicate.bind(this); - this.updateButtonsVisible = this.updateButtonsVisible.bind(this); - } - - componentDidMount() { - const { profile, loadTabData } = this.props; - const currentEmail = profile.email; - this.setState({ currentEmail }); - this.updatePredicate(); - window.addEventListener('resize', this.updatePredicate); - loadTabData(this.props); - } - - componentWillReceiveProps(nextProps) { - const { profileState, profile } = this.props; - if (profile.email !== nextProps.profile.email) { - this.setState({ currentEmail: nextProps.profile.email }); - } - if (profileState.updatingPassword - && !nextProps.profileState.updatingPassword - && !nextProps.settingsPageState.incorrectPassword - ) { - this.setState({ - rePasswordValid: false, - passwordValid: false, - newPassword: '', - currentPassword: '', - reNewPassword: '', - }); - } - - if (nextProps.profileState.updateProfileSuccess - && !nextProps.profileState.updatingProfile - && this.state.isSent) { - this.setState({ - isOpen: true, - }); - } - - if (nextProps.profileState.updateProfileSuccess - && !nextProps.profileState.updatingProfile - && this.state.isSent) { - this.setState({ - isOpen: true, - }); - } - } - - componentWillUnmount() { - window.removeEventListener('resize', this.updatePredicate); - const { - clearIncorrectPassword, - } = this.props; - clearIncorrectPassword(); - } - - onUpdateNewEmailInput(e) { - const { profileState, updateEmailConflict } = this.props; - if (profileState.isEmailConflict) { - updateEmailConflict(false); - } - const newEmail = e.target.value; - const newState = { ...this.state }; - const email = /^([0-9A-Za-z\-_\.+]+)@([0-9A-Za-z]+\.[a-z]{2,3}(\.[a-z]{2})?)$/g; - - newState.newEmail = newEmail; - - if (newEmail === '' || !email.test(newEmail) || newEmail === newState.currentEmail) { - newState.focus['new-email-input'] = true; - newState.isValidEmail = false; - newState.showEmailTips = newEmail !== ''; - newState.newEmailSameAsCurrent = newEmail === newState.currentEmail; - } else { - newState.showEmailTips = false; - newState.isValidEmail = true; - } - - this.setState(newState); - } - - onSendVerificationEmail() { - this.setState({ - isSent: true, - }); - const { updateProfile, profile, tokenV3 } = this.props; - profile.email = this.state.newEmail; - profile.verifyUrl = `${config.URL.EMAIL_VERIFY_URL}`; - updateProfile(omit(profile, ['groups']), tokenV3); - } - - onCancelVerificationEmail() { - const newState = { ...this.state }; - newState.btnChangeEmailVisible = true; - newState.btnVerifiEmailVisible = false; - this.setState(newState); - } - - onChangeEmail() { - const { profileState } = this.props; - if (get(profileState, 'credential.hasPassword')) { - const newState = { ...this.state }; - newState.btnChangeEmailVisible = false; - newState.btnVerifiEmailVisible = true; - this.setState(newState); - } - } - - onUpdatePassword(e) { - const { - profile, - updatePassword, - tokenV3, - profileState, - } = this.props; - - const { - passwordValid, - rePasswordValid, - newPassword, - currentPassword, - } = this.state; - - const { updatingPassword } = profileState; - if (e) e.preventDefault(); - - if (!passwordValid || !rePasswordValid || updatingPassword) { - const newState = { ...this.state }; - newState.focus['new-password-input'] = true; - newState.showNewTips = true; - this.setState(newState); - return; - } - updatePassword( - profile, tokenV3, - newPassword, currentPassword, - ); - } - - onNewEmailFocus(e) { - const newState = { ...this.state }; - newState.focus[e.target.id] = true; - - if (e.target.id === 'new-email-input') { - newState.showEmailTips = true; - } - - this.setState(newState); - } - - onNewEmailBlur(e) { - const newState = { ...this.state }; - newState.focus[e.target.id] = false; - - if (e.target.id === 'new-email-input') { - newState.showEmailTips = false; - } - - this.setState(newState); - } - - onPasswordFocus(e) { - const newState = { ...this.state }; - newState.focus[e.target.id] = true; - - if (e.target.id === 'new-password-input') { - newState.showNewTips = true; - } else if (e.target.id === 'current-password-input') { - newState.showNewTips = true; - } else if (e.target.id === 're-new-password-input') { - newState.showRePasswordTips = true; - } - - this.setState(newState); - } - - onPasswordBlur(e) { - const newState = { ...this.state }; - newState.focus[e.target.id] = false; - - if (e.target.id === 'new-password-input') { - newState.showNewTips = false; - } else if (e.target.id === 're-new-password-input') { - newState.showRePasswordTips = false; - } else { - newState.showNewTips = false; - newState.showRePasswordTips = false; - } - - this.setState(newState); - } - - toggleTypeAttribute(inputId) { - const { - passwordInputType, - } = this.state; - - let type = passwordInputType[inputId]; - if (type === 'text') { - type = 'password'; - } else { - type = 'text'; - } - - this.setState({ - passwordInputType: { - ...passwordInputType, - [inputId]: type, - }, - }); - } - - checkPassword(e) { - const { - clearIncorrectPassword, - } = this.props; - let { newPassword, currentPassword, reNewPassword } = this.state; - - if (e.target.id === 'current-password-input') { - currentPassword = e.target.value; - clearIncorrectPassword(); - } else if (e.target.id === 're-new-password-input') { - reNewPassword = e.target.value; - } else { - newPassword = e.target.value; - } - - let hasLength = false; - let hasLetter = false; - let hasSymbolNumber = false; - let differentOldPassword = false; - if (newPassword) { - hasLength = newPassword.length >= 8; - hasLetter = /[a-zA-Z]/.test(newPassword); - hasSymbolNumber = /[-!$@#%^&*()_+|~=`{}[\]:";'<>?,./]/.test(newPassword) || /[\d]/.test(newPassword); - } - if (currentPassword !== newPassword) { - differentOldPassword = true; - } - this.setState({ - hasLength, - hasLetter, - hasSymbolNumber, - differentOldPassword, - passwordValid: currentPassword.length - && hasLength && hasLetter && hasSymbolNumber && differentOldPassword, - newPassword, - currentPassword, - reNewPassword, - rePasswordValid: reNewPassword.length > 0 && newPassword === reNewPassword, - }); - } - - updatePredicate() { - const { screenSM } = this.state; - this.setState({ isMobileView: window.innerWidth <= screenSM }); - } - - updateButtonsVisible(sendSuccess) { - const newState = { ...this.state }; - if (sendSuccess) { - newState.btnVerifiAgainlVisible = true; - newState.btnVerifiEmailVisible = false; - } - - // rest sent verification email status - newState.isSent = false; - // close modal - newState.isOpen = false; - - this.setState(newState); - } - - render() { - const { - handle, - settingsPageState, - profileState, - } = this.props; - - const { - newEmail, - currentEmail, - btnChangeEmailVisible, - // btnVerifiEmailVisible, - // btnVerifiAgainlVisible, - focus, - hasLength, - hasLetter, - hasSymbolNumber, - differentOldPassword, - passwordInputType, - showNewTips, - showEmailTips, - newEmailSameAsCurrent, - passwordValid, - showRePasswordTips, - rePasswordValid, - // isValidEmail, - isOpen, - } = this.state; - - const { updatingPassword, /* updatingProfile, */ isEmailConflict = false } = profileState; - const { incorrectPassword } = settingsPageState; - - return ( - - { - this.shouldRenderConsent() && this.renderConsent() - } - { - isOpen && ( - -
-
-
- Email Change Verification -
-
- A confirmation email has been sent to both accounts.  - In order to finalize your email address change request,  - you must click on the links in the message sent to both your  - old and new email accounts. -
-
- this.updateButtonsVisible(true)} - > - Close - -
-
-
-
- ) - } -
- -

- Username & Password -

- { - incorrectPassword - && ( -
- Your current password is incorrect. - Please check that you entered the right one. -
- ) - } -
-
- While your Topcoder handle or username and your email cannot be changed, - we encourage to change your password frequently. -
-
-
- - - - - - -
-
- -
-
-
-
- -
-
-

- { - newEmailSameAsCurrent - ? 'The new email cannot be the same as the current email.' - : 'Your email address is not valid.' - } -

-
-
-
-
- { - get(profileState, 'credential.hasPassword') === false && ( -
- Since you joined Topcoder using your <SSO Service> account, - any email updates will need to be handled by logging in to - your <SSO Service> account. -
- ) - } - { - isEmailConflict && ( -
- The email you have entered is already in use. -
- ) - } - {/* TEMPORARY DISABLE CHANGE E-MAIL - community-app#5107 -
-
- - Change Email - -
-
- - Send Verification Email - -
-
- - Send Verification Email Again - -
-
- - Cancel - -
-
- // */} -
- { - profileState.credential && profileState.credential.hasPassword - && ( - -
- - - - - {/* show password */} - {/*
-
-
- -
-
-
*/} - - - -
-

- Your password must have: -

-

- At least 8 characters -

-

- At least one letter -

-

- At least one number or symbol -

-

- Should not be the same as the old password -

-
-
- - {/*
-
-
- -
-
-
*/} - - - -
-

- Your Re-typed password must: -

-

- Match the new password entered -

-
-
- - {/*
-
-
- - -
-
- //
*/} -
- -
- - { !updatingPassword && 'Change Password' } - { updatingPassword && } - -
-
- ) - } - { - profileState.credential && profileState.credential.hasPassword === false - && ( -
-

- You joined Topcoder by using an external account, - so we don't have a password for you. -

-
- ) - } - -
-
-
-
-
- ); - } -} - - -MyAccount.propTypes = { - tokenV3: PT.string.isRequired, - handle: PT.string.isRequired, - settingsUI: PT.shape().isRequired, - profile: PT.shape().isRequired, - profileState: PT.shape().isRequired, - settingsPageState: PT.shape().isRequired, - updatePassword: PT.func.isRequired, - updateProfile: PT.func.isRequired, - clearIncorrectPassword: PT.func.isRequired, - loadTabData: PT.func.isRequired, - updateEmailConflict: PT.func.isRequired, -}; diff --git a/src/shared/components/Settings/Account/MyAccount/styles.scss b/src/shared/components/Settings/Account/MyAccount/styles.scss deleted file mode 100644 index ba61547185..0000000000 --- a/src/shared/components/Settings/Account/MyAccount/styles.scss +++ /dev/null @@ -1,795 +0,0 @@ -@import "../../style"; -@import "~styles/mixins"; - -.hide { - display: none; -} - -.myaccount-container { - display: flex; - flex-direction: column; - align-items: flex-start; - - @include upto-sm { - padding: 20px; - border-bottom: 1px solid $tc-gray-10; - } - - h1 { - @include roboto-regular; - - font-size: 28px; - line-height: 35px; - font-weight: 400; - color: $tc-black; - margin-bottom: 20px; - - @include upto-sm { - display: none; - } - } - - .sub-title { - @include roboto-light; - - color: #888894; - line-height: 35px; - font-weight: 300; - font-size: 28px; - margin-top: 10px; - margin-bottom: 30px; - - @include upto-sm { - display: none; - } - } -} - -.form-container-default { - display: flex; - flex-direction: column; - - .form-default { - display: block; - - @include upto-sm { - display: none; - } - } - - .form-mobile { - display: none; - - @include upto-sm { - display: block; - - .row { - display: flex; - flex-direction: column; - } - } - } - - // Toggle password directive - .toggle-password { - @include merriweather-sans-regular; - - height: 40px; - width: 100%; - font-size: 15px; - line-height: 20px; - margin-bottom: 10px; - background: #fff; - border-radius: 2px; - cursor: auto; - transition: all 0.15s; - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - position: relative; - padding: 0; - - &.focus { - border: 1px solid #0096ff !important; - } - - input.password-input { - margin-bottom: 0; - outline: 0; - width: 100%; - padding-left: 10px; - padding-right: 64px; - height: 100%; - border: none; - - @include placeholder { - @include roboto-regular; - - color: $tc-gray-40; - font-size: 12px; - text-transform: uppercase; - transition: opacity 0.15s; - } - } - - label { - @include roboto-medium; - - display: flex !important; - line-height: 20px !important; - position: absolute; - top: 10px; - right: 0; - text-transform: uppercase; - font-size: 10px; - color: #a3a3ae; - height: 20px; - width: 60px; - padding: 0; - - input[type=checkbox] { - height: 14px; - width: 14px; - visibility: visible; - } - } - } - - .row { - width: 100%; - display: flex; - flex-direction: row; - margin-bottom: 20px; - align-content: space-between; - justify-content: flex-start; - - &.button-group { - justify-content: space-evenly; - } - - .field { - position: relative; - - @include upto-sm { - display: block; - padding-bottom: 10px; - } - - label { - @include roboto-bold; - - font-size: 15px; - line-height: 20px; - font-weight: 700; - color: $tc-gray-80; - - @include upto-sm { - @include roboto-regular; - - font-size: 12px; - } - } - - .passwordCheckbox { - @include roboto-medium; - - font-size: 10px; - line-height: 15px; - font-weight: 500; - color: $tc-gray-80; - margin-bottom: 5px; - } - - &.col-1 { - max-width: 152px; - min-width: 152px; - margin-right: 14px; - align-self: flex-start; - margin-bottom: auto; - margin-top: auto; - white-space: nowrap; - - &.password { - margin-top: 10px; - align-self: flex-start; - border: none; - box-shadow: none; - } - } - - &.col-2 { - align-self: flex-end; - width: 80%; - margin-bottom: auto; - margin-top: auto; - display: flex; - flex-direction: column; - } - - .date-input { - display: flex; - align-items: center; - } - - &.hide { - display: none; - } - } - - &.hide { - display: none; - } - } - - input { - @include roboto-regular; - - height: 40px; - font-size: 15px; - line-height: 20px; - font-weight: 400; - color: $tc-black; - border: 1px solid $tc-gray-20; - border-radius: $corner-radius * 2 $corner-radius * 2 $corner-radius * 2 $corner-radius * 2; - margin-bottom: 0; - } - - .form-field { - background: white; - color: black; - - &:disabled { - color: #b7b7b7; - } - - &.grey { - background-color: #fcfcfc; - color: #151516; - } - } - - .password { - @include merriweather-sans-regular; - - padding-left: 0; - height: 40px; - width: 230px; - font-size: 15px; - line-height: 20px; - color: #3d3d3d; - margin: 0; - outline: none; - background: #fff; - border: 1px solid $tc-gray-20; - box-shadow: inset 0 0 2px 0 hsla(0, 0%, 72%, 0.2); - border-radius: $corner-radius * 2 $corner-radius * 2 $corner-radius * 2 $corner-radius * 2; - cursor: auto; - transition: all 0.15s; - - &:hover { - cursor: text; - } - - input, - input:hover, - input:focus { - background: none; - border: none; - box-shadow: none; - } - - .newPasswordCheckbox, - .currentPasswordCheckbox { - margin: 3px; - } - } - - .validation-bar { - width: 100%; - display: block; - position: relative; - - & input[type='text'], - & input[type='password'] { - width: 100% !important; - } - - .password { - @include merriweather-sans-regular; - - padding-left: 0; - height: 40px; - width: 100%; - font-size: 15px; - line-height: 20px; - color: #3d3d3d; - margin: 0; - outline: none; - background: #fff; - border: 1px solid $tc-gray-20; - box-shadow: inset 0 0 2px 0 hsla(0, 0%, 72%, 0.2); - border-radius: $corner-radius * 2 $corner-radius * 2 $corner-radius * 2 $corner-radius * 2; - cursor: auto; - transition: all 0.15s; - - &:hover { - cursor: text; - } - - input, - input:hover, - input:focus { - background: none; - border: none; - box-shadow: none; - } - - .newPasswordCheckbox, - .currentPasswordCheckbox { - margin: 3px; - } - } - } - - .password-section { - margin-top: 20px; - - @include upto-sm { - display: none; - } - } - - .password-wrap { - width: auto; - } -} - -.form-container { - padding: $pad-xxxxl; - background-color: $color-tc-white; - border-radius: 4px; - margin: $margin-sm 0 $margin-xxxxl 0; - - .password-form { - display: flex; - flex-wrap: wrap; - } - - .account-form { - display: flex; - flex-wrap: wrap; - } - - .error-message { - @include roboto-medium; - - display: block; - border-radius: 5px; - background-color: $tc-red-10; - color: $tc-red-110; - font-size: 15px; - padding: 15px; - margin: 6px 0; - line-height: 20px; - } -} - -.form-title { - @include barlow-semi-bold; - - font-size: 20px; - line-height: 22px; - color: inherit; - text-transform: uppercase; - padding-bottom: $pad-xxxxl; -} - -.form-content { - display: flex; - flex-wrap: wrap; - align-items: flex-start; -} - -.form-label { - flex: 0 0 calc(50% - 13px); - padding-right: 230px; - - @include roboto-regular; - - font-size: 16px; - line-height: 26px; - color: inherit; -} - -.form-body { - flex: 0 0 calc(50% + 13px); -} - -.button-change-password { - margin-bottom: 16px; - - .button { - @include roboto-bold; - - padding: 12px 24px; - background: $tc-white; - border: 2px solid $color-black-5; - border-radius: 50px; - font-size: 16px; - line-height: 24px; - letter-spacing: 0.008em; - text-transform: uppercase; - color: $color-black-60; - height: 48px; - width: 207px; - margin: 0; - - &:hover, - &:active, - &:focus { - outline: none !important; - background: none !important; - border-color: $color-black-5; - color: $color-black-60; - box-shadow: none !important; - } - - &.disabled { - opacity: 0.5; - } - } -} - -@include xs-to-md { - .form-container { - padding: $pad-xxl $pad-lg; - } - - .form-title { - @include barlow-semi-bold; - - font-size: 20px; - line-height: 22px; - padding-bottom: $pad-xxl; - } - - .form-label { - flex: 1 1 100%; - padding: 0; - margin-bottom: $margin-xxl; - font-size: 14px; - line-height: 20px; - } - - .form-body { - flex: 1 1 100%; - } - - .form-footer { - margin: 0; - } -} - -.button-change-email { - margin-left: auto; - margin-right: auto; - - button, - a { - @include roboto-medium; - - height: 40px; - font-size: 15px; - font-weight: 500; - margin: 0; - padding: 0; - width: 170px; - white-space: nowrap; - } - - .white-label { - color: $tc-white; - } - - &.active { - display: block; - } - - &.hide { - display: none; - } -} - -.button-cancel-change-email { - button, - a { - @include roboto-medium; - - height: 40px; - font-size: 15px; - font-weight: 500; - margin: 0; - padding: 0; - width: 170px; - white-space: nowrap; - } - - .white-label { - color: $tc-white; - } - - &.active { - display: block; - } - - &.hide { - display: none; - } -} - -.button-verification-email { - button, - a { - @include roboto-medium; - - height: 40px; - font-size: 15px; - font-weight: 500; - margin: 0; - padding: 0; - width: 200px; - white-space: nowrap; - } - - .white-label { - color: $tc-white; - } - - &.active { - display: block; - } - - &.hide { - display: none; - } -} - -.button-verification-again { - margin-left: auto; - margin-right: auto; - - button, - a { - @include roboto-medium; - - height: 40px; - font-size: 15px; - font-weight: 500; - margin: 0; - padding: 0; - width: 237px; - white-space: nowrap; - } - - .white-label { - color: $tc-white; - } - - &.active { - display: block; - } - - &.hide { - display: none; - } -} - -$tips-shadow: 0 1px 6px 1px rgba(0, 0, 0, 0.2); -$tips-background: $tc-gray-neutral-light; - -// Tip conatiner -.tips { - background-color: $tips-background; - border-radius: 4px; - opacity: 1; - padding: 20px; - transition: all 0.1s ease-in-out; - box-shadow: $tips-shadow; - width: 320px; - padding-bottom: 10px; - text-align: left; - margin-top: 10px; - - @include upto-sm { - margin-top: 0; - margin-bottom: 10px; - margin-left: auto; - margin-right: auto; - } - - // The tip container is hidden - &.ng-hide { - opacity: 0; - } - - h3 { - @include roboto-medium; - - font-size: 14px; - padding-bottom: 15px; - - @media only screen and (max-width: 915px) { - font-size: 16px; - } - } - - p { - // @include merriweather-sans-regular; - @include roboto-medium; - - color: $tc-gray-90; - font-weight: 400; - font-size: 13px; - line-height: 1.3; - padding-bottom: 10px; - position: relative; - text-align: left; - } - - p::before { - @include roboto-medium; - - content: ''; - width: 20px; - font-size: 14px; - left: 0; - top: 0; - position: absolute; - } -} - -// Password tips show checkmark validation -// TODO: refactor name to be context independent, like .validation-tips -.password-tips { - position: absolute; - z-index: 10; - margin-top: 10px; - - p { - padding-left: 20px; - } - - p::before { - color: $tc-green; - content: '\2713 '; - display: none; - } - - .re-password-match::before, - .has-length-between-range::before, - .has-letter::before, - .has-symbol-or-number::before, - .has-number::before, - .different-with-old-password::before { - display: block; - } - - @include upto-sm { - display: none; - - &.mobile { - display: block; - width: 313px; - } - } -} - -.modalContainer { - @include roboto-regular; - - padding: 0; - position: fixed; - overflow: auto; - z-index: 10000; - top: 0; - right: 0; - bottom: 0; - left: 0; - box-sizing: border-box; - width: auto; - max-width: none; - transform: none; - background: transparent; - - .verification-send-container { - background: transparent; - opacity: 1; - position: relative; - padding: 30px; - width: 100%; - height: 100%; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - border-radius: 0; - color: #444; - font-family: Helvetica, sans-serif; - font-size: 1.1em; - line-height: 1.5em; - margin: 0 auto; - max-width: 100%; - } -} - -.verification-send-details { - @include merriweather-sans-light; - - display: flex; - flex-flow: column wrap; - justify-content: space-between; - align-items: center; - background-color: $tc-white; - opacity: 1; - border-radius: 4px; - padding: 40px; - - .verification-send-title { - @include roboto-medium; - - font-size: 20px; - line-height: 24px; - color: $tc-gray-90; - text-transform: uppercase; - } - - .verification-send-message { - margin: 10px 0; - width: 100%; - } - - .verification-send-button { - margin-left: auto; - margin-right: auto; - - button, - a { - @include roboto-medium; - - height: 40px; - font-size: 15px; - font-weight: 500; - margin: 0; - padding: 0; - width: 170px; - white-space: nowrap; - } - - .white-label { - color: $tc-white; - } - } -} - -@media (min-width: 768px) { - .verification-send-details { - width: 520px; - min-height: 256px; - } -} - -.sso-text { - p { - @include roboto-regular; - - margin: 12px 0; - font-size: 16px; - line-height: 26px; - color: inherit; - - @include xs-to-md { - font-size: 14px; - } - } -} diff --git a/src/shared/components/Settings/Account/MyPrimaryRole/FormInputRadio/index.jsx b/src/shared/components/Settings/Account/MyPrimaryRole/FormInputRadio/index.jsx deleted file mode 100644 index cb594d043f..0000000000 --- a/src/shared/components/Settings/Account/MyPrimaryRole/FormInputRadio/index.jsx +++ /dev/null @@ -1,43 +0,0 @@ -import React from 'react'; -import PT from 'prop-types'; - -import './styles.scss'; - -const FormInputRadio = ({ - text, value, selectedValue, onSelectionChange, -}) => { - const handleChange = () => { - onSelectionChange(value); - }; - - const inputId = `roundedInputFieldRadioGroup-${value}`; - return ( -
-
- {text} -
- -
- ); -}; - - -FormInputRadio.propTypes = { - text: PT.string.isRequired, - value: PT.string.isRequired, - selectedValue: PT.string.isRequired, - onSelectionChange: PT.func.isRequired, -}; - -export default FormInputRadio; diff --git a/src/shared/components/Settings/Account/MyPrimaryRole/FormInputRadio/styles.scss b/src/shared/components/Settings/Account/MyPrimaryRole/FormInputRadio/styles.scss deleted file mode 100644 index 58366d3fdb..0000000000 --- a/src/shared/components/Settings/Account/MyPrimaryRole/FormInputRadio/styles.scss +++ /dev/null @@ -1,104 +0,0 @@ -@import "~styles/mixins"; - -.rounded-input-field { - box-sizing: border-box; - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - padding-left: 16px; - height: 72px; - background: #fff; - border: 1px solid #d4d4d4; - border-radius: 8px; - - &:last-child { - margin-right: 0; - margin-bottom: 0; - } - - @media (min-width: 768px) { - width: calc(50% - 32px); // Subtract half the gap size from each button width - margin-right: 32px; // Add the other half of the gap size as margin - } - - @media (max-width: 768px) { - margin-bottom: 24px; - - &:last-child { - margin-bottom: 0; - } - } -} - -.input-option { - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - width: 100%; -} - -.input-text-wrapper { - display: flex; - align-items: center; -} - -.input-text { - @include roboto-medium; - - font-size: 16px; - line-height: 20px; - letter-spacing: 0.5px; - text-transform: capitalize; - color: $tco-black; - flex-grow: 0; -} - -.input-radio-wrapper { - position: relative; - display: flex; - align-items: center; - flex: none; - order: 0; - align-self: stretch; - flex-grow: 0; -} - -.input-radio { - position: absolute; - opacity: 0; - width: 20px; - height: 20px; - cursor: pointer; - z-index: 1; -} - -.custom-radio { - position: absolute; - right: 16px; - top: 55%; - transform: translateY(-50%); - width: 20px; - height: 20px; - background-color: white; - border: 2px solid #aaa; - border-radius: 50%; - cursor: pointer; -} - -.input-radio:checked ~ .custom-radio { - border-color: #137d60; -} - -.input-radio:checked ~ .custom-radio::after { - content: ""; - position: absolute; - width: 10px; - height: 10px; - background-color: #137d60; - border-radius: 50%; - left: 50%; - top: 50%; - transform: translate(-50%, -50%); -} diff --git a/src/shared/components/Settings/Account/MyPrimaryRole/index.jsx b/src/shared/components/Settings/Account/MyPrimaryRole/index.jsx deleted file mode 100644 index 2bad1b2861..0000000000 --- a/src/shared/components/Settings/Account/MyPrimaryRole/index.jsx +++ /dev/null @@ -1,103 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import { withRouter } from 'react-router-dom'; -import { SettingBannerV2 as Collapse } from 'components/Settings/SettingsBanner'; -import { Modal } from 'topcoder-react-ui-kit'; -import { config } from 'topcoder-react-utils'; -import PT from 'prop-types'; -import FormInputRadio from './FormInputRadio'; - -import style from './styles.scss'; - -const MyPrimaryRole = ({ - user, tokenV3, updatePrimaryRole, -}) => { - const [primaryRole, setPrimaryRole] = useState(''); - const [showModal, setShowModal] = useState(false); - - useEffect(() => { - if (user.roles.indexOf('Topcoder Talent') !== -1) { - setPrimaryRole('Topcoder Talent'); - } else { - setPrimaryRole('Topcoder Customer'); - } - }, [user.roles]); - - const handleRoleChange = (value) => { - setPrimaryRole(value); - updatePrimaryRole(value, tokenV3); - setShowModal(true); - }; - - const AUTH_URL = config.URL.AUTH; - const handleSignoutClick = () => { - window.location.href = `${AUTH_URL}?logout=true&retUrl=${encodeURIComponent(config.URL.BASE)}`; - }; - - return ( - - {showModal && ( - -
- -
-
- CONFIRMED -
-
- -
- - You have successfully changed your account role. Please sign out of your account - and login to complete this update. - -
- -
- -
- -
-
- )} -
- -

Account Role

-
-
- Access to Topcoder tools and applications are based on your account - role. If you change this setting, you will be required to sign out - of your account and login. -
-
-
- - - -
-
-
-
-
- ); -}; - -MyPrimaryRole.propTypes = { - user: PT.shape().isRequired, - tokenV3: PT.string.isRequired, - updatePrimaryRole: PT.func.isRequired, -}; - - -export default withRouter(MyPrimaryRole); diff --git a/src/shared/components/Settings/Account/MyPrimaryRole/styles.scss b/src/shared/components/Settings/Account/MyPrimaryRole/styles.scss deleted file mode 100644 index 787ff5d4dc..0000000000 --- a/src/shared/components/Settings/Account/MyPrimaryRole/styles.scss +++ /dev/null @@ -1,254 +0,0 @@ -@import "../../style"; -@import "~styles/mixins"; - -.hide { - display: none; -} - -.form-container-default { - display: flex; - flex-direction: column; - - .form-default { - display: block; - - @include upto-sm { - display: none; - } - } - - .form-mobile { - display: none; - - @include upto-sm { - display: block; - - .row { - display: flex; - flex-direction: column; - } - } - } - - input { - @include roboto-regular; - - height: 40px; - font-size: 15px; - line-height: 20px; - font-weight: 400; - color: $tc-black; - border: 1px solid $tc-gray-20; - border-radius: $corner-radius * 2 $corner-radius * 2 $corner-radius * 2 $corner-radius * 2; - margin-bottom: 0; - } - - .form-field { - background: white; - color: black; - - &:disabled { - color: #b7b7b7; - } - - &.grey { - background-color: #fcfcfc; - color: #151516; - } - } -} - -.form-container { - padding: $pad-xxxxl; - background-color: $color-tc-white; - border-radius: 4px; - margin: $margin-sm 0 $margin-xxxxl 0; - - .account-form { - display: flex; - justify-content: space-between; - width: 100%; - - @media (max-width: 768px) { - flex-direction: column; - } - } -} - -.form-title { - @include barlow-semi-bold; - - font-size: 20px; - line-height: 22px; - color: inherit; - text-transform: uppercase; - padding-bottom: $pad-xxxxl; -} - -.form-content { - display: flex; - flex-wrap: wrap; - align-items: flex-start; -} - -.form-label { - flex: 0 0 calc(50% - 13px); - padding-right: 230px; - - @include roboto-regular; - - font-size: 16px; - line-height: 26px; - color: inherit; -} - -.form-body { - flex: 0 0 calc(50% + 13px); -} - -@include xs-to-md { - .form-container { - padding: $pad-xxl $pad-lg; - } - - .form-title { - @include barlow-semi-bold; - - font-size: 20px; - line-height: 22px; - padding-bottom: $pad-xxl; - } - - .form-label { - flex: 1 1 100%; - padding: 0; - margin-bottom: $margin-xxl; - font-size: 14px; - line-height: 20px; - } - - .form-body { - flex: 1 1 100%; - } - - .form-footer { - margin: 0; - } -} - -.nagModal { - display: flex; - flex-direction: column; - margin: 32px; - - @include xs-to-md { - flex-direction: column; - margin-top: 24px; - } - - .header { - display: flex; - align-items: flex-start; - justify-content: space-between; - border-bottom: 2px solid #e9e9e9; - - @include xs-to-md { - margin-top: 24px; - text-align: center; - } - - .title { - @include barlow-bold; - - color: $tco-black; - font-size: 22px; - font-weight: 600; - line-height: 26px; - margin-bottom: 12px; - text-transform: uppercase; - - @include xs-to-md { - text-align: center; - } - } - - .icon { - cursor: pointer; - } - } - - .description { - @include roboto-regular; - - font-weight: 400; - color: $tco-black; - font-size: 16px; - line-height: 24px; - margin-top: 24px; - - strong { - font-weight: 700; - } - - .badgeWrap { - display: flex; - justify-content: center; - margin-bottom: 12px; - } - - span span { - color: #137d60; - font-weight: bold; - } - } -} - -.container { - box-shadow: 0 1px 5px rgba(0, 0, 0, 0.2); - border-radius: 8px; - min-width: 600px; - max-width: 700px; - - @include xs-to-sm { - width: 90%; - min-width: unset; - } -} - -.overlay { - background-color: #0c0c0c; - opacity: 0.85; -} - -.actionButtons { - display: flex; - align-items: center; - justify-content: flex-end; - margin-top: 32px; - padding-top: 24px; - border-top: 2px solid #e9e9e9; - - .primaryBtn { - background-color: #137d60; - border-radius: 24px; - color: #fff; - font-size: 13px; - font-weight: bolder; - text-decoration: none; - text-transform: uppercase; - line-height: 32px; - padding: 0 20px; - border: none; - outline: none; - display: flex; - - &:hover { - box-shadow: 0 1px 5px 0 rgba(0, 0, 0, 0.2); - background-color: #0ab88a; - } - - @include xs-to-sm { - margin-bottom: 20px; - } - } -} diff --git a/src/shared/components/Settings/Account/Security/Modal/index.jsx b/src/shared/components/Settings/Account/Security/Modal/index.jsx deleted file mode 100644 index 3e33c982e9..0000000000 --- a/src/shared/components/Settings/Account/Security/Modal/index.jsx +++ /dev/null @@ -1,80 +0,0 @@ -import React, { useEffect } from 'react'; -import PT from 'prop-types'; -import DiceImage from 'assets/images/account/security/dicelogosmall.png'; -import CloseButton from 'assets/images/account/security/green-close.svg'; - -import './style.scss'; - -export default function DiceModal({ - children, onCancel, leftButtonName, leftButtonDisabled, leftButtonClick, - rightButtonName, rightButtonDisabled, rightButtonClick, rightButtonHide, -}) { - useEffect(() => { - document.body.style.overflow = 'hidden'; - return () => { document.body.style.overflow = 'unset'; }; - }, []); - - return ( - ( - -
event.stopPropagation()} - > -
-
- diceid -
-
DICE ID authenticator setup
- -
-
-
- {children} -
-
-
-
- {leftButtonName} -
- {!rightButtonHide && ( -
- {rightButtonName} -
- )} -
-
-
- - ) - ); -} -DiceModal.defaultProps = { - children: null, - leftButtonDisabled: false, - rightButtonDisabled: false, - rightButtonHide: false, -}; -DiceModal.propTypes = { - children: PT.node, - onCancel: PT.func.isRequired, - leftButtonName: PT.string.isRequired, - leftButtonDisabled: PT.bool, - leftButtonClick: PT.func.isRequired, - rightButtonName: PT.string.isRequired, - rightButtonDisabled: PT.bool, - rightButtonClick: PT.func.isRequired, - rightButtonHide: PT.bool, -}; diff --git a/src/shared/components/Settings/Account/Security/Modal/style.scss b/src/shared/components/Settings/Account/Security/Modal/style.scss deleted file mode 100644 index 1f972a52ec..0000000000 --- a/src/shared/components/Settings/Account/Security/Modal/style.scss +++ /dev/null @@ -1,162 +0,0 @@ -@import "../../../style"; -@import "~styles/mixins"; - -.overlay { - background: #0c0c0c; - border: none; - height: 100%; - left: 0; - opacity: 0.85; - outline: none; - position: fixed; - top: 0; - width: 100%; - z-index: 950; -} - -.container { - background: #fff; - position: fixed; - max-width: 1000px; - height: 752px; - max-height: 99%; - top: 50%; - left: 50%; - padding: 32px; - box-shadow: 0 0 1px 5px rgba(0, 0, 0, 0.2); - border-radius: 8px; - overflow: auto; - transform: translate(-50%, -50%); - z-index: 951; - display: flex; - flex-direction: column; - align-items: flex-start; - - .header { - display: flex; - align-items: center; - justify-content: space-between; - width: 100%; - margin-bottom: 24px; - - .icon-wrapper { - display: flex; - align-items: center; - justify-content: center; - width: 150px; - height: 40px; - background: #fff; - border-radius: 4px; - margin-right: $margin-md; - - img { - display: block; - } - } - - .title { - @include barlow-semi-bold; - - flex: 1; - font-size: 22px; - line-height: 26px; - color: $tco-black; - text-transform: uppercase; - } - - .close-button { - cursor: pointer; - height: 15px; - width: 15px; - } - } - - .body { - flex: 1; - width: 100%; - display: flex; - flex-direction: column; - margin-bottom: 24px; - } - - .divider { - width: 100%; - min-height: 2px; - background-color: #e9e9e9; - border-radius: 1px; - margin-bottom: 24px; - } - - .footer { - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - width: 100%; - - .left-button { - @include roboto-bold; - - text-align: center; - margin: 0; - height: 48px; - font-size: 16px; - line-height: 21px; - letter-spacing: 0.008em; - text-transform: uppercase; - color: $color-turq-160; - padding: 12px 24px; - background: $tc-white; - border: 2px solid $color-turq-160; - border-radius: 50px; - cursor: pointer; - - &:focus { - outline: none; - } - - &:focus-visible { - outline: none; - } - - &.disabled { - background: #f4f4f4; - color: #767676; - border: none; - line-height: 24px; - pointer-events: none; - } - } - - .right-button { - @include roboto-bold; - - text-align: center; - margin: 0; - height: 48px; - font-size: 16px; - line-height: 24px; - letter-spacing: 0.008em; - text-transform: uppercase; - color: $tc-white; - padding: 12px 24px; - background: $color-turq-160; - border-radius: 50px; - cursor: pointer; - - &:focus { - outline: none; - } - - &:focus-visible { - outline: none; - } - - &.disabled { - background: #f4f4f4; - color: #767676; - pointer-events: none; - } - } - } -} diff --git a/src/shared/components/Settings/Account/Security/VerificationListener/index.jsx b/src/shared/components/Settings/Account/Security/VerificationListener/index.jsx deleted file mode 100644 index 26e0ee9e54..0000000000 --- a/src/shared/components/Settings/Account/Security/VerificationListener/index.jsx +++ /dev/null @@ -1,32 +0,0 @@ -import { useEffect, useCallback } from 'react'; -import PT from 'prop-types'; - -export default function VerificationListener({ - event, callback, origin, type, onProcessing, startType, -}) { - const messageHandler = useCallback((e) => { - if (e.origin === origin && e.data && e.data.type) { - if (e.data.type === startType) { - onProcessing(); - } else if (e.data.type === type) { - callback(e.data); - } - } - }, [origin, type, startType]); - - useEffect(() => { - window.addEventListener(event, messageHandler); - return () => window.removeEventListener(event, messageHandler); - }, [event, messageHandler]); - - return false; -} - -VerificationListener.propTypes = { - event: PT.string.isRequired, - callback: PT.func.isRequired, - origin: PT.string.isRequired, - type: PT.string.isRequired, - onProcessing: PT.func.isRequired, - startType: PT.string.isRequired, -}; diff --git a/src/shared/components/Settings/Account/Security/index.jsx b/src/shared/components/Settings/Account/Security/index.jsx deleted file mode 100644 index 796cf1beba..0000000000 --- a/src/shared/components/Settings/Account/Security/index.jsx +++ /dev/null @@ -1,430 +0,0 @@ -import React, { useState, useEffect, useRef } from 'react'; -import PT from 'prop-types'; -import _ from 'lodash'; -import { config } from 'topcoder-react-utils'; -import QRCode from 'react-qr-code'; -import { SettingBannerV2 as Collapse } from 'components/Settings/SettingsBanner'; -import Tooltip from 'components/Tooltip'; -import MfaImage from 'assets/images/account/security/mfa.svg'; -import DiceLogo from 'assets/images/account/security/dicelogo.png'; -import DiceLogoBig from 'assets/images/account/security/dicelogobig.png'; -import GooglePlay from 'assets/images/account/security/google-play.png'; -import AppleStore from 'assets/images/account/security/apple-store.svg'; -import UnsuccessfulIcon from 'assets/images/account/security/unsuccessful.svg'; -import TooltipInfo from 'assets/images/tooltip-info.svg'; -import Modal from './Modal'; -import VerificationListener from './VerificationListener'; - - -import './styles.scss'; - -export default function Security({ - usermfa, updateUser2fa, updateUserDice, getNewDiceConnection, - getDiceConnection, tokenV3, handle, emailAddress, -}) { - const [setupStep, setSetupStep] = useState(-1); - const [isConnVerifyRunning, setIsConnVerifyRunning] = useState(false); - const [connVerifyCounter, setConnVerifyCounter] = useState(0); - const [isVerificationProcessing, setIsVerificationProcessing] = useState(false); - const diceVerifyUrl = config.DICE_VERIFY_URL; - - const diceTip = ( -
-

Please reach out to support@topcoder.com for deactivating Dice ID

-
- ); - const useInterval = (callback, delay) => { - const savedCallback = useRef(); - - useEffect(() => { - savedCallback.current = callback; - }, [callback]); - - // eslint-disable-next-line consistent-return - useEffect(() => { - function tick() { - savedCallback.current(); - } - if (delay !== null) { - const id = setInterval(tick, delay); - return () => clearInterval(id); - } - setConnVerifyCounter(0); - }, [delay]); - }; - - const getMfaOption = () => { - const mfaEnabled = _.get(usermfa, 'user2fa.mfaEnabled'); - if (mfaEnabled) return true; - return false; - }; - - const getDiceOption = () => { - const diceEnabled = _.get(usermfa, 'user2fa.diceEnabled'); - if (diceEnabled) return true; - return false; - }; - - const mfaChecked = getMfaOption(); - const diceChecked = getDiceOption(); - const userId = _.get(usermfa, 'user2fa.userId'); - const diceConnection = _.get(usermfa, 'diceConnection'); - - const onUpdateMfaOption = () => { - if (usermfa.updatingUser2fa) { - return; - } - updateUser2fa(userId, !mfaChecked, tokenV3); - }; - - const goToConnection = () => { - if (mfaChecked && !usermfa.gettingNewDiceConnection) { - getNewDiceConnection(userId, tokenV3); - } - setSetupStep(1); - setIsConnVerifyRunning(true); - }; - - const getConnectionAccepted = () => { - if (diceConnection.accepted) return true; - return false; - }; - - const openSetup = () => { - setSetupStep(0); - }; - - const closeSetup = () => { - setSetupStep(-1); - setIsVerificationProcessing(false); - }; - - const verifyConnection = () => { - if (getConnectionAccepted() || usermfa.diceConnectionError) { - setIsConnVerifyRunning(false); - } else if (!usermfa.gettingDiceConnection && diceConnection.id) { - if (connVerifyCounter >= 36) { - closeSetup(); - } else { - getDiceConnection(userId, diceConnection.id, tokenV3); - setConnVerifyCounter(connVerifyCounter + 1); - } - } - }; - - const goToVerification = () => { - if (!getConnectionAccepted()) { - return; - } - setSetupStep(2); - }; - - const verificationCallback = (data) => { - if (data.success) { - const userEmail = _.get(data, 'user.profile.Email'); - if (!_.isUndefined(userEmail) && _.lowerCase(userEmail) === _.lowerCase(emailAddress)) { - updateUserDice(userId, true, tokenV3); - setSetupStep(3); - } else { - setSetupStep(4); - } - } else { - setSetupStep(4); - } - }; - - const onStartProcessing = () => { - setIsVerificationProcessing(true); - }; - - useInterval(verifyConnection, setupStep === 1 && isConnVerifyRunning ? 5000 : null); - - const getVerificationStepTitle = () => { - if (isVerificationProcessing) { - return 'Processing...'; - } - return 'STEP 3 OF 3'; - }; - - const getVerificationStepText = () => { - if (isVerificationProcessing) { - return 'Please wait while your credentials are validated.'; - } - return 'Scan the following DICE ID QR Code in your DICE ID mobile application to confirm your credential.'; - }; - - const setupStepNodes = [ - -
-
- STEP 1 OF 3 -
-
- First, please download the DICE ID App from the - Google Play Store or the iOS App Store. -
-
-
- Google Play Store - -
-
- - -
-
-
- After you have downloaded and installed the mobile app, - make sure to complete the configuration process. - When ready, click next below. -
-
-
, - -
-
- STEP 2 OF 3 -
-
- Scan the following DICE ID QR Code in your DICE ID mobile application. -
-
- {diceConnection.connection - ? - : 'Loading'} -
-
- Once the connection is established, the service will offer you a Verifiable Credential. -
Press the ACCEPT button in your DICE ID App. -
If you DECLINE the invitation, please try again after 5 minutes. -
-
-
, - {}} - rightButtonHide - > -
-
- {getVerificationStepTitle()} -
-
- {getVerificationStepText()} -
-