diff --git a/src/components/PostList.astro b/src/components/PostList.astro index 63431ff..70d82a3 100644 --- a/src/components/PostList.astro +++ b/src/components/PostList.astro @@ -1,23 +1,93 @@ --- const { posts, tag } = Astro.props; ---- -{tag &&

Tagged: {tag}

} -{posts.map((post) => ( -
-

- {post.title} -

-
- {new Date(post.date).toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' })} - {post.tags.map((t) => ( - {t} - ))} -
-

{post.rawExcerpt}

+// Extract first cover image directly from the raw markdown body. +// Cheap regex — avoids rendering the full HTML for each card. +function firstImage(body) { + const m = body && body.match(/!\[[^\]]*\]\((\/images\/[^)]+)\)/); + return m ? m[1] : null; +} + +const enriched = posts.map((p) => ({ + ...p, + cover: firstImage(p.body), +})); +const hero = enriched[0]; +const rest = enriched.slice(1); + +const fmt = (d) => new Date(d).toLocaleDateString('en-US', + { year: 'numeric', month: 'long', day: 'numeric' }); +--- +{tag && ( +

+ Tagged: {tag} +

+)} + +{enriched.length > 0 && !tag && hero && ( +
+ + {hero.cover && ( +
+ +
+ )} +
+
Top story
+

{hero.title}

+

{hero.rawExcerpt}

+
+ {fmt(hero.date)} + {hero.tags.slice(0, 4).map((t) => ( + {t} + ))} +
+
+ +
+)} + +{(tag ? enriched : rest).map((post, i) => ( +
+ + {post.cover && ( +
+ +
+ )} +
+

{post.title}

+

{post.rawExcerpt}

+
+ + {post.tags.slice(0, 3).map((t) => ( + {t} + ))} +
+
+
))} -{posts.length === 0 && ( -

No posts yet.

+{enriched.length === 0 && ( +

No posts yet.

)} + + diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index e073901..d84b74f 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -46,21 +46,25 @@ const year = new Date().getFullYear(); - +