"use client"; import { useMemo } from "react"; import { useGitHubStats } from "@/hooks/useGitHubStats"; import { OpenSourceCard } from "@/components/OpenSourceCard"; import { MaintainedProject, OpenSourceContribution, HostedService, } from "@/lib/types"; import ExternalLink from "@/components/ExternalLink"; import { SiGithub } from "react-icons/si"; import { ArrowUpRight } from "lucide-react"; interface OpenSourceContentProps { projects: MaintainedProject[]; contributions: OpenSourceContribution[]; services: HostedService[]; } export function OpenSourceContent({ projects, contributions, services, }: OpenSourceContentProps) { // Collect all GitHub repos for stats fetching const allRepos = useMemo(() => { const repos: string[] = []; projects.forEach((p) => repos.push(p.repo)); contributions.forEach((c) => repos.push(c.repo)); services.filter((s) => s.repo).forEach((s) => repos.push(s.repo!)); return [...new Set(repos)]; // Deduplicate }, [projects, contributions, services]); const { stats, loading } = useGitHubStats(allRepos); // Sort projects: featured first, then by stars const sortedProjects = useMemo(() => { return [...projects].sort((a, b) => { if (a.featured && !b.featured) return -1; if (!a.featured && b.featured) return 1; const starsA = stats[a.repo]?.stars || 0; const starsB = stats[b.repo]?.stars || 0; return starsB - starsA; }); }, [projects, stats]); return (
I believe in open source software. Here are the projects I maintain, my contributions to others, and the services I host.
Projects I actively maintain and develop.
Open source projects I've contributed to.
{contribution.description}
)}Live services and applications I host and maintain.
{service.description}