From c93affadf0942b48f507fed34e8ffda3e3ea10d9 Mon Sep 17 00:00:00 2001 From: Justin Gasper Date: Wed, 31 May 2023 13:20:18 +1000 Subject: [PATCH 1/4] Show the security reminder for NDA challenges --- config/custom-environment-variables.js | 1 + config/default.js | 3 + config/development.js | 3 + config/production.js | 3 + .../components/SecurityReminder/index.jsx | 78 +++++++++++++++++++ .../components/SecurityReminder/styles.scss | 77 ++++++++++++++++++ .../challenge-detail/Header/index.jsx | 8 +- .../containers/challenge-detail/index.jsx | 23 +++++- 8 files changed, 193 insertions(+), 3 deletions(-) create mode 100644 src/shared/components/SecurityReminder/index.jsx create mode 100644 src/shared/components/SecurityReminder/styles.scss diff --git a/config/custom-environment-variables.js b/config/custom-environment-variables.js index d161d20dee..2ccd6884af 100644 --- a/config/custom-environment-variables.js +++ b/config/custom-environment-variables.js @@ -10,6 +10,7 @@ module.exports = { }, DISABLE_SERVICE_WORKER: 'DISABLE_SERVICE_WORKER', LOG_ENTRIES_TOKEN: 'LOG_ENTRIES_TOKEN', + TERM_NDA_ID: 'TERM_NDA_ID', MOCK_TERMS_SERVICE: 'MOCK_TERMS_SERVICE', NEWSLETTER_SIGNUP: { diff --git a/config/default.js b/config/default.js index 0e399b364c..fa819effcf 100644 --- a/config/default.js +++ b/config/default.js @@ -69,6 +69,9 @@ module.exports = { * agreement flow. */ MOCK_TERMS_SERVICE: false, + // Specifically for the terms ID that matches the NDA requirement. + TERM_NDA_ID: '', + /* Holds params to signup for different newsletters. */ NEWSLETTER_SIGNUP: { DEFAUL_LIST_ID: '28bfd3c062', diff --git a/config/development.js b/config/development.js index 5088a55f80..e5bf748a1a 100644 --- a/config/development.js +++ b/config/development.js @@ -6,4 +6,7 @@ module.exports = { }, PLATFORM_SITE_URL: 'https://platform.topcoder-dev.com', PLATFORMUI_SITE_URL: 'https://platform-ui.topcoder-dev.com', + + // Specifically for the terms ID that matches the NDA requirement. + TERM_NDA_ID: 'e5811a7b-43d1-407a-a064-69e5015b4900', }; diff --git a/config/production.js b/config/production.js index a415c0ef66..48f4329a4f 100644 --- a/config/production.js +++ b/config/production.js @@ -237,4 +237,7 @@ module.exports = { /* development id - makes surveys have warning about environment */ UNIVERSAL_NAV_URL: '//uni-nav.topcoder.com/v1/tc-universal-nav.js', SPRIG_ENVIRONMENT_ID: 'a-IZBZ6-r7bU', + + // Specifically for the terms ID that matches the NDA requirement. + TERM_NDA_ID: '05342dcb-3405-445e-95b2-8ea2a3834b0d', }; diff --git a/src/shared/components/SecurityReminder/index.jsx b/src/shared/components/SecurityReminder/index.jsx new file mode 100644 index 0000000000..8c772da75c --- /dev/null +++ b/src/shared/components/SecurityReminder/index.jsx @@ -0,0 +1,78 @@ +/* eslint-disable jsx-a11y/no-noninteractive-tabindex */ +/* eslint jsx-a11y/no-static-element-interactions:0 */ +/* global window */ + +import React, { useState } from 'react'; +import PT from 'prop-types'; +import { Modal, PrimaryButton } from 'topcoder-react-ui-kit'; +import FocusTrap from 'focus-trap-react'; +import Checkbox from 'components/GUIKit/Checkbox'; +import IconClose from 'assets/images/tc-edu/icon-close-big.svg'; + +import style from './styles.scss'; + + +function SecurityReminder({ + onOk, + onCancel, +}) { + const [isAgree, setIsAgree] = useState(false); + return ( +
+ + +
+
+ IMPORTANT REMINDER +
+
+ In accordance with the Terms & Conditions and Code + of Conduct you agree: +
    +
  • + To keep private any downloaded data (including code) +
  • +
      +
    • Except sharing or submission as directed or authorized by Topcoder
    • +
    +
  • To delete such data after completion of the challenge or project
  • +
+ +
+ setIsAgree(checked)} + checked={isAgree} + /> + I agree +
+ +
+ + Register + +
+
+ + + +
+
+
+
+ ); +} + +SecurityReminder.propTypes = { + onOk: PT.func.isRequired, + onCancel: PT.func.isRequired, +}; +export default SecurityReminder; diff --git a/src/shared/components/SecurityReminder/styles.scss b/src/shared/components/SecurityReminder/styles.scss new file mode 100644 index 0000000000..ffe62a2203 --- /dev/null +++ b/src/shared/components/SecurityReminder/styles.scss @@ -0,0 +1,77 @@ +@import "~styles/mixins"; + +.modal-container { + @include roboto-regular; + + color: $tc-black; + display: flex; + flex-direction: column; + padding: 40px 40px 0; + width: 800px; + + @include xs-to-sm { + padding: 3 * $base-unit; + padding-bottom: 0; + } +} + +.modal-content { + display: flex; + flex: 1; + flex-direction: column; + max-height: 100%; + position: relative; + + &:focus { + outline: none; + } + + ul { + list-style: revert; + margin-left: 15px; + } +} + +.agreementList { + margin-top: 20px; +} + +.title { + font-size: 28px; + margin-bottom: 1.5 * $base-unit; + text-align: center; + color: $tc-gray-80; +} + +.desc { + margin-top: 24px; + font-size: 15px; + line-height: 25px; + color: $tc-gray-80; + + @include sm { + margin-top: 20px; + } +} + +.buttons { + padding: (1.5 * $base-unit) 0 (2 * $base-unit); + text-align: center; +} + +.checkboxContainer { + display: flex; + align-items: center; + margin-top: 20px; + + span { + margin-left: 15px; + } +} + +.btn-close { + position: absolute; + top: -15px; + right: -15px; + padding: 5px; +} diff --git a/src/shared/components/challenge-detail/Header/index.jsx b/src/shared/components/challenge-detail/Header/index.jsx index 051d6b7fd9..46d956aaed 100644 --- a/src/shared/components/challenge-detail/Header/index.jsx +++ b/src/shared/components/challenge-detail/Header/index.jsx @@ -14,7 +14,7 @@ import PT from 'prop-types'; import React from 'react'; import { PrimaryButton } from 'topcoder-react-ui-kit'; import { Link } from 'topcoder-react-utils'; -import { COMPETITION_TRACKS } from 'utils/tc'; +import { COMPETITION_TRACKS, CHALLENGE_STATUS } from 'utils/tc'; import { phaseEndDate } from 'utils/challenge-listing/helper'; import { getTimeLeft, @@ -82,6 +82,7 @@ export default function ChallengeHeader(props) { track, } = challenge; const showDeadlineDetail = showDeadlineDetailProp; + const isActivedChallenge = `${status}`.indexOf(CHALLENGE_STATUS.ACTIVE) >= 0; const tags = challenge.tags || []; @@ -275,7 +276,10 @@ export default function ChallengeHeader(props) { } const disabled = !hasRegistered || unregistering || submissionEnded || isLegacyMM; - const registerButtonDisabled = registering || registrationEnded || isLegacyMM; + const registerButtonDisabled = registering + || registrationEnded + || isLegacyMM + || !isActivedChallenge; const unregisterButtonDisabled = unregistering || registrationEnded || hasSubmissions || isLegacyMM; diff --git a/src/shared/containers/challenge-detail/index.jsx b/src/shared/containers/challenge-detail/index.jsx index ed6e3bcc8b..201424022f 100644 --- a/src/shared/containers/challenge-detail/index.jsx +++ b/src/shared/containers/challenge-detail/index.jsx @@ -27,6 +27,7 @@ import LoadingIndicator from 'components/LoadingIndicator'; // eslint-disable-next-line max-len // import RecommendedActiveChallenges from 'components/challenge-detail/RecommendedActiveChallenges'; import Terms from 'containers/Terms'; +import SecurityReminder from 'components/SecurityReminder'; import termsActions from 'actions/terms'; import ChallengeCheckpoints from 'components/challenge-detail/Checkpoints'; import React from 'react'; @@ -170,6 +171,7 @@ class ChallengeDetailPageContainer extends React.Component { }, notFoundCountryFlagUrl: {}, viewAsTable: false, + showSecurityReminder: false, }; this.instanceId = shortId(); @@ -323,13 +325,17 @@ class ChallengeDetailPageContainer extends React.Component { auth, challengeId, communityId, - openTermsModal, registerForChallenge, + openTermsModal, terms, } = this.props; if (!auth.tokenV3) { const utmSource = communityId || 'community-app-main'; window.location.href = `${config.URL.AUTH}/member?retUrl=${encodeURIComponent(window.location.href)}&utm_source=${utmSource}®Source=challenges`; + } else if (terms && !!_.find(terms, { id: config.TERM_NDA_ID })) { + this.setState({ + showSecurityReminder: true, + }); } else if (_.every(terms, 'agreed')) { registerForChallenge(auth, challengeId); } else { @@ -382,6 +388,7 @@ class ChallengeDetailPageContainer extends React.Component { reviewTypes, openForRegistrationChallenges, statisticsData, + openTermsModal, } = this.props; // const displayRecommendedChallenges = getDisplayRecommendedChallenges( @@ -398,6 +405,7 @@ class ChallengeDetailPageContainer extends React.Component { notFoundCountryFlagUrl, mySubmissionsSort, viewAsTable, + showSecurityReminder, } = this.state; const { @@ -680,6 +688,19 @@ class ChallengeDetailPageContainer extends React.Component { }} /> )} + {showSecurityReminder && ( + this.setState({ showSecurityReminder: false })} + onOk={() => { + this.setState({ showSecurityReminder: false }); + if (_.every(terms, 'agreed')) { + registerForChallenge(auth, challengeId); + } else { + openTermsModal(); + } + }} + /> + )} {/* { !isEmpty && displayRecommendedChallenges.length ? ( Date: Wed, 31 May 2023 14:20:06 +1000 Subject: [PATCH 2/4] Fix prod NDA terms ID --- config/production.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/production.js b/config/production.js index 48f4329a4f..05ec83aee0 100644 --- a/config/production.js +++ b/config/production.js @@ -239,5 +239,5 @@ module.exports = { SPRIG_ENVIRONMENT_ID: 'a-IZBZ6-r7bU', // Specifically for the terms ID that matches the NDA requirement. - TERM_NDA_ID: '05342dcb-3405-445e-95b2-8ea2a3834b0d', + TERM_NDA_ID: 'c41e90e5-4d0e-4811-bd09-38ff72674490', }; From f8ec10b06fb2610ad64ac068f52f6065bc6001e6 Mon Sep 17 00:00:00 2001 From: Kiril Kartunov Date: Wed, 31 May 2023 09:59:29 +0300 Subject: [PATCH 3/4] MKTG-1156 update email preferences --- .../components/Settings/Preferences/Email/index.jsx | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/src/shared/components/Settings/Preferences/Email/index.jsx b/src/shared/components/Settings/Preferences/Email/index.jsx index ee25730025..f6f79b718c 100644 --- a/src/shared/components/Settings/Preferences/Email/index.jsx +++ b/src/shared/components/Settings/Preferences/Email/index.jsx @@ -29,13 +29,13 @@ const SAVE_DELAY = 1000; const newsletters = [ { id: 'd0c48e9da3', - name: 'Gig Work', - desc: 'This newsletter gets sent out at various times, specifically when we have an opportunity of mass appeal. For more information you can visit the Gig Work page.', + name: 'Work Opportunities', + desc: 'A weekly summary of available ways to earn, including gig work, challenges, and Thrive articles.', }, { id: 'a8f858cdf1', name: 'Monthly Newsletter', - desc: 'This newsletter gets sent out at the end of every month and contains a variety of important information across all of our tracks.', + desc: 'A monthly newsletter with recent highlights from the Topcoder community.', }, { id: '5e67dba327', @@ -52,11 +52,6 @@ const newsletters = [ name: 'Rapid Development Match (RDM) Reminders', desc: 'Receive notifications of our brand new RDMs! These rated, development matches will be a fun new way to engage with us!', }, - { - id: 'ee26600945', - name: 'NASA Community', - desc: 'Receive email notifications for all the latest news and announcements of our NASA Member Program.', - }, ]; const programs = [ { From 77d444dbe0671979f0d988795abb3bc979d88a6f Mon Sep 17 00:00:00 2001 From: Kiril Kartunov Date: Wed, 31 May 2023 10:01:01 +0300 Subject: [PATCH 4/4] ci: on test --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 89275af291..a83fac55ef 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -356,7 +356,7 @@ workflows: filters: branches: only: - - free + - MKTG-1156 # This is alternate dev env for parallel testing - "build-qa": context : org-global