This commit is contained in:
parent
3ced32a4d0
commit
81c890471c
4 changed files with 250 additions and 89 deletions
|
|
@ -2,7 +2,6 @@
|
|||
import { getCollection, render } from 'astro:content';
|
||||
import DefaultLayout from '@/layouts/DefaultLayout.astro';
|
||||
import { BlogPost } from '@/components/sections/blog-post';
|
||||
import NewsletterSignup from '@/components/sections/newsletter-signup';
|
||||
import { ACTIVE_BLOG_SITE } from '@/blog-sites.js';
|
||||
import { SITE_TITLE } from '@/consts';
|
||||
|
||||
|
|
@ -19,11 +18,9 @@ const { Content } = await render(post);
|
|||
---
|
||||
|
||||
<DefaultLayout title={`${post.data.title} | ${SITE_TITLE}`} description={post.data.description}>
|
||||
<div class="py-16 md:py-28 lg:py-32">
|
||||
<BlogPost post={post} client:only="react">
|
||||
<div class="py-10 md:py-16 lg:py-20">
|
||||
<BlogPost post={post}>
|
||||
<Content />
|
||||
</BlogPost>
|
||||
</div>
|
||||
|
||||
<NewsletterSignup client:load />
|
||||
</DefaultLayout>
|
||||
|
|
|
|||
|
|
@ -3,21 +3,116 @@ import { getCollection } from 'astro:content';
|
|||
import DefaultLayout from '@/layouts/DefaultLayout.astro';
|
||||
import { SITE_TITLE, SITE_DESCRIPTION } from '@/consts';
|
||||
import { ACTIVE_BLOG_SITE } from '@/blog-sites.js';
|
||||
import { BlogPosts } from '@/components/sections/blog-posts';
|
||||
|
||||
const posts = (await getCollection(ACTIVE_BLOG_SITE.key)).sort(
|
||||
(a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf(),
|
||||
);
|
||||
|
||||
const formatDate = new Intl.DateTimeFormat('en', {
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
year: 'numeric',
|
||||
timeZone: 'UTC',
|
||||
});
|
||||
|
||||
const poems = posts.map((post) => ({
|
||||
title: post.data.title,
|
||||
description: post.data.description,
|
||||
href: `/${post.id.replace(/\/index$/, '')}/`,
|
||||
dateLabel: formatDate.format(post.data.pubDate),
|
||||
searchText: `${post.data.title} ${post.data.description}`.toLowerCase(),
|
||||
}));
|
||||
|
||||
const recentPoems = poems.slice(0, 3);
|
||||
---
|
||||
|
||||
<DefaultLayout title={SITE_TITLE} description={SITE_DESCRIPTION}>
|
||||
<div class="py-12 md:py-20 lg:py-24">
|
||||
<div class="container max-w-5xl">
|
||||
<div class="mb-10">
|
||||
<h1 class="blog-page-title mb-3">{ACTIVE_BLOG_SITE.title}</h1>
|
||||
<p class="text-lg text-muted-foreground">{ACTIVE_BLOG_SITE.description}</p>
|
||||
<section class="poetry-home">
|
||||
<div class="poetry-home-panel">
|
||||
<div class="poetry-home-chrome" aria-hidden="true">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</div>
|
||||
|
||||
<header class="poetry-home-header">
|
||||
<div>
|
||||
<p class="poetry-home-kicker">{ACTIVE_BLOG_SITE.description}</p>
|
||||
<h1>{ACTIVE_BLOG_SITE.title}</h1>
|
||||
</div>
|
||||
|
||||
<form class="poetry-search" data-poem-search-form role="search">
|
||||
<label class="sr-only" for="poem-search">Search poems</label>
|
||||
<input
|
||||
id="poem-search"
|
||||
data-poem-search-input
|
||||
type="search"
|
||||
autocomplete="off"
|
||||
placeholder="Search poems"
|
||||
/>
|
||||
<button type="submit" aria-label="Search poems">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true">
|
||||
<circle cx="11" cy="11" r="6.5"></circle>
|
||||
<path d="m16 16 4 4"></path>
|
||||
</svg>
|
||||
</button>
|
||||
</form>
|
||||
</header>
|
||||
|
||||
<div class="poetry-home-grid">
|
||||
<section class="poetry-recent" aria-labelledby="recent-poems">
|
||||
<h2 id="recent-poems">Recent</h2>
|
||||
<ol>
|
||||
{recentPoems.map((poem) => (
|
||||
<li>
|
||||
<time>{poem.dateLabel}</time>
|
||||
<a href={poem.href}>{poem.title}</a>
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
</section>
|
||||
|
||||
<section class="poetry-archive" aria-labelledby="all-poems">
|
||||
<h2 id="all-poems">All Poems</h2>
|
||||
<ol data-poem-list>
|
||||
{poems.map((poem) => (
|
||||
<li data-poem-row data-search={poem.searchText}>
|
||||
<a href={poem.href}>{poem.title}</a>
|
||||
<time>{poem.dateLabel}</time>
|
||||
</li>
|
||||
))}
|
||||
</ol>
|
||||
<p class="poetry-empty" data-poem-empty hidden>No poems found.</p>
|
||||
</section>
|
||||
</div>
|
||||
<BlogPosts posts={posts} client:only="react" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<script is:inline>
|
||||
const form = document.querySelector("[data-poem-search-form]");
|
||||
const input = document.querySelector("[data-poem-search-input]");
|
||||
const rows = [...document.querySelectorAll("[data-poem-row]")];
|
||||
const empty = document.querySelector("[data-poem-empty]");
|
||||
|
||||
function filterPoems() {
|
||||
const query = input.value.trim().toLowerCase();
|
||||
let visibleCount = 0;
|
||||
|
||||
for (const row of rows) {
|
||||
const isVisible = !query || row.dataset.search.includes(query);
|
||||
row.hidden = !isVisible;
|
||||
if (isVisible) visibleCount += 1;
|
||||
}
|
||||
|
||||
empty.hidden = visibleCount !== 0;
|
||||
}
|
||||
|
||||
form.addEventListener("submit", (event) => {
|
||||
event.preventDefault();
|
||||
input.focus();
|
||||
filterPoems();
|
||||
});
|
||||
|
||||
input.addEventListener("input", filterPoems);
|
||||
</script>
|
||||
</DefaultLayout>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue