🪛 03 routing
This commit is contained in:
95
app/blog/page.tsx
Normal file
95
app/blog/page.tsx
Normal file
@@ -0,0 +1,95 @@
|
||||
import { Metadata } from 'next'
|
||||
import Link from 'next/link'
|
||||
import { getAllPosts } from '@/lib/markdown'
|
||||
import { formatDate } from '@/lib/utils'
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Blog',
|
||||
description: 'Toate articolele din blog',
|
||||
}
|
||||
|
||||
function PostCard({ post }: { post: any }) {
|
||||
return (
|
||||
<article className="border-b border-gray-200 dark:border-gray-700 pb-8 mb-8 last:border-0">
|
||||
<div className="flex flex-col lg:flex-row gap-6">
|
||||
{post.frontmatter.image && (
|
||||
<div className="lg:w-1/3">
|
||||
<img src={post.frontmatter.image} alt={post.frontmatter.title} className="w-full h-48 lg:h-full object-cover rounded-lg" />
|
||||
</div>
|
||||
)}
|
||||
<div className={post.frontmatter.image ? 'lg:w-2/3' : 'w-full'}>
|
||||
<div className="flex items-center gap-4 text-sm text-gray-500 mb-2">
|
||||
<time dateTime={post.frontmatter.date}>{formatDate(post.frontmatter.date)}</time>
|
||||
<span>•</span>
|
||||
<span>{post.readingTime} min citire</span>
|
||||
<span>•</span>
|
||||
<span>{post.frontmatter.author}</span>
|
||||
</div>
|
||||
<h2 className="text-2xl font-bold mb-3">
|
||||
<Link href={`/blog/${post.slug}`} className="hover:text-primary-600 transition">
|
||||
{post.frontmatter.title}
|
||||
</Link>
|
||||
</h2>
|
||||
<p className="text-gray-600 dark:text-gray-400 mb-4">{post.frontmatter.description}</p>
|
||||
{post.frontmatter.tags && post.frontmatter.tags.length > 0 && (
|
||||
<div className="flex flex-wrap gap-2 mb-4">
|
||||
{post.frontmatter.tags.map((tag: string) => (
|
||||
<span key={tag} className="px-3 py-1 bg-gray-100 dark:bg-gray-800 text-sm rounded-full">
|
||||
#{tag}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
<Link href={`/blog/${post.slug}`} className="inline-flex items-center text-primary-600 hover:text-primary-700 transition">
|
||||
Citește articolul complet
|
||||
<svg className="ml-2 w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
||||
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 5l7 7-7 7" />
|
||||
</svg>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</article>
|
||||
)
|
||||
}
|
||||
|
||||
function BlogFilters({ totalPosts }: { totalPosts: number }) {
|
||||
return (
|
||||
<div className="bg-gray-50 dark:bg-gray-800 rounded-lg p-6 mb-8">
|
||||
<div className="flex items-center justify-between">
|
||||
<div>
|
||||
<h1 className="text-3xl font-bold mb-2">Articole Blog</h1>
|
||||
<p className="text-gray-600 dark:text-gray-400">
|
||||
{totalPosts} {totalPosts === 1 ? 'articol' : 'articole'} publicate
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default async function BlogPage() {
|
||||
const posts = await getAllPosts()
|
||||
|
||||
if (posts.length === 0) {
|
||||
return (
|
||||
<div className="text-center py-12">
|
||||
<h1 className="text-3xl font-bold mb-4">Blog</h1>
|
||||
<p className="text-gray-600 dark:text-gray-400 mb-8">Nu există articole publicate încă.</p>
|
||||
<Link href="/" className="inline-block px-6 py-3 bg-primary-600 text-white rounded-lg hover:bg-primary-700 transition">
|
||||
Înapoi la pagina principală
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="max-w-4xl mx-auto">
|
||||
<BlogFilters totalPosts={posts.length} />
|
||||
<div>
|
||||
{posts.map((post) => (
|
||||
<PostCard key={post.slug} post={post} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user