Skip to content

Commit caccd93

Browse files
authored
Merge pull request #6885 from topcoder-platform/develop
PROD -- Security reminder popup / email preferences change
2 parents 4f6873c + 84441af commit caccd93

File tree

10 files changed

+197
-12
lines changed

10 files changed

+197
-12
lines changed

.circleci/config.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ workflows:
357357
filters:
358358
branches:
359359
only:
360-
- free
360+
- MKTG-1156
361361
# This is alternate dev env for parallel testing
362362
- "build-qa":
363363
context : org-global

config/custom-environment-variables.js

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ module.exports = {
1010
},
1111
DISABLE_SERVICE_WORKER: 'DISABLE_SERVICE_WORKER',
1212
LOG_ENTRIES_TOKEN: 'LOG_ENTRIES_TOKEN',
13+
TERM_NDA_ID: 'TERM_NDA_ID',
1314
MOCK_TERMS_SERVICE: 'MOCK_TERMS_SERVICE',
1415

1516
NEWSLETTER_SIGNUP: {

config/default.js

+3
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ module.exports = {
6969
* agreement flow. */
7070
MOCK_TERMS_SERVICE: false,
7171

72+
// Specifically for the terms ID that matches the NDA requirement.
73+
TERM_NDA_ID: '',
74+
7275
/* Holds params to signup for different newsletters. */
7376
NEWSLETTER_SIGNUP: {
7477
DEFAUL_LIST_ID: '28bfd3c062',

config/development.js

+3
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,7 @@ module.exports = {
66
},
77
PLATFORM_SITE_URL: 'https://platform.topcoder-dev.com',
88
PLATFORMUI_SITE_URL: 'https://platform-ui.topcoder-dev.com',
9+
10+
// Specifically for the terms ID that matches the NDA requirement.
11+
TERM_NDA_ID: 'e5811a7b-43d1-407a-a064-69e5015b4900',
912
};

config/production.js

+3
Original file line numberDiff line numberDiff line change
@@ -237,4 +237,7 @@ module.exports = {
237237
/* development id - makes surveys have warning about environment */
238238
UNIVERSAL_NAV_URL: '//uni-nav.topcoder.com/v1/tc-universal-nav.js',
239239
SPRIG_ENVIRONMENT_ID: 'a-IZBZ6-r7bU',
240+
241+
// Specifically for the terms ID that matches the NDA requirement.
242+
TERM_NDA_ID: 'c41e90e5-4d0e-4811-bd09-38ff72674490',
240243
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/* eslint-disable jsx-a11y/no-noninteractive-tabindex */
2+
/* eslint jsx-a11y/no-static-element-interactions:0 */
3+
/* global window */
4+
5+
import React, { useState } from 'react';
6+
import PT from 'prop-types';
7+
import { Modal, PrimaryButton } from 'topcoder-react-ui-kit';
8+
import FocusTrap from 'focus-trap-react';
9+
import Checkbox from 'components/GUIKit/Checkbox';
10+
import IconClose from 'assets/images/tc-edu/icon-close-big.svg';
11+
12+
import style from './styles.scss';
13+
14+
15+
function SecurityReminder({
16+
onOk,
17+
onCancel,
18+
}) {
19+
const [isAgree, setIsAgree] = useState(false);
20+
return (
21+
<div>
22+
<FocusTrap>
23+
<Modal
24+
onCancel={onCancel}
25+
theme={{ container: style['modal-container'] }}
26+
>
27+
<div styleName="modal-content" tabIndex="0">
28+
<div styleName="title">
29+
IMPORTANT REMINDER
30+
</div>
31+
<div styleName="desc">
32+
In accordance with the Terms & Conditions and Code
33+
of Conduct you agree:
34+
<ul styleName="agreementList">
35+
<li>
36+
To keep private any downloaded data (including code)
37+
</li>
38+
<ul>
39+
<li>Except sharing or submission as directed or authorized by Topcoder</li>
40+
</ul>
41+
<li>To delete such data after completion of the challenge or project</li>
42+
</ul>
43+
44+
<div styleName="checkboxContainer">
45+
<Checkbox
46+
onChange={checked => setIsAgree(checked)}
47+
checked={isAgree}
48+
/>
49+
<span>I agree</span>
50+
</div>
51+
52+
<div styleName="buttons">
53+
<PrimaryButton
54+
disabled={!isAgree}
55+
onClick={onOk}
56+
theme={style}
57+
>
58+
Register
59+
</PrimaryButton>
60+
</div>
61+
</div>
62+
63+
<button styleName="btn-close" type="button" onClick={onCancel}>
64+
<IconClose />
65+
</button>
66+
67+
</div>
68+
</Modal>
69+
</FocusTrap>
70+
</div>
71+
);
72+
}
73+
74+
SecurityReminder.propTypes = {
75+
onOk: PT.func.isRequired,
76+
onCancel: PT.func.isRequired,
77+
};
78+
export default SecurityReminder;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
@import "~styles/mixins";
2+
3+
.modal-container {
4+
@include roboto-regular;
5+
6+
color: $tc-black;
7+
display: flex;
8+
flex-direction: column;
9+
padding: 40px 40px 0;
10+
width: 800px;
11+
12+
@include xs-to-sm {
13+
padding: 3 * $base-unit;
14+
padding-bottom: 0;
15+
}
16+
}
17+
18+
.modal-content {
19+
display: flex;
20+
flex: 1;
21+
flex-direction: column;
22+
max-height: 100%;
23+
position: relative;
24+
25+
&:focus {
26+
outline: none;
27+
}
28+
29+
ul {
30+
list-style: revert;
31+
margin-left: 15px;
32+
}
33+
}
34+
35+
.agreementList {
36+
margin-top: 20px;
37+
}
38+
39+
.title {
40+
font-size: 28px;
41+
margin-bottom: 1.5 * $base-unit;
42+
text-align: center;
43+
color: $tc-gray-80;
44+
}
45+
46+
.desc {
47+
margin-top: 24px;
48+
font-size: 15px;
49+
line-height: 25px;
50+
color: $tc-gray-80;
51+
52+
@include sm {
53+
margin-top: 20px;
54+
}
55+
}
56+
57+
.buttons {
58+
padding: (1.5 * $base-unit) 0 (2 * $base-unit);
59+
text-align: center;
60+
}
61+
62+
.checkboxContainer {
63+
display: flex;
64+
align-items: center;
65+
margin-top: 20px;
66+
67+
span {
68+
margin-left: 15px;
69+
}
70+
}
71+
72+
.btn-close {
73+
position: absolute;
74+
top: -15px;
75+
right: -15px;
76+
padding: 5px;
77+
}

src/shared/components/Settings/Preferences/Email/index.jsx

+3-8
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,13 @@ const SAVE_DELAY = 1000;
2929
const newsletters = [
3030
{
3131
id: 'd0c48e9da3',
32-
name: 'Gig Work',
33-
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 <a href="https://www.topcoder.com/community/taas" style="color:#0d61bf;text-decoration:none;font-weight:500;">Gig Work page.</a>',
32+
name: 'Work Opportunities',
33+
desc: 'A weekly summary of available ways to earn, including gig work, challenges, and Thrive articles.',
3434
},
3535
{
3636
id: 'a8f858cdf1',
3737
name: 'Monthly Newsletter',
38-
desc: 'This newsletter gets sent out at the end of every month and contains a variety of important information across all of our tracks.',
38+
desc: 'A monthly newsletter with recent highlights from the Topcoder community.',
3939
},
4040
{
4141
id: '5e67dba327',
@@ -52,11 +52,6 @@ const newsletters = [
5252
name: 'Rapid Development Match (RDM) Reminders',
5353
desc: 'Receive notifications of our brand new RDMs! These rated, development matches will be a fun new way to engage with us!',
5454
},
55-
{
56-
id: 'ee26600945',
57-
name: 'NASA Community',
58-
desc: 'Receive email notifications for all the latest news and announcements of our <a href="https://www.topcoder.com/community/nasa" style="color:#0d61bf;text-decoration:none;font-weight:500;">NASA Member Program</a>.',
59-
},
6055
];
6156
const programs = [
6257
{

src/shared/components/challenge-detail/Header/index.jsx

+6-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import PT from 'prop-types';
1414
import React from 'react';
1515
import { PrimaryButton } from 'topcoder-react-ui-kit';
1616
import { Link } from 'topcoder-react-utils';
17-
import { COMPETITION_TRACKS } from 'utils/tc';
17+
import { COMPETITION_TRACKS, CHALLENGE_STATUS } from 'utils/tc';
1818
import { phaseEndDate } from 'utils/challenge-listing/helper';
1919
import {
2020
getTimeLeft,
@@ -82,6 +82,7 @@ export default function ChallengeHeader(props) {
8282
track,
8383
} = challenge;
8484
const showDeadlineDetail = showDeadlineDetailProp;
85+
const isActivedChallenge = `${status}`.indexOf(CHALLENGE_STATUS.ACTIVE) >= 0;
8586

8687
const tags = challenge.tags || [];
8788

@@ -275,7 +276,10 @@ export default function ChallengeHeader(props) {
275276
}
276277

277278
const disabled = !hasRegistered || unregistering || submissionEnded || isLegacyMM;
278-
const registerButtonDisabled = registering || registrationEnded || isLegacyMM;
279+
const registerButtonDisabled = registering
280+
|| registrationEnded
281+
|| isLegacyMM
282+
|| !isActivedChallenge;
279283
const unregisterButtonDisabled = unregistering
280284
|| registrationEnded || hasSubmissions || isLegacyMM;
281285

src/shared/containers/challenge-detail/index.jsx

+22-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import LoadingIndicator from 'components/LoadingIndicator';
2727
// eslint-disable-next-line max-len
2828
// import RecommendedActiveChallenges from 'components/challenge-detail/RecommendedActiveChallenges';
2929
import Terms from 'containers/Terms';
30+
import SecurityReminder from 'components/SecurityReminder';
3031
import termsActions from 'actions/terms';
3132
import ChallengeCheckpoints from 'components/challenge-detail/Checkpoints';
3233
import React from 'react';
@@ -170,6 +171,7 @@ class ChallengeDetailPageContainer extends React.Component {
170171
},
171172
notFoundCountryFlagUrl: {},
172173
viewAsTable: false,
174+
showSecurityReminder: false,
173175
};
174176

175177
this.instanceId = shortId();
@@ -323,13 +325,17 @@ class ChallengeDetailPageContainer extends React.Component {
323325
auth,
324326
challengeId,
325327
communityId,
326-
openTermsModal,
327328
registerForChallenge,
329+
openTermsModal,
328330
terms,
329331
} = this.props;
330332
if (!auth.tokenV3) {
331333
const utmSource = communityId || 'community-app-main';
332334
window.location.href = `${config.URL.AUTH}/member?retUrl=${encodeURIComponent(window.location.href)}&utm_source=${utmSource}&regSource=challenges`;
335+
} else if (terms && !!_.find(terms, { id: config.TERM_NDA_ID })) {
336+
this.setState({
337+
showSecurityReminder: true,
338+
});
333339
} else if (_.every(terms, 'agreed')) {
334340
registerForChallenge(auth, challengeId);
335341
} else {
@@ -382,6 +388,7 @@ class ChallengeDetailPageContainer extends React.Component {
382388
reviewTypes,
383389
openForRegistrationChallenges,
384390
statisticsData,
391+
openTermsModal,
385392
} = this.props;
386393

387394
// const displayRecommendedChallenges = getDisplayRecommendedChallenges(
@@ -398,6 +405,7 @@ class ChallengeDetailPageContainer extends React.Component {
398405
notFoundCountryFlagUrl,
399406
mySubmissionsSort,
400407
viewAsTable,
408+
showSecurityReminder,
401409
} = this.state;
402410

403411
const {
@@ -680,6 +688,19 @@ class ChallengeDetailPageContainer extends React.Component {
680688
}}
681689
/>
682690
)}
691+
{showSecurityReminder && (
692+
<SecurityReminder
693+
onCancel={() => this.setState({ showSecurityReminder: false })}
694+
onOk={() => {
695+
this.setState({ showSecurityReminder: false });
696+
if (_.every(terms, 'agreed')) {
697+
registerForChallenge(auth, challengeId);
698+
} else {
699+
openTermsModal();
700+
}
701+
}}
702+
/>
703+
)}
683704
{/* {
684705
!isEmpty && displayRecommendedChallenges.length ? (
685706
<RecommendedActiveChallenges

0 commit comments

Comments
 (0)