import type { ReactNode } from "react";
import { useTranslation } from "react-i18next";
import { useLocale, useLocalizePath } from "~/i18n";
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, pluginListing } 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 ? (
![]()
) : (
)}
);
}
/**
* Gallery 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 PluginCard({ plugin, children }: { plugin: Plugin; children?: ReactNode }) {
const author = getAuthor(plugin);
const listing = pluginListing(plugin, useLocale());
const localize = useLocalizePath();
return (
// Grid items size to their content by default; min-w-0 keeps the card in its column.
{listing.description}
{author.name}
{children !== undefined && (
<>
ยท
{children}
>
)}
);
}
/** Ranked row for the directory's Most installed list. */
export function PluginRankRow({
plugin,
rank,
installs,
}: {
plugin: Plugin;
rank: number;
installs: number;
}) {
const { t } = useTranslation();
const listing = pluginListing(plugin, useLocale());
const localize = useLocalizePath();
const category = getCategory(plugin.categories[0]);
return (
{rank}
{listing.name}
{category && t(`plugins.categories.${category}.label`)}
);
}