bfc6a65638
Multi-agent arch/UX review pass. Architecture: real HTTP 404 on not-found, breadcrumb links by slug not lowercased title, CMS pages surface their plugins, shared status taxonomy (src/lib/statuses.ts) consumed by all three frontend consumers, data-driven status filter, typed emdash collections (src/emdash-collections.d.ts), removed unused @astrojs/react + react deps and dead pnpm block, tsconfig extends Astro strict preset, dev deps pruned from the runtime image. UI/UX: fixed StatusBadge WCAG-AA contrast, labelled the search/filter controls, canonical URL + BreadcrumbList JSON-LD + og:type, human status labels, filtered result count + recoverable empty state, auto-submit filters, mobile overflow fixes, skip-to-content, :focus-visible. Commit the npm lockfile so the Dockerfile's `npm ci` path engages. astro check: 0 errors / 0 warnings / 0 hints.
36 lines
1.2 KiB
Plaintext
36 lines
1.2 KiB
Plaintext
---
|
|
import { getEmDashCollection } from "emdash";
|
|
import Base from "../../layouts/Base.astro";
|
|
|
|
export const prerender = false;
|
|
|
|
const { entries: cmses, cacheHint } = await getEmDashCollection("cmses", {
|
|
orderBy: { title: "asc" },
|
|
});
|
|
Astro.cache.set(cacheHint);
|
|
|
|
const PLUGIN_FETCH_CAP = 10000;
|
|
const { entries: plugins } = await getEmDashCollection("plugins", { limit: PLUGIN_FETCH_CAP });
|
|
if (plugins.length >= PLUGIN_FETCH_CAP) console.warn("[cms] plugin fetch hit cap", PLUGIN_FETCH_CAP, "- counts/lists may be truncated");
|
|
const countBySource = new Map<string, number>();
|
|
const countByTarget = new Map<string, number>();
|
|
for (const p of plugins) {
|
|
const s = p.data.source_cms;
|
|
if (s) countBySource.set(s, (countBySource.get(s) ?? 0) + 1);
|
|
const t = p.data.target_cms;
|
|
if (t) countByTarget.set(t, (countByTarget.get(t) ?? 0) + 1);
|
|
}
|
|
---
|
|
<Base title="By CMS" description="Browse plugins grouped by source CMS.">
|
|
<h1>By CMS</h1>
|
|
<ul class="plugin-grid">
|
|
{cmses.map((c) => (
|
|
<li class="plugin-card">
|
|
<h3><a href={`/cms/${c.id}`}>{c.data.title}</a></h3>
|
|
<p class="meta">{countBySource.get(c.data.title) ?? 0} from · {countByTarget.get(c.data.title) ?? 0} targeting</p>
|
|
{c.data.description && <p>{c.data.description}</p>}
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</Base>
|