Skip to content

Commit 126d369

Browse files
committed
TSJR-158 better collapse skills UI
1 parent bc11f31 commit 126d369

File tree

3 files changed

+84
-33
lines changed

3 files changed

+84
-33
lines changed

src/apps/profiles/src/member-profile/skills/MemberSkillsInfo.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,16 @@ const MemberSkillsInfo: FC<MemberSkillsInfoProps> = (props: MemberSkillsInfoProp
9191
setSkillsCatsCollapsed(!skillsCatsCollapsed)
9292
}
9393

94+
function toggleCollapseUIButton(collapsed: boolean): void {
95+
if (collapsed === false && !!skillsCatsCollapsed) {
96+
setSkillsCatsCollapsed(false)
97+
}
98+
99+
if (collapsed === true && skillsCatsCollapsed === false) {
100+
setSkillsCatsCollapsed(true)
101+
}
102+
}
103+
94104
return (
95105
<div className={styles.container}>
96106
{
@@ -137,6 +147,7 @@ const MemberSkillsInfo: FC<MemberSkillsInfoProps> = (props: MemberSkillsInfoProp
137147
<GroupedSkillsUI
138148
groupedSkillsByCategory={groupedSkillsByCategory}
139149
skillsCatsCollapsed={skillsCatsCollapsed}
150+
onAllSkillsSameDisplayState={toggleCollapseUIButton}
140151
/>
141152
)}
142153
{!memberSkills.length && (

src/libs/shared/lib/components/collapsible-skills-list/CollapsibleSkillsList.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ interface CollapsibleSkillsListProps {
1313
headerClass?: string
1414
contentClass?: string
1515
isCollapsed: boolean
16+
onDisplayChnage?: (isCollapsed: boolean) => void
1617
}
1718

1819
const CollapsibleSkillsList: FC<CollapsibleSkillsListProps> = (props: CollapsibleSkillsListProps) => {
@@ -24,7 +25,10 @@ const CollapsibleSkillsList: FC<CollapsibleSkillsListProps> = (props: Collapsibl
2425
}, [props.isCollapsed])
2526

2627
function toggleCollapse(): void {
27-
setIsCollapsed(!isCollapsed)
28+
const newIsCollapsed: boolean = !isCollapsed
29+
30+
setIsCollapsed(newIsCollapsed)
31+
if (props.onDisplayChnage) props.onDisplayChnage(newIsCollapsed)
2832
}
2933

3034
return (
Lines changed: 68 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { FC } from 'react'
1+
import { Dispatch, FC, SetStateAction, useEffect, useState } from 'react'
22
import Masonry, { ResponsiveMasonry } from 'react-responsive-masonry'
33

44
import { UserSkill } from '~/libs/core'
@@ -11,37 +11,73 @@ import styles from './GroupedSkillsUI.module.scss'
1111
interface GroupedSkillsUIProps {
1212
groupedSkillsByCategory: { [key: string]: UserSkill[] }
1313
skillsCatsCollapsed: boolean
14+
onAllSkillsSameDisplayState: (collapsed: boolean) => void
15+
}
16+
const GroupedSkillsUI: FC<GroupedSkillsUIProps> = (props: GroupedSkillsUIProps) => {
17+
const [collapsedMap, setCollapsedMap]:
18+
[{ [key: string]: boolean }, Dispatch<SetStateAction<{ [key: string]: boolean }>>]
19+
= useState<{ [key: string]: boolean }>({})
20+
21+
useEffect(() => {
22+
const newCollapsedMap: { [key: string]: boolean } = {}
23+
24+
Object.keys(props.groupedSkillsByCategory)
25+
.forEach((categoryName: string) => {
26+
newCollapsedMap[categoryName] = props.skillsCatsCollapsed
27+
})
28+
29+
setCollapsedMap(newCollapsedMap)
30+
}, [props.groupedSkillsByCategory, props.skillsCatsCollapsed])
31+
32+
useEffect(() => {
33+
const arr: boolean[] = Object.values(collapsedMap)
34+
35+
if (arr.every(val => val === arr[0])) {
36+
props.onAllSkillsSameDisplayState(arr[0])
37+
}
38+
// eslint-disable-next-line react-hooks/exhaustive-deps
39+
}, [collapsedMap])
40+
41+
function handleCollapseChange(categoryName: string, isCollapsed: boolean): void {
42+
setCollapsedMap({
43+
...collapsedMap,
44+
[categoryName]: isCollapsed,
45+
})
46+
}
47+
48+
return (
49+
<ResponsiveMasonry
50+
className={styles.skillsCategories}
51+
columnsCountBreakPoints={{ 350: 1, 750: 2, 1368: 3 }}
52+
>
53+
<Masonry>
54+
{
55+
Object.keys(props.groupedSkillsByCategory)
56+
.map((categoryName: string) => (
57+
58+
<CollapsibleSkillsList
59+
key={categoryName}
60+
header={categoryName}
61+
isCollapsed={collapsedMap[categoryName]}
62+
// eslint-disable-next-line react/jsx-no-bind
63+
onDisplayChnage={handleCollapseChange.bind(this, categoryName)}
64+
>
65+
{
66+
props.groupedSkillsByCategory[categoryName]
67+
.map((skill: UserSkill) => (
68+
<SkillPill
69+
skill={skill}
70+
key={skill.id}
71+
theme='catList'
72+
/>
73+
))
74+
}
75+
</CollapsibleSkillsList>
76+
))
77+
}
78+
</Masonry>
79+
</ResponsiveMasonry>
80+
)
1481
}
15-
const GroupedSkillsUI: FC<GroupedSkillsUIProps> = (props: GroupedSkillsUIProps) => (
16-
<ResponsiveMasonry
17-
className={styles.skillsCategories}
18-
columnsCountBreakPoints={{ 350: 1, 750: 2, 1368: 3 }}
19-
>
20-
<Masonry>
21-
{
22-
Object.keys(props.groupedSkillsByCategory)
23-
.map((categoryName: string) => (
24-
25-
<CollapsibleSkillsList
26-
key={categoryName}
27-
header={categoryName}
28-
isCollapsed={props.skillsCatsCollapsed}
29-
>
30-
{
31-
props.groupedSkillsByCategory[categoryName]
32-
.map((skill: UserSkill) => (
33-
<SkillPill
34-
skill={skill}
35-
key={skill.id}
36-
theme='catList'
37-
/>
38-
))
39-
}
40-
</CollapsibleSkillsList>
41-
))
42-
}
43-
</Masonry>
44-
</ResponsiveMasonry>
45-
)
4682

4783
export default GroupedSkillsUI

0 commit comments

Comments
 (0)