diff options
| author | Bertrand Yuan <bert.yuan@outlook.com> | 2025-12-16 00:12:49 +0800 |
|---|---|---|
| committer | Bertrand Yuan <bert.yuan@outlook.com> | 2025-12-16 00:12:49 +0800 |
| commit | 02ae938c238c9d18448d17a8ec92c0edd8c17463 (patch) | |
| tree | dcd6a30505adb52522b20af2c0ac27f713403f10 /src/app/(main)/(home)/_components/posts.tsx | |
| parent | 48b07bc308a35734a6a7a305c8fdccbfa47de7d8 (diff) | |
feat(back-end): introduce payload
Payload is the next.js Headless CMS and App Framework,
I would like to pick it up and modify it as it is MIT licensed.
Many features in Payload is not applicable for our project.
So, I modify it so that it is light and clear.
Diffstat (limited to 'src/app/(main)/(home)/_components/posts.tsx')
| -rw-r--r-- | src/app/(main)/(home)/_components/posts.tsx | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/src/app/(main)/(home)/_components/posts.tsx b/src/app/(main)/(home)/_components/posts.tsx new file mode 100644 index 0000000..00ada0c --- /dev/null +++ b/src/app/(main)/(home)/_components/posts.tsx @@ -0,0 +1,89 @@ +import { Icons } from '@/components/icons/icons'; +import { PostCard } from '@/components/posts/post-card'; +import { Section } from '@/components/section'; +import { buttonVariants } from '@/components/ui/button'; +import type { Page } from '@/lib/source'; +import type { BlogPost } from '@/lib/payload-posts'; +import Link from 'next/link'; + +// 统一的文章数据格式 +interface UnifiedPost { + title: string; + description: string; + image?: string | null; + url: string; + date: string; + author: string; + tags?: string[]; +} + +// 将 MDX Page 转换为统一格式 +function transformMdxPost(post: Page): UnifiedPost { + return { + title: post.data.title, + description: post.data.description ?? '', + image: post.data.image, + url: post.url, + date: new Date(post.data.date).toDateString(), + author: post.data.author, + tags: post.data.tags, + }; +} + +// 将 Payload BlogPost 转换为统一格式 +function transformPayloadPost(post: BlogPost): UnifiedPost { + return { + title: post.title, + description: post.description, + image: post.image, + url: post.url, + date: post.date.toDateString(), + author: post.author, + tags: post.tags, + }; +} + +interface PostsProps { + mdxPosts?: Page[]; + payloadPosts?: BlogPost[]; +} + +export default function Posts({ mdxPosts = [], payloadPosts = [] }: PostsProps) { + // 转换并合并所有文章 + const allPosts: UnifiedPost[] = [ + ...mdxPosts.map(transformMdxPost), + ...payloadPosts.map(transformPayloadPost), + ]; + + // 按日期排序 + allPosts.sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()); + + return ( + <Section> + <div className='grid divide-y divide-dashed divide-border/70 text-left dark:divide-border'> + {allPosts.map((post) => ( + <PostCard + title={post.title} + description={post.description} + image={post.image} + url={post.url} + date={post.date} + key={post.url} + author={post.author} + tags={post.tags} + /> + ))} + <Link + href='/posts' + className={buttonVariants({ + variant: 'default', + className: 'group rounded-none py-4 sm:py-8', + })} + > + View More + <Icons.arrowUpRight className='group-hover:-rotate-12 ml-2 size-5 transition-transform' /> + </Link> + </div> + </Section> + ); +} |
