refactor: add a generic listing page component

This commit is contained in:
Oliver Davies 2023-02-11 22:53:00 +00:00
parent bcd846f08c
commit 2efcb575f1
4 changed files with 71 additions and 57 deletions

View file

@ -0,0 +1,24 @@
---
import PageLayout from "~/layouts/PageLayout.astro";
import ListingPageItem from "./ListingPageItem.astro";
interface Item {
description: string;
title: string;
}
interface Props {
items: Array<Item>;
title: string;
}
const { items, title } = Astro.props as Props;
---
<PageLayout title={title}>
<slot name="intro" />
<div class="mt-6 space-y-6">
{items.map((item) => <ListingPageItem item={item} />)}
</div>
</PageLayout>

View file

@ -0,0 +1,31 @@
---
interface ItemProps {
date: string;
description?: string;
excerpt?: string;
title: string;
}
const { date, description, excerpt, title } = Astro.props.item.item
.frontmatter as ItemProps;
const { slug } = Astro.props.item;
---
<article>
<a href={slug} class="mb-2"><h2>{title}</h2></a>
{
date && (
<time class="mt-0 mb-2 block text-base" datetime={date}>
{new Date(date).toLocaleDateString("en-GB", {
day: "numeric",
month: "long",
year: "numeric",
})}
</time>
)
}
{description && <p>{description}</p>}
{excerpt && <p>{excerpt}</p>}
</article>

View file

@ -1,4 +1,5 @@
---
import ListingPage from "~/components/ListingPage.astro";
import PageLayout from "~/layouts/PageLayout.astro";
import { getSlugFromFile } from "~/utils.ts";
@ -11,50 +12,21 @@ const filteredPosts = posts
const sortedPosts = filteredPosts
.map((post) => {
const slug = getSlugFromFile(post.file);
const slug = `/blog/${getSlugFromFile(post.file)}`;
return { post, slug };
return { item: post, slug };
})
.sort(
(a, b) =>
new Date(b.post.frontmatter.date).valueOf() -
new Date(a.post.frontmatter.date).valueOf()
new Date(b.item.frontmatter.date).valueOf() -
new Date(a.item.frontmatter.date).valueOf()
);
---
<PageLayout title="Blog">
<p>
<ListingPage items={sortedPosts} title="Blog">
<p slot="intro">
This is where I publish my personal blog posts as well as technical posts
and tutorials on topics such as Drupal, PHP, Tailwind CSS, automated
testing, and systems administration.
</p>
<div>
{
sortedPosts.map((post) => (
<article>
<a href={`/blog/${post.slug}`}>
<h2>{post.post.frontmatter.title}</h2>
</a>
{post.post.frontmatter.date && (
<time class="text-base" datetime={post.post.frontmatter.date}>
{new Date(post.post.frontmatter.date).toLocaleDateString(
"en-GB",
{
day: "numeric",
month: "long",
year: "numeric",
}
)}
</time>
)}
<div class="mt-1">
<p>{post.post.frontmatter.excerpt}</p>
</div>
</article>
))
}
</div>
</PageLayout>
</ListingPage>

View file

@ -2,6 +2,7 @@
import PageLayout from "~/layouts/PageLayout.astro";
import _ from "lodash";
import { getSlugFromFile } from "~/utils.ts";
import ListingPage from "~/components/ListingPage.astro";
const talks = await Astro.glob("../../talks/*.md");
@ -11,14 +12,14 @@ const talkCount = _(talks)
const sortedTalks = talks
.map((talk) => {
const slug = getSlugFromFile(talk.file);
const slug = `/talks/${getSlugFromFile(talk.file)}`;
return { slug, talk };
return { slug, item: talk };
})
.sort((b, a) => {
const events = [
a.talk.frontmatter.events[a.talk.frontmatter.events.length - 1],
b.talk.frontmatter.events[b.talk.frontmatter.events.length - 1],
a.item.frontmatter.events[a.item.frontmatter.events.length - 1],
b.item.frontmatter.events[b.item.frontmatter.events.length - 1],
];
return (
@ -27,24 +28,10 @@ const sortedTalks = talks
});
---
<PageLayout title="Talks and workshops">
<p>
<ListingPage items={sortedTalks} title="Talks and workshops">
<p slot="intro">
Starting with my first talk in September 2012, I have given {talkCount} presentations
and workshops at various conferences and meetups, in-person and remotely, on
topics including PHP, Drupal, automated testing, Git, CSS, and systems administration.
</p>
<div>
{
sortedTalks.map((talk) => (
<article>
<a href={`/talks/${talk.slug}`}>
<h2>{talk.talk.frontmatter.title}</h2>
</a>
{talk.talk.frontmatter.description}
</article>
))
}
</div>
</PageLayout>
</ListingPage>