personal-website/app/blog/page.tsx
Filipe Medeiros 23083a7552
feat: topics
Signed-off-by: Filipe Medeiros <hello@filipesm.eu>
2023-12-03 12:25:57 +01:00

95 lines
3 KiB
TypeScript

import Card, {
CardCta,
CardDescription,
CardEyebrow,
CardTags,
CardTitle,
} from '@/components/server/Card'
import SimpleLayout from '@/components/server/SimpleLayout'
import Tag from '@/components/server/Tag'
import formatDate from '@/lib/formatDate'
import { getFirstBlogPosts } from '@/lib/notion/content/blogPosts'
import { SelectColor } from '@/lib/notion/types'
import richTextAsPlainText from '@/lib/notion/utils/richTextToPlainText'
export const revalidate = 600
function BlogPost({
slug,
title,
description,
publishDate,
topics,
}: {
slug: string
title: string
description: string
publishDate: string
topics: { name: string; color: SelectColor }[]
}) {
return (
<article className="md:grid md:grid-cols-4 md:items-baseline">
<Card className="md:col-span-3">
<CardTitle href={`/blog/${slug}`}>{title}</CardTitle>
<CardEyebrow
as="time"
dateTime={publishDate}
className="relative z-10 order-first mb-3 flex items-center pl-3.5 text-sm text-zinc-400 dark:text-zinc-500 md:hidden"
decorate
>
{formatDate(publishDate)}
</CardEyebrow>
<CardDescription>{description}</CardDescription>
<CardTags>
{topics.map((topic) => (
<Tag color={topic.color} key={topic.name}>
{topic.name}
</Tag>
))}
</CardTags>
<CardCta> o artigo</CardCta>
</Card>
<CardEyebrow
as="time"
dateTime={publishDate}
className="relative z-10 order-first mt-1 mb-3 items-center text-sm text-zinc-400 dark:text-zinc-500 max-md:hidden md:block"
>
{formatDate(publishDate)}
</CardEyebrow>
</article>
)
}
export default async function Blog() {
const { results: blogPosts } = await getFirstBlogPosts()
return (
<SimpleLayout
title="Os meus artigos"
intro="Todos os meus pensamentos que são demasiado grandes para meter num toot e demasiado curtos para escrever um livro. Por ordem cronológica."
>
<div className="md:border-l md:border-zinc-100 md:pl-6 md:dark:border-zinc-700/40">
<div className="flex max-w-3xl flex-col space-y-16">
{blogPosts.map((blogPost) => (
<BlogPost
key={richTextAsPlainText(blogPost.properties.Slug.rich_text)}
title={richTextAsPlainText(blogPost.properties.Name.title)}
description={richTextAsPlainText(
blogPost.properties.Description.rich_text,
)}
topics={blogPost.properties.Topics.multi_select.map(
({ name, color }) => ({ name, color }),
)}
slug={richTextAsPlainText(blogPost.properties.Slug.rich_text)}
publishDate={richTextAsPlainText(
blogPost.properties.PublishDate.date?.start ??
blogPost.created_time,
)}
/>
))}
</div>
</div>
</SimpleLayout>
)
}