Skip to content

Commit 471e36f

Browse files
authored
Merge pull request #742 from topcoder-platform/issue-738
Onboarding - Use different field for bio + Next on last screen
2 parents b3c83dc + 122ea41 commit 471e36f

File tree

6 files changed

+157
-22
lines changed

6 files changed

+157
-22
lines changed

src/apps/onboarding/src/config/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export const ACTIONS: {
77
SET_PERSONALIZATION: string;
88
SET_ADDRESS: string;
99
SET_CONNECT_INFO: string;
10+
SET_DESCRIPTION: string;
1011
SET_LOADING_MEMBER_TRAITS: string;
1112
SET_LOADING_MEMBER_INFO: string;
1213
};
@@ -15,6 +16,7 @@ export const ACTIONS: {
1516
GET_MEMBER: 'GET_MEMBER',
1617
SET_ADDRESS: 'SET_ADDRESS',
1718
SET_CONNECT_INFO: 'SET_CONNECT_INFO',
19+
SET_DESCRIPTION: 'SET_DESCRIPTION',
1820
SET_EDUCATIONS: 'SET_EDUCATIONS',
1921
SET_LOADING_MEMBER_INFO: 'SET_LOADING_MEMBER_INFO',
2022
SET_LOADING_MEMBER_TRAITS: 'SET_LOADING_MEMBER_TRAITS',
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import { Dispatch, MutableRefObject, SetStateAction, useEffect, useState } from 'react'
2+
import _ from 'lodash'
3+
4+
import MemberInfo from '../models/MemberInfo'
5+
6+
export interface useAutoSaveMemberDescriptionType {
7+
description: string | undefined
8+
loading: boolean
9+
setDescription: Dispatch<SetStateAction<string | undefined>>
10+
}
11+
12+
type useAutoSaveMemberDescriptionFunctionType = (
13+
memberInfo: MemberInfo | undefined,
14+
updateMemberDescription: (description: string) => void,
15+
shouldSavingData: MutableRefObject<boolean>,
16+
) => useAutoSaveMemberDescriptionType
17+
18+
export const useAutoSaveMemberDescription: useAutoSaveMemberDescriptionFunctionType = (
19+
memberInfo: MemberInfo | undefined,
20+
updateMemberDescription: (description: string) => void,
21+
shouldSavingData: MutableRefObject<boolean>,
22+
) => {
23+
const [loading, setLoading] = useState<boolean>(false)
24+
const [description, setDescription] = useState<string | undefined>(undefined)
25+
26+
const saveData: any = async () => {
27+
if (description === undefined) {
28+
return
29+
}
30+
31+
setLoading(true)
32+
await updateMemberDescription(description)
33+
34+
setLoading(false)
35+
}
36+
37+
useEffect(() => {
38+
if (description !== undefined && !_.isEqual(memberInfo?.description, description)) {
39+
if (loading) {
40+
shouldSavingData.current = true
41+
return
42+
}
43+
44+
saveData()
45+
.then(_.noop)
46+
}
47+
/* eslint-disable react-hooks/exhaustive-deps */
48+
}, [description])
49+
50+
useEffect(() => {
51+
if (description === undefined && memberInfo && memberInfo.description !== undefined) {
52+
setDescription(memberInfo.description)
53+
}
54+
/* eslint-disable react-hooks/exhaustive-deps */
55+
}, [memberInfo])
56+
57+
useEffect(() => {
58+
if (!loading && shouldSavingData.current) {
59+
shouldSavingData.current = false
60+
saveData()
61+
.then(_.noop)
62+
}
63+
/* eslint-disable react-hooks/exhaustive-deps */
64+
}, [loading])
65+
66+
return {
67+
description,
68+
loading,
69+
setDescription,
70+
}
71+
}

src/apps/onboarding/src/models/MemberInfo.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,5 @@ export default interface MemberInfo {
1919
country: string
2020
photoURL: string
2121
createdAt: number
22+
description: string
2223
}

src/apps/onboarding/src/pages/personalization/index.tsx

Lines changed: 54 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,19 @@ import classNames from 'classnames'
66
import { Button, IconOutline, PageDivider } from '~/libs/ui'
77
import { EnvironmentConfig } from '~/config'
88

9-
import { useAutoSavePersonalization, useAutoSavePersonalizationType } from '../../hooks/useAutoSavePersonalization'
109
import { ProgressBar } from '../../components/progress-bar'
10+
import {
11+
useAutoSaveMemberDescription,
12+
useAutoSaveMemberDescriptionType,
13+
} from '../../hooks/useAutoSaveMemberDescription'
14+
import {
15+
useAutoSavePersonalization,
16+
useAutoSavePersonalizationType,
17+
} from '../../hooks/useAutoSavePersonalization'
1118
import {
1219
createMemberPersonalizations,
1320
setMemberPhotoUrl,
21+
updateMemberDescription,
1422
updateMemberPersonalizations,
1523
updateMemberPhotoUrl,
1624
} from '../../redux/actions/member'
@@ -31,11 +39,14 @@ const PagePersonalizationContent: FC<{
3139
createMemberPersonalizations: (infos: PersonalizationInfo[]) => void
3240
setMemberPhotoUrl: (photoUrl: string) => void
3341
updateMemberPhotoUrl: (photoUrl: string) => void
42+
updateMemberDescription: (photoUrl: string) => void
3443
loadingMemberTraits: boolean
44+
loadingMemberInfo: boolean
3545
}> = props => {
3646
const navigate: any = useNavigate()
3747

3848
const shouldSavingData: MutableRefObject<boolean> = useRef<boolean>(false)
49+
const shouldSavingMemberData: MutableRefObject<boolean> = useRef<boolean>(false)
3950
const shouldNavigateTo: MutableRefObject<string> = useRef<string>('')
4051

4152
const {
@@ -49,16 +60,42 @@ const PagePersonalizationContent: FC<{
4960
shouldSavingData,
5061
)
5162

63+
const {
64+
loading: loadingMemberInfo,
65+
description,
66+
setDescription,
67+
}: useAutoSaveMemberDescriptionType = useAutoSaveMemberDescription(
68+
props.memberInfo,
69+
props.updateMemberDescription,
70+
shouldSavingMemberData,
71+
)
72+
5273
useEffect(() => {
53-
if (!loading && !shouldSavingData.current && !!shouldNavigateTo.current) {
74+
if (
75+
!loading
76+
&& !loadingMemberInfo
77+
&& !shouldSavingData.current
78+
&& !shouldSavingMemberData.current
79+
&& !!shouldNavigateTo.current
80+
) {
5481
if (shouldNavigateTo.current.startsWith('../')) {
5582
navigate(shouldNavigateTo.current)
5683
} else {
5784
window.location.href = shouldNavigateTo.current
5885
}
5986
}
6087
/* eslint-disable react-hooks/exhaustive-deps */
61-
}, [loading])
88+
}, [loading, loadingMemberInfo])
89+
90+
function nextPage(pageUrl: string): void {
91+
if (loading || loadingMemberInfo) {
92+
shouldNavigateTo.current = pageUrl
93+
} else if (pageUrl.startsWith('../')) {
94+
navigate(pageUrl)
95+
} else {
96+
window.location.href = pageUrl
97+
}
98+
}
6299

63100
return (
64101
<div className={classNames('d-flex flex-column', styles.container)}>
@@ -93,16 +130,13 @@ const PagePersonalizationContent: FC<{
93130
<InputTextareaAutoSave
94131
name='shortBio'
95132
label='Bio'
96-
value={personalizationInfo?.shortBio || ''}
133+
value={description || ''}
97134
onChange={function onChange(value: string | undefined) {
98-
setPersonalizationInfo({
99-
...(personalizationInfo || blankPersonalizationInfo),
100-
shortBio: value || '',
101-
})
135+
setDescription(value || '')
102136
}}
103137
placeholder='Share something that makes you, you.'
104138
tabIndex={0}
105-
disabled={props.loadingMemberTraits}
139+
disabled={props.loadingMemberInfo}
106140
/>
107141
</div>
108142
</div>
@@ -119,26 +153,21 @@ const PagePersonalizationContent: FC<{
119153
secondary
120154
iconToLeft
121155
icon={IconOutline.ChevronLeftIcon}
156+
disabled={!!shouldNavigateTo.current}
122157
onClick={function previousPage() {
123-
if (loading) {
124-
shouldNavigateTo.current = '../educations'
125-
} else {
126-
navigate('../educations')
127-
}
158+
nextPage('../educations')
128159
}}
129160
/>
130161
<Button
131162
size='lg'
132163
primary
133164
iconToLeft
134-
onClick={function nextPage() {
135-
if (loading) {
136-
shouldNavigateTo.current
137-
= `${EnvironmentConfig.USER_PROFILE_URL}/${props.memberInfo?.handle}`
138-
} else {
139-
window.location.href
140-
= `${EnvironmentConfig.USER_PROFILE_URL}/${props.memberInfo?.handle}`
141-
}
165+
disabled={!!shouldNavigateTo.current}
166+
onClick={function onClick() {
167+
nextPage(
168+
`${EnvironmentConfig.USER_PROFILE_URL}/${props.memberInfo?.handle}`
169+
+ '?edit-mode=onboardingCompleted',
170+
)
142171
}}
143172
>
144173
next
@@ -151,11 +180,13 @@ const PagePersonalizationContent: FC<{
151180
const mapStateToProps: any = (state: any) => {
152181
const {
153182
loadingMemberTraits,
183+
loadingMemberInfo,
154184
personalization,
155185
memberInfo,
156186
}: any = state.member
157187

158188
return {
189+
loadingMemberInfo,
159190
loadingMemberTraits,
160191
memberInfo,
161192
reduxPersonalization: personalization,
@@ -165,6 +196,7 @@ const mapStateToProps: any = (state: any) => {
165196
const mapDispatchToProps: any = {
166197
createMemberPersonalizations,
167198
setMemberPhotoUrl,
199+
updateMemberDescription,
168200
updateMemberPersonalizations,
169201
updateMemberPhotoUrl,
170202
}

src/apps/onboarding/src/redux/actions/member.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ export const updateAddress: any = (address: MemberAddress) => ({
4747
type: ACTIONS.MEMBER.SET_ADDRESS,
4848
})
4949

50+
export const setMemberDescription: any = (description: string) => ({
51+
payload: description,
52+
type: ACTIONS.MEMBER.SET_DESCRIPTION,
53+
})
54+
5055
export const updateLoadingMemberTraits: any = (loading: boolean) => ({
5156
payload: loading,
5257
type: ACTIONS.MEMBER.SET_LOADING_MEMBER_TRAITS,
@@ -434,6 +439,17 @@ export const updateMemberHomeAddresss: any = (addresses: MemberAddress[]) => asy
434439
}
435440
}
436441

442+
export const updateMemberDescription: any = (description: string) => async (dispatch: any) => {
443+
try {
444+
const tokenInfo: TokenModel = await getAsyncToken()
445+
await putMemberInfo(tokenInfo.handle || '', {
446+
description,
447+
})
448+
dispatch(setMemberDescription(description))
449+
} catch (error) {
450+
}
451+
}
452+
437453
export const updateMemberPhotoUrl: any = (photoURL: string) => async (dispatch: any) => {
438454
try {
439455
const tokenInfo: TokenModel = await getAsyncToken()

src/apps/onboarding/src/redux/reducers/member.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,19 @@ const memberReducer: any = (
6767
...state,
6868
educations: action.payload,
6969
}
70+
case ACTIONS.MEMBER.SET_DESCRIPTION: {
71+
if (!state.memberInfo) {
72+
return state
73+
}
74+
75+
return {
76+
...state,
77+
memberInfo: {
78+
...state.memberInfo,
79+
description: action.payload,
80+
},
81+
}
82+
}
7083

7184
case ACTIONS.MEMBER.UPDATE_MEMBER_PHOTO_URL: {
7285
if (!state.memberInfo) {

0 commit comments

Comments
 (0)