Skip to content

Commit b422607

Browse files
committed
MP-34 member communities
1 parent 60eff58 commit b422607

File tree

15 files changed

+237
-10
lines changed

15 files changed

+237
-10
lines changed
Loading
Loading
Loading

src/apps/accounts/src/lib/assets/tcandyou/index.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,14 @@
11
import { ReactComponent as DevelopmentTrackIcon } from './develop.svg'
22
import { ReactComponent as DesignTrackIcon } from './design.svg'
33
import { ReactComponent as DataScienceTrackIcon } from './data_science.svg'
4+
import ethereumCommunityImage from './ico-ethereum.png'
5+
import ibmCommunityImage from './ico-ibmcloud.png'
6+
import veteransCommunityImage from './ico-veteran.png'
47

58
export {
9+
ethereumCommunityImage,
10+
ibmCommunityImage,
11+
veteransCommunityImage,
612
DesignTrackIcon,
713
DataScienceTrackIcon,
814
DevelopmentTrackIcon,

src/apps/accounts/src/settings/tabs/AccountSettingsTabs.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ const AccountSettingsTabs: FC<AccountSettingsTabsProps> = (props: AccountSetting
2424
const [activeTab, setActiveTab]: [string, Dispatch<SetStateAction<string>>]
2525
= useState<string>(activeTabHash)
2626

27-
const memberTraits: UserTraits[] | undefined = useMemberTraits(props.profile.handle)
27+
const { data: memberTraits }: {
28+
data: UserTraits[] | undefined
29+
} = useMemberTraits(props.profile.handle)
2830

2931
function handleTabChange(tabId: string): void {
3032
setActiveTab(tabId)

src/apps/accounts/src/settings/tabs/account/user-and-pass/UserAndPassword.tsx

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,22 @@
11
import { Dispatch, FC, useCallback, useEffect, useMemo, useState } from 'react'
22
import { has, trim } from 'lodash'
33
import { toast } from 'react-toastify'
4+
import { KeyedMutator } from 'swr'
45

56
import {
67
Collapsible,
78
Form,
89
FormInputModel,
910
FormToggleSwitch,
1011
} from '~/libs/ui'
11-
import { updateMemberPasswordAsync, updateMemberTraitsAsync, UserProfile, UserTrait, UserTraits } from '~/libs/core'
12+
import {
13+
updateMemberPasswordAsync,
14+
updateMemberTraitsAsync,
15+
useMemberTraits,
16+
UserProfile,
17+
UserTrait,
18+
UserTraits,
19+
} from '~/libs/core'
1220
import { SettingSection } from '~/apps/accounts/src/lib'
1321

1422
import { UserAndPassFromConfig } from './user-and-pass.form.config'
@@ -30,6 +38,8 @@ const UserAndPassword: FC<UserAndPasswordProps> = (props: UserAndPasswordProps)
3038
[props.memberTraits],
3139
)
3240

41+
const { mutate: mutateTraits }: { mutate: KeyedMutator<any> } = useMemberTraits(props.profile.handle)
42+
3343
const [userConsent, setUserConsent]: [boolean, Dispatch<boolean>] = useState(false)
3444

3545
const requestGenerator: (inputs: ReadonlyArray<FormInputModel>) => any
@@ -70,6 +80,7 @@ const UserAndPassword: FC<UserAndPasswordProps> = (props: UserAndPasswordProps)
7080
}])
7181
.then(() => {
7282
setUserConsent(!userConsent)
83+
mutateTraits()
7384
toast.success('User consent updated successfully.')
7485
})
7586
.catch(() => {

src/apps/accounts/src/settings/tabs/tcandyou/TCandYouTab.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ import { FC } from 'react'
33
import { UserProfile, UserTraits } from '~/libs/core'
44

55
import { Tracks } from './tracks'
6+
import { Communities } from './communities'
67
import styles from './TCandYouTab.module.scss'
78

89
interface TCandYouTabProps {
910
profile: UserProfile
10-
// eslint-disable-next-line react/no-unused-prop-types
1111
memberTraits: UserTraits[] | undefined
1212
}
1313

@@ -16,6 +16,11 @@ const TCandYouTab: FC<TCandYouTabProps> = (props: TCandYouTabProps) => (
1616
<h3>You And Topcoder</h3>
1717

1818
<Tracks profile={props.profile} />
19+
20+
<Communities
21+
communityTraits={props.memberTraits?.find(trait => trait.traitId === 'communities')}
22+
profile={props.profile}
23+
/>
1924
</div>
2025
)
2126

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
@import '@libs/ui/styles/includes';
2+
3+
.container {
4+
margin: $sp-8 0;
5+
6+
.content {
7+
display: flex;
8+
flex-direction: column;
9+
margin-bottom: 0;
10+
11+
.communityCard {
12+
border: 1px solid #d4d4d4;
13+
border-radius: 8px;
14+
padding: $sp-4;
15+
margin-bottom: $sp-4;
16+
display: flex;
17+
justify-content: space-between;
18+
align-items: flex-start;
19+
20+
.communityCardHeader {
21+
display: flex;
22+
align-items: flex-start;
23+
24+
@include ltelg {
25+
flex-direction: column;
26+
}
27+
}
28+
29+
img {
30+
margin-right: $sp-4;
31+
border-radius: 4px;
32+
33+
@include ltelg {
34+
margin-right: 0;
35+
margin-bottom: $sp-4;
36+
}
37+
}
38+
39+
.communityInfo {
40+
flex: 1;
41+
42+
.infoText {
43+
padding-right: 74px;
44+
color: #767676;
45+
margin: $sp-3 0;
46+
}
47+
}
48+
}
49+
}
50+
}
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import { Dispatch, FC, SetStateAction, useEffect, useState } from 'react'
2+
import { bind } from 'lodash'
3+
import { KeyedMutator } from 'swr'
4+
import { toast } from 'react-toastify'
5+
6+
import { updateMemberTraitsAsync, useMemberTraits, UserProfile, UserTraits } from '~/libs/core'
7+
import { Button, Collapsible, FormToggleSwitch } from '~/libs/ui'
8+
9+
import { communitiesConfig } from './communities-config'
10+
import styles from './Communities.module.scss'
11+
12+
interface CommunitiesProps {
13+
communityTraits: UserTraits | undefined
14+
profile: UserProfile
15+
}
16+
17+
interface CommunitiesDataStatus {
18+
[key: string]: boolean
19+
}
20+
21+
const Communities: FC<CommunitiesProps> = (props: CommunitiesProps) => {
22+
const [memberCommunities, setMemberCommunities]: [
23+
CommunitiesDataStatus | undefined,
24+
Dispatch<SetStateAction<CommunitiesDataStatus | undefined>>
25+
]
26+
= useState<CommunitiesDataStatus | undefined>()
27+
28+
const { mutate: mutateTraits }: { mutate: KeyedMutator<any> } = useMemberTraits(props.profile.handle)
29+
30+
useEffect(() => {
31+
setMemberCommunities(props.communityTraits?.traits.data[0])
32+
}, [props.communityTraits])
33+
34+
function handleCommunitiesChange(communityId: string): void {
35+
const updatedCommunities: CommunitiesDataStatus = {
36+
...memberCommunities,
37+
[communityId]: !memberCommunities?.[communityId],
38+
}
39+
40+
updateMemberTraitsAsync(props.profile.handle, [{
41+
categoryName: 'Communities',
42+
traitId: 'communities',
43+
traits: {
44+
data: [updatedCommunities],
45+
},
46+
}])
47+
.then(() => {
48+
setMemberCommunities(updatedCommunities)
49+
mutateTraits()
50+
toast.success('Communities updated successfully.')
51+
})
52+
.catch(() => {
53+
toast.error('Failed to update user Communities.')
54+
})
55+
}
56+
57+
function handleLearnMoreClick(link: string): void {
58+
window.open(link, '_blank')
59+
}
60+
61+
return (
62+
<Collapsible
63+
header={<h3>Your Communities</h3>}
64+
containerClass={styles.container}
65+
contentClass={styles.content}
66+
>
67+
{
68+
communitiesConfig.map(community => (
69+
<div className={styles.communityCard} key={community.id}>
70+
<div className={styles.communityCardHeader}>
71+
<img src={community.icon} alt={community.name} />
72+
<div className={styles.communityInfo}>
73+
<p className='body-main-bold'>{community.name}</p>
74+
<p className={styles.infoText}>{community.description}</p>
75+
<Button
76+
secondary
77+
size='sm'
78+
label='Learn More'
79+
onClick={bind(handleLearnMoreClick, this, community.link)}
80+
/>
81+
</div>
82+
</div>
83+
<FormToggleSwitch
84+
name={community.id}
85+
onChange={bind(handleCommunitiesChange, this, community.id)}
86+
value={memberCommunities?.[community.id] || false}
87+
/>
88+
</div>
89+
))
90+
}
91+
</Collapsible>
92+
)
93+
}
94+
95+
export default Communities
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/* eslint-disable @typescript-eslint/typedef */
2+
/* eslint-disable max-len */
3+
/* eslint-disable sort-keys */
4+
import { ethereumCommunityImage, ibmCommunityImage, veteransCommunityImage } from '~/apps/accounts/src/lib'
5+
6+
export const communitiesConfig = [
7+
{
8+
id: 'blockchain',
9+
icon: ethereumCommunityImage,
10+
programID: 20000010,
11+
name: 'Topcoder Blockchain Community',
12+
description: 'Meet like-minded peers from around the world, share tips and insights, and collaborate with customers to build cutting-edge solutions. The Topcoder Blockchain Community provides opportunities to learn from Ethereum experts and work with top companies that are embracing blockchain technology.',
13+
link: 'https://blockchain.topcoder.com/',
14+
},
15+
{
16+
id: 'cognitive',
17+
icon: ibmCommunityImage,
18+
programID: 3449,
19+
name: 'Topcoder Cognitive Community',
20+
description: 'By becoming a member of the Topcoder Community and registering for this specialized community, you can compete in fun cognitive challenges, access educational resources, and win money by solving real-life business problems for companies in need of cognitive expertise. ',
21+
link: 'https://cognitive.topcoder.com/',
22+
},
23+
{
24+
id: 'veteran',
25+
icon: veteransCommunityImage,
26+
programID: 3450,
27+
name: 'Topcoder Veterans Community',
28+
description: 'We help military service members and veterans transition to a career in technology with the world\'s premier crowdsourcing platform.',
29+
link: 'https://veterans.topcoder.com/',
30+
},
31+
]
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default as Communities } from './Communities'

src/apps/accounts/src/settings/tabs/tools/service-provider/ServiceProvider.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { Dispatch, FC, MutableRefObject, SetStateAction, useEffect, useRef, useState } from 'react'
22
import { bind, isEmpty, reject, trim } from 'lodash'
33
import { toast } from 'react-toastify'
4+
import { KeyedMutator } from 'swr'
45
import classNames from 'classnames'
56

6-
import { createMemberTraitsAsync, updateMemberTraitsAsync, UserProfile, UserTrait } from '~/libs/core'
7+
import { createMemberTraitsAsync, updateMemberTraitsAsync, useMemberTraits, UserProfile, UserTrait } from '~/libs/core'
78
import { Button, Collapsible, ConfirmModal, IconOutline, InputSelect, InputText } from '~/libs/ui'
89
import {
910
FinancialInstitutionIcon,
@@ -64,6 +65,8 @@ const ServiceProvider: FC<ServiceProviderProps> = (props: ServiceProviderProps)
6465
const [itemToRemove, setItemToRemove]: [UserTrait | undefined, Dispatch<SetStateAction<UserTrait | undefined>>]
6566
= useState<UserTrait | undefined>()
6667

68+
const { mutate: mutateTraits }: { mutate: KeyedMutator<any> } = useMemberTraits(props.profile.handle)
69+
6770
useEffect(() => {
6871
setServiceProviderTypesData(props.serviceProviderTrait?.traits.data)
6972
}, [props.serviceProviderTrait])
@@ -155,6 +158,7 @@ const ServiceProvider: FC<ServiceProviderProps> = (props: ServiceProviderProps)
155158
...updatedServiceProviderTypesData || [],
156159
serviceProviderTypeUpdate,
157160
])
161+
mutateTraits()
158162
})
159163
.catch(() => {
160164
toast.error('Error updating Service Provider')
@@ -183,6 +187,7 @@ const ServiceProvider: FC<ServiceProviderProps> = (props: ServiceProviderProps)
183187
...serviceProviderTypesData || [],
184188
serviceProviderTypeUpdate,
185189
])
190+
mutateTraits()
186191
})
187192
.catch(() => {
188193
toast.error('Error adding new Service Provider')
@@ -222,6 +227,7 @@ const ServiceProvider: FC<ServiceProviderProps> = (props: ServiceProviderProps)
222227
.then(() => {
223228
toast.success('Service Provider deleted successfully')
224229
setServiceProviderTypesData(updatedServiceProviderTypesData)
230+
mutateTraits()
225231
})
226232
.catch(() => {
227233
toast.error('Error deleting Service Provider')

src/apps/accounts/src/settings/tabs/tools/software/Software.tsx

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import { Dispatch, FC, MutableRefObject, SetStateAction, useEffect, useRef, useState } from 'react'
22
import { bind, isEmpty, reject, trim } from 'lodash'
33
import { toast } from 'react-toastify'
4+
import { KeyedMutator } from 'swr'
45
import classNames from 'classnames'
56

6-
import { createMemberTraitsAsync, updateMemberTraitsAsync, UserProfile, UserTrait } from '~/libs/core'
7+
import { createMemberTraitsAsync, updateMemberTraitsAsync, useMemberTraits, UserProfile, UserTrait } from '~/libs/core'
78
import { Button, Collapsible, ConfirmModal, IconOutline, InputSelect, InputText } from '~/libs/ui'
89
import { SettingSection, SoftwareIcon } from '~/apps/accounts/src/lib'
910

@@ -57,6 +58,8 @@ const Software: FC<SoftwareProps> = (props: SoftwareProps) => {
5758
const [itemToRemove, setItemToRemove]: [UserTrait | undefined, Dispatch<SetStateAction<UserTrait | undefined>>]
5859
= useState<UserTrait | undefined>()
5960

61+
const { mutate: mutateTraits }: { mutate: KeyedMutator<any> } = useMemberTraits(props.profile.handle)
62+
6063
useEffect(() => {
6164
setSoftwareTypesData(props.softwareTrait?.traits.data)
6265
}, [props.softwareTrait])
@@ -144,6 +147,7 @@ const Software: FC<SoftwareProps> = (props: SoftwareProps) => {
144147
...updatedSoftwareTypesData || [],
145148
softwareTypeUpdate,
146149
])
150+
mutateTraits()
147151
})
148152
.catch(() => {
149153
toast.error('Error updating software')
@@ -172,6 +176,7 @@ const Software: FC<SoftwareProps> = (props: SoftwareProps) => {
172176
...softwareTypesData || [],
173177
softwareTypeUpdate,
174178
])
179+
mutateTraits()
175180
})
176181
.catch(() => {
177182
toast.error('Error adding new software')
@@ -211,6 +216,7 @@ const Software: FC<SoftwareProps> = (props: SoftwareProps) => {
211216
.then(() => {
212217
toast.success('Software deleted successfully')
213218
setSoftwareTypesData(updatedSoftwareTypesData)
219+
mutateTraits()
214220
})
215221
.catch(() => {
216222
toast.error('Error deleting software')

0 commit comments

Comments
 (0)