Skip to content

Commit

Permalink
feat: add data from API to contributors page for hacktoberfest (#431)
Browse files Browse the repository at this point in the history
Relates to #404
  • Loading branch information
brandonroberts committed Sep 27, 2022
1 parent 5066562 commit 56e12ea
Show file tree
Hide file tree
Showing 15 changed files with 325 additions and 282 deletions.
156 changes: 75 additions & 81 deletions components/molecules/ContributorTable/contributor-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { IconContext } from "react-icons";
import { FaRegDotCircle, FaRegCheckCircle } from "react-icons/fa";
import { BsFileDiff } from "react-icons/bs";
import { GoDiff } from "react-icons/go";
import { VscGitPullRequest,VscGitPullRequestClosed, VscGitMerge, VscGitPullRequestDraft } from "react-icons/vsc";
import { VscGitPullRequest, VscGitPullRequestClosed, VscGitMerge, VscGitPullRequestDraft } from "react-icons/vsc";
import { useTopicContributorPRs } from "lib/hooks/useTopicContributorPRs";
import { calcDistanceFromToday } from "lib/utils/date-utils";

export interface PRs {
prStatus: string;
Expand All @@ -15,101 +17,93 @@ export interface PRs {
}

interface CardTableProps {
listOfPRs: PRs[];
contributor: string;
}

const ContributorTable = ({ listOfPRs }: CardTableProps) => {
return (
listOfPRs.length > 0 ?
<>
<div className="flex flex-col">
<div className="flex gap-2 items-center bg-light-slate-3 rounded-md px-2 py-1">
<div className="w-3/5">
<Text className="font-medium">
Latest PRs
</Text>
</div>
<IconContext.Provider value={{ color: "gray", style: { width: 14, height: 14 } }}>
<div className="flex justify-end w-[calc(10%-4px)]">
<FaRegDotCircle title="When Pull Request was issued" />
</div>
</IconContext.Provider>
<IconContext.Provider value={{ color: "gray", style: { width: 14, height: 14 } }}>
<div className="flex justify-end w-[calc(10%-4px)]">
<FaRegCheckCircle title="When Pull Request was merged" />
</div>
</IconContext.Provider>
<IconContext.Provider value={{ color: "gray", style: { width: 14, height: 14, strokeWidth: 0.3 } }}>
<div className="flex justify-end w-[calc(10%-4px)]">
<GoDiff title="Files changed in Pull Request" />
</div>
</IconContext.Provider>
<IconContext.Provider value={{ color: "gray", style: { width: 14, height: 14, strokeWidth: 0.5 } }}>
<div className="flex justify-end w-[calc(10%-4px)]">
<BsFileDiff title="Lines changed in Pull Request" />
</div>
</IconContext.Provider>
const ContributorTable = ({ contributor }: CardTableProps) => {
const { data, isLoading } = useTopicContributorPRs(contributor);

return data.length > 0 ? (
<>
<div className="flex flex-col">
<div className="flex gap-2 items-center bg-light-slate-3 rounded-md px-2 py-1">
<div className="w-3/5">
<Text className="font-medium">Latest PRs</Text>
</div>
<div className="flex flex-col gap-0.5">
{listOfPRs.map(({prName, prStatus, prIssuedTime, prClosedTime, noOfFilesChanged, noOfLinesChanged}, index) =>
<IconContext.Provider value={{ color: "gray", style: { width: 14, height: 14 } }}>
<div className="flex justify-end w-[calc(10%-4px)]">
<FaRegDotCircle title="When Pull Request was issued" />
</div>
</IconContext.Provider>
<IconContext.Provider value={{ color: "gray", style: { width: 14, height: 14 } }}>
<div className="flex justify-end w-[calc(10%-4px)]">
<FaRegCheckCircle title="When Pull Request was merged" />
</div>
</IconContext.Provider>
<IconContext.Provider value={{ color: "gray", style: { width: 14, height: 14, strokeWidth: 0.3 } }}>
<div className="flex justify-end w-[calc(10%-4px)]">
<GoDiff title="Files changed in Pull Request" />
</div>
</IconContext.Provider>
<IconContext.Provider value={{ color: "gray", style: { width: 14, height: 14, strokeWidth: 0.5 } }}>
<div className="flex justify-end w-[calc(10%-4px)]">
<BsFileDiff title="Lines changed in Pull Request" />
</div>
</IconContext.Provider>
</div>
<div className="flex flex-col gap-0.5">
{data.map(
(
{
title: prName,
state: prStatus,
merged,
merged_at: prMergedTime,
created_at: prIssuedTime,
filesCount: noOfFilesChanged,
linesCount: noOfLinesChanged
},
index
) => (
<div key={index} className="flex gap-2 items-center px-2 py-1">
<div className="flex item-center gap-2 w-3/5">
{prStatus === "open" ?
{prStatus === "open" ? (
<IconContext.Provider value={{ color: "green", style: { width: 14, height: 14, marginTop: 2 } }}>
<VscGitPullRequest title="Open Pull Request"/>
<VscGitPullRequest title="Open Pull Request" />
</IconContext.Provider>

:

prStatus === "closed" ?
<IconContext.Provider value={{ color: "red", style: { width: 14, height: 14, marginTop: 2 } }}>
<VscGitPullRequestClosed title="Closed Pull Request" />
</IconContext.Provider>

:

prStatus === "merged" ?
<IconContext.Provider value={{ color: "purple", style: { width: 14, height: 14, marginTop: 2 } }}>
<VscGitMerge title="Merged Pull Request" />
</IconContext.Provider>

:

<IconContext.Provider value={{ color: "gray", style: { width: 14, height: 14, marginTop: 2 } }}>
<VscGitPullRequestDraft title="Draft Pull Request" />
</IconContext.Provider>
}
<Text>
{prIssuedTime}
</Text>
<Text className="!text-light-slate-12 !font-medium">
{prName}
</Text>
</div>
<div className="flex justify-end w-[calc(10%-4px)] text-sm text-light-slate-11">
{prIssuedTime}
</div>
<div className="flex justify-end w-[calc(10%-4px)] text-sm text-light-slate-11">
{prClosedTime}
) : prStatus === "closed" ? (
<IconContext.Provider value={{ color: "red", style: { width: 14, height: 14, marginTop: 2 } }}>
<VscGitPullRequestClosed title="Closed Pull Request" />
</IconContext.Provider>
) : merged ? (
<IconContext.Provider value={{ color: "purple", style: { width: 14, height: 14, marginTop: 2 } }}>
<VscGitMerge title="Merged Pull Request" />
</IconContext.Provider>
) : (
<IconContext.Provider value={{ color: "gray", style: { width: 14, height: 14, marginTop: 2 } }}>
<VscGitPullRequestDraft title="Draft Pull Request" />
</IconContext.Provider>
)}
<Text>{calcDistanceFromToday(new Date(parseInt(prIssuedTime, 10)))}</Text>
<Text className="!text-light-slate-12 !font-medium">{prName}</Text>
</div>
<div className="flex justify-end w-[calc(10%-4px)] text-sm text-light-slate-11">
{noOfFilesChanged}
{calcDistanceFromToday(new Date(parseInt(prIssuedTime, 10)))}
</div>
<div className="flex justify-end w-[calc(10%-4px)] text-sm text-light-slate-11">
{noOfLinesChanged}
{merged ? calcDistanceFromToday(new Date(parseInt(prMergedTime, 10))) : "-"}
</div>
<div className="flex justify-end w-[calc(10%-4px)] text-sm text-light-slate-11">{noOfFilesChanged}</div>
<div className="flex justify-end w-[calc(10%-4px)] text-sm text-light-slate-11">{noOfLinesChanged}</div>
</div>
)}
</div>
)
)}
</div>
</>

:

<div className="px-2 py-1">
There are currently no PRs...
</div>
</>
) : (
<div className="px-2 py-1">{isLoading ? "Loading..." : "There are currently no PRs..."}</div>
);
};

export default ContributorTable;
export default ContributorTable;
29 changes: 2 additions & 27 deletions components/molecules/RepoRow/repo-row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,19 @@ import { RepositoriesRows } from "components/organisms/RepositoriesTable/reposit
import Pill from "components/atoms/Pill/pill";
import { useContributionsList } from "lib/hooks/useContributionsList";
import { useRepositoryCommits } from "lib/hooks/useRepositoryCommits";
import differenceInDays from "date-fns/differenceInDays";
import { getCommitsLast30Days } from "lib/utils/get-recent-commits";
import TableRepositoryName from "../TableRepositoryName/table-repository-name";
import Sparkline from "components/atoms/Sparkline/sparkline";
import PullRequestOverview from "../PullRequestOverview/pull-request-overview";
import StackedAvatar from "../StackedAvatar/stacked-avatar";
import { useState } from "react";
import { classNames } from "components/organisms/RepositoriesTable/repositories-table";
import clsx from "clsx";

interface RepoProps {
repo: RepositoriesRows;
}

interface CommitGraphData {
x: number,
y: number;
}

const getActivity = (total?: number, loading?: boolean) => {
if (total === undefined || loading) {
return "-";
Expand All @@ -36,27 +32,6 @@ const getActivity = (total?: number, loading?: boolean) => {
return <Pill icon={<ArrowTrendingDownIcon color="red" className="h-4 w-4" />} text="Low" color="red" />;
};

const getCommitsLast30Days = (commits: DbRepoCommit[]): CommitGraphData[] => {
const commitDays = commits.reduce((days: { [name: string]: number }, curr: DbRepoCommit) => {
const day = differenceInDays(new Date(), new Date(Number(curr.commit_time)));

if (days[day]) {
days[day]++;
} else {
days[day] = 1;
}

return days;
}, {});

const days: any[] = [];
for(let d=30;d>=0;d--) {
days.push({ x: d, y: commitDays[d] || 0 });
}

return days;
};

const getTotalPrs = (openPrsCount?: number, mergedPrsCount?: number, closedPrsCount?: number, draftPrsCount?: number): number => {
const open = openPrsCount || 0;
const merged = mergedPrsCount || 0;
Expand Down
12 changes: 6 additions & 6 deletions components/organisms/ContributorCard/contributor-card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import CardHorizontalBarChart, { LanguageObject } from "components/molecules/Car
import CardLineChart from "components/molecules/CardLineChart/card-line-chart";
import CardProfile from "components/molecules/CardProfile/card-profile";
import CardRepoList, { RepoList } from "components/molecules/CardRepoList/card-repo-list";
import ContributorTable, { PRs } from "components/molecules/ContributorTable/contributor-table";
import ContributorTable from "components/molecules/ContributorTable/contributor-table";
import { useTopicContributorCommits } from "lib/hooks/useTopicContributorCommits";
import { useState } from "react";

/*
Expand All @@ -20,9 +21,7 @@ interface ContributorObject {
dateOfFirstPR: string;
};
repoList: RepoList[];
lineChart: object;
languageList: LanguageObject[];
listOfPRs: PRs[];
}

interface ContributorCardProps {
Expand All @@ -31,8 +30,9 @@ interface ContributorCardProps {
}

const ContributorCard = ({ className, contributor }: ContributorCardProps) => {
const { profile, repoList, lineChart, languageList, listOfPRs } = contributor;
const { profile, repoList, languageList } = contributor;
const [ showPRs, setShowPRs ] = useState(false);
const { chart } = useTopicContributorCommits(profile.githubName);

return (
<Card className={className}>
Expand All @@ -44,11 +44,11 @@ const ContributorCard = ({ className, contributor }: ContributorCardProps) => {
</div>
</div>
<div className="h-[110px] overflow-hidden">
<CardLineChart lineChartOption={lineChart} />
<CardLineChart lineChartOption={chart} />
</div>
<CardRepoList repoList={repoList} />
{showPRs ? (
<ContributorTable listOfPRs={listOfPRs} />
<ContributorTable contributor={profile.githubName} />
) : null}
<div className="flex w-full justify-center">
<button
Expand Down
74 changes: 39 additions & 35 deletions components/organisms/Contributors/contributors.tsx
Original file line number Diff line number Diff line change
@@ -1,53 +1,57 @@
import { useContributionsList } from "lib/hooks/useContributionsList";
import useContributorData from "lib/hooks/useContributorData";
import { calcMonthsFromToday } from "lib/utils/date-utils";
import { calcDistanceFromToday } from "lib/utils/date-utils";
import ContributorCard from "../ContributorCard/contributor-card";
import color from "lib/utils/color.json";
import { useTopicContributions } from "lib/hooks/useTopicContributions";

const Contributors = (): JSX.Element =>{
const colorKeys = Object.keys(color);

const Contributors = (): JSX.Element => {
const contributorData = useContributorData();
const { data, isError, isLoading } = useContributionsList("769");
const { data, isError, isLoading } = useTopicContributions();

const freeCodeCamp = "freecodecamp";

const contributorArray = isError ? [] : data?.map(contributor => {
const timeSinceFirstCommit = calcMonthsFromToday(new Date(parseInt(contributor.first_commit_time)));
const contributorLanguageList = contributor.langs.split(",");
const contributorArray = isError
? []
: data?.map((contributor) => {
const timeSinceFirstCommit = calcDistanceFromToday(new Date(parseInt(contributor.first_commit_time)));
const contributorLanguageList = (contributor.langs || "").split(",");
const repoList = (contributor.recent_repo_list || "").split(",").map((repo) => {
const [repoOwner, repoName] = repo.split("/");

return {
...contributorData,
profile: {
...contributorData.profile,
githubAvatar: `https://www.github.com/${contributor.host_login}.png?size=60`,
githubName: contributor.host_login,
dateOfFirstPR: `${timeSinceFirstCommit}${timeSinceFirstCommit !== 1 ? "mos" : "mo"}`
},
languageList: contributorLanguageList.map(language => {
const preparedLanguageKey = Object.keys(color).find(key => key.toLowerCase() === language.toLowerCase());
return {
repoName,
repoIcon: `https://www.github.com/${repoOwner ?? "github"}.png?size=460`
};
});
const languageList = contributorLanguageList.map((language) => {
const preparedLanguageKey = colorKeys.find((key) => key.toLowerCase() === language.toLowerCase());

return {
languageName: preparedLanguageKey ? preparedLanguageKey : language,
percentageUsed: Math.round( ( 1 / contributorLanguageList.length ) * 100)
percentageUsed: Math.round((1 / contributorLanguageList.length) * 100)
};
}),
repoList: [
{
repoName: freeCodeCamp,
repoIcon: `https://www.github.com/${freeCodeCamp ?? "github"}.png?size=460`
}
]
};
});
});

return {
...contributorData,
profile: {
...contributorData.profile,
githubAvatar: `https://www.github.com/${contributor.host_login}.png?size=60`,
githubName: contributor.host_login,
dateOfFirstPR: timeSinceFirstCommit
},
languageList,
repoList
};
});

return (
<div className="w-full grid grid-cols-automobile md:grid-cols-autodesktop gap-3">
{isLoading ? "Loading..." : ""}
{
contributorArray.map((contributor, index) => (
<ContributorCard key={index} className="" contributor={{ ...contributor }} />
))
}
{contributorArray.map((contributor, index) => (
<ContributorCard key={index} className="" contributor={{ ...contributor }} />
))}
</div>
);
};
export default Contributors;
export default Contributors;
4 changes: 4 additions & 0 deletions interfaces/commit-graph.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface CommitGraphData {
x: number,
y: number;
}
Loading

0 comments on commit 56e12ea

Please sign in to comment.