Skip to content
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { FC } from 'react'

import { UserProfile } from '~/libs/core'
import { BaseModal } from '~/libs/ui'

interface HiringFormModalProps {
onClose: () => void
authProfile: UserProfile | undefined
profile: UserProfile
searchedSkills: string[]
}

function populateIframeForm(profile: UserProfile, authProfile: any | undefined, searchedSkills: string[]): string {
const formUrl = `https://go.topcoder.com/talent-search-intake?handle=${profile.handle}`

if (authProfile) {
return `${formUrl}
&first_name=${authProfile.firstName}
&last_name=${authProfile.lastName}
&email=${authProfile.email}
&searched_skills=${searchedSkills.join(',')}`
}

return formUrl
}

const HiringFormModal: FC<HiringFormModalProps> = (props: HiringFormModalProps) => (
<BaseModal
onClose={props.onClose}
open
title={(
<p className='body-large-bold'>
Interested in working with one of our experts?
<br />
Start with this form.
</p>
)}
size='lg'
>
<iframe
src={populateIframeForm(props.profile, props.authProfile, props.searchedSkills)}
title='Start Hiring Form'
id='start-hiring-form'
/>
</BaseModal>
)

export default HiringFormModal
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as HiringFormModal } from './HiringFormModal'
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
padding-bottom: 150px;
flex-direction: column;
}

.photoWrap {
position: relative;
margin-right: 60px;
Expand Down Expand Up @@ -50,44 +51,67 @@
}
}

