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
16 changes: 2 additions & 14 deletions src/apps/onboarding/src/config/index.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,4 @@
export const ACTIONS: {
MEMBER: {
GET_MEMBER: string;
UPDATE_MEMBER_PHOTO_URL: string;
SET_WORKS: string;
SET_EDUCATIONS: string;
SET_PERSONALIZATIONS: string;
SET_ADDRESS: string;
SET_CONNECT_INFO: string;
SET_DESCRIPTION: string;
SET_LOADING_MEMBER_TRAITS: string;
SET_LOADING_MEMBER_INFO: string;
};
} = {
export const ACTIONS = {
MEMBER: {
GET_MEMBER: 'GET_MEMBER',
SET_ADDRESS: 'SET_ADDRESS',
Expand All @@ -20,6 +7,7 @@ export const ACTIONS: {
SET_EDUCATIONS: 'SET_EDUCATIONS',
SET_LOADING_MEMBER_INFO: 'SET_LOADING_MEMBER_INFO',
SET_LOADING_MEMBER_TRAITS: 'SET_LOADING_MEMBER_TRAITS',
SET_OPEN_FOR_WORK: 'SET_OPEN_FOR_WORK',
SET_PERSONALIZATIONS: 'SET_PERSONALIZATIONS',
SET_WORKS: 'SET_WORKS',
UPDATE_MEMBER_PHOTO_URL: 'UPDATE_MEMBER_PHOTO_URL',
Expand Down
1 change: 1 addition & 0 deletions src/apps/onboarding/src/models/MemberInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export default interface MemberInfo {
maxRating: MemberMaxRating
skills: Array<UserSkill>
stats: Array<MemberStats>
availableForGigs: boolean
addresses?: MemberAddress[]
country: string
photoURL: string
Expand Down
2 changes: 0 additions & 2 deletions src/apps/onboarding/src/models/PersonalizationInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@ export default interface PersonalizationInfo {
referAs?: string
profileSelfTitle?: string
shortBio?: string
availableForGigs?: boolean
}

export const emptyPersonalizationInfo: () => PersonalizationInfo = () => ({
availableForGigs: true,
profileSelfTitle: '',
referAs: '',
shortBio: '',
Expand Down
99 changes: 27 additions & 72 deletions src/apps/onboarding/src/pages/open-to-work/index.tsx
Original file line number Diff line number Diff line change
@@ -1,75 +1,51 @@
import { useNavigate } from 'react-router-dom'
import { FC, MutableRefObject, useEffect, useMemo, useRef } from 'react'
import { FC, MutableRefObject, useEffect, useRef, useState } from 'react'
import { connect } from 'react-redux'
import { pick } from 'lodash'
import classNames from 'classnames'

import { Button, IconOutline, PageDivider } from '~/libs/ui'
import { FormInputCheckbox } from '~/apps/self-service/src/components/form-elements'

import { createMemberPersonalizations, updateMemberPersonalizations } from '../../redux/actions/member'
import { ProgressBar } from '../../components/progress-bar'
import { useAutoSavePersonalization, useAutoSavePersonalizationType } from '../../hooks/useAutoSavePersonalization'
import PersonalizationInfo, { emptyPersonalizationInfo } from '../../models/PersonalizationInfo'
import { updateMemberOpenForWork } from '../../redux/actions/member'

import styles from './styles.module.scss'

const FormInputCheckboxMiddleware: any = FormInputCheckbox as any

const blankPersonalizationInfo: PersonalizationInfo = emptyPersonalizationInfo()

interface PageOpenToWorkContentReduxProps {
reduxPersonalizations: PersonalizationInfo[] | undefined
loadingMemberTraits: boolean
}

interface PageOpenToWorkContentProps extends PageOpenToWorkContentReduxProps {
updateMemberPersonalizations: (infos: PersonalizationInfo[]) => void
createMemberPersonalizations: (infos: PersonalizationInfo[]) => void
interface PageOpenToWorkContentProps {
availableForGigs: boolean
updateMemberOpenForWork: (isOpenForWork: boolean) => void
}

export const PageOpenToWorkContent: FC<PageOpenToWorkContentProps> = props => {
const navigate: any = useNavigate()

const [loading, setLoading] = useState<boolean>(false)

const shouldSavingData: MutableRefObject<boolean> = useRef<boolean>(false)
const shouldNavigateTo: MutableRefObject<string> = useRef<string>('')

const {
loading,
personalizationInfo,
setPersonalizationInfo,
}: useAutoSavePersonalizationType = useAutoSavePersonalization(
props.reduxPersonalizations,
['availableForGigs'],
props.updateMemberPersonalizations,
props.createMemberPersonalizations,
shouldSavingData,
)

const availableForGigsValue: boolean | undefined = useMemo(() => {
if (!personalizationInfo || personalizationInfo.availableForGigs === undefined) {
return blankPersonalizationInfo.availableForGigs
}

return personalizationInfo.availableForGigs
}, [personalizationInfo])

useEffect(() => {
if (!loading && !shouldSavingData.current && !!shouldNavigateTo.current) {
navigate(shouldNavigateTo.current)
}
/* eslint-disable react-hooks/exhaustive-deps */
}, [loading])

function checkToNavigateNextPage(pageUrl: string): void {
if (!personalizationInfo || personalizationInfo.availableForGigs === undefined) {
shouldNavigateTo.current = pageUrl
setPersonalizationInfo({
...(personalizationInfo || {}),
availableForGigs: blankPersonalizationInfo.availableForGigs,
})
} else {
navigate(pageUrl)
}
function goToPreviousStep(): void {
navigate('../skills')
}

function goToNextStep(): void {
navigate('../works')
}

async function handleSaveAvailableForGigs(e: any): Promise<void> {
setLoading(true)
await props.updateMemberOpenForWork(e.target.checked)
setLoading(false)
}

return (
Expand All @@ -90,15 +66,10 @@ export const PageOpenToWorkContent: FC<PageOpenToWorkContentProps> = props => {
<div className='mt-26'>
<FormInputCheckboxMiddleware
label='Yes, I’m open to work'
checked={availableForGigsValue}
checked={props.availableForGigs}
inline
onChange={function onChange(e: any) {
setPersonalizationInfo({
...(personalizationInfo || {}),
availableForGigs: e.target.checked,
})
}}
disabled={props.loadingMemberTraits || loading}
onChange={handleSaveAvailableForGigs}
disabled={loading}
/>
</div>
</div>
Expand All @@ -117,18 +88,14 @@ export const PageOpenToWorkContent: FC<PageOpenToWorkContentProps> = props => {
iconToLeft
disabled={loading}
icon={IconOutline.ChevronLeftIcon}
onClick={function previousPage() {
checkToNavigateNextPage('../skills')
}}
onClick={goToPreviousStep}
/>
<Button
size='lg'
primary
iconToLeft
disabled={loading}
onClick={function nextPage() {
checkToNavigateNextPage('../works')
}}
onClick={goToNextStep}
>
next
</Button>
Expand All @@ -137,22 +104,10 @@ export const PageOpenToWorkContent: FC<PageOpenToWorkContentProps> = props => {
)
}

const mapStateToProps: (state: any) => PageOpenToWorkContentReduxProps
= (state: any): PageOpenToWorkContentReduxProps => {
const {
loadingMemberTraits,
personalizations,
}: any = state.member

return {
loadingMemberTraits,
reduxPersonalizations: personalizations,
}
}
const mapStateToProps: any = (state: any) => pick(state.member, 'availableForGigs')

const mapDispatchToProps: any = {
createMemberPersonalizations,
updateMemberPersonalizations,
updateMemberOpenForWork,
}

export const PageOpenToWork: any = connect(mapStateToProps, mapDispatchToProps)(PageOpenToWorkContent)
Expand Down
20 changes: 19 additions & 1 deletion src/apps/onboarding/src/redux/actions/member.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import _ from 'lodash'

import { TokenModel, UserTraitCategoryNames, UserTraitIds } from '~/libs/core'
import { TokenModel, updateMemberProfileAsync, UserTraitCategoryNames, UserTraitIds } from '~/libs/core'
import { getAsync as getAsyncToken } from '~/libs/core/lib/auth/token-functions/token.functions'
import {
createMemberTraits,
Expand Down Expand Up @@ -396,6 +396,11 @@ export const setMemberPhotoUrl: any = (photoUrl: string) => ({
type: ACTIONS.MEMBER.UPDATE_MEMBER_PHOTO_URL,
})

export const setMemberOpenForWork: any = (isOpenForWork: boolean) => ({
payload: isOpenForWork,
type: ACTIONS.MEMBER.SET_OPEN_FOR_WORK,
})

export const updateMemberHomeAddresss: any = (addresses: MemberAddress[]) => async (dispatch: any) => {
try {
const tokenInfo: TokenModel = await getAsyncToken()
Expand Down Expand Up @@ -436,3 +441,16 @@ export const updateMemberPhotoUrl: any = (photoURL: string) => async (dispatch:
} catch (error) {
}
}

export const updateMemberOpenForWork: any = (isOpenForWork: boolean) => async (dispatch: any) => {
try {
const tokenInfo: TokenModel = await getAsyncToken()

await updateMemberProfileAsync(
tokenInfo.handle || '',
{ availableForGigs: isOpenForWork },
)
dispatch(setMemberOpenForWork(isOpenForWork))
} catch (error) {
}
}
7 changes: 7 additions & 0 deletions src/apps/onboarding/src/redux/reducers/member.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable complexity */
import _ from 'lodash'

import { notifyUniNavi } from '~/apps/profiles/src/lib'
Expand All @@ -19,6 +20,7 @@ const initialState: {
connectInfo?: ConnectInfo
loadingMemberTraits?: boolean
loadingMemberInfo?: boolean
availableForGigs?: boolean
} = {
}

Expand All @@ -35,6 +37,11 @@ const memberReducer: any = (
...state,
memberInfo: action.payload,
}
case ACTIONS.MEMBER.SET_OPEN_FOR_WORK:
return {
...state,
availableForGigs: action.payload,
}
case ACTIONS.MEMBER.SET_WORKS:
return {
...state,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { Dispatch, FC, SetStateAction, useEffect, useMemo, useState } from 'react'
import { Dispatch, FC, SetStateAction, useEffect, useState } from 'react'
import { useSearchParams } from 'react-router-dom'
import { KeyedMutator } from 'swr'
import classNames from 'classnames'

import { useMemberTraits, UserProfile, UserTrait, UserTraitIds, UserTraits } from '~/libs/core'
import { UserProfile } from '~/libs/core'

import { EditMemberPropertyBtn } from '../../../components'
import { OpenForGigsModifyModal } from '../OpenForGigsModifyModal'
Expand All @@ -26,24 +25,15 @@ const OpenForGigs: FC<OpenForGigsProps> = (props: OpenForGigsProps) => {
const [isEditMode, setIsEditMode]: [boolean, Dispatch<SetStateAction<boolean>>]
= useState<boolean>(false)

const openForWork = props.profile.availableForGigs

useEffect(() => {
if (props.authProfile && editMode === profileEditModes.openForWork) {
setIsEditMode(true)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [props.authProfile])

const { data: memberPersonalizationTraits, mutate: mutateTraits }: {
data: UserTraits[] | undefined,
mutate: KeyedMutator<any>,
}
= useMemberTraits(props.profile.handle, { traitIds: UserTraitIds.personalization })

const openForWork: UserTrait | undefined
= useMemo(() => memberPersonalizationTraits?.[0]?.traits?.data?.find(
(trait: UserTrait) => trait.availableForGigs !== undefined,
), [memberPersonalizationTraits])

function handleModifyOpenForWorkClick(): void {
setIsEditMode(true)
}
Expand All @@ -55,16 +45,15 @@ const OpenForGigs: FC<OpenForGigsProps> = (props: OpenForGigsProps) => {
function handleModifyOpenForWorkSave(): void {
setTimeout(() => {
setIsEditMode(false)
mutateTraits()
props.refreshProfile(props.profile.handle)
triggerSurvey()
}, 1000)
}

return props.canEdit || openForWork ? (
<div className={styles.container}>
<p className={classNames('body-main-bold', !openForWork?.availableForGigs ? styles.notOopenToWork : '')}>
{openForWork?.availableForGigs ? 'open to work' : 'not open to work'}
<p className={classNames('body-main-bold', !openForWork ? styles.notOopenToWork : '')}>
{openForWork ? 'open to work' : 'not open to work'}
</p>
{
props.canEdit && (
Expand All @@ -78,8 +67,7 @@ const OpenForGigs: FC<OpenForGigsProps> = (props: OpenForGigsProps) => {
<OpenForGigsModifyModal
onClose={handleModifyOpenForWorkClose}
onSave={handleModifyOpenForWorkSave}
openForWork={openForWork?.availableForGigs || false}
memberPersonalizationTraitsFullData={memberPersonalizationTraits?.[0]?.traits?.data}
openForWork={openForWork ?? false}
profile={props.profile}
/>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,15 @@
import { Dispatch, FC, SetStateAction, useEffect, useState } from 'react'
import { toast } from 'react-toastify'
import { reject } from 'lodash'

import { BaseModal, Button, InputText } from '~/libs/ui'
import {
updateOrCreateMemberTraitsAsync,
UserProfile,
UserTrait,
UserTraitCategoryNames,
UserTraitIds,
} from '~/libs/core'
import { updateMemberProfileAsync, UserProfile } from '~/libs/core'

import styles from './OpenForGigsModifyModal.module.scss'

interface OpenForGigsModifyModalProps {
onClose: () => void
onSave: () => void
openForWork: boolean
memberPersonalizationTraitsFullData: UserTrait[] | undefined
profile: UserProfile
}

Expand All @@ -35,24 +27,10 @@ const OpenForGigsModifyModal: FC<OpenForGigsModifyModalProps> = (props: OpenForG
function handleOpenForWorkSave(): void {
setIsSaving(true)

const updatedPersonalizationTraits: UserTrait[]
= reject(
props.memberPersonalizationTraitsFullData,
(trait: UserTrait) => trait.availableForGigs !== undefined,
)

updateOrCreateMemberTraitsAsync(props.profile.handle, [{
categoryName: UserTraitCategoryNames.personalization,
traitId: UserTraitIds.personalization,
traits: {
data: [
...(updatedPersonalizationTraits || []),
{
availableForGigs: openForWork,
},
],
},
}])
updateMemberProfileAsync(
props.profile.handle,
{ availableForGigs: openForWork },
)
.then(() => {
toast.success('Work availability updated successfully.', { position: toast.POSITION.BOTTOM_RIGHT })
props.onSave()
Expand Down
1 change: 1 addition & 0 deletions src/libs/core/lib/profile/modify-user-profile.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export interface UpdateProfileRequest {
streetAddr2?: string
zip?: string
}>
availableForGigs?: boolean,
competitionCountryCode?: string
homeCountryCode?: string
firstName?: string
Expand Down
Loading