84 lines
2.5 KiB
TypeScript
84 lines
2.5 KiB
TypeScript
import Link from 'next/link';
|
|
import Image from 'next/image';
|
|
import { BookOpen, Code, FileText, ExternalLink } from 'lucide-react';
|
|
import type { BlogPost, RelatedDoc } from '../types';
|
|
|
|
interface BlogSidebarProps {
|
|
relatedArticles: BlogPost[];
|
|
relatedDocs: RelatedDoc[];
|
|
}
|
|
|
|
const iconMap: Record<string, React.ComponentType<{ className?: string }>> = {
|
|
book: BookOpen,
|
|
code: Code,
|
|
file: FileText,
|
|
};
|
|
|
|
export const BlogSidebar = ({
|
|
relatedArticles,
|
|
relatedDocs,
|
|
}: BlogSidebarProps) => {
|
|
if (relatedArticles.length === 0 && relatedDocs.length === 0) {
|
|
return null;
|
|
}
|
|
|
|
return (
|
|
<aside className="space-y-8">
|
|
{relatedArticles.length > 0 && (
|
|
<div>
|
|
<h3 className="text-sm font-semibold text-gray-900 mb-4">
|
|
Related Articles
|
|
</h3>
|
|
<ul className="space-y-3">
|
|
{relatedArticles.map((article) => (
|
|
<li key={article.slug}>
|
|
<Link
|
|
href={`/blog/${article.slug}`}
|
|
className="flex items-start gap-3 group"
|
|
>
|
|
<div className="w-16 h-12 relative rounded overflow-hidden flex-shrink-0 bg-gray-100">
|
|
<Image
|
|
src={article.heroImage}
|
|
alt={article.title}
|
|
fill
|
|
className="object-cover"
|
|
/>
|
|
</div>
|
|
<span className="text-sm text-gray-600 group-hover:text-purple-600 transition-colors line-clamp-2">
|
|
{article.title}
|
|
</span>
|
|
</Link>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
)}
|
|
|
|
{relatedDocs.length > 0 && (
|
|
<div>
|
|
<h3 className="text-sm font-semibold text-gray-900 mb-4">
|
|
Related Documentation
|
|
</h3>
|
|
<ul className="space-y-2">
|
|
{relatedDocs.map((doc) => {
|
|
const Icon = iconMap[doc.icon] || FileText;
|
|
return (
|
|
<li key={doc.href}>
|
|
<Link
|
|
href={doc.href}
|
|
className="flex items-center gap-2 text-sm text-gray-600 hover:text-purple-600 transition-colors"
|
|
>
|
|
<Icon className="w-4 h-4" />
|
|
<span>{doc.title}</span>
|
|
<ExternalLink className="w-3 h-3 ml-auto" />
|
|
</Link>
|
|
</li>
|
|
);
|
|
})}
|
|
</ul>
|
|
</div>
|
|
)}
|
|
</aside>
|
|
);
|
|
};
|