feat(ui): improve empty state for taxonomy pages

Add visual indicators and back-to-blog links for empty categories, tags, and search results
This commit is contained in:
joyzhao
2025-06-19 18:31:45 +08:00
parent f4ff971c85
commit 62364d1d11
3 changed files with 62 additions and 19 deletions

View File

@@ -48,14 +48,29 @@ const title = titles[lang] || titles[defaultLang];
{title}
</h3>
<div class="space-y-2">
{categories.map((cat) => {
const categoryId = categoryMap.get(cat) || cat.toLowerCase();
return (
<a href={`${baseUrl}/categories/${encodeURIComponent(categoryId)}`}
class={`block transition-colors duration-200 ${categoryId === currentCategory.toLowerCase() ? 'text-purple-500 font-medium' : 'text-muted-foreground hover:text-purple-500'}`}>
{cat}
{categories.length > 0 ? (
categories.map((cat) => {
const categoryId = categoryMap.get(cat) || cat.toLowerCase();
return (
<a href={`${baseUrl}/categories/${encodeURIComponent(categoryId)}`}
class={`block transition-colors duration-200 ${categoryId === currentCategory.toLowerCase() ? 'text-purple-500 font-medium' : 'text-muted-foreground hover:text-purple-500'}`}>
{cat}
</a>
);
})
) : (
<div class="flex flex-col items-center justify-center py-6 space-y-4">
<svg class="w-12 h-12 text-purple-500/50" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M19 11H5m14-7l2 2-2 2m2-2H9m10 0V9M5 19l2-2-2-2m2 2H3m2 0v2"></path>
</svg>
<p class="text-muted-foreground text-center">{lang === 'zh' ? '暂无分类' : 'No categories yet'}</p>
<a href={baseUrl} class="inline-flex items-center px-4 py-2 rounded-full text-sm font-medium bg-purple-500 text-white shadow-sm hover:bg-purple-600 transition-all duration-200 hover:shadow-md">
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"></path>
</svg>
{lang === 'zh' ? '返回博客列表' : 'Back to blog list'}
</a>
);
})}
</div>
)
</div>
</div>

View File

@@ -48,16 +48,31 @@ const title = titles[lang] || titles[defaultLang];
{title}
</h3>
<div class="flex flex-wrap gap-2">
{tags.map((tagItem) => {
const tagName = tagItem.slice(2); // 去掉 '# ' 前缀
const tagId = tagMap.get(tagName) || tagName.toLowerCase();
const isCurrentTag = tagId === currentTag.toLowerCase();
return (
<a href={`${baseUrl}/tags/${encodeURIComponent(tagId)}`}
class={`inline-block px-3 py-1 text-sm rounded-full transition-all duration-200 ${isCurrentTag ? 'bg-purple-500/20 text-purple-500 font-medium' : 'bg-muted text-muted-foreground hover:bg-purple-500/20 hover:text-purple-500'}`}>
{tagItem}
{tags.length > 0 ? (
tags.map((tagItem) => {
const tagName = tagItem.slice(2); // 去掉 '# ' 前缀
const tagId = tagMap.get(tagName) || tagName.toLowerCase();
const isCurrentTag = tagId === currentTag.toLowerCase();
return (
<a href={`${baseUrl}/tags/${encodeURIComponent(tagId)}`}
class={`inline-block px-3 py-1 text-sm rounded-full transition-all duration-200 ${isCurrentTag ? 'bg-purple-500/20 text-purple-500 font-medium' : 'bg-muted text-muted-foreground hover:bg-purple-500/20 hover:text-purple-500'}`}>
{tagItem}
</a>
);
})
) : (
<div class="flex flex-col items-center justify-center py-6 space-y-4 w-full">
<svg class="w-12 h-12 text-purple-500/50" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z"></path>
</svg>
<p class="text-muted-foreground text-center">{lang === 'zh' ? '暂无标签' : 'No tags yet'}</p>
<a href={baseUrl} class="inline-flex items-center px-4 py-2 rounded-full text-sm font-medium bg-purple-500 text-white shadow-sm hover:bg-purple-600 transition-all duration-200 hover:shadow-md">
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"></path>
</svg>
{lang === 'zh' ? '返回博客列表' : 'Back to blog list'}
</a>
);
})}
</div>
)}
</div>
</div>

View File

@@ -86,8 +86,21 @@ const localizedText = getLocalizedText();
{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">
<div class="bg-card/50 backdrop-blur-sm rounded-2xl p-8 text-center border border-border flex flex-col items-center justify-center space-y-4">
<svg class="w-16 h-16 text-purple-500/50" fill="none" stroke="currentColor" viewBox="0 0 24 24">
{taxonomyType === 'category' ? (
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M19 11H5m14-7l2 2-2 2m2-2H9m10 0V9M5 19l2-2-2-2m2 2H3m2 0v2"></path>
) : (
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M7 7h.01M7 3h5c.512 0 1.024.195 1.414.586l7 7a2 2 0 010 2.828l-7 7a2 2 0 01-2.828 0l-7-7A1.994 1.994 0 013 12V7a4 4 0 014-4z"></path>
)}
</svg>
<p class="text-lg text-muted-foreground">{localizedText.noResults}</p>
<a href={`/${lang === 'en' ? '' : 'zh/'}blog`} class="inline-flex items-center px-4 py-2 rounded-full text-sm font-medium bg-purple-500 text-white shadow-sm hover:bg-purple-600 transition-all duration-200 hover:shadow-md mt-2">
<svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 19l-7-7m0 0l7-7m-7 7h18"></path>
</svg>
{lang === 'zh' ? '返回博客列表' : 'Back to blog list'}
</a>
</div>
)}
</div>