feat(admin): collapse create-feed form into accordion

Wrap the "Create New Feed" form in a native <details> accordion, collapsed
by default and auto-opened when no feeds exist. After creating a feed,
redirect to the "Your Feeds" anchor so the new feed is immediately visible.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Julien Herr
2026-05-23 21:41:25 +02:00
parent 5fc91a0be4
commit 3368b0d1d2
4 changed files with 44 additions and 6 deletions
+1 -1
View File
@@ -148,7 +148,7 @@ describe("Admin Routes", () => {
});
expect(res.status).toBe(302); // Redirects back to dashboard
expect(res.headers.get("Location")).toBe("/admin?view=list");
expect(res.headers.get("Location")).toBe("/admin?view=list#your-feeds");
// Verify feed was created in KV
const feedList = (await mockEnv.EMAIL_STORAGE.get(
+9 -4
View File
@@ -383,8 +383,13 @@ app.get("/", async (c) => {
</div>
</div>
<div class="card">
<h2>Create New Feed</h2>
<details
class="card create-feed-card"
open={feedsWithConfig.length === 0}
>
<summary class="create-feed-summary">
<h2>Create New Feed</h2>
</summary>
<form action="/admin/feeds/create" method="post">
<div class="form-group">
<label for="title">Feed Title</label>
@@ -458,7 +463,7 @@ app.get("/", async (c) => {
Create Feed
</button>
</form>
</div>
</details>
{message === "bulkDeleted" && (
<div class="card">
@@ -471,7 +476,7 @@ app.get("/", async (c) => {
</div>
)}
<div class="toolbar">
<div class="toolbar" id="your-feeds">
<div class="toolbar-group">
<h2 style="margin: 0;">Your Feeds</h2>
<span class="pill" id="feed-total-count">
+1 -1
View File
@@ -212,7 +212,7 @@ feedsRouter.post("/create", async (c) => {
});
}
return c.redirect(`/admin?view=${view}`);
return c.redirect(`/admin?view=${view}#your-feeds`);
} catch (error) {
logger.error("Error creating feed", { error: String(error) });
if (c.req.header("Content-Type")?.includes("application/json")) {
+33
View File
@@ -13,6 +13,39 @@
margin-top: 0;
}
/* Create-feed accordion */
.create-feed-card > summary {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--spacing-md);
cursor: pointer;
list-style: none;
}
.create-feed-card > summary::-webkit-details-marker {
display: none;
}
.create-feed-summary h2 {
margin: 0;
}
.create-feed-card > summary::after {
content: "+";
color: var(--color-primary);
font-size: var(--font-size-xl);
line-height: 1;
}
.create-feed-card[open] > summary::after {
content: "\2212";
}
.create-feed-card[open] > summary {
margin-bottom: var(--spacing-md);
}
/* Feed header styling */
.feed-header {
margin-bottom: var(--spacing-md);