Vectrum
Sign In
48 lines · 2.1 KB · TypeScript
import Link from "next/link";
import { Card } from "@unlocalhosted/metalui";
import { timeAgo } from "@/lib/format";
import { listPath, type RepoList } from "@/lib/lists";
import { BookmarkIcon, ClockIcon, RepoIcon } from "./icons";
import { CardDescription, CardTitle } from "./metal";
import { VisibilityLabel } from "./ui";

export type ListCardItem = RepoList & { repoCount: number };

/** Lists as cards, like RepoList: the title is the one link. */
export function ListCards({ lists, showOwner = false }: { lists: ListCardItem[]; showOwner?: boolean }) {
  return (
    <ul className="grid gap-4 sm:grid-cols-2">
      {lists.map((l) => (
        <li key={l.id} className="flex">
          <Card className="w-full grid-rows-[auto_1fr_auto]">
            <div className="flex items-start gap-3">
              <span className="icon-tile size-10 shrink-0 rounded-[12px]">
                <BookmarkIcon width={18} height={18} />
              </span>
              <div className="min-w-0 flex-1">
                <CardTitle render={<Link href={listPath(l)} />} className="truncate">
                  {showOwner && <span className="font-normal text-ink3">{l.owner.username} / </span>}
                  {l.name}
                </CardTitle>
                <div className="mt-1.5 flex flex-wrap items-center gap-1.5">
                  <VisibilityLabel visibility={l.visibility} />
                </div>
              </div>
            </div>
            <CardDescription className={`mt-1.5 line-clamp-2 ${l.description ? "" : "text-ink3 italic"}`}>{l.description || "No description"}</CardDescription>
            <div className="rule-t mt-2 flex items-center gap-3 pt-2.5 type-readout text-ink3">
              <span className="flex items-center gap-1.5">
                <RepoIcon width={12} height={12} />
                {l.repoCount} {l.repoCount === 1 ? "repository" : "repositories"}
              </span>
              <span className="flex items-center gap-1.5">
                <ClockIcon width={12} height={12} />
                Updated {timeAgo(l.updatedAt)}
              </span>
            </div>
          </Card>
        </li>
      ))}
    </ul>
  );
}