.profileInfo {
.profileHeaderWrap {
display: flex;
flex-direction: column;
flex: 1;
justify-content: space-between;
align-items: flex-start;
margin-top: $sp-8;
flex: 1;
width: 100%;

.nameWrap {
@include ltelg {
flex-direction: column;
align-items: flex-start;
}

.profileInfo {
display: flex;
align-items: center;
margin-bottom: $sp-2;
flex-direction: column;
flex: 1;

.nameWrap {
display: flex;
align-items: center;
margin-bottom: $sp-2;

p {
font-size: 40px;
font-weight: $font-weight-bold;
font-family: $font-barlow;

@include ltelg {
font-size: 32px;
line-height: 33px;
}
}

p {
font-size: 40px;
font-weight: $font-weight-bold;
font-family: $font-barlow;
button {
color: $tc-white;
}
}

.memberSince {
margin-top: $sp-2;
font-size: 20px;

@include ltelg {
font-size: 32px;
line-height: 33px;
font-size: 16px;
margin-top: 0;
}
}

button {
color: $tc-white;
span {
font-weight: $font-weight-bold;
}
}
}

.memberSince {
margin-top: $sp-2;
font-size: 20px;
.hiringClickWrap {
background-color: $tc-white;
padding: $sp-1;
border-radius: 200px;

@include ltelg {
font-size: 16px;
margin-top: 0;
}

span {
font-weight: $font-weight-bold;
margin-top: $sp-4;
}
}
}
Expand All @@ -114,3 +138,7 @@
}
}
}

:global(#start-hiring-form) {
min-height: 380px;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* eslint-disable complexity */
import { Dispatch, FC, SetStateAction, useEffect, useMemo, useState } from 'react'
import { useSearchParams } from 'react-router-dom'
import { Location, useLocation, useSearchParams } from 'react-router-dom'
import { KeyedMutator } from 'swr'
import moment from 'moment'

Expand All @@ -12,13 +12,16 @@ import {
UserTraits,
} from '~/libs/core'
import { ProfilePicture, useCheckIsMobile } from '~/libs/shared'
import { Button } from '~/libs/ui'

import { AddButton, EditMemberPropertyBtn } from '../../components'
import { EDIT_MODE_QUERY_PARAM, profileEditModes } from '../../config'
import { MemberProfileContextValue, useMemberProfileContext } from '../MemberProfile.context'

import { OpenForGigs } from './OpenForGigs'
import { ModifyMemberNameModal } from './ModifyMemberNameModal'
import { ModifyMemberPhotoModal } from './ModifyMemberPhotoModal'
import { HiringFormModal } from './HiringFormModal'
import styles from './ProfileHeader.module.scss'

interface ProfileHeaderProps {
Expand Down Expand Up @@ -57,6 +60,18 @@ const ProfileHeader: FC<ProfileHeaderProps> = (props: ProfileHeaderProps) => {
(trait: UserTrait) => trait.namesAndHandleAppearance,
), [memberPersonalizationTraits])

const [isHiringFormOpen, setIsHiringFormOpen]: [boolean, Dispatch<SetStateAction<boolean>>]
= useState<boolean>(false)

const { isTalentSearch }: MemberProfileContextValue = useMemberProfileContext()

const { state }: Location = useLocation()

const searchedSkills: string[] = useMemo(
() => (state.queriedSkills || []).map((s: any) => s.name),
[state.queriedSkills],
)

useEffect(() => {
if (props.authProfile && editMode === profileEditModes.names) {
setIsNameEditMode(true)
Expand All @@ -68,11 +83,6 @@ const ProfileHeader: FC<ProfileHeaderProps> = (props: ProfileHeaderProps) => {
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [props.authProfile])

// Enable this with talent search app
// function handleHireMeClick(): void {
// console.log('Hire Me button clicked')
// }

function handleModifyNameClick(): void {
setIsNameEditMode(true)
}
Expand Down Expand Up @@ -109,16 +119,6 @@ const ProfileHeader: FC<ProfileHeaderProps> = (props: ProfileHeaderProps) => {
<div className={styles.profileActions}>
<span>My status:</span>
<OpenForGigs canEdit={canEdit} authProfile={props.authProfile} profile={props.profile} />
{/* Enable this with talent search app */}
{/* {
!canEdit && (
<Button
label={`Hire ${props.profile.firstName}`}
primary
onClick={handleHireMeClick}
/>
)
} */}
</div>
)
}
Expand All @@ -144,50 +144,68 @@ const ProfileHeader: FC<ProfileHeaderProps> = (props: ProfileHeaderProps) => {
)
}

function handleStartHiringToggle(): void {
setIsHiringFormOpen(!isHiringFormOpen)
}

return (
<div className={styles.container}>
{
!isMobile ? renderMemberPhotoWrap() : undefined
}

{!traitsLoading && (
<div className={styles.profileInfo}>
<div className={styles.nameWrap}>
<p>
<div className={styles.profileHeaderWrap}>
<div className={styles.profileInfo}>
<div className={styles.nameWrap}>
<p>
{
namesAndHandleAppearanceData?.namesAndHandleAppearance === 'handleOnly'
? props.profile.handle
: `${props.profile.firstName} ${props.profile.lastName}`
}
</p>
{
namesAndHandleAppearanceData?.namesAndHandleAppearance === 'handleOnly'
? props.profile.handle
: `${props.profile.firstName} ${props.profile.lastName}`
canEdit && (
<EditMemberPropertyBtn
onClick={handleModifyNameClick}
/>
)
}
</p>
{
canEdit && (
<EditMemberPropertyBtn
onClick={handleModifyNameClick}
/>
)
}
</div>
</div>

<p className={styles.memberSince}>
{
// If the user hasn't set a name and handle appareance, display both name and handle
(namesAndHandleAppearanceData?.namesAndHandleAppearance === 'namesAndHandle'
|| !namesAndHandleAppearanceData) ? (
<p className={styles.memberSince}>
{
// If the user hasn't set a name and handle appareance, display both name and handle
(namesAndHandleAppearanceData?.namesAndHandleAppearance === 'namesAndHandle'
|| !namesAndHandleAppearanceData) ? (
// eslint-disable-next-line react/jsx-indent
<>
<span>{props.profile.handle}</span>
{' '}
|
{' '}
</>
) : undefined
}
Member Since
{' '}
{moment(props.profile.createdAt)
.format('MMM YYYY')}
</p>
<>
<span>{props.profile.handle}</span>
{' '}
|
{' '}
</>
) : undefined
}
Member Since
{' '}
{moment(props.profile.createdAt)
.format('MMM YYYY')}
</p>
</div>
{
!canEdit && isTalentSearch ? (
<div className={styles.hiringClickWrap}>
<Button
label='Start Hiring'
primary
size='lg'
onClick={handleStartHiringToggle}
/>
</div>
) : undefined
}
</div>
)}

Expand All @@ -201,6 +219,17 @@ const ProfileHeader: FC<ProfileHeaderProps> = (props: ProfileHeaderProps) => {
isMobile ? renderMemberPhotoWrap() : undefined
}

{
isHiringFormOpen && (
<HiringFormModal
onClose={handleStartHiringToggle}
authProfile={props.authProfile}
profile={props.profile}
searchedSkills={searchedSkills}
/>
)
}

{
isNameEditMode && (
<ModifyMemberNameModal
Expand Down