Skip to content

Commit

Permalink
Add a toggle feature to the 'contributors' section to allow visitors …
Browse files Browse the repository at this point in the history
…to sort the list of contributors by the number of commits or the lastest commits
  • Loading branch information
activus-d committed Jan 10, 2025
1 parent 55b7607 commit 92c7c0d
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 9 deletions.
1 change: 1 addition & 0 deletions ui/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ export * from './components/table';
export * from './components/tabs';
export * from './components/tooltip';
export * from './components/typography';
export * from './components/toggle-group';
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
'use client';

import { Avatar, AvatarFallback, AvatarImage, Button, Typography } from '@socialincome/ui';
import { ToggleGroup, ToggleGroupItem } from '@socialincome/ui';
import { useState } from 'react';

type ContributorProp = {
Expand All @@ -9,6 +10,13 @@ type ContributorProp = {
avatarUrl: string;
};

interface Contributor {
id: number;
name: string;
avatarUrl: string;
commits: number;
}

function Contributor({ name, commits, avatarUrl }: ContributorProp) {
return (
<article className="flex min-w-60 flex-row items-center py-2">
Expand All @@ -29,18 +37,31 @@ function Contributor({ name, commits, avatarUrl }: ContributorProp) {
}

export function OpenSourceContributorsClient({
contributors,
contributorsByCommitCount,
contributorsByLatestCommit,
heading,
totalContributors,
}: {
contributors: Array<{ name: string; commits: number; avatarUrl: string; id: number }>;
contributorsByCommitCount: Contributor[];
contributorsByLatestCommit: Contributor[];
heading: string;
totalContributors: number;
}) {
const [showAllContributors, setShowAllContributors] = useState(false);
const [selectedToggle, setSelectedToggle] = useState("commit count");
const [contributors, setContributors] = useState(contributorsByCommitCount);

const displayedContributors = showAllContributors ? contributors : contributors.slice(0, 16);

const handleToggleChange = (value: string) => {
setSelectedToggle(value);
if (value === "latest commit") {
setContributors(contributorsByLatestCommit);
} else {
setContributors(contributorsByCommitCount);
}
};

return (
<section className="flex flex-col justify-self-start">
<section>
Expand All @@ -49,8 +70,15 @@ export function OpenSourceContributorsClient({
</Typography>
</section>

<section className="flex mb-10">
<ToggleGroup type="single" value={selectedToggle} onValueChange={handleToggleChange}>
<ToggleGroupItem value="commit count">Commit Count</ToggleGroupItem>
<ToggleGroupItem value="latest commit">Latest Commit</ToggleGroupItem>
</ToggleGroup>
</section>

<section className="flex flex-wrap gap-4">
{displayedContributors.map((contributor) => (
{displayedContributors.map((contributor: Contributor) => (
<Contributor
key={contributor.id}
name={contributor.name}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ interface GitHubCommit {
id: number;
login: string;
avatar_url: string;
} | null;
};
commit: {
author: {
date: string;
};
};
}
};

export async function getCommits() {
// Calculate the date 30 days ago from today
Expand All @@ -34,7 +34,6 @@ export async function getCommits() {

// Extract the last page number from the Link header to get the total commit count
const linkHeader = totalCommitsRes.headers.get('link');
// Default to 1 in case no Link header is provided
let totalCommits = 1;

if (linkHeader) {
Expand All @@ -48,8 +47,20 @@ export async function getCommits() {
console.warn('No Link header found; assuming a single commit.');
}

// Fetch total commit data
let totalCommitsData: GitHubCommit[] = [];
for (let page = 1; page <= Math.ceil(totalCommits / 100); page++) {
const pagedUrl = `https://api.github.com/repos/${owner}/${repo}/commits?per_page=100&page=${page}`;
const pagedRes = await fetchData(owner, repo, pagedUrl);
const pagedData: GitHubCommit[] = await pagedRes.json();
totalCommitsData = totalCommitsData.concat(pagedData);
}

// return the total number of commits,
// the total number of commits made in the last 30 days, and the total commit data
return {
totalCommits,
newCommits: recentCommits.length,
totalCommitsData,
};
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,34 @@
import { DefaultParams } from '@/app/[lang]/[region]';
import { Translator } from '@socialincome/shared/src/utils/i18n';
import { OpenSourceContributorsClient } from '../(components)/contributors-client';
import { getCommits } from '../(components)/get-commits';
import { getContributors } from '../(components)/get-contributors';
import { OpenSourceContributorsClient } from '../(components)/contributors-client';

type Metadata = {
heading: string;
};

interface GitHubCommit {
author: {
id: number;
login: string;
avatar_url: string;
};
commit: {
author: {
date: string;
};
};
}

interface CombinedContributor {
id: number;
name: string;
avatarUrl: string;
commits: number;
latestCommitDate: Date;
}

export async function OpenSourceContributors({ lang }: DefaultParams) {
const translator = await Translator.getInstance({
language: lang,
Expand All @@ -17,10 +39,49 @@ export async function OpenSourceContributors({ lang }: DefaultParams) {
const heading = metadata.heading;

const contributors = await getContributors();
const totalContributors = contributors.length;
const { totalCommitsData } = await getCommits();

// Collect the latest commit date for each contributor
const latestCommitDates = new Map<number, Date>();
totalCommitsData.forEach((commit: GitHubCommit) => {
if (commit.author?.id && commit.commit?.author?.date) {
const contributorId = commit.author.id;
const commitDate = new Date(commit.commit.author.date);
const existingDate = latestCommitDates.get(contributorId);
if (!existingDate || commitDate > existingDate) {
latestCommitDates.set(contributorId, commitDate);
}
}
});

// Combine contributors' data with their latest commit dates
const combinedContributors = contributors
.filter((contributor) => latestCommitDates.has(contributor.id))
.map((contributor) => ({
id: contributor.id,
name: contributor.name,
avatarUrl: contributor.avatarUrl,
commits: contributor.commits,
latestCommitDate: latestCommitDates.get(contributor.id) || new Date(0),
}));

const totalContributors = combinedContributors.length;

const contributorsByCommitCount = [...combinedContributors].sort(
(a: CombinedContributor, b: CombinedContributor) => b.commits - a.commits
);

const contributorsByLatestCommit = [...combinedContributors].sort(
(a: CombinedContributor, b: CombinedContributor) => b.latestCommitDate.getTime() - a.latestCommitDate.getTime()
);

return (
<OpenSourceContributorsClient contributors={contributors} heading={heading} totalContributors={totalContributors} />
<OpenSourceContributorsClient
contributorsByCommitCount={contributorsByCommitCount}
contributorsByLatestCommit={contributorsByLatestCommit}
heading={heading}
totalContributors={totalContributors}
/>
);
}

Expand Down

0 comments on commit 92c7c0d

Please sign in to comment.