Skip to content

Commit 1f9f3be

Browse files
Merge pull request #5420 from topcoder-platform/develop
Release 2021/03/04 (v1.8.1)
2 parents e9f0be3 + a689614 commit 1f9f3be

File tree

11 files changed

+206
-10
lines changed

11 files changed

+206
-10
lines changed

.circleci/config.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ workflows:
283283
filters:
284284
branches:
285285
only:
286-
- free
286+
- gigwork-updates
287287
# This is alternate dev env for parallel testing
288288
- "build-qa":
289289
context : org-global

__tests__/shared/components/GUIKit/TextInput/__snapshots__/index.jsx.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ exports[`Default render 1`] = `
1111
onChange={[Function]}
1212
onKeyPress={[Function]}
1313
placeholder=""
14+
readOnly={false}
1415
type="text"
1516
/>
1617
</div>

src/server/services/growsurf.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ export default class GrowsurfService {
8787
email: body.email,
8888
firstName: body.firstName,
8989
lastName: body.lastName,
90+
metadata: {
91+
tcHandle: body.tcHandle,
92+
},
9093
}));
9194
if (result.error) {
9295
res.status(result.code);

src/server/services/recruitCRM.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ export default class RecruitCRMService {
195195
// referral tracking via growsurf
196196
if (referralCookie && referralCookie.gigId === id) {
197197
const gs = new GrowsurfService();
198+
const tcHandle = _.findIndex(form.custom_fields, { field_id: 2 });
198199
const growRes = await gs.addParticipant(JSON.stringify({
199200
email: form.email,
200201
referredBy: referralCookie.referralId,
@@ -203,6 +204,7 @@ export default class RecruitCRMService {
203204
lastName: form.last_name,
204205
metadata: {
205206
gigId: id,
207+
tcHandle: form.custom_fields[tcHandle].value,
206208
},
207209
}));
208210
// If everything set in Growsurf

src/shared/components/GUIKit/TextInput/index.jsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ function TextInput({
1919
size,
2020
type,
2121
onEnterKey,
22+
readonly,
2223
}) {
2324
const [val, setVal] = useState(value);
2425
const delayedOnChange = useRef(
@@ -29,6 +30,7 @@ function TextInput({
2930
return (
3031
<div className="textInputContainer" styleName={`container ${sizeStyle}`}>
3132
<input
33+
readOnly={readonly}
3234
defaultValue={value}
3335
type={type}
3436
placeholder={`${placeholder}${placeholder && required ? ' *' : ''}`}
@@ -67,6 +69,7 @@ TextInput.defaultProps = {
6769
size: 'lg',
6870
type: 'text',
6971
onEnterKey: () => {},
72+
readonly: false,
7073
};
7174

7275
TextInput.propTypes = {
@@ -79,6 +82,7 @@ TextInput.propTypes = {
7982
size: PT.oneOf(['xs', 'lg']),
8083
type: PT.string,
8184
onEnterKey: PT.func,
85+
readonly: PT.bool,
8286
};
8387

8488
export default TextInput;

src/shared/components/Gigs/GigApply/index.jsx

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,11 @@ import BackArrowGig from 'assets/images/back-arrow-gig-apply.svg';
2323

2424
export default function GigApply(props) {
2525
const {
26-
job, onFormInputChange, formData, formErrors, onApplyClick, applying, application,
26+
job, onFormInputChange, formData, formErrors, onApplyClick, applying, application, user,
2727
} = props;
28+
const retUrl = window.location.href;
2829

29-
return (
30+
return user ? (
3031
<div styleName="container">
3132
{
3233
job.error || job.enable_job_application_form !== 1 ? (
@@ -150,7 +151,6 @@ export default function GigApply(props) {
150151
</div>
151152
</div>
152153
<h4>TOPCODER INFORMATION</h4>
153-
<p>If you have a Topcoder profile, please share. <a href="https://accounts.topcoder.com/member/registration?utm_source=community&utm_campaign=recruit&utm_medium=GigWork-application-page" target="_blank" rel="noopener noreferrer">Not a Member</a>?</p>
154154
<div styleName="form-section">
155155
<div styleName="form-row">
156156
<TextInput
@@ -159,13 +159,15 @@ export default function GigApply(props) {
159159
onChange={val => onFormInputChange('handle', val)}
160160
errorMsg={formErrors.handle}
161161
value={formData.handle}
162+
readonly
162163
/>
163164
<TextInput
164165
placeholder="Topcoder Profile (topcoder.com/members/[username])"
165166
label="Topcoder Profile"
166167
onChange={val => onFormInputChange('tcProfileLink', val)}
167168
errorMsg={formErrors.tcProfileLink}
168-
value={formData.handle ? `topcoder.com/members/${formData.handle}` : null}
169+
value={formData.handle ? `https://topcoder.com/members/${formData.handle}` : null}
170+
readonly
169171
/>
170172
</div>
171173
</div>
@@ -279,13 +281,26 @@ export default function GigApply(props) {
279281
)
280282
}
281283
</div>
284+
) : (
285+
<div styleName="container">
286+
<div styleName="wrap">
287+
<div styleName="error">
288+
<h3>You must be a Topcoder member to apply!</h3>
289+
<div styleName="cta-buttons">
290+
<Link to={`${config.URL.AUTH}/member?retUrl=${encodeURIComponent(retUrl)}`} styleName="primaryBtn">Login</Link>
291+
</div>
292+
<p styleName="regTxt">Not a member? Register <a href={`${config.URL.AUTH}/member/registration?retUrl=${encodeURIComponent(retUrl)}`}>here</a>.</p>
293+
</div>
294+
</div>
295+
</div>
282296
);
283297
}
284298

