astro/src/pages/fics/[ficId]/index.astro

118 lines
3.2 KiB
Plaintext

---
import type { GetStaticPaths } from "astro";
import { Font } from "astro:assets";
import { getCollection, getEntries, render } from "astro:content";
import { marked } from "marked";
import Layout from "@/layouts/Layout.astro";
import formatDate from "@/utils/formatDate";
import ChapterContent from "~/ChapterContent.astro";
export const getStaticPaths = (async () => {
const fics = await getCollection("fics");
return fics.map(fic => ({
params: { ficId: fic.id },
props: { fic },
}));
}) satisfies GetStaticPaths;
const { fic } = Astro.props;
const chapters = await getEntries(fic.data.chapters ?? []);
chapters.length = Math.min(chapters.length, 5);
chapters.sort((a, b) => a.data.sortOrder - b.data.sortOrder);
const { Content } = await render(fic);
const parser = marked.use({ gfm: true, breaks: true });
const summary = await parser.parse(fic.data.summary);
const lastMod = fic.rendered && (fic.rendered.metadata!.frontmatter as any)['lastModified'];
const notes = fic.rendered && await parser.parse((fic.rendered.metadata!.frontmatter as any)["notes"]);
---
<Layout title={fic.data.title}>
<Fragment slot="head">
{fic.data.chapters && <link rel="alternate" type="application/rss+xml" title={fic.data.title} href={new URL(`/fics/${Astro.params.ficId}/rss.xml`, Astro.site)} />}
<meta name="description" content={fic.data.summary?.substring(0, 150) + "…"} />
{fic.body && <Font cssVariable="--serif" preload />}
</Fragment>
<main>
<section>
<h1>{fic.data.title}</h1>
<header class="info">
<dl>
<dt>Fandom</dt>
{typeof fic.data.series === "object"
? <ul>{fic.data.series.map(fandom => (<li>{fandom}</li>))}</ul>
: <dd>{fic.data.series}</dd>
}
<dt>Date</dt>
<dd>
<time datetime={formatDate(fic.data.publishedAt, true)}>
<span class="data">{formatDate(fic.data.publishedAt)}</span>
</time>
</dd>
<dt>Summary</dt>
<dd>
<blockquote>
<Fragment set:html={summary} />
</blockquote>
</dd>
</dl>
<div class="links">
{chapters.length > 0 && <>
<a class="button" href={`/fics/${chapters[0].id}`}>start reading</a>
<a class="button" href={`/fics/${Astro.params.ficId}/rss.xml`}>rss feed</a>
</>}
</div>
</header>
{chapters.length > 0 && (
<h2>chapters</h2>
<ul>
{chapters.map(chapter => (
<li><a href={chapter.id}>{chapter.data.title}</a></li>
))}
</ul>
)}
</section>
{fic.body && (
<section id="oneshot">
<ChapterContent lastModified={lastMod} notes={notes}>
<Content />
</ChapterContent>
</section>
)}
</main>
</Layout>
<style>
main {
display: grid;
place-content: center;
section {
max-width: 80ch;
.info {
dl {
dt { font-weight: bold; }
}
blockquote {
margin: 1rem 2rem;
}
.links {
display: flex;
align-content: center;
justify-content: space-around;
}
}
}
#oneshot {
margin-top: 2rem;
}
}
</style>