Files
zhaoguiyang.site/src/components/blog/PostMeta.astro
zguiyang 0d050b0c14 refactor: update styles and animations across pages for improved consistency and aesthetics
- Changed background gradients and color schemes in `now.astro` and `projects.astro` to use primary colors.
- Updated text styles and backgrounds to enhance readability and visual appeal.
- Added new font imports for better typography.
- Introduced custom animations and hover effects in `global.css` for enhanced user interaction.
- Adjusted CSS variables for a more cohesive design across light and dark modes.
2026-03-13 14:39:09 +08:00

160 lines
5.2 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
import { type Lang } from '@/types/i18n';
import { useTranslations } from '@/i18n/utils';
export interface Props {
lang: Lang;
publishDate?: string;
readingTime?: number;
tags?: string[];
tagId?: string[];
category?: string | string[];
categoryId?: string[] | string;
className?: string;
}
const {
lang,
publishDate,
readingTime,
tags,
tagId,
category,
categoryId,
className = ''
} = Astro.props;
const t = useTranslations(lang);
/**
* Format date according to locale
*/
const formatDate = (dateString: string) => {
const date = new Date(dateString);
return date.toLocaleDateString(lang === 'zh' ? 'zh-CN' : 'en-US', {
year: 'numeric',
month: 'long',
day: 'numeric'
});
};
/**
* Get reading time text based on language
*/
const getReadingTimeText = (minutes: number) => {
if (lang === 'zh') {
return `${minutes} 分钟阅读`;
}
return `${minutes} min read`;
};
---
<div class={`space-y-6 ${className}`} data-component="PostMeta">
<!-- Primary Meta Info: Date and Reading Time -->
<div class="flex flex-wrap items-center gap-4 text-sm md:text-base text-muted-foreground">
<!-- Publish Date -->
{publishDate && (
<div class="flex items-center gap-2">
<svg class="w-4 h-4 md:w-5 md:h-5 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect>
<line x1="16" y1="2" x2="16" y2="6"></line>
<line x1="8" y1="2" x2="8" y2="6"></line>
<line x1="3" y1="10" x2="21" y2="10"></line>
</svg>
<time datetime={publishDate} class="font-medium">
{formatDate(publishDate)}
</time>
</div>
)}
<!-- Reading Time -->
{readingTime && (
<div class="flex items-center gap-2">
<svg class="w-4 h-4 md:w-5 md:h-5 text-green-500" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10"></circle>
<polyline points="12,6 12,12 16,14"></polyline>
</svg>
<span class="font-medium">{getReadingTimeText(readingTime)}</span>
</div>
)}
</div>
<!-- Secondary Meta Info: Category and Tags -->
{(category || (tags && tags.length > 0)) && (
<div class="space-y-3">
<!-- Category Section -->
{category && (
<div class="space-y-2">
<div class="text-xs font-medium text-muted-foreground uppercase tracking-wide">
{lang === 'zh' ? '分类' : 'Categories'}
</div>
<div class="flex gap-2 flex-wrap">
{Array.isArray(category) ? (
category.map((cat, index) => {
// 获取对应的 categoryId如果存在
const catId = categoryId && Array.isArray(categoryId) && index < categoryId.length
? categoryId[index]
: cat.toLowerCase();
return (
<a href={`/${lang === 'en' ? '' : 'zh/'}blog/categories/${encodeURIComponent(catId)}`} class="inline-flex items-center px-3 py-1.5 rounded-full text-xs font-medium bg-gradient-to-r from-primary to-primary text-white shadow-sm hover:shadow-md transition-all duration-200 hover:scale-105">
{cat}
</a>
);
})
) : (
<a href={`/${lang === 'en' ? '' : 'zh/'}blog/categories/${encodeURIComponent(categoryId?.toString() || category.toLowerCase())}`} class="inline-flex items-center px-3 py-1.5 rounded-full text-xs font-medium bg-gradient-to-r from-primary to-primary text-white shadow-sm hover:shadow-md transition-all duration-200 hover:scale-105">
{category}
</a>
)}
</div>
</div>
)}
<!-- Tags Section -->
{tags && tags.length > 0 && (
<div class="space-y-2">
<div class="text-xs font-medium text-muted-foreground uppercase tracking-wide">
{lang === 'zh' ? '标签' : 'Tags'}
</div>
<div class="flex gap-2 flex-wrap">
{tags.map((tag, index) => {
// 获取对应的 tagId如果存在
const tagRoute = tagId && Array.isArray(tagId) && index < tagId.length
? tagId[index]
: tag.toLowerCase();
return (
<a href={`/${lang === 'en' ? '' : 'zh/'}blog/tags/${encodeURIComponent(tagRoute)}`} class="inline-flex items-center px-2.5 py-1 rounded-md text-xs font-medium bg-gray-100 text-gray-700 hover:bg-gray-200 dark:bg-gray-800 dark:text-gray-300 dark:hover:bg-gray-700 transition-colors border border-gray-200 dark:border-gray-600">
# {tag}
</a>
);
})}
</div>
</div>
)}
</div>
)}
</div>
<style>
/* Ensure smooth transitions for hover effects */
.transition-colors {
transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out;
}
/* Responsive adjustments */
@media (max-width: 640px) {
.flex-wrap {
gap: 0.75rem;
}
.text-sm {
font-size: 0.8rem;
}
}
</style>