import type { Metadata } from "next"; import Link from "next/link"; import { GitHubContributeSection } from "@/components/gitHub-contribute-section"; import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; import { Card, CardContent } from "@/components/ui/card"; import { EXTERNAL_TOOLS } from "@/constants/site-constants"; import { BasePage } from "../base-page"; export const metadata: Metadata = { title: "Contributors - OpenCut", description: "Meet the amazing people who contribute to OpenCut, the free and open-source video editor.", openGraph: { title: "Contributors - OpenCut", description: "Meet the amazing people who contribute to OpenCut, the free and open-source video editor.", type: "website", }, }; interface Contributor { id: number; login: string; avatar_url: string; html_url: string; contributions: number; type: string; } async function getContributors(): Promise { try { const response = await fetch( "https://api.github.com/repos/OpenCut-app/OpenCut/contributors?per_page=100", { headers: { Accept: "application/vnd.github.v3+json", "User-Agent": "OpenCut-Web-App", }, next: { revalidate: 600 }, // 10 minutes }, ); if (!response.ok) { console.error("Failed to fetch contributors"); return []; } const contributors = (await response.json()) as Contributor[]; const filteredContributors = contributors.filter( (contributor) => contributor.type === "User", ); return filteredContributors; } catch (error) { console.error("Error fetching contributors:", error); return []; } } export default async function ContributorsPage() { const contributors = await getContributors(); const topContributors = contributors.slice(0, 2); const otherContributors = contributors.slice(2); const totalContributions = contributors.reduce( (sum, c) => sum + c.contributions, 0, ); return (
{topContributors.length > 0 && ( )} {otherContributors.length > 0 && ( )}
); } function StatItem({ value, label }: { value: number; label: string }) { return (
{value} {label}
); } function TopContributorsSection({ contributors, }: { contributors: Contributor[]; }) { return (

Top contributors

Leading the way in contributions

{contributors.map((contributor) => ( ))}
); } function TopContributorCard({ contributor }: { contributor: Contributor }) { return ( {contributor.login.charAt(0).toUpperCase()}

{contributor.login}

{contributor.contributions} contributions
); } function AllContributorsSection({ contributors, }: { contributors: Contributor[]; }) { return (

All contributors

Everyone who makes OpenCut better

{contributors.map((contributor) => (
{contributor.login.charAt(0).toUpperCase()}

{contributor.login}

{contributor.contributions}

))}
); } function ExternalToolsSection() { return (

External tools

Tools we use to build OpenCut

{EXTERNAL_TOOLS.map((tool, index) => (

{tool.name}

{tool.description}

))}
); }