285299
GigApply.defaultProps = {
286300
formErrors: {},
287301
applying: false,
288302
application: null,
303+
user: null,
289304
};
290305

291306
GigApply.propTypes = {
@@ -296,4 +311,5 @@ GigApply.propTypes = {
296311
onApplyClick: PT.func.isRequired,
297312
applying: PT.bool,
298313
application: PT.shape(),
314+
user: PT.shape(),
299315
};

src/shared/components/Gigs/GigApply/style.scss

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,25 @@
2828
padding: 0 15px;
2929
}
3030

31-
.error {
31+
.wrap .error {
3232
display: flex;
3333
flex-direction: column;
3434
align-items: center;
3535
margin-top: 27px;
3636
height: 80vh;
37+
38+
h3 {
39+
text-align: center;
40+
}
41+
42+
.cta-buttons a.primaryBtn {
43+
margin-bottom: 0 !important;
44+
}
45+
46+
.regTxt {
47+
font-size: 14px;
48+
margin: 10px 0 0;
49+
}
3750
}
3851

3952
.checkboxes-row {

src/shared/components/Gigs/GigDetails/index.jsx

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import iconLabel2 from 'assets/images/l2.png';
2626
import iconLabel3 from 'assets/images/l3.png';
2727
import SadFace from 'assets/images/sad-face-icon.svg';
2828
import ReferralModal from '../ReferralModal';
29+
import LoginModal from '../LoginModal';
2930

3031
// Cleanup HTML from style tags
3132
// so it won't affect other parts of the UI
@@ -43,15 +44,18 @@ export default function GigDetails(props) {
4344
job, application, profile, onSendClick, isReferrSucess, formData, formErrors, onFormInputChange, isReferrError, getReferralId, referralId, onReferralDone,
4445
} = props;
4546
let shareUrl;
47+
let retUrl;
4648
if (isomorphy.isClientSide()) {
4749
shareUrl = encodeURIComponent(window.location.href);
50+
retUrl = `${window.location.origin}${window.location.pathname}/apply${window.location.search}`;
4851
}
4952
let skills = getCustomField(job.custom_fields, 'Technologies Required');
5053
if (skills !== 'n/a') skills = skills.split(',').join(', ');
5154
const hPerW = getCustomField(job.custom_fields, 'Hours per week');
5255
const compens = job.min_annual_salary === job.max_annual_salary ? job.max_annual_salary : `${job.min_annual_salary} - ${job.max_annual_salary} (USD)`;
5356

5457
const [isModalOpen, setModalOpen] = useState(false);
58+
const [isLoginModalOpen, setLoginModalOpen] = useState(false);
5559
let inputRef;
5660

5761
useEffect(() => {
@@ -131,7 +135,17 @@ export default function GigDetails(props) {
131135
<div styleName="cta-buttons">
132136
{
133137
!application || !application.success ? (
134-
<Link styleName="primaryBtn" to={`${config.GIGS_PAGES_PATH}/${job.slug}/apply`}>APPLY TO THIS JOB</Link>
138+
<Link
139+
styleName="primaryBtn"
140+
to={`${config.GIGS_PAGES_PATH}/${job.slug}/apply`}
141+
onClick={(e) => {
142+
if (isEmpty(profile)) {
143+
e.preventDefault();
144+
setLoginModalOpen(true);
145+
}
146+
}}
147+
>APPLY TO THIS JOB
148+
</Link>
135149
) : null
136150
}
137151
<Link to={config.GIGS_PAGES_PATH}>VIEW OTHER JOBS</Link>
@@ -179,15 +193,15 @@ export default function GigDetails(props) {
179193
<ul>
180194
<li>
181195
<img src={iconLabel1} alt="label 1" />
182-
<div><strong>Make sure your <a target="_blank" rel="noreferrer" href="https://www.topcoder.com/settings/profile">Topcoder profile</a> says it all.</strong> Fill out your profile to the best of your ability. Your skills, your location, your devices, etc, all help you improve your chances of being selected for a gig.</div>
196+
<div><strong>Make sure your <a target="_blank" rel="noreferrer" href="/settings/profile">Topcoder profile</a> says it all.</strong> Fill out your profile to the best of your ability. Your skills, your location, your devices, etc, all help you improve your chances of being selected for a gig.</div>
183197
</li>
184198
<li>
185199
<img src={iconLabel2} alt="label 2" />
186-
<div><strong>Let us know you’re here!</strong> Check in on our <a target="_blank" rel="noreferrer" href="https://apps.topcoder.com/forums/?module=ThreadList&forumID=703475">Gig Work forum</a> and tell us you’re looking for a gig. It’s great visibility for the Gig team.</div>
200+
<div><strong>Let us know you’re here!</strong> Check in on our <a target="_blank" rel="noreferrer" href={`${config.URL.FORUMS_VANILLA}/categories/gig-work-discusssions`}>Gig Work forum</a> and tell us you’re looking for a gig. It’s great visibility for the Gig team.</div>
187201
</li>
188202
<li>
189203
<img src={iconLabel3} alt="label 3" />
190-
<div><strong>Check out our <a target="_blank" rel="noreferrer" href="https://www.topcoder.com/challenges">Topcoder challenges</a> and participate.</strong> Challenges showing your technology skills make you a “qualified” candidate so we know you’re good. The proof is in the pudding!</div>
204+
<div><strong>Check out our <a target="_blank" rel="noreferrer" href="/challenges">Topcoder challenges</a> and participate.</strong> Challenges showing your technology skills make you a “qualified” candidate so we know you’re good. The proof is in the pudding!</div>
191205
</li>
192206
</ul>
193207
</div>
@@ -211,6 +225,9 @@ export default function GigDetails(props) {
211225
)
212226
}
213227
</div>
228+
{
229+
isLoginModalOpen && <LoginModal retUrl={retUrl} onCancel={() => setLoginModalOpen(false)} />
230+
}
214231
</div>
215232
</div>
216233
</div>
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* The modal used for login enforcing
3+
*/
4+
5+
/* global window */
6+
7+
import PT from 'prop-types';
8+
import React from 'react';
9+
import { Modal, PrimaryButton } from 'topcoder-react-ui-kit';
10+
import { config } from 'topcoder-react-utils';
11+
import tc from 'components/buttons/themed/tc.scss';
12+
import modalStyle from './modal.scss';
13+
14+
/** Themes for buttons
15+
* those overwrite PrimaryButton style to match achieve various styles.
16+
* Should implement pattern of classes.
17+
*/
18+
const buttonThemes = {
19+
tc,
20+
};
21+
22+
function LoginModal({ retUrl, onCancel }) {
23+
return (
24+
<Modal
25+
theme={modalStyle}
26+
onCancel={onCancel}
27+
>
28+
<div className={modalStyle.loginRequired}>
29+
<h3 className={modalStyle.title}>WARNING</h3>
30+
<p className={modalStyle.loginMsg}>You must be a Topcoder member to apply!</p>
31+
<div className={modalStyle.ctaButtons}>
32+
<PrimaryButton
33+
onClick={() => {
34+
window.location = `${config.URL.AUTH}/member?retUrl=${encodeURIComponent(retUrl)}`;
35+
}}
36+
theme={{
37+
button: buttonThemes.tc['primary-green-md'],
38+
}}
39+
>
40+
LOGIN
41+
</PrimaryButton>
42+
</div>
43+
<p className={modalStyle.regTxt}>Not a member? Register <a href={`${config.URL.AUTH}/member/registration?retUrl=${encodeURIComponent(retUrl)}`}>here</a>.</p>
44+
</div>
45+
</Modal>
46+
);
47+
}
48+
49+
LoginModal.propTypes = {
50+
retUrl: PT.string.isRequired,
51+
onCancel: PT.func.isRequired,
52+
};
53+
54+
export default LoginModal;
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
@import "~styles/mixins";
2+
@import "~components/Contentful/default";
3+
4+
.container {
5+
padding: 0;
6+
width: auto;
7+
max-width: 95vw;
8+
height: auto;
9+
max-height: 95vh;
10+
border-radius: 10px;
11+
display: flex;
12+
flex-direction: column;
13+
justify-content: center;
14+
15+
@include gui-kit-headers;
16+
@include gui-kit-content;
17+
18+
.title {
19+
color: #1e94a3;
20+
font-family: BarlowCondensed, sans-serif;
21+
font-size: 34px;
22+
line-height: 38px;
23+
font-weight: 500;
24+
margin: 0;
25+
margin-bottom: 20px;
26+
}
27+
28+
.loginMsg {
29+
color: #ef476f;
30+
font-size: 24px;
31+
line-height: 36px;
32+
margin-bottom: 40px;
33+
}
34+
35+
.ctaButtons {
36+
display: flex;
37+
align-content: center;
38+
justify-content: center;
39+
40+
& > button:first-child {
41+
margin-right: 10px !important;
42+
}
43+
44+
& > a:first-child {
45+
margin-right: 10px !important;
46+
}
47+
}
48+
49+
.referrals {
50+
display: flex;
51+
overflow: auto;
52+
53+
.sucessMsg {
54+
font-size: 24px;
55+
line-height: 36px;
56+
margin-bottom: 40px;
57+
}
58+
59+
.rightAlign {
60+
justify-content: flex-end;
61+
}
62+
}
63+
64+
.loginRequired,
65+
.referrSucess {
66+
display: flex;
67+
flex-direction: column;
68+
padding: 100px 80px;
69+
text-align: center;
70+
71+
@include xs-to-sm {
72+
padding: 50px 40px;
73+
}
74+
75+
.regTxt {
76+
font-size: 14px;
77+
margin: 10px 0 0;
78+
}
79+
}
80+
}
81+
82+
.overlay {
83+
background-color: #2a2a2a;
84+
opacity: 0.95;
85+
}

src/shared/containers/Gigs/RecruitCRMJobDetails.jsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ ${config.URL.BASE}${config.GIGS_PAGES_PATH}/${props.id}`,
155155
email: profile.email,
156156
firstName: profile.firstName,
157157
lastName: profile.lastName,
158+
tcHandle: profile.handle,
158159
}),
159160
headers: {
160161
'Content-Type': 'application/json',

0 commit comments

Comments
 (0)