"use client";
import Link from "next/link";
import { usePathname } from "next/navigation";
import { useState } from "react";
import { BranchIcon, CodeIcon, GearIcon, HistoryIcon, IssueOpenedIcon } from "./icons";
import { SlidingIndicator, thumbClass } from "./sliding-indicator";
/**
* A repository's sections on the switcher track: they are pages, so they are links (not MetalUI Tabs),
* with the switcher's raised thumb gliding under the current one.
*/
export function RepoTabs({ base, openIssues, showSettings }: { base: string; openIssues: number; showSettings: boolean }) {
const pathname = usePathname();
const section = pathname.slice(base.length).split("/")[1] ?? "";
const tabs = [
{ href: base, label: "Code", icon: CodeIcon, active: !["issues", "branches", "commits", "commit", "settings"].includes(section) },
{ href: `${base}/issues`, label: "Issues", icon: IssueOpenedIcon, count: openIssues, active: section === "issues" },
{ href: `${base}/commits`, label: "Commits", icon: HistoryIcon, active: section === "commits" || section === "commit" },
{ href: `${base}/branches`, label: "Branches", icon: BranchIcon, active: section === "branches" },
...(showSettings ? [{ href: `${base}/settings`, label: "Settings", icon: GearIcon, active: section === "settings" }] : []),
];
// Move the thumb as soon as a tab is clicked instead of waiting for the next page;
// the optimistic choice is dropped once the URL changes.
const [clicked, setClicked] = useState<{ from: string; index: number } | null>(null);
const activeIndex = clicked?.from === pathname ? clicked.index : tabs.findIndex((t) => t.active);
return (
<div className="-mx-1 overflow-x-auto px-1 py-1">
<nav aria-label="Repository" className="relative inline-flex items-center gap-0.5 rounded-pill recipe-well-track p-[3px]">
<SlidingIndicator className={thumbClass} />
{tabs.map((t, i) => {
const active = i === activeIndex;
return (
<Link
key={t.label}
href={t.href}
aria-current={active ? "page" : undefined}
onClick={() => setClicked({ from: pathname, index: i })}
className={`mu-icon-trigger relative z-1 flex h-7 shrink-0 items-center gap-1.5 rounded-pill px-3 type-ui outline-none transition-colors duration-150 focus-visible:focus-ring ${
active ? "text-ink" : "text-ink2 hover:text-ink"
}`}
>
<t.icon width={14} height={14} />
{t.label}
{t.count ? <span className="type-readout text-ink3">{t.count}</span> : null}
</Link>
);
})}
</nav>
</div>
);
}