import type { ReactNode } from "react"; import { AuthorAvatar } from "./author-link"; import { InstallCount } from "./install-count"; import { pluginCardScreenshot } from "./thumbnails"; import { pluginHref } from "./links"; import { PluginTile } from "./plugin-tile"; import { firstMediaImage, getAuthor, getCategory, type Plugin } from "./registry"; export const PLUGIN_GRID_CLASS = "grid gap-x-4 gap-y-8 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4"; /** First allowed image, or the plugin tile on a quiet backdrop when there is none. */ function PluginShot({ plugin }: { plugin: Plugin }) { const url = firstMediaImage(plugin); return (
{url ? ( ) : (
)}
); } /** * What's new and Featured card, in three rows under the screenshot: tile and name, description, * then author and `children`, such as when the plugin was added or its install count. */ export function NewPluginCard({ plugin, children }: { plugin: Plugin; children?: ReactNode }) { const author = getAuthor(plugin); return (

{plugin.name}

{plugin.description}

{author.name} {children !== undefined && ( <> ยท {children} )}

); } /** Grid card: screenshot; tile, name, and `children` such as an install count; description. */ export function PluginCard({ plugin, children }: { plugin: Plugin; children?: ReactNode }) { return (

{plugin.name}

{children}

{plugin.description}

); } /** Ranked row for the directory's Most installed list. */ export function PluginRankRow({ plugin, rank, installs, }: { plugin: Plugin; rank: number; installs: number; }) { return ( {rank}

{plugin.name}

{getCategory(plugin.categories[0])?.label}

); }