--- import { CATEGORIES, TOOLS } from "@snapotter/shared"; import * as lucideIcons from "lucide"; import SectionHeading from "./SectionHeading.astro"; const toolCount = TOOLS.length; const categoryMap = new Map(CATEGORIES.map((c) => [c.id, c])); const modalities = [ { id: "all", label: "All", count: TOOLS.length }, { id: "image", label: "Image", count: TOOLS.filter((t) => t.modality === "image").length }, { id: "video", label: "Video", count: TOOLS.filter((t) => t.modality === "video").length }, { id: "audio", label: "Audio", count: TOOLS.filter((t) => t.modality === "audio").length }, { id: "document,file", label: "PDF & Files", count: TOOLS.filter((t) => t.modality === "document" || t.modality === "file").length, }, ]; function renderIcon(iconName: string): string { const iconData = (lucideIcons as Record)[iconName]; if (!iconData || !Array.isArray(iconData)) return ""; return iconData .map(([tag, attrs]: [string, Record]) => { const attrStr = Object.entries(attrs) .map(([k, v]) => `${k}="${v}"`) .join(" "); return `<${tag} ${attrStr}/>`; }) .join(""); } ---
{modalities.map((m) => ( ))}
{CATEGORIES.map((cat) => { const count = TOOLS.filter((t) => t.category === cat.id).length; return ( ); })}

Showing {toolCount} of {toolCount} tools

{TOOLS.map((tool) => { const cat = categoryMap.get(tool.category); return ( {tool.name}

{tool.description}

); })}