Vectrum
Sign In
44 lines · 2.0 KB · TypeScript
import { syncForkAction } from "@/app/actions/forks";
import type { ForkStatus } from "@/lib/forks";
import { ActionButton } from "./action-button";
import { ForkIcon, PullRequestIcon } from "./icons";
import { Box, ButtonLink, RefChip } from "./ui";

const commits = (n: number) => `${n} commit${n === 1 ? "" : "s"}`;

/** On a fork's front page: how its default branch compares with the original's, with Sync and Contribute. */
export function ForkStatusBar({ fork, status, canWrite }: { fork: { owner: string; name: string }; status: ForkStatus; canWrite: boolean }) {
  const upstream = `${status.upstream.owner}/${status.upstream.name}`;
  const compare = `/${upstream}/compare?${new URLSearchParams({ base: status.upstreamBranch, head_repo: `${fork.owner}/${fork.name}`, head: status.branch })}`;
  const where = <RefChip>{`${upstream}:${status.upstreamBranch}`}</RefChip>;
  return (
    <Box className="mb-4 flex flex-wrap items-center gap-x-3 gap-y-2 px-4 py-3">
      <ForkIcon width={15} height={15} className="text-ink3" />
      <span className="flex flex-wrap items-center gap-1.5 type-ui text-ink2">
        {status.ahead === 0 && status.behind === 0 ? (
          <>This branch is up to date with {where}.</>
        ) : (
          <>
            This branch is
            {status.ahead > 0 && <strong className="font-medium text-ink">{commits(status.ahead)} ahead of</strong>}
            {status.ahead > 0 && status.behind > 0 && "and"}
            {status.behind > 0 && <strong className="font-medium text-ink">{commits(status.behind)} behind</strong>}
            {where}.
          </>
        )}
      </span>
      <div className="ml-auto flex flex-wrap gap-2">
        {status.ahead > 0 && (
          <ButtonLink href={compare} icon={<PullRequestIcon />}>
            Contribute
          </ButtonLink>
        )}
        {canWrite && status.behind > 0 && (
          <ActionButton action={syncForkAction.bind(null, fork.owner, fork.name)} icon={<ForkIcon />}>
            Sync Fork
          </ActionButton>
        )}
      </div>
    </Box>
  );
}