app/components/taxonomy-listing.tsx
83 lines and 5 functions in DrDustinEdwards/dustinedwards-info, at commit 1590ba4 on 2026-10-24. This file on GitHub.
Functions
| Function | Lines | Complexity | Covered | CRAP | Mutation |
|---|---|---|---|---|---|
| listingHref | 12 to 14 | 2 | No data: no coverage report in this map | No data: no coverage report in this map | No data: no mutants in this code |
| redirectPastLastPage | 17 to 19 | 2 | No data: no coverage report in this map | No data: no coverage report in this map | No data: no mutants in this code |
| TaxonomyListing | 24 to 92 | 2 | No data: no coverage report in this map | No data: no coverage report in this map | No data: no mutants in this code |
| <anonymous:77> | 77 to 79 | 1 | No data: no coverage report in this map | No data: no coverage report in this map | No data: no mutants in this code |
| <anonymous:83> | 83 to 83 | 1 | No data: no coverage report in this map | No data: no coverage report in this map | No data: no mutants in this code |
Imports
It imports app/components/evidence-row.tsx, app/components/post-row.tsx, app/components/shell-footer.tsx, app/components/site-header.tsx, app/lib/blog-listing.mjs, app/lib/json-ld.mjs, app/lib/seo.ts. Imported by app/routes/blog.series.$series.tsx, app/routes/blog.tags.$tag.tsx.
Source
import { Link, redirect } from "react-router";
import { EvidenceRow } from "~/components/evidence-row";
import { PostRow, Pager } from "~/components/post-row";
import { ShellFooter } from "~/components/shell-footer";
import { SiteHeader } from "~/components/site-header";
import { listingFacts } from "~/lib/blog-listing.mjs";
import { jsonLd } from "~/lib/json-ld.mjs";
import { SITE_ORIGIN, breadcrumbJsonLd } from "~/lib/seo";
/** A taxonomy page's URL for page `n`: the bare path for the first page, `?page=n` after it. */
export function listingHref(base: string, n: number) {
return n > 1 ? `${base}?page=${n}` : base;
}
/** Out of range redirects to the last real page, so the URL never claims a page that does not exist. */
export function redirectPastLastPage(page: number, pageCount: number, base: string) {
if (page > pageCount) throw redirect(listingHref(base, pageCount));
}
type ListingPost = Parameters<typeof PostRow>[0]["post"];
/** The tag and series pages: one listing of posts under a name, with a pager and its own feeds. */
export function TaxonomyListing({
base,
name,
heading,
dek,
posts,
page,
pageCount,
total,
span,
}: {
/** The page's path, which its feeds hang off. */
base: string;
/** The breadcrumb's last step. */
name: string;
heading: string;
/** The sentence under the heading; an "All posts" link follows it. */
dek: React.ReactNode;
posts: ListingPost[];
page: number;
pageCount: number;
total: number;
span: Parameters<typeof listingFacts>[1];
}) {
return (
<>
<SiteHeader />
<main className="tracks list-tracks" id="main" tabIndex={-1}>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: jsonLd(
breadcrumbJsonLd(SITE_ORIGIN, [
["Home", "/"],
["Writing", "/writing"],
[name, base],
]),
),
}}
/>
<header className="list-head">
<h1 className="list-label">{heading}</h1>
<p className="list-dek">
{dek} <Link to="/writing">All posts</Link>
</p>
<EvidenceRow facts={listingFacts(total, span)} />
</header>
{posts.length === 0 ? (
<p className="list-empty">No posts here yet.</p>
) : (
<ul className="entry-list">
{posts.map((post) => (
<PostRow key={post.slug} post={post} />
))}
</ul>
)}
<Pager page={page} pageCount={pageCount} hrefFor={(n) => listingHref(base, n)} />
<p className="list-feeds">
Subscribe: <a href={`${base}/rss.xml`}>RSS</a> <a href={`${base}/feed.json`}>JSON</a>
</p>
</main>
<ShellFooter />
</>
);
}