Skip to content

Commit 9e54c11

Browse files
committed
feat: blog post card component
1 parent d79d1fa commit 9e54c11

File tree

5 files changed

+72
-39
lines changed

5 files changed

+72
-39
lines changed

src/components/BlogPost.astro

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
import { Icon } from "astro-icon";
3+
import DateTime from "./DateTime.astro";
4+
import type { CollectionEntry } from "astro:content";
5+
6+
interface Props {
7+
post: CollectionEntry<"posts">;
8+
}
9+
10+
const { post } = Astro.props;
11+
---
12+
13+
<li class="">
14+
<a
15+
href={`/posts/${post.slug}`}
16+
class="relative block overflow-hidden rounded-lg border border-gray-600 p-4 sm:p-6 lg:p-8 bg-slate-800 hover:border-teal-300 transition-colors duration-300"
17+
>
18+
<span
19+
class="absolute inset-x-0 bottom-0 h-2 bg-gradient-to-r from-teal-300 via-blue-500 to-purple-600"
20+
></span>
21+
<h3 class="text-lg text-teal-300 pb-1">{post.data.title}</h3>
22+
<div class="flex gap-2">
23+
<Icon class="w-4" name="lucide:calendar" />
24+
<DateTime pubDate={post.data.pubDate} />
25+
</div>
26+
<p class="pt-4">{post.data.description}</p>
27+
</a>
28+
</li>

src/components/DateTime.astro

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
interface Props {
3+
pubDate: Date;
4+
}
5+
6+
const { pubDate } = Astro.props;
7+
8+
const formatDate = (date: Date): string => {
9+
const nth = (day: number): string => {
10+
if (day > 3 && day < 21) return "th";
11+
switch (day % 10) {
12+
case 1:
13+
return "st";
14+
case 2:
15+
return "nd";
16+
case 3:
17+
return "rd";
18+
default:
19+
return "th";
20+
}
21+
};
22+
23+
const parts = new Intl.DateTimeFormat("en-US", {
24+
day: "numeric",
25+
month: "long",
26+
year: "numeric",
27+
}).formatToParts(date);
28+
29+
return parts
30+
.map((part) => {
31+
if (part.type === "day") {
32+
return `${part.value}${nth(parseInt(part.value))}`;
33+
}
34+
return part.value;
35+
})
36+
.join("");
37+
};
38+
---
39+
40+
<p>{formatDate(pubDate)}</p>

src/layouts/BlogLayout.astro

+2-32
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,8 @@
11
---
22
import Layout from "./Layout.astro";
3+
import DateTime from "../components/DateTime.astro";
34
45
const { frontmatter } = Astro.props;
5-
6-
const formatDate = (date: Date): string => {
7-
const nth = (day: number): string => {
8-
if (day > 3 && day < 21) return "th";
9-
switch (day % 10) {
10-
case 1:
11-
return "st";
12-
case 2:
13-
return "nd";
14-
case 3:
15-
return "rd";
16-
default:
17-
return "th";
18-
}
19-
};
20-
21-
const parts = new Intl.DateTimeFormat("en-US", {
22-
day: "numeric",
23-
month: "long",
24-
year: "numeric",
25-
}).formatToParts(date);
26-
27-
return parts
28-
.map((part) => {
29-
if (part.type === "day") {
30-
return `${part.value}${nth(parseInt(part.value))}`;
31-
}
32-
return part.value;
33-
})
34-
.join("");
35-
};
366
---
377

388
<Layout title={frontmatter.title} description={frontmatter.description}>
@@ -42,7 +12,7 @@ const formatDate = (date: Date): string => {
4212
<h1 class="leading-tight font-bold text-3xl text-slate-200">
4313
{frontmatter.title}
4414
</h1>
45-
<p class="pt-2 pb-8">{formatDate(frontmatter.pubDate)}</p>
15+
<DateTime pubDate={frontmatter.pubDate} />
4616
<slot />
4717
<p class="pt-8 font-medium text-slate-200">
4818
Written by {frontmatter.author}

src/pages/blog.astro

+2-7
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
---
22
import { getCollection } from "astro:content";
33
import Layout from "../layouts/Layout.astro";
4+
import BlogPost from "../components/BlogPost.astro";
45
56
const metadata = {
67
title: "The Lucas Machado Blog",
@@ -23,13 +24,7 @@ const postCollection = await getCollection("posts");
2324
Posts
2425
</h2>
2526
<ul>
26-
{
27-
postCollection.map((post) => (
28-
<li>
29-
<a href={`/posts/${post.slug}`}>{post.data.title}</a>
30-
</li>
31-
))
32-
}
27+
{postCollection.map((post) => <BlogPost post={post} />)}
3328
</ul>
3429
</div>
3530
</div>

src/pages/newFile.tsx

Whitespace-only changes.

0 commit comments

Comments
 (0)