Skip to content

Release 2021/03/04 (v1.8.1) #5420

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ workflows:
filters:
branches:
only:
- free
- gigwork-updates
# This is alternate dev env for parallel testing
- "build-qa":
context : org-global
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ exports[`Default render 1`] = `
onChange={[Function]}
onKeyPress={[Function]}
placeholder=""
readOnly={false}
type="text"
/>
</div>
Expand Down
3 changes: 3 additions & 0 deletions src/server/services/growsurf.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ export default class GrowsurfService {
email: body.email,
firstName: body.firstName,
lastName: body.lastName,
metadata: {
tcHandle: body.tcHandle,
},
}));
if (result.error) {
res.status(result.code);
Expand Down
2 changes: 2 additions & 0 deletions src/server/services/recruitCRM.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ export default class RecruitCRMService {
// referral tracking via growsurf
if (referralCookie && referralCookie.gigId === id) {
const gs = new GrowsurfService();
const tcHandle = _.findIndex(form.custom_fields, { field_id: 2 });
const growRes = await gs.addParticipant(JSON.stringify({
email: form.email,
referredBy: referralCookie.referralId,
Expand All @@ -203,6 +204,7 @@ export default class RecruitCRMService {
lastName: form.last_name,
metadata: {
gigId: id,
tcHandle: form.custom_fields[tcHandle].value,
},
}));
// If everything set in Growsurf
Expand Down
4 changes: 4 additions & 0 deletions src/shared/components/GUIKit/TextInput/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ function TextInput({
size,
type,
onEnterKey,
readonly,
}) {
const [val, setVal] = useState(value);
const delayedOnChange = useRef(
Expand All @@ -29,6 +30,7 @@ function TextInput({
return (
<div className="textInputContainer" styleName={`container ${sizeStyle}`}>
<input
readOnly={readonly}
defaultValue={value}
type={type}
placeholder={`${placeholder}${placeholder && required ? ' *' : ''}`}
Expand Down Expand Up @@ -67,6 +69,7 @@ TextInput.defaultProps = {
size: 'lg',
type: 'text',
onEnterKey: () => {},
readonly: false,
};

TextInput.propTypes = {
Expand All @@ -79,6 +82,7 @@ TextInput.propTypes = {
size: PT.oneOf(['xs', 'lg']),
type: PT.string,
onEnterKey: PT.func,
readonly: PT.bool,
};

export default TextInput;
24 changes: 20 additions & 4 deletions src/shared/components/Gigs/GigApply/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ import BackArrowGig from 'assets/images/back-arrow-gig-apply.svg';

export default function GigApply(props) {
const {
job, onFormInputChange, formData, formErrors, onApplyClick, applying, application,
job, onFormInputChange, formData, formErrors, onApplyClick, applying, application, user,
} = props;
const retUrl = window.location.href;

return (
return user ? (
<div styleName="container">
{
job.error || job.enable_job_application_form !== 1 ? (
Expand Down Expand Up @@ -150,7 +151,6 @@ export default function GigApply(props) {
</div>
</div>
<h4>TOPCODER INFORMATION</h4>
<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>
<div styleName="form-section">
<div styleName="form-row">
<TextInput
Expand All @@ -159,13 +159,15 @@ export default function GigApply(props) {
onChange={val => onFormInputChange('handle', val)}
errorMsg={formErrors.handle}
value={formData.handle}
readonly
/>
<TextInput
placeholder="Topcoder Profile (topcoder.com/members/[username])"
label="Topcoder Profile"
onChange={val => onFormInputChange('tcProfileLink', val)}
errorMsg={formErrors.tcProfileLink}
value={formData.handle ? `topcoder.com/members/${formData.handle}` : null}
value={formData.handle ? `https://topcoder.com/members/${formData.handle}` : null}
readonly
/>
</div>
</div>
Expand Down Expand Up @@ -279,13 +281,26 @@ export default function GigApply(props) {
)
}
</div>
) : (
<div styleName="container">
<div styleName="wrap">
<div styleName="error">
<h3>You must be a Topcoder member to apply!</h3>
<div styleName="cta-buttons">
<Link to={`${config.URL.AUTH}/member?retUrl=${encodeURIComponent(retUrl)}`} styleName="primaryBtn">Login</Link>
</div>
<p styleName="regTxt">Not a member? Register <a href={`${config.URL.AUTH}/member/registration?retUrl=${encodeURIComponent(retUrl)}`}>here</a>.</p>
</div>
</div>
</div>
);
}

GigApply.defaultProps = {
formErrors: {},
applying: false,
application: null,
user: null,
};

GigApply.propTypes = {
Expand All @@ -296,4 +311,5 @@ GigApply.propTypes = {
onApplyClick: PT.func.isRequired,
applying: PT.bool,
application: PT.shape(),
user: PT.shape(),
};
15 changes: 14 additions & 1 deletion src/shared/components/Gigs/GigApply/style.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,25 @@
padding: 0 15px;
}

