137 lines
5.5 KiB
TypeScript
137 lines
5.5 KiB
TypeScript
import Link from 'next/link'
|
|
import Image from 'next/image'
|
|
import { Post } from '@/lib/types/frontmatter'
|
|
import { formatDate } from '@/lib/utils'
|
|
|
|
interface BlogCardProps {
|
|
post: Post
|
|
variant: 'image-top' | 'image-side' | 'text-only'
|
|
}
|
|
|
|
export function BlogCard({ post, variant }: BlogCardProps) {
|
|
const hasImage = !!post.frontmatter.image
|
|
|
|
if (!hasImage || variant === 'text-only') {
|
|
return (
|
|
<Link href={`/blog/${post.slug}`} className="block cursor-pointer">
|
|
<article className="border border-slate-700 bg-slate-900 p-6 h-full cyber-glitch-hover">
|
|
<div className="border-l-2 pl-4 mb-4" style={{ borderColor: 'var(--neon-pink)' }}>
|
|
<span className="font-mono text-xs text-zinc-100 uppercase tracking-wider">
|
|
{post.frontmatter.category} <span style={{ color: 'var(--neon-cyan)' }}>//</span>{' '}
|
|
{formatDate(post.frontmatter.date)}
|
|
</span>
|
|
</div>
|
|
<h3 className="font-mono text-xl font-bold text-zinc-100 uppercase mb-3">
|
|
{post.frontmatter.title}
|
|
</h3>
|
|
<p className="font-mono text-sm text-zinc-400 mb-4 leading-relaxed">
|
|
{post.frontmatter.description}
|
|
</p>
|
|
<div className="flex flex-wrap gap-2 mb-4">
|
|
{post.frontmatter.tags.map(tag => (
|
|
<span
|
|
key={tag}
|
|
className="px-3 py-1 bg-zinc-800 border border-slate-700 text-cyan-400 font-mono text-xs uppercase"
|
|
>
|
|
#{tag}
|
|
</span>
|
|
))}
|
|
</div>
|
|
<span className="inline-flex items-center font-mono text-xs uppercase text-cyan-400 hover:text-cyan-300 transition-colors">
|
|
> READ [{post.readingTime}MIN]
|
|
</span>
|
|
</article>
|
|
</Link>
|
|
)
|
|
}
|
|
|
|
if (variant === 'image-side') {
|
|
return (
|
|
<Link href={`/blog/${post.slug}`} className="block cursor-pointer">
|
|
<article className="border border-slate-700 bg-slate-900 overflow-hidden h-full cyber-glitch-hover">
|
|
<div className="flex flex-col md:flex-row h-full">
|
|
<div className="md:w-1/3 relative h-64 md:h-auto bg-zinc-900">
|
|
<Image
|
|
src={post.frontmatter.image!}
|
|
alt={post.frontmatter.title}
|
|
fill
|
|
className="object-cover grayscale"
|
|
/>
|
|
<div className="absolute inset-0 bg-zinc-900/60" />
|
|
</div>
|
|
<div className="md:w-2/3 p-6">
|
|
<div className="border-l-2 border-cyan-400 pl-4 mb-4">
|
|
<span className="font-mono text-xs text-zinc-100 uppercase tracking-wider">
|
|
{post.frontmatter.category} // {formatDate(post.frontmatter.date)}
|
|
</span>
|
|
</div>
|
|
<h3 className="font-mono text-xl font-bold text-zinc-100 uppercase mb-3">
|
|
{post.frontmatter.title}
|
|
</h3>
|
|
<p className="font-mono text-sm text-zinc-400 mb-4 leading-relaxed">
|
|
{post.frontmatter.description}
|
|
</p>
|
|
<div className="flex flex-wrap gap-2 mb-4">
|
|
{post.frontmatter.tags.map(tag => (
|
|
<span
|
|
key={tag}
|
|
className="px-3 py-1 bg-zinc-800 border border-slate-700 text-cyan-400 font-mono text-xs uppercase"
|
|
>
|
|
#{tag}
|
|
</span>
|
|
))}
|
|
</div>
|
|
<span className="inline-flex items-center font-mono text-xs uppercase text-cyan-400 hover:text-cyan-300 transition-colors">
|
|
> READ [{post.readingTime}MIN]
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</article>
|
|
</Link>
|
|
)
|
|
}
|
|
|
|
return (
|
|
<Link href={`/blog/${post.slug}`} className="block cursor-pointer">
|
|
<article className="border border-slate-700 bg-slate-900 overflow-hidden transition-all duration-300 cyber-glitch-hover h-full">
|
|
<div className="relative h-64 bg-zinc-900">
|
|
<Image
|
|
src={post.frontmatter.image!}
|
|
alt={post.frontmatter.title}
|
|
fill
|
|
className="object-cover grayscale"
|
|
/>
|
|
<div className="absolute inset-0 bg-zinc-900/60" />
|
|
</div>
|
|
<div className="p-6">
|
|
<div className="border-l-2 pl-4 mb-4" style={{ borderColor: 'var(--neon-pink)' }}>
|
|
<span className="font-mono text-xs text-zinc-100 uppercase tracking-wider">
|
|
{post.frontmatter.category} <span style={{ color: 'var(--neon-cyan)' }}>//</span>{' '}
|
|
{formatDate(post.frontmatter.date)}
|
|
</span>
|
|
</div>
|
|
<h3 className="font-mono text-xl font-bold text-zinc-100 uppercase mb-3">
|
|
{post.frontmatter.title}
|
|
</h3>
|
|
<p className="font-mono text-sm text-zinc-400 mb-4 leading-relaxed">
|
|
{post.frontmatter.description}
|
|
</p>
|
|
<div className="flex flex-wrap gap-2 mb-4">
|
|
{post.frontmatter.tags.map(tag => (
|
|
<span
|
|
key={tag}
|
|
className="px-3 py-1 bg-zinc-800 border border-slate-700 text-cyan-400 font-mono text-xs uppercase"
|
|
>
|
|
#{tag}
|
|
</span>
|
|
))}
|
|
</div>
|
|
<span className="inline-flex items-center font-mono text-xs uppercase text-cyan-400 hover:text-cyan-300 transition-colors">
|
|
> READ [{post.readingTime}MIN]
|
|
</span>
|
|
</div>
|
|
</article>
|
|
</Link>
|
|
)
|
|
}
|