129 lines · 4.7 KB
import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { compareRefs } from "~/fns/git-write";
import { getPullTemplate } from "~/fns/pull-review";
import { useViewer } from "~/hooks/use-viewer";
import { useRepo } from "~/hooks/use-repo";
import { CommitList } from "~/components/CommitList";
import { CreatePullForm } from "~/components/CreatePullForm";
import { DiffView } from "~/components/DiffView";
import { Badge } from "~/ui/Badge";
import { EmptyState } from "~/ui/EmptyState";
import { Panel } from "~/ui/Panel";
import { SelectField } from "~/ui/Field";
import { TextLink } from "~/ui/TextLink";

function parseSplat(splat: string, fallback: string) {
  const [base, head] = splat.includes("...") ? splat.split("...", 2) : [fallback, splat];
  return { base: base || fallback, head: head || fallback };
}

export const Route = createFileRoute("/$owner/$repo/compare/$")({
  loader: async ({ params }) => {
    const { base, head } = parseSplat(params._splat ?? "", "main");
    if (base === head) return { kind: "pick" as const, base, head };
    const [comparison, template] = await Promise.all([
      compareRefs({ data: { owner: params.owner, repo: params.repo, base, head } }),
      getPullTemplate({ data: { owner: params.owner, repo: params.repo, base } }),
    ]);
    return { kind: "compare" as const, ...comparison, template: template.template };
  },
  component: ComparePage,
});

function ComparePicker({ base, head, branches }: { base: string; head: string; branches: string[] }) {
  const navigate = useNavigate();
  const params = Route.useParams();
  const options = branches.map((branch) => ({ value: branch, label: branch }));
  return (
    <div className="flex flex-wrap items-end gap-3">
      <SelectField
        label="Base"