feat(taxonomy): add unified taxonomy page layout and utilities
refactor blog category and tag pages to use new TaxonomyPageLayout add utility functions for processing taxonomy page data pass lang prop to GlassHeader component
This commit is contained in:
@@ -39,7 +39,7 @@ const lang = Astro.currentLocale as Lang || defaultLang;
|
||||
<div class="absolute inset-0 bg-gradient-to-br from-purple-50/30 via-transparent to-blue-50/20 dark:from-purple-950/20 dark:via-transparent dark:to-blue-950/10"></div>
|
||||
</div>
|
||||
<!-- Glass Header with navigation -->
|
||||
<GlassHeader client:load />
|
||||
<GlassHeader lang={lang} client:load />
|
||||
|
||||
<!-- Main content with proper spacing for fixed header -->
|
||||
<div class="pt-16">
|
||||
|
||||
95
src/layouts/TaxonomyPageLayout.astro
Normal file
95
src/layouts/TaxonomyPageLayout.astro
Normal file
@@ -0,0 +1,95 @@
|
||||
---
|
||||
/**
|
||||
* TaxonomyPageLayout component
|
||||
* A unified layout for category and tag pages
|
||||
*/
|
||||
import BlogLayout from './BlogLayout.astro';
|
||||
import BlogList from '../components/blog/BlogList.astro';
|
||||
import CategoryCard from '../components/blog/CategoryCard.astro';
|
||||
import TagCard from '../components/blog/TagCard.astro';
|
||||
import { type Lang } from '@/i18n/utils';
|
||||
import { defaultLang } from '@/i18n/ui';
|
||||
import { type BlogPost } from '@/types';
|
||||
|
||||
interface Props {
|
||||
lang: Lang;
|
||||
title: string;
|
||||
description?: string;
|
||||
taxonomyType: 'category' | 'tag';
|
||||
currentTaxonomy: string;
|
||||
displayName?: string;
|
||||
posts: BlogPost[];
|
||||
categories: Map<string, string>;
|
||||
tags: Map<string, string>;
|
||||
}
|
||||
|
||||
const {
|
||||
lang,
|
||||
title,
|
||||
taxonomyType,
|
||||
currentTaxonomy,
|
||||
displayName,
|
||||
posts,
|
||||
categories,
|
||||
tags
|
||||
} = Astro.props;
|
||||
|
||||
// Get localized text based on language and taxonomy type
|
||||
const getLocalizedText = () => {
|
||||
if (taxonomyType === 'category') {
|
||||
return {
|
||||
heading: lang === 'zh' ? '分类' : 'Category',
|
||||
noResults: lang === 'zh' ? '该分类下没有文章' : 'No posts in this category',
|
||||
};
|
||||
} else {
|
||||
return {
|
||||
heading: lang === 'zh' ? '标签' : 'Tag',
|
||||
noResults: lang === 'zh' ? '该标签下没有文章' : 'No posts with this tag',
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const localizedText = getLocalizedText();
|
||||
---
|
||||
|
||||
<BlogLayout title={title} description={Astro.props.description}>
|
||||
<div class="container max-w-6xl px-4 py-8">
|
||||
<!-- Header Section - Centered at the top -->
|
||||
<div class="text-center mb-10">
|
||||
<h1 class="text-4xl font-bold mb-3">
|
||||
{displayName || currentTaxonomy}
|
||||
</h1>
|
||||
|
||||
<p class="text-xl text-muted-foreground">
|
||||
{localizedText.heading}: {posts.length} {lang === 'zh' ? '篇文章' : 'posts'}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Content Section - Sidebar and Main Content -->
|
||||
<div class="flex flex-col md:flex-row gap-8">
|
||||
<!-- Sidebar - Left on desktop, top on mobile -->
|
||||
<div class="w-full md:w-80 space-y-6 md:flex-shrink-0">
|
||||
<CategoryCard
|
||||
lang={lang}
|
||||
currentCategory={taxonomyType === 'category' ? currentTaxonomy : undefined}
|
||||
/>
|
||||
|
||||
<TagCard
|
||||
lang={lang}
|
||||
currentTag={taxonomyType === 'tag' ? currentTaxonomy : undefined}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<!-- Main Content -->
|
||||
<div class="flex-1">
|
||||
{posts.length > 0 ? (
|
||||
<BlogList posts={posts} lang={lang} />
|
||||
) : (
|
||||
<div class="bg-card/50 backdrop-blur-sm rounded-2xl p-8 text-center border border-border">
|
||||
<p class="text-lg text-muted-foreground">{localizedText.noResults}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</BlogLayout>
|
||||
Reference in New Issue
Block a user