Skip to content

Commit 2e274bd

Browse files
authored
feat: add custom sorting (#117)
* feat: add filter for state of PR * feat: handle issue (Add custom sorting #60)
1 parent c5596a3 commit 2e274bd

File tree

7 files changed

+197
-73
lines changed

7 files changed

+197
-73
lines changed

src/components/ReposFilters.tsx

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
import { FC } from "react";
2-
import { PullRequestState, RepositoryRenderFormat } from "@/types/github";
2+
import {
3+
PullRequestState,
4+
RepositoryOrder,
5+
RepositoryRenderFormat,
6+
} from "@/types/github";
37

48
type ReposFiltersProps = {
59
searchQuery: string;
610
setSearchQuery: React.Dispatch<React.SetStateAction<string>>;
711
pullRequestState: PullRequestState;
812
setpullRequestState: React.Dispatch<React.SetStateAction<PullRequestState>>;
13+
repositoriesOrder: RepositoryOrder;
14+
setRepositoriesOrder: React.Dispatch<React.SetStateAction<RepositoryOrder>>;
915
baseYear: number;
1016
year: number;
1117
setYear: React.Dispatch<React.SetStateAction<number>>;
@@ -20,6 +26,8 @@ export const ReposFilters: FC<ReposFiltersProps> = ({
2026
setSearchQuery,
2127
pullRequestState,
2228
setpullRequestState,
29+
repositoriesOrder,
30+
setRepositoriesOrder,
2331
baseYear,
2432
year,
2533
setYear,
@@ -47,6 +55,10 @@ export const ReposFilters: FC<ReposFiltersProps> = ({
4755
setpullRequestState(selectedState);
4856
};
4957

58+
const handleRepositoriesOrderChange = (selectedOrder: RepositoryOrder) => {
59+
setRepositoriesOrder(selectedOrder);
60+
};
61+
5062
return (
5163
<div className="flex justify-between sm:gap-0 sm:flex-row flex-col gap-3">
5264
<div className="sm:text-left text-center">
@@ -78,7 +90,7 @@ export const ReposFilters: FC<ReposFiltersProps> = ({
7890
onChange={(e) => setSearchQuery(e.target.value)}
7991
/>
8092
</div>
81-
<div className="my-5 flex flex-col sm:items-start items-center">
93+
<div className="my-5 mr-2 flex flex-col sm:items-start items-center">
8294
<label className="mb-2">State of PR</label>
8395
<select
8496
className="select select-bordered w-full max-w-md"
@@ -93,6 +105,23 @@ export const ReposFilters: FC<ReposFiltersProps> = ({
93105
<option value="CLOSED">Closed</option>
94106
</select>
95107
</div>
108+
<div className="my-5 flex flex-col sm:items-start items-center">
109+
<label className="mb-2">Order by</label>
110+
<select
111+
className="select select-bordered w-full max-w-md"
112+
value={repositoriesOrder}
113+
onChange={(e) =>
114+
handleRepositoriesOrderChange(e.target.value as RepositoryOrder)
115+
}
116+
>
117+
<option value="OWNER">Owner</option>
118+
<option value="REPOSITORY">Repository</option>
119+
<option value="PRASCENDING">N° PR Ascending</option>
120+
<option value="PRDESCENDING" selected>
121+
N° PR Descending
122+
</option>
123+
</select>
124+
</div>
96125
</div>
97126

98127
<div className="flex sm:items-start items-center justify-center md:justify-start">

src/hooks/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
export * from "./useGitHubPullRequests";
22
export * from "./useGitHubQuery";
3-
export * from "./useFilteredRepositories";
3+
export * from "./useHandleStateRepositories";

src/hooks/useFilteredRepositories.ts

Lines changed: 0 additions & 66 deletions
This file was deleted.
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
import { useMemo } from "react";
2+
import { useSession } from "next-auth/react";
3+
import {
4+
PullRequestContributionsByRepository,
5+
PullRequestState,
6+
RepositoryOrder,
7+
} from "@/types/github";
8+
import { compareArrayString } from "@/utils/compare";
9+
10+
export const useHandleStateRepositories = (
11+
repositories: PullRequestContributionsByRepository[],
12+
searchQuery: string,
13+
hideOwnRepo: boolean,
14+
pullRequestState: PullRequestState,
15+
orderState: RepositoryOrder
16+
) => {
17+
const { data: session } = useSession();
18+
19+
const filteredRepositories = useMemo(() => {
20+
//Filter section
21+
const filterOutOwnRepos = (
22+
repos: PullRequestContributionsByRepository[]
23+
) => {
24+
return repos?.filter(
25+
(repoData) => repoData.repository.owner.login !== session?.user.login
26+
);
27+
};
28+
const filterReposBySearchQuery = (
29+
repos: PullRequestContributionsByRepository[]
30+
) => {
31+
const query = searchQuery.toLowerCase();
32+
return repos?.filter((repoData) =>
33+
repoData.repository.name.toLowerCase().includes(query)
34+
);
35+
};
36+
const filterReposByPullRequestState = (
37+
repos: PullRequestContributionsByRepository[]
38+
) => {
39+
return repos?.filter((repoData) =>
40+
repoData.contributions.nodes.some(
41+
(contribution) => contribution.pullRequest.state === pullRequestState
42+
)
43+
);
44+
};
45+
46+
const filterRepos = (repos: PullRequestContributionsByRepository[]) => {
47+
let filteredRepos = repos;
48+
if (!searchQuery) {
49+
filteredRepos = hideOwnRepo ? filterOutOwnRepos(repos) : repos;
50+
} else {
51+
const filteredReposBySearchQuery = filterReposBySearchQuery(repos);
52+
filteredRepos = hideOwnRepo
53+
? filterOutOwnRepos(filteredReposBySearchQuery)
54+
: filteredReposBySearchQuery;
55+
}
56+
57+
filteredRepos = pullRequestState
58+
? filterReposByPullRequestState(filteredRepos)
59+
: filteredRepos;
60+
61+
return filteredRepos;
62+
};
63+
/** */
64+
65+
//Order section
66+
const orderRepoByOwner = (
67+
repos: PullRequestContributionsByRepository[]
68+
) => {
69+
return [...repos].sort((a, b) =>
70+
compareArrayString(a.repository.owner.login, b.repository.owner.login)
71+
);
72+
};
73+
const orderRepoByName = (repos: PullRequestContributionsByRepository[]) => {
74+
return [...repos].sort((a, b) =>
75+
compareArrayString(a.repository.name, b.repository.name)
76+
);
77+
};
78+
const orderRepoByCountAscending = (
79+
repos: PullRequestContributionsByRepository[]
80+
) => {
81+
return [...repos].sort(
82+
(a, b) => a.contributions.totalCount - b.contributions.totalCount
83+
);
84+
};
85+
const orderRepoByCountDescending = (
86+
repos: PullRequestContributionsByRepository[]
87+
) => {
88+
return [...repos].sort(
89+
(a, b) => b.contributions.totalCount - a.contributions.totalCount
90+
);
91+
};
92+
93+
const orderRepos = (repos: PullRequestContributionsByRepository[]) => {
94+
let orderedRepos = repos;
95+
if (orderState === "OWNER") {
96+
orderedRepos =
97+
orderedRepos !== undefined ? orderRepoByOwner(repos) : orderedRepos;
98+
} else if (orderState === "REPOSITORY") {
99+
orderedRepos =
100+
orderedRepos !== undefined ? orderRepoByName(repos) : orderedRepos;
101+
} else if (orderState === "PRASCENDING") {
102+
orderedRepos =
103+
orderedRepos !== undefined
104+
? orderRepoByCountAscending(repos)
105+
: orderedRepos;
106+
} else if (orderState === "PRDESCENDING") {
107+
orderedRepos =
108+
orderedRepos !== undefined
109+
? orderRepoByCountDescending(repos)
110+
: orderedRepos;
111+
}
112+
113+
return orderedRepos;
114+
};
115+
/** */
116+
117+
const filterAndOrderRepos = (
118+
repos: PullRequestContributionsByRepository[]
119+
) => {
120+
return orderRepos(filterRepos(repos));
121+
};
122+
123+
return filterAndOrderRepos(repositories);
124+
}, [
125+
repositories,
126+
searchQuery,
127+
hideOwnRepo,
128+
pullRequestState,
129+
orderState,
130+
session,
131+
]);
132+
133+
return filteredRepositories;
134+
};

src/pages/stats/[login].tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
import { useState } from "react";
22
import { useSession } from "next-auth/react";
33
import { useRouter } from "next/router";
4-
import { useGitHubPullRequests, useFilteredRepositories } from "@/hooks";
4+
import { useGitHubPullRequests, useHandleStateRepositories } from "@/hooks";
55
import { CardSkeleton, FormatStatsRender, ReposFilters } from "@/components";
6-
import { PullRequestState, RepositoryRenderFormat } from "@/types/github";
6+
import {
7+
PullRequestState,
8+
RepositoryOrder,
9+
RepositoryRenderFormat,
10+
} from "@/types/github";
711

812
export default function Stats() {
913
const { data: session } = useSession();
@@ -16,18 +20,22 @@ export default function Stats() {
1620
const [pullRequestState, setpullRequestState] = useState<PullRequestState>(
1721
null!
1822
);
23+
const [repositoriesOrder, setRepositoriesOrder] = useState<RepositoryOrder>(
24+
null!
25+
);
1926
const [hideOwnRepo, setHideOwnRepo] = useState<boolean>(false);
2027

2128
const { repositories, isLoading } = useGitHubPullRequests(
2229
year,
2330
login as string
2431
);
2532

26-
const filteredRepositories = useFilteredRepositories(
33+
const filteredRepositories = useHandleStateRepositories(
2734
repositories,
2835
searchQuery,
2936
hideOwnRepo,
30-
pullRequestState
37+
pullRequestState,
38+
repositoriesOrder
3139
);
3240

3341
return (
@@ -42,6 +50,8 @@ export default function Stats() {
4250
<ReposFilters
4351
pullRequestState={pullRequestState!}
4452
setpullRequestState={setpullRequestState}
53+
repositoriesOrder={repositoriesOrder}
54+
setRepositoriesOrder={setRepositoriesOrder}
4555
searchQuery={searchQuery}
4656
setSearchQuery={setSearchQuery}
4757
baseYear={baseYear}

src/types/github.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,5 +43,10 @@ export type User = {
4343
};
4444
};
4545

46+
export type RepositoryOrder =
47+
| "OWNER"
48+
| "REPOSITORY"
49+
| "PRASCENDING"
50+
| "PRDESCENDING";
4651
export type RepositoryRenderFormat = "cards" | "text" | "json";
4752
export type PullRequestState = "MERGED" | "CLOSED" | "OPEN";

src/utils/compare.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export const compareArrayString = (
2+
itemNumberOne: string,
3+
itemNumberTwo: string
4+
) => {
5+
if (itemNumberOne < itemNumberTwo) {
6+
return -1;
7+
}
8+
if (itemNumberOne > itemNumberTwo) {
9+
return 1;
10+
}
11+
return 0;
12+
};

0 commit comments

Comments
 (0)