Skip to content

Commit 97bc703

Browse files
authored
Merge pull request #341 from boostcampwm-2022/refactor/ranking-table
Refactor: RankingTable 컴포넌트 Body 추가
2 parents 98d9790 + 6ba927c commit 97bc703

File tree

6 files changed

+114
-95
lines changed

6 files changed

+114
-95
lines changed

frontend/src/components/Ranking/LanguageRanking/index.tsx

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,19 @@ function LanguageRanking() {
2626
<RankingTable.Element />
2727
<RankingTable.Element>{t('common:table-user-num')}</RankingTable.Element>
2828
</RankingTable.Head>
29-
{rankingByProgrammingLang?.map(({ language, count }) => (
30-
<RankingTable.Row key={language}>
31-
<RankingTable.Element>
32-
<LanguageIcon language={language} width={30} height={30} />
33-
</RankingTable.Element>
34-
<RankingTable.Element>{language}</RankingTable.Element>
35-
<RankingTable.Element>
36-
<span>{count}</span>
37-
</RankingTable.Element>
38-
</RankingTable.Row>
39-
))}
29+
<RankingTable.Body>
30+
{rankingByProgrammingLang?.map(({ language, count }) => (
31+
<RankingTable.Row key={language}>
32+
<RankingTable.Element>
33+
<LanguageIcon language={language} width={30} height={30} />
34+
</RankingTable.Element>
35+
<RankingTable.Element>{language}</RankingTable.Element>
36+
<RankingTable.Element>
37+
<span>{count}</span>
38+
</RankingTable.Element>
39+
</RankingTable.Row>
40+
))}
41+
</RankingTable.Body>
4042
</RankingTable>
4143
</>
4244
);

frontend/src/components/Ranking/OverallRanking/index.tsx

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -34,22 +34,24 @@ function OverallRanking({ searchUser }: OverallRankingProps) {
3434
<RankingTable.Element>{t('common:table-user')}</RankingTable.Element>
3535
<RankingTable.Element>{t('common:table-score')}</RankingTable.Element>
3636
</RankingTable.Head>
37-
{rankingByScore?.users.map(({ id, tier, avatarUrl, username, score }, idx) => (
38-
<RankingTable.Row key={id} onClick={() => searchUser(username)}>
39-
<RankingTable.Element>
40-
<CubeIcon tier={tier} />
41-
</RankingTable.Element>
42-
<RankingTable.Element>
43-
<span> {idx < 3 ? <Image src={MEDAL_IMG[idx]} width={20} height={30} alt='medal' /> : idx + 1}</span>
44-
</RankingTable.Element>
45-
<RankingTable.Element>
46-
<Avatar src={avatarUrl} name={username} />
47-
</RankingTable.Element>
48-
<RankingTable.Element>
49-
<span>{score.toLocaleString()}</span>
50-
</RankingTable.Element>
51-
</RankingTable.Row>
52-
))}
37+
<RankingTable.Body>
38+
{rankingByScore?.users.map(({ id, tier, avatarUrl, username, score }, idx) => (
39+
<RankingTable.Row key={id} onClick={() => searchUser(username)}>
40+
<RankingTable.Element>
41+
<CubeIcon tier={tier} />
42+
</RankingTable.Element>
43+
<RankingTable.Element>
44+
<span> {idx < 3 ? <Image src={MEDAL_IMG[idx]} width={20} height={30} alt='medal' /> : idx + 1}</span>
45+
</RankingTable.Element>
46+
<RankingTable.Element>
47+
<Avatar src={avatarUrl} name={username} />
48+
</RankingTable.Element>
49+
<RankingTable.Element>
50+
<span>{score.toLocaleString()}</span>
51+
</RankingTable.Element>
52+
</RankingTable.Row>
53+
))}
54+
</RankingTable.Body>
5355
</RankingTable>
5456
</>
5557
);

frontend/src/components/Ranking/RankingTable/index.tsx

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import { Children } from 'react';
21
import styled, { css } from 'styled-components';
32

43
type TextAlignType = 'center' | 'right' | 'left';
@@ -7,6 +6,10 @@ interface HeadProps {
76
children?: React.ReactNode;
87
}
98

9+
interface BodyProps {
10+
children?: React.ReactNode;
11+
}
12+
1013
interface RowProps {
1114
children?: React.ReactNode;
1215
onClick?: () => void;
@@ -47,6 +50,13 @@ function Head({ children }: HeadProps) {
4750
);
4851
}
4952

