import Link from "next/link";
import type { ReactNode } from "react";
import { Field } from "@unlocalhosted/metalui";
import { BookmarkIcon, HeartIcon, PlusIcon, RepoIcon, SearchIcon } from "./icons";
import { FieldIcon, FieldInput } from "./metal";
import { ButtonLink, Counter, Segmented, segmentClass } from "./ui";
export type ProfileTab = "repositories" | "lists" | "likes";
export const profileTab = (value: unknown): ProfileTab => (value === "lists" || value === "likes" ? value : "repositories");
const TABS: Record<ProfileTab, { label: string; icon: ReactNode; find: string }> = {
repositories: { label: "Repositories", icon: <RepoIcon />, find: "Find a repository…" },
lists: { label: "Lists", icon: <BookmarkIcon />, find: "Find a list…" },
likes: { label: "Liked", icon: <HeartIcon />, find: "Find a repository…" },
};
/**
* A profile's main column: its tabs (repositories, lists and, for people, the repositories they
* like) with their counts, the search box, and a New key for what the tab shows.
*/
export function ProfileTabs({
username,
tab,
counts,
q,
newHref,
children,
}: {
username: string;
tab: ProfileTab;
/** Tabs without a count aren't shown. */
counts: Partial<Record<ProfileTab, number>>;
q: string;
newHref?: string | false | null;
children: ReactNode;
}) {
const tabs = (Object.keys(TABS) as ProfileTab[]).filter((t) => counts[t] !== undefined);
return (
<section>
<div className="mb-5 flex flex-wrap items-center gap-3">
<Segmented className="max-w-full overflow-x-auto">
{tabs.map((t) => (
<Link
key={t}
href={t === "repositories" ? `/${username}` : `/${username}?tab=${t}`}
className={segmentClass(t === tab)}
aria-current={t === tab ? "page" : undefined}
>
{TABS[t].icon} {TABS[t].label} <Counter>{counts[t]}</Counter>
</Link>
))}
</Segmented>
<div className="ml-auto flex w-full items-center gap-2 sm:w-auto">
<form role="search" className="flex-1 sm:w-72">
{tab !== "repositories" && <input type="hidden" name="tab" value={tab} />}
<Field size="regular">
<FieldIcon>
<SearchIcon />
</FieldIcon>
<FieldInput name="q" defaultValue={q} placeholder={TABS[tab].find} aria-label={TABS[tab].find.slice(0, -1)} />
</Field>
</form>
{newHref && (
<ButtonLink href={newHref} variant="primary" icon={<PlusIcon />}>
New
</ButtonLink>
)}
</div>
</div>
{children}
</section>
);
}
/** Whether a repository or list matches the profile's search. */
export const matches = (q: string, item: { name: string; description: string }) =>
!q || item.name.toLowerCase().includes(q) || item.description.toLowerCase().includes(q);