-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add dynamic categories page and improve header interaction
1. Enable users to configure categories (links, titles, icons) via config.yml. 2. Move type interfaces from getConfig to global types for better type management. 3. Implement dynamic category page generation based on user settings. 4. Update post pages to make thumbnails and titles clickable, and link categories to their respective category pages (via CategoryLinks.tsx). 5. Enhance accessibility in the header and implement desktop hover interaction on the "Posts" menu to display user-defined categories, with indentation for categories on mobile. 6. Refactor services folder structure, add subfolders, and update imports accordingly.
- Loading branch information
Showing
25 changed files
with
464 additions
and
204 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,23 @@ background: '/images/background.jpg' | |
# Slogan displayed on your homepage, under your avatar. | ||
slogan: "As long as the code or the developer is able to run, it's all good." | ||
|
||
####################### | ||
# HEADER SETTINGS | ||
####################### | ||
# Post Categories: Add your post categories here. | ||
# Use icons from link below (e.g., 'FaHouse' for 'fa6 FaHouse'). | ||
# https://react-icons.github.io/react-icons/icons/fa6/ | ||
postCategories: | ||
- name: '前端' # Category name, same ad frontmatter category, will show in frontend. | ||
slug: 'frontend' # (Optional) Category slug, if not set, will be same as name. | ||
icon: 'FaHtml5' # (Optional) Font Awesome 6 icon name. If not set, no icon. | ||
- name: '全栈' | ||
slug: 'fullstack' | ||
icon: 'FaCode' | ||
- name: '教程' | ||
slug: 'tutorial' | ||
icon: 'FaGraduationCap' | ||
|
||
####################### | ||
# SOCIAL MEDIA SETTINGS | ||
####################### | ||
|
@@ -34,7 +51,7 @@ socialMedia: | |
bilibili: 'https://space.bilibili.com/29018759' # Bilibili profile URL. | ||
zhihu: 'https://www.zhihu.com/people/zl-asica' # Zhihu profile URL. | ||
email: '[email protected]' # Your email address (do NOT include the mailto: prefix). | ||
rss: '' # Optional: RSS feed URL (). | ||
rss: '' # RSS feed URL (can be relative url). | ||
|
||
####################### | ||
# PAGES (ABOUT, FRIENDS) SETTINGS | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import { getAllPosts } from '@/services/content/posts'; | ||
import { getConfig } from '@/services/config/getConfig'; | ||
import { notFound } from 'next/navigation'; | ||
import PostListLayout from '@/components/layout/PostListLayout'; | ||
|
||
export async function generateStaticParams() { | ||
const config = getConfig(); | ||
return config.postCategories.map((category) => ({ | ||
categorySlug: category.slug, | ||
})); | ||
} | ||
|
||
export default async function CategoryPage({ | ||
params, | ||
}: { | ||
params: { categorySlug: string }; | ||
}) { | ||
const posts = await getAllPosts(); | ||
const config = getConfig(); | ||
|
||
// Find the category based on the slug from params | ||
const category = config.postCategories.find( | ||
(cat) => cat.slug === params.categorySlug, | ||
); | ||
|
||
if (!category) { | ||
// If the category doesn't exist, show 404 | ||
notFound(); | ||
} | ||
|
||
// Filter posts by the category name | ||
const filteredPosts = posts.filter((post) => | ||
post.frontmatter.categories?.includes(category.name), | ||
); | ||
|
||
return ( | ||
<div className='container mx-auto p-4'> | ||
<h1 className='mb-6 text-center text-4xl font-bold'>{category.name}</h1> | ||
|
||
<PostListLayout posts={filteredPosts} /> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,85 +1,15 @@ | ||
import { getAllPosts } from '@/services/posts'; | ||
import Link from 'next/link'; | ||
import PostListLayout from '@/components/layout/PostListLayout'; | ||
import { getAllPosts } from '@/services/content/posts'; | ||
import { PostData } from '@/types'; | ||
import Image from 'next/image'; | ||
import { FaFolder, FaRegClock, FaEye } from 'react-icons/fa6'; | ||
|
||
export default async function PostsPage() { | ||
const posts: PostData[] = await getAllPosts(); | ||
|
||
// TODO: Replace with actual read count | ||
const readCount: number = 29; | ||
|
||
posts.forEach((post) => { | ||
const plainText = post.contentHtml | ||
.replace(/<!--more-->/g, '[[MORE_PLACEHOLDER]]') | ||
.replace(/<[^>]*>/g, ''); | ||
|
||
const moreIndex = plainText.indexOf('[[MORE_PLACEHOLDER]]'); | ||
|
||
post.contentHtml = | ||
moreIndex > 0 | ||
? plainText.slice(0, moreIndex).replace('[[MORE_PLACEHOLDER]]', '') | ||
: plainText.slice(0, 150); | ||
}); | ||
|
||
return ( | ||
<div className='container mx-auto p-4'> | ||
<h1 className='mb-6 text-center text-4xl font-bold'>All Posts</h1> | ||
|
||
<div className='grid grid-cols-1 gap-6'> | ||
{posts.map((post, index) => ( | ||
<Link | ||
key={post.slug} | ||
href={`/posts/${post.slug}`} | ||
className={`flex flex-col overflow-hidden rounded-lg shadow-lg transition-shadow duration-300 hover:shadow-xl md:flex-row ${index % 2 !== 0 ? 'md:flex-row-reverse' : ''} mx-auto`} | ||
style={{ maxWidth: '780px', maxHeight: '400px' }} // Set max width and height | ||
> | ||
{/* Thumbnail */} | ||
<div className='max-h-[400px] w-full md:w-1/2'> | ||
{post.frontmatter.thumbnail && ( | ||
<Image | ||
src={post.frontmatter.thumbnail} | ||
alt={post.frontmatter.title} | ||
width={780} | ||
height={400} | ||
className='h-full w-full object-cover' | ||
/> | ||
)} | ||
</div> | ||
|
||
{/* Content */} | ||
<div className='flex flex-col justify-between p-4 md:w-1/2'> | ||
<div> | ||
{/* Date of Publish */} | ||
<div className='text-gray-450 mb-2 flex items-center text-sm'> | ||
<FaRegClock className='mr-2' /> | ||
<span>{post.frontmatter.date.split(' ')[0]}</span> | ||
</div> | ||
{/* Title in Frontmatter */} | ||
<h2 className='mb-2 text-2xl font-bold'> | ||
{post.frontmatter.title} | ||
</h2> | ||
<p className='text-sm text-gray-300'>{post.contentHtml}</p> | ||
</div> | ||
<div className='mt-4'> | ||
<div className='text-gray-450 flex items-center justify-between text-sm'> | ||
{/* Read Count */} | ||
<span className='flex items-center'> | ||
<FaEye className='mr-1' /> | ||
{readCount} 热度 | ||
</span> | ||
{/* Category */} | ||
<span className='flex items-center'> | ||
<FaFolder className='mr-1' /> | ||
{post.frontmatter.categories?.join(', ') || '未分类'} | ||
</span> | ||
</div> | ||
</div> | ||
</div> | ||
</Link> | ||
))} | ||
</div> | ||
<PostListLayout posts={posts} /> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.