"use client"; import { useMemo } from "react"; import * as HeatGraph from "heat-graph"; import type { ActivityPoint } from "@/lib/traction"; const COMMIT_COLORS = [ "color-mix(in oklab, var(--color-muted-foreground) 14%, transparent)", "color-mix(in oklab, var(--color-chart-1) 30%, transparent)", "color-mix(in oklab, var(--color-chart-1) 55%, transparent)", "color-mix(in oklab, var(--color-chart-1) 80%, transparent)", "var(--color-chart-1)", ]; const RELEASE_RING = "inset 0 0 0 1.5px var(--color-chart-2)"; const formatDate = (date: Date) => date.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric", }); const localDateKey = (d: Date): string => { const y = d.getFullYear(); const m = String(d.getMonth() + 1).padStart(2, "0"); const day = String(d.getDate()).padStart(2, "0"); return `${y}-${m}-${day}`; }; export function ActivityHeatmap({ commits, releases, }: { commits: ActivityPoint[]; releases: ActivityPoint[]; }) { const releaseDays = useMemo(() => { const set = new Set(); for (const r of releases) { if (r.count > 0) set.add(r.date); } return set; }, [releases]); if (commits.length === 0 && releases.length === 0) { return (
Activity is currently unavailable.
); } return (
{({ label, totalWeeks }) => ( {HeatGraph.MONTH_SHORT[label.month]} )}
{({ label }) => ( {label.row % 2 === 1 ? ( {HeatGraph.DAY_SHORT[label.dayOfWeek]?.charAt(0)} ) : null} )}
{({ cell }) => { const released = releaseDays.has(localDateKey(cell.date)); return ( ); }}
Less {() => ( )} More
Released
{({ cell }) => { const released = releaseDays.has(localDateKey(cell.date)); const headline = cell.count > 0 ? `${cell.count} ${cell.count === 1 ? "commit" : "commits"}` : released ? "Released" : "No commits"; return ( <> {headline} {released && cell.count > 0 ? ( {" · released"} ) : null} {" — "} {formatDate(cell.date)} ); }}
); }