.error {
.wrap .error {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 27px;
height: 80vh;

h3 {
text-align: center;
}

.cta-buttons a.primaryBtn {
margin-bottom: 0 !important;
}

.regTxt {
font-size: 14px;
margin: 10px 0 0;
}
}

.checkboxes-row {
Expand Down
25 changes: 21 additions & 4 deletions src/shared/components/Gigs/GigDetails/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import iconLabel2 from 'assets/images/l2.png';
import iconLabel3 from 'assets/images/l3.png';
import SadFace from 'assets/images/sad-face-icon.svg';
import ReferralModal from '../ReferralModal';
import LoginModal from '../LoginModal';

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

const [isModalOpen, setModalOpen] = useState(false);
const [isLoginModalOpen, setLoginModalOpen] = useState(false);
let inputRef;

useEffect(() => {
Expand Down Expand Up @@ -131,7 +135,17 @@ export default function GigDetails(props) {
<div styleName="cta-buttons">
{
!application || !application.success ? (
<Link styleName="primaryBtn" to={`${config.GIGS_PAGES_PATH}/${job.slug}/apply`}>APPLY TO THIS JOB</Link>
<Link
styleName="primaryBtn"
to={`${config.GIGS_PAGES_PATH}/${job.slug}/apply`}
onClick={(e) => {
if (isEmpty(profile)) {
e.preventDefault();
setLoginModalOpen(true);
}
}}
>APPLY TO THIS JOB
</Link>
) : null
}
<Link to={config.GIGS_PAGES_PATH}>VIEW OTHER JOBS</Link>
Expand Down Expand Up @@ -179,15 +193,15 @@ export default function GigDetails(props) {
<ul>
<li>
<img src={iconLabel1} alt="label 1" />
<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>
<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>
</li>
<li>
<img src={iconLabel2} alt="label 2" />
<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>
<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>
</li>
<li>
<img src={iconLabel3} alt="label 3" />
<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>
<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>
</li>
</ul>
</div>
Expand All @@ -211,6 +225,9 @@ export default function GigDetails(props) {
)
}
</div>
{
isLoginModalOpen && <LoginModal retUrl={retUrl} onCancel={() => setLoginModalOpen(false)} />
}
</div>
</div>
</div>
Expand Down
54 changes: 54 additions & 0 deletions src/shared/components/Gigs/LoginModal/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/**
* The modal used for login enforcing
*/

/* global window */

import PT from 'prop-types';
import React from 'react';
import { Modal, PrimaryButton } from 'topcoder-react-ui-kit';
import { config } from 'topcoder-react-utils';
import tc from 'components/buttons/themed/tc.scss';
import modalStyle from './modal.scss';

/** Themes for buttons
* those overwrite PrimaryButton style to match achieve various styles.
* Should implement pattern of classes.
*/
const buttonThemes = {
tc,
};

function LoginModal({ retUrl, onCancel }) {
return (
<Modal
theme={modalStyle}
onCancel={onCancel}
>
<div className={modalStyle.loginRequired}>
<h3 className={modalStyle.title}>WARNING</h3>
<p className={modalStyle.loginMsg}>You must be a Topcoder member to apply!</p>
<div className={modalStyle.ctaButtons}>
<PrimaryButton
onClick={() => {
window.location = `${config.URL.AUTH}/member?retUrl=${encodeURIComponent(retUrl)}`;
}}
theme={{
button: buttonThemes.tc['primary-green-md'],
}}
>
LOGIN
</PrimaryButton>
</div>
<p className={modalStyle.regTxt}>Not a member? Register <a href={`${config.URL.AUTH}/member/registration?retUrl=${encodeURIComponent(retUrl)}`}>here</a>.</p>
</div>
</Modal>
);
}

LoginModal.propTypes = {
retUrl: PT.string.isRequired,
onCancel: PT.func.isRequired,
};

export default LoginModal;
85 changes: 85 additions & 0 deletions src/shared/components/Gigs/LoginModal/modal.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
@import "~styles/mixins";
@import "~components/Contentful/default";

.container {
padding: 0;
width: auto;
max-width: 95vw;
height: auto;
max-height: 95vh;
border-radius: 10px;
display: flex;
flex-direction: column;
justify-content: center;

@include gui-kit-headers;
@include gui-kit-content;

.title {
color: #1e94a3;
font-family: BarlowCondensed, sans-serif;
font-size: 34px;
line-height: 38px;
font-weight: 500;
margin: 0;
margin-bottom: 20px;
}

.loginMsg {
color: #ef476f;
font-size: 24px;
line-height: 36px;
margin-bottom: 40px;
}

.ctaButtons {
display: flex;
align-content: center;
justify-content: center;

& > button:first-child {
margin-right: 10px !important;
}

& > a:first-child {
margin-right: 10px !important;
}
}

.referrals {
display: flex;
overflow: auto;

.sucessMsg {
font-size: 24px;
line-height: 36px;
margin-bottom: 40px;
}

.rightAlign {
justify-content: flex-end;
}
}

.loginRequired,
.referrSucess {
display: flex;
flex-direction: column;
padding: 100px 80px;
text-align: center;

@include xs-to-sm {
padding: 50px 40px;
}

.regTxt {
font-size: 14px;
margin: 10px 0 0;
}
}
}

.overlay {
background-color: #2a2a2a;
opacity: 0.95;
}
1 change: 1 addition & 0 deletions src/shared/containers/Gigs/RecruitCRMJobDetails.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ ${config.URL.BASE}${config.GIGS_PAGES_PATH}/${props.id}`,
email: profile.email,
firstName: profile.firstName,
lastName: profile.lastName,
tcHandle: profile.handle,
}),
headers: {
'Content-Type': 'application/json',
Expand Down