Skip to content

Commit bcb32eb

Browse files
committed
convert to functional component
1 parent 9585c93 commit bcb32eb

3 files changed

Lines changed: 73 additions & 84 deletions

File tree

Lines changed: 53 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from "react";
1+
import React, { useState } from "react";
22
import PropTypes from "prop-types";
33
import Loading from "../loading/Loading";
44
import SkillCard from "./SkillCard";
@@ -8,8 +8,8 @@ import styles from "./SkillsSection.module.scss";
88
import {
99
Skill,
1010
SkillSortComparator,
11-
COMPARATORS,
12-
DEFAULT_COMPARATOR
11+
SkillComparatorDisplayNames,
12+
COMPARATORS_MAP
1313
} from "./skillsUtils";
1414
import { Error } from "../error/errorUtils";
1515

@@ -19,46 +19,18 @@ interface Props {
1919
skills: Skill[];
2020
}
2121

22-
interface State {
23-
sortComparator: SkillSortComparator;
24-
}
25-
2622
function getSkillCards(skills: Skill[]): JSX.Element[] {
2723
return skills.map(skill => <SkillCard skill={skill} key={skill.name} />);
2824
}
2925

30-
export default class SkillsSection extends React.Component<Props, State> {
31-
static propTypes = {
32-
loading: PropTypes.bool,
33-
error: PropTypes.shape({
34-
message: PropTypes.string
35-
}),
36-
skills: PropTypes.arrayOf(
37-
PropTypes.shape({
38-
name: PropTypes.string.isRequired,
39-
displayName: PropTypes.string.isRequired,
40-
repoCount: PropTypes.number.isRequired
41-
})
42-
).isRequired
43-
};
44-
45-
static defaultProps = {
46-
loading: false,
47-
error: undefined
48-
};
49-
50-
constructor(props: Props) {
51-
super(props);
26+
export default function SkillsSection(props: Props): JSX.Element {
27+
const { loading, error, skills } = props;
5228

53-
this.state = {
54-
sortComparator: DEFAULT_COMPARATOR
55-
};
56-
}
57-
58-
getContent = (): JSX.Element | JSX.Element[] => {
59-
const { loading, error, skills } = this.props;
60-
const { sortComparator } = this.state;
29+
const [currentSort, setCurrentSort] = useState(
30+
SkillComparatorDisplayNames.DATE
31+
);
6132

33+
function getContent(): JSX.Element | JSX.Element[] {
6234
if (loading) {
6335
return <Loading />;
6436
}
@@ -73,32 +45,53 @@ export default class SkillsSection extends React.Component<Props, State> {
7345
);
7446
}
7547

48+
const sortComparator = COMPARATORS_MAP.get(
49+
currentSort
50+
) as SkillSortComparator;
51+
7652
const sortedSkills = skills.sort(sortComparator);
7753

7854
return getSkillCards(sortedSkills);
79-
};
80-
81-
handleSort = (event: React.ChangeEvent<HTMLSelectElement>): void => {
82-
const sortType = event.target.value;
83-
const sortComparator = COMPARATORS.get(sortType) as SkillSortComparator;
84-
85-
this.setState({ sortComparator });
86-
};
87-
88-
render(): JSX.Element {
89-
const { loading } = this.props;
90-
91-
return (
92-
<section className={styles.contentSection}>
93-
<div className={styles.container}>
94-
<header>
95-
<h2>Skills</h2>
55+
}
9656

97-
<SkillSortSelector disabled={loading} onChange={this.handleSort} />
98-
</header>
99-
<div className={styles.list}>{this.getContent()}</div>
100-
</div>
101-
</section>
102-
);
57+
function handleChangeSkillSort(
58+
event: React.ChangeEvent<HTMLSelectElement>
59+
): void {
60+
setCurrentSort(event.target.value as SkillComparatorDisplayNames);
10361
}
62+
63+
return (
64+
<section className={styles.contentSection}>
65+
<div className={styles.container}>
66+
<header>
67+
<h2>Skills</h2>
68+
69+
<SkillSortSelector
70+
disabled={loading}
71+
onChange={handleChangeSkillSort}
72+
/>
73+
</header>
74+
<div className={styles.list}>{getContent()}</div>
75+
</div>
76+
</section>
77+
);
10478
}
79+
80+
SkillsSection.propTypes = {
81+
loading: PropTypes.bool,
82+
error: PropTypes.shape({
83+
message: PropTypes.string
84+
}),
85+
skills: PropTypes.arrayOf(
86+
PropTypes.shape({
87+
name: PropTypes.string.isRequired,
88+
displayName: PropTypes.string.isRequired,
89+
repoCount: PropTypes.number.isRequired
90+
})
91+
).isRequired
92+
};
93+
94+
SkillsSection.defaultProps = {
95+
loading: false,
96+
error: undefined
97+
};

src/components/skills/skillsUtils.test.ts

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@ import {
55
Skill,
66
EMPTY_SKILL,
77
nameSkillComparator,
8-
repoCountComparator,
9-
commitRecencySkillComparator,
10-
DEFAULT_COMPARATOR
8+
countSkillComparator,
9+
dateSkillComparator
1110
} from "./skillsUtils";
1211

1312
function getSkillNames(skills: Skill[]): string[] {
@@ -59,7 +58,7 @@ describe("`skillsUtils`", () => {
5958
skillC.name = "React";
6059
skillC.repoCount = 20;
6160

62-
const sortedSkills = skills.sort(repoCountComparator);
61+
const sortedSkills = skills.sort(countSkillComparator);
6362

6463
expect(getSkillNames(sortedSkills)).toEqual(["React", "Jest", "Git"]);
6564
});
@@ -72,7 +71,7 @@ describe("`skillsUtils`", () => {
7271
skillC.name = "Git";
7372
skillC.repoCount = 20;
7473

75-
const sortedSkills = skills.sort(repoCountComparator);
74+
const sortedSkills = skills.sort(countSkillComparator);
7675

7776
expect(getSkillNames(sortedSkills)).toEqual(["Git", "Jest", "React"]);
7877
});
@@ -90,7 +89,7 @@ describe("`skillsUtils`", () => {
9089
skillC.repoCount = 13;
9190
skillC.lastCommitTime = moment("2011-11-11", DATE_FORMAT);
9291

93-
const sortedSkills = skills.sort(commitRecencySkillComparator);
92+
const sortedSkills = skills.sort(dateSkillComparator);
9493

9594
expect(getSkillNames(sortedSkills)).toEqual(["React", "Git", "Jest"]);
9695
});
@@ -106,7 +105,7 @@ describe("`skillsUtils`", () => {
106105
skillC.repoCount = 13;
107106
skillC.lastCommitTime = moment("2012-12-12", DATE_FORMAT);
108107

109-
const sortedSkills = skills.sort(commitRecencySkillComparator);
108+
const sortedSkills = skills.sort(dateSkillComparator);
110109

111110
expect(getSkillNames(sortedSkills)).toEqual(["Git", "Jest", "React"]);
112111
});
@@ -122,16 +121,10 @@ describe("`skillsUtils`", () => {
122121
skillC.repoCount = 22;
123122
skillC.lastCommitTime = moment("2012-12-12", DATE_FORMAT);
124123

125-
const sortedSkills = skills.sort(commitRecencySkillComparator);
124+
const sortedSkills = skills.sort(dateSkillComparator);
126125

127126
expect(getSkillNames(sortedSkills)).toEqual(["Jest", "Git", "React"]);
128127
});
129128
});
130129
});
131-
132-
describe("`DEFAULT_COMPARATOR`", () => {
133-
it("should be `nameSkillComparator`", () => {
134-
expect(DEFAULT_COMPARATOR).toBe(commitRecencySkillComparator);
135-
});
136-
});
137130
});

