// Adapted from Kibo UI (MIT), with owned React/CSS APIs. See THIRD_PARTY_NOTICES.md. "use client"; import type { ComponentProps } from "react"; export interface Contribution { date: string; count: number; level?: number; } export type ContributionGraphProps = ComponentProps<"div"> & { data: readonly Contribution[]; label?: string; }; export function ContributionGraph({ data, label = "Activity", className = "", ...props }: ContributionGraphProps) { const sorted = [...data].sort((a, b) => a.date.localeCompare(b.date)); const first = sorted[0], last = sorted.at(-1); const start = first ? Date.parse(first.date + "T00:00:00Z") : 0; const end = last ? Date.parse(last.date + "T00:00:00Z") : 0; const count = first ? Math.round((end - start) / 86400000) + 1 : 0; if (!Number.isFinite(count) || count < 0 || count > 3660) throw new Error( "Contribution dates must be ISO dates spanning at most 10 years.", ); const lookup = new Map(data.map((item) => [item.date, item])); const total = data.reduce((sum, item) => sum + Math.max(0, item.count), 0); return (
{total} contributions ยท {label}
{!count ? (No activity yet.
) : ( <>