Repository Public MIT
1import Link from "next/link";2import type { ArtifactDto } from "@/server/registry";3import { relative } from "@/lib/format";4import { StateBadge, TrustBadges, TypeBadge } from "./badges";56export function ArtifactCard({ a }: { a: ArtifactDto }) {7 return (8 <article className="card card-hover relative flex h-full flex-col p-5">9 <div className="mb-3 flex flex-wrap items-center gap-1.5">10 <TypeBadge type={a.type} />11 <StateBadge state={a.state} reason={a.deprecationReason} />12 <TrustBadges identityVerified={a.publisher.identityVerified} sourceVerified={a.sourceVerified} compact />13 </div>14 <h3 className="font-mono text-[15px] font-medium tracking-tight text-text">15 <Link href={`/@${a.namespace}/${a.slug}`} className="after:absolute after:inset-0 after:rounded-[10px] focus-visible:outline-none focus-visible:after:outline focus-visible:after:outline-2 focus-visible:after:outline-accent">16 <span className="text-muted">@{a.namespace}/</span>17 {a.slug}18 </Link>19 </h3>20 <p className="mt-2 line-clamp-3 flex-1 text-sm text-muted">{a.summary}</p>21 <dl className="mt-4 flex flex-wrap items-center gap-x-4 gap-y-1 border-t border-line pt-3 font-mono text-[11px] text-faint">22 <div className="flex gap-1.5">23 <dt className="sr-only">Latest version</dt>24 <dd>{a.latestVersion ? `v${a.latestVersion}` : "no release"}</dd>25 </div>26 {a.license && (27 <div className="flex gap-1.5">28 <dt className="sr-only">Licence</dt>29 <dd>{a.license}</dd>30 </div>31 )}32 <div className="ml-auto flex gap-1.5">33 <dt className="sr-only">Updated</dt>34 <dd>{relative(a.updatedAt)}</dd>35 </div>36 </dl>37 </article>38 );39}4041export function ArtifactGrid({ items }: { items: ArtifactDto[] }) {42 return (43 <ul className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">44 {items.map((a) => (45 <li key={a.id}>46 <ArtifactCard a={a} />47 </li>48 ))}49 </ul>50 );51}5253export function EmptyState({ title, children }: { title: string; children?: React.ReactNode }) {54 return (55 <div className="card flex flex-col items-center px-6 py-14 text-center">56 <div aria-hidden className="mb-4 grid h-10 w-10 place-items-center rounded-lg border border-line-strong font-mono text-sm text-faint">57 ∅58 </div>59 <p className="text-base font-medium text-text">{title}</p>60 {children && <div className="mt-2 max-w-md text-sm text-muted">{children}</div>}61 </div>62 );63}64