src/components/skills/skillsUtils.ts

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ export function nameSkillComparator(a: Skill, b: Skill): number {
4040
return 0;
4141
}
4242

43-
export function repoCountComparator(a: Skill, b: Skill): number {
43+
export function countSkillComparator(a: Skill, b: Skill): number {
4444
if (a.repoCount === b.repoCount) {
4545
return nameSkillComparator(a, b);
4646
}
@@ -49,7 +49,7 @@ export function repoCountComparator(a: Skill, b: Skill): number {
4949
return b.repoCount - a.repoCount;
5050
}
5151

52-
export function commitRecencySkillComparator(a: Skill, b: Skill): number {
52+
export function dateSkillComparator(a: Skill, b: Skill): number {
5353
// descending
5454
if (a.lastCommitTime.isBefore(b.lastCommitTime)) {
5555
return 1;
@@ -67,13 +67,16 @@ export function commitRecencySkillComparator(a: Skill, b: Skill): number {
6767
return nameSkillComparator(a, b);
6868
}
6969

70-
export const COMPARATORS: Map<string, SkillSortComparator> = new Map([
71-
["Recency", commitRecencySkillComparator],
72-
["Skill Name", nameSkillComparator],
73-
["Repo Count", repoCountComparator]
70+
export enum SkillComparatorDisplayNames {
71+
DATE = "Recency",
72+
NAME = "Skill Name",
73+
COUNT = "Repo Count"
74+
}
75+
76+
export const COMPARATORS_MAP: Map<string, SkillSortComparator> = new Map([
77+
[SkillComparatorDisplayNames.DATE, dateSkillComparator],
78+
[SkillComparatorDisplayNames.NAME, nameSkillComparator],
79+
[SkillComparatorDisplayNames.COUNT, countSkillComparator]
7480
]);
7581

76-
export const SKILL_SORT_OPTIONS = Array.from(COMPARATORS.keys());
77-
// the default value is always the first in the list
78-
export const DEFAULT_COMPARATOR: SkillSortComparator = COMPARATORS.values().next()
79-
.value;
82+
export const SKILL_SORT_OPTIONS = Object.values(SkillComparatorDisplayNames);

0 commit comments

Comments
 (0)