Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Website: Add a toggle feature to sort open-source contributors #1006

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ui/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,6 @@ export * from './components/separator';
export * from './components/switch';
export * from './components/table';
export * from './components/tabs';
export * from './components/toggle-group';
export * from './components/tooltip';
export * from './components/typography';
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
'use client';

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

type ContributorProp = {
Expand All @@ -9,6 +17,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 +44,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 +77,15 @@ export function OpenSourceContributorsClient({
</Typography>
</section>

<section className="mb-10 flex">
<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,7 +8,7 @@ interface GitHubCommit {
id: number;
login: string;
avatar_url: string;
} | null;
};
commit: {
author: {
date: string;
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);
}
activus-d marked this conversation as resolved.
Show resolved Hide resolved

// 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,
};
activus-d marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ interface IssueProps extends Pick<Issue, 'title' | 'url'> {
export function Issue({ title, url, text }: IssueProps) {
return (
<TableRow className="p-5 hover:bg-transparent">
<TableCell className="text-xl">{title}</TableCell>
<TableCell className="max-w-80 text-xl">{title}</TableCell>
<TableCell className="text-right text-xl">
<Button asChild variant="link" className="hover:underline">
<Link href={url} target="_blank" rel="noopener noreferrer">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export function IssueClient({ title, issues, labels, tableHeader, filterText, li
<TableHeader>
<TableRow className="border-foreground p-5 hover:bg-transparent">
<TableCell className="text-xl">{tableHeader}</TableCell>
<TableCell className="text-xl"></TableCell>
</TableRow>
</TableHeader>
<TableBody>
Expand Down
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';

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
Loading