MultiSite/components/DocumentList.tsx

183 lines
8.2 KiB
TypeScript
Raw Permalink Normal View History

2025-09-12 17:03:28 +08:00
'use client';
import { ContentItem } from '../lib/content';
interface DocumentListProps {
documents: ContentItem[];
currentLang: string;
}
export function DocumentList({ documents, currentLang }: DocumentListProps) {
const formatDate = (dateString: string) => {
const date = new Date(dateString);
return date.toLocaleDateString(currentLang === 'en' ? 'en-US' : 'zh-CN', {
year: 'numeric',
month: 'long',
day: 'numeric',
});
};
const getCategoryColor = (category: string) => {
const colors = {
: 'bg-green-100 text-green-800',
: 'bg-blue-100 text-blue-800',
: 'bg-purple-100 text-purple-800',
: 'bg-orange-100 text-orange-800',
'Getting Started': 'bg-green-100 text-green-800',
Configuration: 'bg-blue-100 text-blue-800',
Content: 'bg-purple-100 text-purple-800',
Deployment: 'bg-orange-100 text-orange-800',
};
return colors[category] || 'bg-gray-100 text-gray-800';
};
if (documents.length === 0) {
return (
<div className="text-center py-12">
<div className="text-gray-400 mb-4">
<svg
className="w-16 h-16 mx-auto"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={1}
d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
/>
</svg>
</div>
<p className="text-gray-500">
{currentLang === 'en' ? 'No documents found' : '暂无文档'}
</p>
</div>
);
}
return (
<div className="space-y-6">
{documents.map((doc) => (
<article
key={doc.slug}
className="bg-white rounded-lg border border-gray-200 p-6 hover:shadow-md transition-shadow"
>
<div className="flex items-start justify-between mb-4">
<div className="flex-1">
<h2 className="text-xl font-semibold text-gray-900 mb-2">
<a
href={`/docs/${doc.slug}`}
className="hover:text-blue-600 transition-colors"
>
{doc.metadata.title}
</a>
</h2>
<p className="text-gray-600 mb-3 leading-relaxed">
{doc.metadata.description}
</p>
</div>
<span
className={`px-3 py-1 rounded-full text-xs font-medium ${getCategoryColor(doc.metadata.category)}`}
>
{doc.metadata.category}
</span>
</div>
<div className="flex items-center justify-between text-sm text-gray-500">
<div className="flex items-center space-x-4">
<span className="flex items-center">
<svg
className="w-4 h-4 mr-1"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"
/>
</svg>
{doc.metadata.author}
</span>
<span className="flex items-center">
<svg
className="w-4 h-4 mr-1"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M8 7V3a1 1 0 011-1h6a1 1 0 011 1v4h3a1 1 0 011 1v9a2 2 0 01-2 2H5a2 2 0 01-2-2V8a1 1 0 011-1h3z"
/>
</svg>
{formatDate(doc.metadata.date)}
</span>
</div>
{doc.metadata.tags && doc.metadata.tags.length > 0 && (
<div className="flex items-center space-x-2">
<svg
className="w-4 h-4"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
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"
/>
</svg>
<div className="flex flex-wrap gap-1">
{doc.metadata.tags.slice(0, 3).map((tag) => (
<span
key={tag}
className="px-2 py-1 bg-gray-100 text-gray-600 rounded text-xs"
>
{tag}
</span>
))}
{doc.metadata.tags.length > 3 && (
<span className="text-gray-400 text-xs">
+{doc.metadata.tags.length - 3}
</span>
)}
</div>
</div>
)}
</div>
<div className="mt-4 pt-4 border-t border-gray-100">
<a
href={`/docs/${doc.slug}`}
className="inline-flex items-center text-blue-600 hover:text-blue-700 font-medium text-sm"
>
{currentLang === 'en' ? 'Read more' : '阅读更多'}
<svg
className="w-4 h-4 ml-1"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M9 5l7 7-7 7"
/>
</svg>
</a>
</div>
</article>
))}
</div>
);
}