--- import type { GetStaticPaths, Page } from "astro"; import { Image } from "astro:assets"; import { getCollection } from "astro:content"; import GalleryLayout from "../../layouts/GalleryLayout.astro"; import type { CollectionEntry } from "astro:content"; import { t } from "../../i18n"; type Props = { page: Page<CollectionEntry<"stories">>; }; export const getStaticPaths: GetStaticPaths = async ({ paginate }) => { const stories = (await getCollection("stories", (story) => !story.data.isDraft && story.data.pubDate)).sort( (a, b) => b.data.pubDate!.getTime() - a.data.pubDate!.getTime(), ); return paginate(stories, { pageSize: 30 }) satisfies { props: Props }[]; }; const { page } = Astro.props; const totalPages = Math.ceil(page.total / page.size); --- <GalleryLayout pageTitle="Stories"> <meta slot="head-description" property="og:description" content={`Bad Manners || ${page.total} stories.`} /> <h1 class="m-2 text-2xl font-semibold text-stone-800 dark:text-stone-100">Stories</h1> <p class="my-4">The bulk of my content!</p> <p class="text-center font-light text-stone-950 dark:text-white"> { page.start == page.end ? `Displaying story #${page.start + 1}` : `Displaying stories #${page.start + 1}–${page.end + 1}` } / {page.total} </p> <div class="mx-auto mb-6 mt-2 flex w-fit rounded-lg border border-stone-400 dark:border-stone-500"> { page.url.prev && ( <a class="text-link border-r border-stone-400 px-2 py-1 underline dark:border-stone-500" href={page.url.prev}> Previous page </a> ) } { [...Array(totalPages).keys()].map((p) => p + 1 == page.currentPage ? ( <span class="border-r border-stone-400 px-4 py-1 font-semibold text-stone-900 dark:border-stone-500 dark:text-stone-50"> {p + 1} </span> ) : ( <a class="text-link border-r border-stone-400 px-2 py-1 underline dark:border-stone-500" href={page.url.current.replace(`/${page.currentPage}`, `/${p + 1}`)} > {p + 1} </a> ), ) } { page.url.next && ( <a class="text-link px-2 py-1 underline" href={page.url.next}> Next page </a> ) } </div> <ul class="flex flex-wrap items-start justify-center gap-4 text-center md:justify-normal"> { page.data.map((story) => ( <li class="break-inside-avoid"> <a class="text-link hover:underline focus:underline" href={`/stories/${story.slug}`} title={t(story.data.lang, "story/warnings", story.data.wordCount, story.data.contentWarning.trim())} > {story.data.thumbnail ? ( <div class="flex aspect-square max-w-[192px] justify-center"> <Image class="m-auto" src={story.data.thumbnail} alt={`Thumbnail for ${story.data.title}`} width={192} /> </div> ) : null} <div class="max-w-[192px] text-sm"> <span>{story.data.title}</span> <br /> <span class="italic"> {story.data.pubDate!.toLocaleDateString("en-US", { month: "short", day: "numeric", year: "numeric" })} </span> </div> </a> </li> )) } </ul> <div class="mx-auto my-6 flex w-fit rounded-lg border border-stone-400 dark:border-stone-500"> { page.url.prev && ( <a class="text-link border-r border-stone-400 px-2 py-1 underline dark:border-stone-500" href={page.url.prev}> Previous page </a> ) } { [...Array(totalPages).keys()].map((p) => p + 1 == page.currentPage ? ( <span class="border-r border-stone-400 px-4 py-1 font-semibold text-stone-900 dark:border-stone-500 dark:text-stone-50"> {p + 1} </span> ) : ( <a class="text-link border-r border-stone-400 px-2 py-1 underline dark:border-stone-500" href={page.url.current.replace(`/${page.currentPage}`, `/${p + 1}`)} > {p + 1} </a> ), ) } { page.url.next && ( <a class="text-link px-2 py-1 underline" href={page.url.next}> Next page </a> ) } </div> </GalleryLayout>