53+
/**
54+
* Body 컴포넌트는 Ranking 컴포넌트의 자식 컴포넌트로 사용되어야 하고 Row 컴포넌트를 자식 컴포넌트로 가져야 합니다.
55+
*/
56+
function Body({ children }: BodyProps) {
57+
return <tbody>{children}</tbody>;
58+
}
59+
5060
/**
5161
* Row 컴포넌트는 Ranking 컴포넌트의 자식 컴포넌트로 사용되어야 합니다.
5262
*/
@@ -70,18 +80,17 @@ function Element({ children }: ElementProps) {
7080
* Ranking 컴포넌트는 Row와 Element 컴포넌트를 자식 컴포넌트로 가져야합니다.
7181
*/
7282
function RankingTable({ width, columnWidthList, columnAlignList, children }: RankingProps) {
73-
const doms = Children.toArray(children);
7483
return (
7584
<Container width={width} tdWidthList={columnWidthList} tdAlignList={columnAlignList}>
76-
{doms[0]}
77-
<tbody>{doms.slice(1)}</tbody>
85+
{children}
7886
</Container>
7987
);
8088
}
8189

8290
RankingTable.Head = Head;
8391
RankingTable.Row = Row;
8492
RankingTable.Element = Element;
93+
RankingTable.Body = Body;
8594

8695
export default RankingTable;
8796

frontend/src/components/Ranking/RisingRanking/index.tsx

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -32,27 +32,29 @@ function RisingRanking({ searchUser }: RisingRankingProps) {
3232
<RankingTable.Element>{t('common:table-user')}</RankingTable.Element>
3333
<RankingTable.Element>{t('common:table-score')}</RankingTable.Element>
3434
</RankingTable.Head>
35-
{rankingByRising?.map(({ id, tier, username, avatarUrl, scoreDifference }, idx) => (
36-
<RankingTable.Row key={id} onClick={() => searchUser(username)}>
37-
<RankingTable.Element>
38-
<CubeIcon tier={tier} />
39-
</RankingTable.Element>
40-
<RankingTable.Element>{idx + 1}</RankingTable.Element>
41-
<RankingTable.Element>
42-
<Avatar src={avatarUrl} name={username} />
43-
</RankingTable.Element>
44-
<RankingTable.Element>
45-
{scoreDifference > 0 ? (
46-
<Change>
47-
<Image src='/icons/arrow-up.svg' width={16} height={16} alt='down' />
48-
<span>{numberCompactFormatter(scoreDifference)}</span>
49-
</Change>
50-
) : (
51-
<NotChange src='/icons/arrow-bar.svg' width={10} height={10} alt='not change' />
52-
)}
53-
</RankingTable.Element>
54-
</RankingTable.Row>
55-
))}
35+
<RankingTable.Body>
36+
{rankingByRising?.map(({ id, tier, username, avatarUrl, scoreDifference }, idx) => (
37+
<RankingTable.Row key={id} onClick={() => searchUser(username)}>
38+
<RankingTable.Element>
39+
<CubeIcon tier={tier} />
40+
</RankingTable.Element>
41+
<RankingTable.Element>{idx + 1}</RankingTable.Element>
42+
<RankingTable.Element>
43+
<Avatar src={avatarUrl} name={username} />
44+
</RankingTable.Element>
45+
<RankingTable.Element>
46+
{scoreDifference > 0 ? (
47+
<Change>
48+
<Image src='/icons/arrow-up.svg' width={16} height={16} alt='down' />
49+
<span>{numberCompactFormatter(scoreDifference)}</span>
50+
</Change>
51+
) : (
52+
<NotChange src='/icons/arrow-bar.svg' width={10} height={10} alt='not change' />
53+
)}
54+
</RankingTable.Element>
55+
</RankingTable.Row>
56+
))}
57+
</RankingTable.Body>
5658
</RankingTable>
5759
</>
5860
);

frontend/src/components/Ranking/ViewsRanking/index.tsx

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -30,22 +30,24 @@ function ViewsRanking({ searchUser }: ViewsRankingProps) {
3030
<RankingTable.Element>{t('common:table-user')}</RankingTable.Element>
3131
<RankingTable.Element>{t('common:table-views')}</RankingTable.Element>
3232
</RankingTable.Head>
33-
{rankingByViews?.map(({ id, tier, username, avatarUrl, dailyViews }, idx) => (
34-
<RankingTable.Row key={id} onClick={() => searchUser(username)}>
35-
<RankingTable.Element>
36-
<CubeIcon tier={tier} />
37-
</RankingTable.Element>
38-
<RankingTable.Element>
39-
<span>{idx + 1}</span>
40-
</RankingTable.Element>
41-
<RankingTable.Element>
42-
<Avatar src={avatarUrl} name={username} />
43-
</RankingTable.Element>
44-
<RankingTable.Element>
45-
<span>{dailyViews.toLocaleString()}</span>
46-
</RankingTable.Element>
47-
</RankingTable.Row>
48-
))}
33+
<RankingTable.Body>
34+
{rankingByViews?.map(({ id, tier, username, avatarUrl, dailyViews }, idx) => (
35+
<RankingTable.Row key={id} onClick={() => searchUser(username)}>
36+
<RankingTable.Element>
37+
<CubeIcon tier={tier} />
38+
</RankingTable.Element>
39+
<RankingTable.Element>
40+
<span>{idx + 1}</span>
41+
</RankingTable.Element>
42+
<RankingTable.Element>
43+
<Avatar src={avatarUrl} name={username} />
44+
</RankingTable.Element>
45+
<RankingTable.Element>
46+
<span>{dailyViews.toLocaleString()}</span>
47+
</RankingTable.Element>
48+
</RankingTable.Row>
49+
))}
50+
</RankingTable.Body>
4951
</RankingTable>
5052
</>
5153
);

frontend/src/pages/ranking.tsx

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -70,33 +70,35 @@ function Ranking({ tier, username, page }: RankingProps) {
7070
<RankingTable.Element>{t('common:table-score')}</RankingTable.Element>
7171
<RankingTable.Element>{t('common:table-tech-stack')}</RankingTable.Element>
7272
</RankingTable.Head>
73-
{data?.users.map(
74-
({ id, username, avatarUrl, tier: eachTier, score, primaryLanguages, totalRank, tierRank }) => (
75-
<RankingTable.Row key={id} onClick={() => searchUser(username)}>
76-
<RankingTable.Element>
77-
<GrayText>{tier === 'all' ? totalRank : tierRank}</GrayText>
78-
</RankingTable.Element>
79-
<RankingTable.Element>
80-
<Avatar src={avatarUrl} name={username} />
81-
</RankingTable.Element>
82-
<RankingTable.Element>
83-
<CubeIcon tier={eachTier} />
84-
</RankingTable.Element>
85-
<RankingTable.Element>
86-
<GrayText>{score?.toLocaleString()}</GrayText>
87-
</RankingTable.Element>
88-
<RankingTable.Element>
89-
<TechStackList>
90-
{primaryLanguages.map((lang) => (
91-
<li key={lang}>
92-
<LanguageIcon language={lang} width={35} height={35} />
93-
</li>
94-
))}
95-
</TechStackList>
96-
</RankingTable.Element>
97-
</RankingTable.Row>
98-
),
99-
)}
73+
<RankingTable.Body>
74+
{data?.users.map(
75+
({ id, username, avatarUrl, tier: eachTier, score, primaryLanguages, totalRank, tierRank }) => (
76+
<RankingTable.Row key={id} onClick={() => searchUser(username)}>
77+
<RankingTable.Element>
78+
<GrayText>{tier === 'all' ? totalRank : tierRank}</GrayText>
79+
</RankingTable.Element>
80+
<RankingTable.Element>
81+
<Avatar src={avatarUrl} name={username} />
82+
</RankingTable.Element>
83+
<RankingTable.Element>
84+
<CubeIcon tier={eachTier} />
85+
</RankingTable.Element>
86+
<RankingTable.Element>
87+
<GrayText>{score?.toLocaleString()}</GrayText>
88+
</RankingTable.Element>
89+
<RankingTable.Element>
90+
<TechStackList>
91+
{primaryLanguages.map((lang) => (
92+
<li key={lang}>
93+
<LanguageIcon language={lang} width={35} height={35} />
94+
</li>
95+
))}
96+
</TechStackList>
97+
</RankingTable.Element>
98+
</RankingTable.Row>
99+
),
100+
)}
101+
</RankingTable.Body>
100102
</RankingTable>
101103
{isLoading && Array.from({ length: COUNT_PER_PAGE }).map((_, index) => <RankingSkeleton key={index} />)}
102104
{isError && <NotFound />}

0 commit comments

Comments
 (0)