mirror of
https://github.com/KazooTTT/kazoottt-blog.git
synced 2025-06-16 23:41:21 +08:00
Refactor FormattedDate and PostPreview components to include cover image support; enhance blog post display with year markers in pagination
This commit is contained in:
@ -1,18 +1,31 @@
|
|||||||
---
|
---
|
||||||
import type { HTMLAttributes } from 'astro/types'
|
import type { HTMLAttributes } from 'astro/types'
|
||||||
|
|
||||||
import { getFormattedDate } from '@/utils'
|
interface Props extends HTMLAttributes<'time'> {
|
||||||
|
|
||||||
type Props = HTMLAttributes<'time'> & {
|
|
||||||
date: Date
|
date: Date
|
||||||
dateTimeOptions?: Intl.DateTimeFormatOptions
|
coverImage: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const { date, dateTimeOptions, ...attrs } = Astro.props
|
const { date, coverImage: coverImage, ...attrs } = Astro.props
|
||||||
|
console.log('coverImage', coverImage)
|
||||||
|
|
||||||
const postDate = getFormattedDate(date, dateTimeOptions)
|
const formattedDate = date.toISOString().slice(0, 10).replace(/-/g, '')
|
||||||
---
|
---
|
||||||
|
|
||||||
<time datetime={date.toISOString()} {...attrs}>
|
{
|
||||||
{postDate}
|
coverImage ? (
|
||||||
</time>
|
<div class='relative'>
|
||||||
|
<time datetime={date.toISOString()} {...attrs}>
|
||||||
|
{formattedDate}
|
||||||
|
</time>
|
||||||
|
<img
|
||||||
|
src={coverImage}
|
||||||
|
class='absolute left-0 top-0 -z-10 h-full w-full object-cover opacity-10'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<time datetime={date.toISOString()} {...attrs}>
|
||||||
|
{formattedDate}
|
||||||
|
</time>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
@ -8,14 +8,18 @@ type Props<Tag extends HTMLTag> = Polymorphic<{ as: Tag }> & {
|
|||||||
post: CollectionEntry<'post'>
|
post: CollectionEntry<'post'>
|
||||||
prefix?: string
|
prefix?: string
|
||||||
withDesc?: boolean
|
withDesc?: boolean
|
||||||
|
showYear?: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
const { as: Tag = 'div', post, prefix = '/blog/', withDesc = false } = Astro.props
|
const { as: Tag = 'div', post, prefix = '/blog/', withDesc = false, showYear = false } = Astro.props
|
||||||
const postDate = post.data.date
|
const postDate = post.data.date
|
||||||
|
const year = postDate.getFullYear()
|
||||||
|
const coverImage = post.data.coverImage
|
||||||
---
|
---
|
||||||
|
|
||||||
|
{showYear && <h2 class='my-2 text-xl font-semibold'>{year}</h2>}
|
||||||
<li class='flex flex-col gap-2 sm:flex-row sm:gap-x-4 [&_q]:basis-full'>
|
<li class='flex flex-col gap-2 sm:flex-row sm:gap-x-4 [&_q]:basis-full'>
|
||||||
<FormattedDate class='min-w-[120px]' date={postDate} />
|
<FormattedDate class='min-w-[80px]' date={postDate} coverImage={coverImage} />
|
||||||
|
|
||||||
<Tag>
|
<Tag>
|
||||||
{post.data.draft && <span class='text-red-500'>(Draft) </span>}
|
{post.data.draft && <span class='text-red-500'>(Draft) </span>}
|
||||||
|
@ -15,11 +15,10 @@ interface Props {
|
|||||||
|
|
||||||
const { post, simple = false, backHref = '/blog' } = Astro.props
|
const { post, simple = false, backHref = '/blog' } = Astro.props
|
||||||
const {
|
const {
|
||||||
data: { description, ogImage, title, date },
|
data: { description, ogImage, title, date }
|
||||||
slug
|
|
||||||
} = post
|
} = post
|
||||||
|
|
||||||
const socialImage = ogImage ?? `/og-image/${slug}.png`
|
const socialImage = ogImage
|
||||||
const articleDate = date?.toISOString()
|
const articleDate = date?.toISOString()
|
||||||
const { headings } = await post.render()
|
const { headings } = await post.render()
|
||||||
---
|
---
|
||||||
|
@ -53,6 +53,14 @@ const paginationProps = {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Group posts by year and mark first post of each year
|
||||||
|
const postsWithYearMarkers = page.data.map((post, index) => {
|
||||||
|
const currentYear = post.data.date.getFullYear()
|
||||||
|
const prevYear = index > 0 ? page.data[index - 1].data.date.getFullYear() : null
|
||||||
|
const showYear = currentYear !== prevYear
|
||||||
|
return { post, showYear }
|
||||||
|
})
|
||||||
---
|
---
|
||||||
|
|
||||||
<PageLayout meta={meta}>
|
<PageLayout meta={meta}>
|
||||||
@ -81,8 +89,8 @@ const paginationProps = {
|
|||||||
<div class='grid gap-y-16 sm:grid-cols-[3fr_1fr] sm:gap-x-8'>
|
<div class='grid gap-y-16 sm:grid-cols-[3fr_1fr] sm:gap-x-8'>
|
||||||
<section aria-label='Blog posts list'>
|
<section aria-label='Blog posts list'>
|
||||||
<ul class='flex flex-col gap-y-4 text-start'>
|
<ul class='flex flex-col gap-y-4 text-start'>
|
||||||
{page.data.map((p) => (
|
{postsWithYearMarkers.map(({ post, showYear }) => (
|
||||||
<PostPreview post={p} />
|
<PostPreview post={post} showYear={showYear} withDesc={true} />
|
||||||
))}
|
))}
|
||||||
</ul>
|
</ul>
|
||||||
<Pagination {...paginationProps} />
|
<Pagination {...paginationProps} />
|
||||||
|
Reference in New Issue
Block a user