72 lines · 2.6 KB
import { createFileRoute, Link } from "@tanstack/react-router";
import { z } from "zod";
import { getRepoInsights } from "~/fns/insights";
import { CommitActivity, Contributors, PulseStats } from "~/components/insights/InsightsCharts";
import { usePollWhile } from "~/hooks/use-poll-while";
import { Callout } from "~/ui/Callout";
import { Heading } from "~/ui/Heading";
import { cn } from "~/utils/cn";

const INDEXING_POLL_MS = 3000;

const PERIOD_OPTIONS = [
  { value: "week", label: "Past week" },
  { value: "month", label: "Past month" },
] as const;

export const Route = createFileRoute("/$owner/$repo/insights")({
  validateSearch: z.object({ period: z.enum(["week", "month"]).optional() }),
  loaderDeps: ({ search }) => search,
  loader: ({ params, deps }) =>
    getRepoInsights({ data: { owner: params.owner, repo: params.repo, period: deps.period ?? "week" } }),
  head: ({ params }) => ({ meta: [{ title: `Insights · ${params.owner}/${params.repo}` }] }),
  component: InsightsPage,
});

function InsightsPage() {
  const insights = Route.useLoaderData();
  const params = Route.useParams();
  usePollWhile(insights.status === "indexing", INDEXING_POLL_MS);

  return (
    <div className="space-y-5">
      <div className="flex flex-wrap items-center gap-3">
        <Heading level={2} size="md">
          Pulse
        </Heading>
        <div className="ml-auto flex gap-1 rounded-md border border-kumo-hairline p-0.5 text-xs">
          {PERIOD_OPTIONS.map((option) => (
            <Link
              key={option.value}