Component Details

Hero Component 02

Hero Component 02

PostCard.tsx

Next.jsTailwind CSS
1// Dummy data for blog posts
2const dummyPosts = [
3  {
4    id: 1,
5    slug: "getting-started-with-nextjs",
6    title: "Getting Started with Next.js 14",
7    excerpt: "Learn how to build modern web applications with Next.js 14 and its new features including Server Actions and partial prerendering.",
8    category: "Web Development",
9    author: "Jane Doe",
10    date: "2024-01-15",
11    readTime: 5,
12  },
13  {
14    id: 2,
15    slug: "tailwind-css-best-practices",
16    title: "Tailwind CSS Best Practices for 2024",
17    excerpt: "Discover the most effective ways to use Tailwind CSS in your projects, from component architecture to performance optimization.",
18    category: "CSS",
19    author: "John Smith",
20    date: "2024-01-10",
21    readTime: 8,
22  },
23  {
24    id: 3,
25    slug: "react-performance-tips",
26    title: "Advanced React Performance Optimization",
27    excerpt: "Explore techniques to improve your React application performance including memoization, code splitting, and virtualization.",
28    category: "React",
29    author: "Alex Johnson",
30    date: "2024-01-05",
31    readTime: 10,
32  },
33];
34
35// PostCard Component
36interface PostCardProps {
37  slug: string;
38  title: string;
39  excerpt: string;
40  category: string;
41  author: string;
42  date: string;
43  readTime: number;
44}
45
46export function PostCard({
47  slug,
48  title,
49  excerpt,
50  category,
51  author,
52  date,
53  readTime,
54}: PostCardProps) {
55  function formatDate(dateString: string) {
56    const date = new Date(dateString);
57    const months = [
58      "Jan",
59      "Feb",
60      "Mar",
61      "Apr",
62      "May",
63      "Jun",
64      "Jul",
65      "Aug",
66      "Sep",
67      "Oct",
68      "Nov",
69      "Dec",
70    ];
71    return `${
72      months[date.getMonth()]
73    } ${date.getDate()}, ${date.getFullYear()}`;
74  }
75
76  return (
77    <Link href={`/blog/${slug}`}>
78      <Card className="hover:shadow-lg transition h-full">
79        <CardHeader>
80          <div className="flex items-start justify-between gap-2 mb-2">
81            <Badge variant="outline">{category}</Badge>
82            <span className="text-sm text-muted-foreground">
83              {readTime} min read
84            </span>
85          </div>
86          <CardTitle className="line-clamp-2">{title}</CardTitle>
87        </CardHeader>
88        <CardContent>
89          <p className="text-sm text-muted-foreground mb-4 line-clamp-2">
90            {excerpt}
91          </p>
92          <div className="flex justify-between items-center text-xs text-muted-foreground">
93            <span>{author}</span>
94            <span>{formatDate(date)}</span>
95          </div>
96        </CardContent>
97      </Card>
98    </Link>
99  );
100}
101
102// Homepage Component
103export default function Home() {
104  const posts = dummyPosts
105    .sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime())
106    .slice(0, 3);
107
108  return (
109    <div className="flex flex-col">
110      <main className="max-w-4xl mx-auto px-4 sm:px-6 lg:px-0 py-12 w-full">
111        {/* Hero */}
112        <section className="mb-16">
113          <h1 className="text-4xl font-bold mb-4 text-balance">
114            Welcome to My Blog
115          </h1>
116          <p className="text-lg text-muted-foreground mb-8 max-w-2xl">
117            Explore articles about web development, design, and modern
118            technologies. Stay updated with the latest trends and best
119            practices.
120          </p>
121          <Link href="/blog">
122            <Button size="lg" className="cursor-pointer">
123              Read All Articles
124            </Button>
125          </Link>
126        </section>
127
128        {/* Recent Posts */}
129        <section>
130          <h2 className="text-3xl font-bold mb-8">Recent Articles</h2>
131          <div className="grid gap-6 md:grid-cols-2 lg:grid-cols-3">
132            {posts.map((post) => (
133              <PostCard
134                key={post.id}
135                slug={post.slug}
136                title={post.title}
137                excerpt={post.excerpt}
138                category={post.category}
139                author={post.author}
140                date={post.date}
141                readTime={post.readTime}
142              />
143            ))}
144          </div>
145        </section>
146      </main>
147    </div>
148  );
149}