129 lines · 5.0 KB
import { Link } from "@tanstack/react-router";
import { Avatar } from "~/ui/Avatar";
import { Panel } from "~/ui/Panel";
import { cn } from "~/utils/cn";
import type { getRepoInsights } from "~/fns/insights";

type Insights = Awaited<ReturnType<typeof getRepoInsights>>;

const DAYS_PER_WEEK = 7;
const WEEK_MS = DAYS_PER_WEEK * 24 * 60 * 60 * 1000;
const MONTH_FORMAT = new Intl.DateTimeFormat(undefined, { month: "short", timeZone: "UTC" });
const WEEK_FORMAT = new Intl.DateTimeFormat(undefined, { month: "short", day: "numeric", timeZone: "UTC" });

const PULSE_ITEMS = [
  { key: "pullsMerged", label: "Pull requests merged" },
  { key: "pullsOpened", label: "Pull requests opened" },
  { key: "issuesClosed", label: "Issues closed" },
  { key: "issuesOpened", label: "Issues opened" },
  { key: "activeAuthors", label: "Active authors" },
] as const;

export function PulseStats({ pulse }: { pulse: Insights["pulse"] }) {
  return (
    <dl className="grid grid-cols-2 gap-px overflow-hidden rounded-lg border border-kumo-hairline bg-kumo-fill sm:grid-cols-5">
      {PULSE_ITEMS.map((item) => (
        <div key={item.key} className="bg-kumo-canvas p-4 last:col-span-2 sm:last:col-span-1">
          <dt className="text-xs text-kumo-subtle">{item.label}</dt>
          <dd className="mt-1 text-2xl font-semibold text-kumo-strong tabular-nums">{pulse[item.key]}</dd>
        </div>
      ))}
    </dl>
  );
}

function Bars({ values, weekStart, className }: { values: number[]; weekStart: number; className?: string }) {
  const peak = Math.max(1, ...values);
  const total = values.reduce((sum, value) => sum + value, 0);
  return (
    <div className={cn("flex items-end gap-0.5", className)}>
      <span className="sr-only">